//***********************************************************************************************
//*author:      Fred Larsen                                                                     *
//*         <fred@bitwyze.com>                                                                  *
//*when:    7/27/00                                                                             *
//*name:    mask.js                                                                             *
//*description:                                                                                 *
//*   Library to easly check forms for valid user input.  The design is modular enough          *
//*   for the addition of custom class to be added.  One of these days when I have time         *
//*   I might add more detailed insturctions on its use.                                        *
//*functions:                                                                                   *
//*   createItem(func,theForm,field,err,required)                                               *
//*       creates a new object of type func and adds it to the global validArray of objects     *
//*   checkAll(form)                                                                            *
//*       checks all of the objects for the form arguemnet                                      *
//*   bomb()                                                                                    *
//*       default member function for handling user errors                                      *
//*   trim(field)                                                                               *
//*       no built in javascript time function so I rolled my own.                              *
//*   trim_all(field)                                                                           *
//*       kills ALL of the spaces in field "field"                                              *
//***********************************************************************************************
//global vars
validArray = new Array();

function checkAll(whichForm) {
  cnt = validArray[whichForm].length;
	for(ii=0; ii < cnt; ii++) {		
    obj = validArray[whichForm][ii];
    if(!obj.check())
      return false;
	}
	return true;
}

function bomb() {
  if (arguments.length)
    alert(this.err + '\n' + arguments[0]);
  else
    alert(this.err);
    
  this.field.focus();
  this.field.select();
  return false;
}

function trim(field) {
  trimStr = field.value;
  var temp = "";
  var re = /^\s+/;
  var re2 = /\s+$/;
  splitString = trimStr.split(re);
  temp = splitString[0];
  splitString = temp.split(re2);
  temp = splitString[0];
  field.value = temp;
  return true;
}

function trim_all(field) {
  splitstring = trimStr.split(" ");
  for(i = 0; i < splitstring.length; i++)
      temp += splitstring[i];
  field.value = temp;
  return true;
}

function Mask(field,err,required,mask) {
  //constructor for the mask object
  //arguments are 
  //				field     = form field to check
  //				err       = error message
  //				required  = (default = 0 or not required) whether it is required or not   
  //        mask      = the input mask
  this.field = field;       // object form item for ID
  this.err   = err;         // english field name
  this.req   = required;    // check required or not
  this.mask  = mask;        // objects mask  
  this.check = checkMask;   // function that checks the mask
  this.bomb  = bomb;        // function to call when dieing
  return true;
}

function Range(field,err,required,type,atLeast,atMost) {
  //constructor for the Range object
  //arguments are 
  //				field   = form field to check
  //				err     = error message 
  //				required= (default = 0 or not required) whether it is required or not 
  //        type    = datatype of the field
  //				atLeast = smallest value or length
  //				atMost  = largest value or length
  this.field = field        // form object to be checked
  this.err   = err;         // error message
  this.req   = required;    // required or not  
  this.type     = type;     // objects type
  this.valFrom = atLeast;   // least value or length
  this.valTo = atMost;      // greatest value or length
  this.check = checkRange;  // function that checks the item
  this.bomb  = bomb;        // function to call when dieing
  return true;
}

function Email(field,err,required) { 
  //constructor for the mask object
  //arguments are 
  //				field   = form field to check
  //				err     = error message
  //				required= (default = 0 or not required) whether it is required or not   
  this.field = field        // form object to be checked
  this.err   = err;         // english label for the field  
  this.req   = required;    // required or not  
  this.check = checkEmail;  // function that checks the mask
  this.bomb  = bomb;        // function to call when dieing
  return true;
}

function Twins(field,field2,junk,err) {
  //constructor for the mask object
  //arguments are 
  //				field   = form field to check
  //				field2  = form field2 to check
  //        junk    = junk that is passed buy the createItem function
  //				err     = error message to spit out if match fials
  this.field  = field;
  this.field2 = field2;
  this.err    = err;
  this.check  = checkTwins;
  return true;
}

function Chckbox(field,err,required) {
  this.field  = field;
  this.err    = err;
  this.req    = required
  this.check  = checkChckbox;
  return true;
}

function checkChckbox() {
  if (this.field.length) {
    var cnt = this.field.length;
    for (i=0; i < cnt; i++) {
      if (this.field[i].checked)
        return true;
    }
  } else {
    if (this.field.checked) return true;
  }  

  alert(this.err);
  return false;
}

