var formValidator = new FormValidator();
function FormValidator(){
 var self = this;
 this.Validators = new Object();
 this.validate = function(obj){
   var returnVal = true;
   if(typeof(self.Validators[obj.id]) !== 'undefined')
     for(var i = 0; i < self.Validators[obj.id].length; i++){
       if(!self.Validators[obj.id][i].validate(obj))
         return false;
     }
   try{
     returnVal = eval(getValidateFunction(obj.id));
   } catch(e){}
   return returnVal;
 };
 this.addValidator = function(formID,obj) {
   if(typeof(self.Validators[formID]) === 'undefined'){
     self.Validators[formID] = new Array();
   }
   self.Validators[formID][self.Validators[formID].length] = obj;
 };
 function getValidateFunction(id){
   var arr = id.split(':');
   return arr[arr.length - 1] + '_Validate(\'' + id + '\')';
 }
}

function SSNValidator(fieldID, errorMsg, focus, isMultiField) {
  var self = this;
  var REG = "^[0-9]{3}-[0-9]{2}-[0-9]{4}$";
  this.fieldID = fieldID;
  this.errorMsg = errorMsg;
  this.validate = function (obj) {
    var returnValue = true;
    if (isMultiField) {
      if (obj[self.fieldID + "_ssn1"].value.length > 0 || obj[self.fieldID + "_ssn2"].value.length || obj[self.fieldID + "_ssn3"].value.length) {
        var reg = new RegExp(REG);
        var val = obj[self.fieldID + "_ssn1"].value + "-" + obj[self.fieldID + "_ssn2"].value + "-" + obj[self.fieldID + "_ssn3"].value;
        returnValue = val.match(reg);
        if (!returnValue) {
          alert(self.errorMsg);
          if (focus) {
            obj[self.fieldID + "_ssn1"].focus();
          }
        }
      }
    } else {
      if (obj[self.fieldID].value.length > 0) {
        var reg = new RegExp(REG);
        returnValue = obj[self.fieldID].value.match(reg);
        if (!returnValue) {
          window.alert(self.errorMsg);
          if (focus) {
            obj[self.fieldID].focus();
          }
        }
      }
    }
    return returnValue;
  };
}


function DateValidator(fieldID, type, errorMsg, focus){ 
 var self = this;
 var REG = new Array();
 REG[0] = '^[0-1]?[0-9]?[-/\\.][0-3]?[0-9]?[-/\\.][1-9][0-9]{3}$';
REG[1] = '^[A-Z][a-z]{2} [A-Z][a-z]{2} [0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} [A-Z]{3} [1-9][0-9]{3}$';
REG[2] = '^[1-9][0-9]{13}$';
REG[3] = '^[1-9][0-9]{7}$';

 this.fieldID = fieldID;
 this.type = type;
 this.errorMsg = errorMsg;
 this.validate = function(obj){
   var returnValue = true;
   if(obj[self.fieldID].value.length > 0) {
     var reg = new RegExp(REG[self.type]);
     returnValue = obj[self.fieldID].value.match(reg);
     if(!returnValue){
       window.alert(self.errorMsg);
       if(focus){
         obj[self.fieldID].focus();
       }
     }
   }
   return returnValue;
 };
}
DateValidator.SHORT_DATE_FORMAT = 0;
DateValidator.DATE_TIME_FORMAT = 1;
DateValidator.ANSI_DATE_TIME_FORMAT = 2;
DateValidator.ANSI_DATE_FORMAT = 3;


function ZipCodeValidator(fieldID, errorMsg, focus) {
  var self = this;
  var REG = "^[0-9]{5}(-[0-9]{4})?$";
  this.fieldID = fieldID;
  this.errorMsg = errorMsg;
  this.validate = function (obj) {
    var returnValue = true;
    if (obj[self.fieldID].value.length > 0) {
      var reg = new RegExp(REG);
      returnValue = obj[self.fieldID].value.match(reg);
      if (!returnValue) {
        window.alert(self.errorMsg);
        if (focus) {
          obj[self.fieldID].focus();
        }
      }
    }
    return returnValue;
  };
}


