function Validator(form){
  this.form   = this._pickForm(form);
  this.errors = {};
  
  this.REGEX = {
       DIGIT          :   '^\d*$',
       WORD           :   '^\\w[\\w\\s]*$',
       NON_WORD       :   '^[^\\w\\s]*$', 
       LATIN          :   '^[a-zA-Z]*$',
       LATIN_EXTENDED :   '^[_a-zA-Z0-9]*$',
       LOGIN          :   '^[a-zA-Z0-9_]([a-zA-Z0-9_\\-\\.]*[a-zA-Z0-9_\\-])?$',
       PHONE          :   '^(\\+)?(\\([\\d\\s\\-]+\\))?[\\d\\s\\-]+$',
       EMAIL          :   '^\\w+([\\.\\w_\\-]+)*\\w@\\w((\\.\\w_\\-)*\\w+)*\\.\\w{2,3}$'        
   };
}

Validator.prototype ={

 validateLength : function(obj,min,max){
      var value = this._pickObject(obj);
      
      value = this._trimWhitespaces(value);
      
      if(value==''){
         return this._fixError(obj,'EMPTY');
      }
      else if(value.length<min){
         return this._fixError(obj,'LACK_LENGTH');
      }
        
      if(max&&value.length>max){
          return this._fixError(obj,'EXCEED_LENGTH');
      } 
     return true;      
  },



 validateString: function(obj,regex,min,max){
 
      if(!this.validateLength(obj,min,max))
          return false;
         
      var value = this._pickObject(obj); 
      value = this._trimWhitespaces(value);
       
      var regex = this.REGEX[regex]?this.REGEX[regex]:regex; 
      var re = new RegExp(regex); 
       
      if(!re.test(value))
          return this._fixError(obj,'INVALID_SYMBOLS');
  
      return true; 
   },



 validateNumeric: function(obj,min,max){

    var value = this._pickObject(obj); 
    value = this._trimWhitespaces(value);
    
    if(!this.validateString(field,'DIGIT',0))
       return false;
      
    if(value < min)
       return  this._fixError(obj,'SMALL_VALUE');
 
    if(max&&value>max)
       return this._fixError(obj,'BIG_VALUE');
    
     return true;  
   },


 
 validateDate: function(obj,minYear,maxYear){

      day   = this.form.elements[obj.forms[0]].value; 
      month = this.form.elements[obj.forms[1]].value; 
      year  = this.form.elements[obj.forms[2]].value; alert(this._daysInMonth(month,year));
      
      var re1 = new RegExp('^[0-9]{1,2}$');
      var re2 = new RegExp('^[0-9]{4}$');
      
      if(!(re1.test(day)&&re1.test(day)&&re2.test(year))
         ||!(day>0&&day<32)||!(month>0&&month<13)
         ||(day>this._daysInMonth(month,year))
         ||(minYear&&year<minYear)||(maxYear&&year<maxYear)
       ){
           return  this._fixError(obj,'INVALID_VALUE');    
        } 
     return true;    
  },
 
 
  compareValues: function(obj1,obj2){
      if(this._pickObject(obj1)!= this._pickObject(obj2))
         return this._fixError(obj1,'DO_NOT_MATCH');
      return true;     
   },
  
  getErrors: function(){
     return this.errors;
  },
   

 _trimWhitespaces: function(str){
    str = str.replace(/^\s+/,'');
    str = str.replace(/\s+$/,'');
    str = str.replace(/\s+/,' ');
    return str;
 }, 

 _pickForm:  function(formid){
      if(typeof formid == 'string')
         var f = (document.getElementById(formid)|| document.forms[formid]);
      else if(typeof formid == 'object')  
         var f = formid;
      return f; 
  },


 _pickObject:  function(obj){
      if(typeof obj == 'object')
        {  
          if(obj.form)
             return this.form.elements[obj.form].value;
          else if(obj.string)
             return obj.string;
        }
      else
        return this.form.elements[obj].value;  
   },


 _fixError: function(obj,errno){
      var key ='';
      if(typeof obj == 'object')
         {  
           if(obj.prompt)
               key = obj.prompt;          
           else if(obj.form)
               key = obj.form;
        }
      else
         key = obj; 
         
     this.errors[key] = errno;
     return false;
  },
   
   
 _daysInMonth: function(month,year) {
     if(month==4||month==6||month==9||month==11)
       return 30;
     else if(month==2)
       return year%4==0?29:28;
     else return 31;      
  }
    
}