function checkEmail() {
  trim(this.field);
  emailStr = this.field.value;
  /* used to check if entered e-mail fits user@domain format, also 
     used to separate the username from the domain. */
  var emailPat=/^(.+)@(.+)$/;
  /* pattern for matching all special characters. including ( ) < > @ , ; : \ " . [ ]    */
  var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]";
  /* range of characters not allowed in a  username or domainname.*/
  var validChars="\[^\\s" + specialChars + "\]";
  /* The following pattern applies if the "user" is a quoted string (in
     which case, there are no rules about which characters are allowed
     and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
     is a legal e-mail address. */
  var quotedUser="(\"[^\"]*\")";
  /* pattern applies for domains that are IP addresses,
     rather than symbolic names. NOTE: The square brackets are required. */
  var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
  /* represents an atom (basically a series of non-special characters.) */
  var atom=validChars + '+';
  /* represents one word in the typical username.*/
  var word="(" + atom + "|" + quotedUser + ")";
  // The following pattern describes the structure of the user
  var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
  /* describes structure of a normal symbolic domain */
  var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
  
  /* Begin with the coarse pattern to simply break up user@domain into
     different pieces that are easy to analyze. */
  var matchArray=emailStr.match(emailPat)
  if (matchArray==null) 
    return this.bomb(); /* Too many/few @'s */    

  var user=matchArray[1];
  var domain=matchArray[2];
  
  // See if "user" is valid 
  if (user.match(userPat)==null) // user is not valid
    return this.bomb('User does not seem to be valid.');
  
  /* if the e-mail address is at an IP address (as opposed to a symbolic
     host name) make sure the IP address is valid. */
  var IPArray=domain.match(ipDomainPat)
  if (IPArray != null) {
      // this is an IP address
  	  for (var i=1;i<=4;i++) {
  	    if (IPArray[i]>255) {
  	      return this.bomb('IP address does not seem to be valid.');
  	    }
      }
      return true
  }
  
  // Domain is symbolic name
  var domainArray=domain.match(domainPat)
  if (domainArray==null) 
    return this.bomb('Domain does not seem to be valid.');
  
  /* domain name seems valid, but now make sure that it ends in a
     three-letter word (like com, edu, gov) or a two-letter word,
     representing country (uk, nl), and that there's a hostname preceding 
     the domain or country. */
  /* Now we need to break up the domain to get a count of how many atoms
     it consists of. */
  var atomPat=new RegExp(atom,"g")
  var domArr=domain.match(atomPat)
  var len=domArr.length
  if (domArr[domArr.length-1].length < 2 || domArr[domArr.length-1].length > 3)      // must end in a 2|3 letter word.
    return this.bomb('Host name does not seem to be valid.');
  
  // Make sure there's a host name preceding the domain.
  if (len<2)
    return this.bomb('Host name does not seem to be valid.');
  
  return true;
}

function checkRange(){
  var ok = 0;
	if(this.req ==1 || this.field.value.length > 0) {
	trim(this.field);
    if(!this.field) {
			return this.bomb('field is no good'); //this.field,'The ' + this.label + ' field must be between ' + this.valFrom + ' and ' + this.valTo + ' charters in length');
		} else {	
			if(this.type == 'char') {
				var bla = 0;
				bla = this.field.value.length;
				if(!(bla >= this.valFrom && bla <= this.valTo)) {
    			return this.bomb();
        }
			}
			if(this.type == 'int') {			
        //this.field.value = this.field.value - 0;
				if(isNaN(this.field.value)) {
				  return this.bomb();
        }
				var foo = 0;
				foo = this.field.value - 0;
				if(!(foo >= this.valFrom && foo <= this.valTo)) {
				  return this.bomb();
				}											
			}
		}  		
	}
  return true;
}

function checkMask() {
//  window.alert('You have to enter data into the ' + bar.label + ' field in this format ' + bar.mask);
//  bar.val.focus();
//  bar.val.select();
//  return false;
  ok = 0;
	if(this.req ==1 || this.field.value.length > 0) {
    if(this.mask.length != this.field.value.length) {
      ok = -1;
    } else {
    	for (i = 0;  i < this.mask.length;  i++) {
    	  if (this.mask.charAt(i) == '#') {
    			if(isNaN(this.field.value.charAt(i)))
    			  ok = -1;
    		} else if (this.mask.charAt(i) == 'A') {
    			if(isNaN(this.field.value.charAt(i)) == 0)
    			 	ok = -1;
    		} else {
    			if(this.mask.charAt(i) != this.field.value.charAt(i))
    				ok = -1;
        }
      }
    }  
  }
  if ( ok == -1 ) {
    return this.bomb('The letter "A" representing any letter from a-z and\n the # representing any number 0-9.');
  } else {
    return true;	
  }
}

function checkTwins() {
  if ( this.field.value != this.field2.value ) {
    alert(this.err);
    this.field.value = '';
    this.field2.value = '';
    this.field.focus(); 
    return false;
  }
  return true;
}

function createItem(func,theForm,field,err,required) { 
// This function is basically just to add objects to the validArray
  var args = "";
  //---------Check the passed in values befor you use them----------
  if (!eval('document.'+ theForm)){
    window.alert('The form name ('+theForm+') that you entered is invalid\n Please check your validation objects and try again.');
		return false;
	}
	if( !eval('document.' + theForm + '.elements["' + field + '"]') ) {
		window.alert('The field name ('+field+') that you entered is invalid.\n Please check your mask objects and try again.');
		return false;
	}
  //done checking  
  if (!validArray[theForm]) validArray[theForm] = new Array();
  cn = validArray[theForm].length;    

  for (i=3; i<arguments.length; i++) {  //packing up the variable number of args
    args += '\'' + arguments[i] + '\',';
  }
  args += 0; 

//  trim(eval('document.' + theForm + '.elements["' + field + '"]'));

  if (func == 'Twins') {
    validArray[theForm][cn] = eval('new Twins (document.' + theForm + '.elements["' + field + '"],document.' + theForm + '.elements["' + err + '"],' + args + ')');
  } else {
    validArray[theForm][cn] = eval('new ' + func + '(document.' + theForm + '.elements["' + field + '"],' + args + ')');
  }
//  validArray[theForm][cn] = eval('new ' + func + '(' + args + ')');
}