function RequiredValidator(fieldID, errorMsg, focus) {
  var self = this;
  var REG = "^[: :]+$";
  this.fieldID = fieldID;
  this.errorMsg = errorMsg;
  this.validate = function (obj) {
    var reg = new RegExp(REG);
    var returnValue = true;
    var selectItems = null;
    var isCB = false;
    if (typeof (obj[self.fieldID].value) == "undefined") {
      selectItems = document.getElementsByName(self.fieldID);
      returnValue = false;
      for (var i = 0; i < selectItems.length; i++) {
        if (selectItems[i].checked) {
          returnValue = true;
        }
      }
    } else {
      if (obj[self.fieldID].tagName == "INPUT" && obj[self.fieldID].type.toLowerCase() == "checkbox") {
        returnValue = obj[self.fieldID].checked;
      } else {
        if(obj[self.fieldID].previousSibling != null 
        && obj[self.fieldID].previousSibling.tagName == "INPUT"
        && obj[self.fieldID].previousSibling.type.toLowerCase() == "checkbox"){
          returnValue = (obj[self.fieldID].value === 'false')? false : true;
          isCB = true;
        } else {
          returnValue = !obj[self.fieldID].value.match(reg) && obj[self.fieldID].value.length > 0;
        }
      }
    }
    if (!returnValue) {
      window.alert(self.errorMsg);
      if (focus && selectItems !== null) {
        selectItems[0].focus();
      } else {
       	if(isCB){
       	  obj[self.fieldID].previousSibling.focus();
       	} else {
       	  obj[self.fieldID].focus();
        }
      }
    }
    return returnValue;
  };
}

function EmailValidator(fieldID, errorMsg, focus) { 
 var self = this;
 var REG = '^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$';
 this.fieldID = fieldID;
 this.errorMsg = errorMsg;
 this.validate = function(obj){
   var returnValue = true;
   if(obj[self.fieldID].value.length > 0) {
     var reg = new RegExp(REG);
     returnValue = obj[self.fieldID].value.match(reg);
     if(!returnValue){
       window.alert(self.errorMsg);
       if(focus){
         obj[self.fieldID].focus();
       }
     }
   }
   return returnValue;
 };
}

function LengthValidator(fieldID, maximum, minimum, errorMsg, focus){ 
 var self = this;
 this.fieldID = fieldID;
 this.errorMsg = errorMsg;
 this.maximum = maximum;
 this.minimum = minimum;
 this.validate = function(obj){
   var returnValue = true;
   if(self.maximum != -1 && obj[self.fieldID].value.length > self.maximum){ 
     returnValue = false;
   }
   if(self.minimum != -1 && obj[self.fieldID].value.length != 0 && obj[self.fieldID].value.length < self.minimum){ 
     returnValue = false;
   }
   if(!returnValue){
     window.alert(self.errorMsg + '\nCurrently ' + obj[self.fieldID].value.length + ' characters have been used.');
     if(focus){
     	obj[self.fieldID].focus();
     }
   }
   return returnValue;
 };
}

function PhoneNumberValidator(fieldID, type, errorMsg, focus, isMultiField){ 
 var self = this;
 var REG = new Array();
 REG[0] = '^((\\+\\d(\\d)?)?(\\(\\d\\{3}?)))? \\d{3}?-\\d{4}$';
REG[1] = '^\\(?\\d{3}\\)?(\\s|-)\\d{3}-\\d{4}$';

 this.fieldID = fieldID;
 this.type = type;
 this.errorMsg = errorMsg;
 this.validate = function(obj){
   var returnValue = true;
   if(isMultiField){
    if(obj[self.fieldID + '_pn1'].value.length > 0 || obj[self.fieldID + '_pn2'].value.length > 0 || obj[self.fieldID + '_pn3'].value.length > 0) {
      var reg = new RegExp(REG[self.type]);
      var val = obj[self.fieldID + '_pn1'].value + '-' + obj[self.fieldID + '_pn2'].value + '-' + obj[self.fieldID + '_pn3'].value
      returnValue = val.match(reg);
      if(!returnValue){
        window.alert(self.errorMsg);
        if(focus){
          obj[self.fieldID + '_pn1'].focus();
        }
      }
    }
   }else{
    if(obj[self.fieldID].value.length > 0) {
      var reg = new RegExp(REG[self.type]);
      returnValue = obj[self.fieldID].value.match(reg);
      if(!returnValue){
        window.alert(self.errorMsg);
        if(focus){
          obj[self.fieldID].focus();
        }
      }
    }
   }
   return returnValue;
 };
}
PhoneNumberValidator.INTERNATIONAL = 0;
PhoneNumberValidator.US = 1;


function RegexValidator(fieldID,regex,errorMsg, focus) { 
 var self = this;
 this.fieldID = fieldID;
 this.regex = regex;
 this.errorMsg = errorMsg;
 this.validate = function(obj){
   var reg = new RegExp(regex);
   var returnValue = (obj[self.fieldID].value != "")?obj[self.fieldID].value.match(reg):true;
   if(!returnValue){
     window.alert(self.errorMsg);
     if(focus){
       obj[self.fieldID].focus();
     }
   }
   return returnValue;
 };
}

function ConditionalRequiredValidator(fieldID, cond, errorMsg, focus, operator) { 
  var self = this;
  var REG = '^[: :]+$';
  this.fieldID = fieldID;
  this.errorMsg = errorMsg;
  this.cond = cond;
  this.operator = operator;
  this.validate = function(obj){
    var reg = new RegExp(REG);
    var retVal = true;
    var selectItems = null;
  	var allReqMet = ("OR" == self.operator || "XOR" == self.operator)?false:true;
    for(var i=0; i < cond.requirements.length; i++){
    	var req = cond.requirements[i];
		var reqMet = req.inverse;
    	var isRB = typeof(obj[req.id].value) == 'undefined';
    	var isCB = obj[req.id].type == 'checkbox';
		var rbs = (isRB)? document.getElementsByName(req.id): null;
		for(var j=0; j < req.value.length; j++){
			var val = req.value[j];
			if(isCB){
				reqMet = obj[req.id].checked != req.inverse;
			} else if(isRB){
				for(var k=0; k < rbs.length; k++){
					var rb = rbs[k];
					if(rb.checked && rb.value == val){
						reqMet = !req.inverse;
						break;
					}
				}	
				if(reqMet != req.inverse){
					break;
				}				
			} else {
				if(obj[req.id].value == val ){
  					reqMet = !req.inverse;
  					break;
  				}
			}
		}
		if("OR" === self.operator){
			allReqMet = allReqMet || reqMet;
		}else if("XOR" === self.operator){
			allReqMet = allReqMet != reqMet;
		}else if("XNOR" === self.operator){
			allReqMet = allReqMet == reqMet;
		}else {
			allReqMet = allReqMet && reqMet;
		}
	}
  	if(allReqMet) {
  		retVal = false;
  		var inputItems = null;
     	if(typeof(obj[self.fieldID].value) == 'undefined' || obj[self.fieldID].type == 'checkbox' ){
       		inputItems = document.getElementsByName(self.fieldID);
	       	for(var i=0; i< inputItems.length; i++) {
	         	if(inputItems[i].checked){
	           		retVal = true;
                }
	       	}
     	} else {
     		retVal = !obj[self.fieldID].value.match(reg) && obj[self.fieldID].value.length > 0;
     	}
     	if(!retVal){
       		window.alert(self.errorMsg);
       		if(focus && inputItems !== null){
         		inputItems[0].focus();
       		}else if(focus){
        		obj[self.fieldID].focus();
            }
     	}
   	}
    return retVal;    
  };
}

function NumericValidator(fieldID, type, errorMsg, focus){ 
 var self = this;
 var REG = new Array();
 REG[0] = '^[0-9a-fA-F]+[\\.]{0,1}[0-9a-fA-F]+$';
REG[1] = '^[0-8]+[\\.]{0,1}[0-8]+$';
REG[2] = '^[0-9]+$';
REG[3] = '^\\${0,1}((0||[1-9][0-9]*)||([1-9][0-9]{0,2}(,[0-9]{3})*))(\\.[0-9]{1,2}){0,1}$';
REG[4] = '^((100)|[0-9]{0,1}[0-9]{1,1})$';
REG[5] = '^[0-9]+\\.[0-9]+$';
REG[6] = '^[0-9]+[\\.]{0,1}[0-9]+$';
REG[7] = '^[0-1]+[\\.]{0,1}[0-1]+$';

 this.fieldID = fieldID;
 this.type = type;
 this.errorMsg = errorMsg;
 this.validate = function(obj){
   var returnValue = true;
   if(obj[self.fieldID].value.length > 0) {
     var reg = new RegExp(REG[self.type]);
     returnValue = obj[self.fieldID].value.match(reg);
     if(!returnValue){
       window.alert(self.errorMsg);
       if(focus){
         obj[self.fieldID].focus();
       }
     }
   }
   return returnValue;
 };
}
NumericValidator.HEXADECIMAL = 0;
NumericValidator.OCTAL = 1;
NumericValidator.INTEGER = 2;
NumericValidator.CURRENCY = 3;
NumericValidator.PERCENTAGE = 4;
NumericValidator.DECIMAL = 5;
NumericValidator.NUMBER = 6;
NumericValidator.BINARY = 7;


