function Validator() {
	
	this.NOT_BLANK = 1;              
	this.NUMBER = 2;		// Integer
	this.NUMBERS = 2;		// Integer
	this.FLOAT = 3;         
	this.MAX_LENGTH = 4; 
	this.SPECIAL_CHARACTERS = 5;   // characters that create displaying problems, such as \\, <, >, "  
	this.APOSTROPHE = 6;    		// ' or "
	this.DATE_ENTERED = 7;    		// typing in the date, instead of using the widget

	this.VALUE_MATCHES = 10; 
	this.VALUE_DOESNT_MATCH = 11;  
	
	this.VALUE_SELECTED = 20;
	this.RADIO_SELECTED = 21;
	this.CHECKBOX_ARR_CHECKED = 22;

	this.EMAIL = 30;      
	this.EMAIL_MULTIPLE = 31;
	this.USERNAME = 32;            
	this.PASSWORD = 33;            
	this.VALID_FILE_TYPE = 34;    
	
    this.arrValidations = new Array();
    
    this.messages = new Array();
    this.messages[this.NOT_BLANK] = "Please enter a value for \"{0}\"";
    this.messages[this.NUMBER] = "Please enter a valid number (ex. \"10\" or \"123\") for \"{0}\"";
    this.messages[this.FLOAT] = "Please enter a valid number (ex. \"10\" or \"1.23\") for \"{0}\"";
    this.messages[this.MAX_LENGTH] = "Please make sure \"{0}\" is a maximum of {1} characters, you currently have {2}";
    this.messages[this.SPECIAL_CHARACTERS] = "Please check that you have not entered any of the following characters for \"{0}\": \\, \", &gt;, &lt;";
    this.messages[this.APOSTROPHE] = "Please check that you have not entered any of the following characters for \"{0}\": \'";
    this.messages[this.DATE_ENTERED] = "Please enter a valid date in the format 'mm/dd/yyyy' for \"{0}\"";   

    this.messages[this.VALUE_MATCHES] = "Please confirm that you have entered the same value for \"{0}\" and \"{1}\".";
    this.messages[this.VALUE_DOESNT_MATCH] = "Please check that you have entered a different {0}.";

    this.messages[this.RADIO_SELECTED] = "Please select an option for \"{0}\"";
    this.messages[this.VALUE_SELECTED] = "Please select a value for \"{0}\"";
    this.messages[this.CHECKBOX_ARR_CHECKED] = "{0}";

    this.messages[this.EMAIL] = "Please enter a valid email address for \"{0}\"";
    this.messages[this.EMAIL_MULTIPLE] = "Please enter all valid email addresses, separated with a ',' for \"{0}\"";
    this.messages[this.USERNAME] = "Please select a {0} with a length of 4 to 15 characters";
    this.messages[this.PASSWORD] = "Please select a {0} with a length of 5 to 15 characters";
    this.messages[this.VALID_FILE_TYPE] = "You must upload a valid file type for \"{0}\".  Allowed file types include: {1}.";

    this.messages['DATE_TIME_FORMAT'] = "Please fill in the time in the following format: hh:mm.  Ex: 12:30";
    this.messages['DATE_REQUIRED'] = "Please enter a complete date for \"{0}\"";   
}

Validator.prototype.validate = function(inputObj,fieldLabel,isRequired,validationType,arg0,arg1,arg2) {
    //alert('start validate, type: ' + validationType);
    var isValid = true;

    switch (validationType) {
		
    case Validator.NOT_BLANK:
        var inputValue = inputObj.value;
        if (inputValue.length <= 0 || inputValue.match(/^\s*$/)) {
            inputObj.value = '';
        	this.showMessage(inputObj, validationType, [fieldLabel]);
            return false;
        }
        break;
        
    case Validator.NUMBER:
        var inputValue = inputObj.value;
        if (isRequired || inputValue != '') {
            if (!inputValue.match(/^\d+$/)) {
            	this.showMessage(inputObj, validationType, [fieldLabel]);
                return false;
            }
        }
        break;

    case Validator.FLOAT:
        var inputValue = inputObj.value;
        //alert('input value:' + inputValue + '! required? ' + (isRequired ? 'true' : 'false'));
        if (isRequired || inputValue != '') {
            if (!inputValue.match(/^((\d+(\.\d*)?)|((\d*\.)?\d+))$/)) {
            	this.showMessage(inputObj, validationType, [fieldLabel]);
                return false;
            }
        }
        break;

    case Validator.MAX_LENGTH:
        var inputValue = inputObj.value;
        if (inputValue.length > arg0) {
        	this.showMessage(inputObj, validationType, [fieldLabel]);
            return false;
        }
        break;

    case Validator.SPECIAL_CHARACTERS:
        var inputValue = inputObj.value;

        if (inputValue.indexOf("\\") != -1 ||
            inputValue.indexOf('<') != -1 ||
            inputValue.indexOf('>') != -1 ||
            inputValue.indexOf('"') != -1 ) {
        	this.showMessage(inputObj, validationType, [fieldLabel]);
            return false;
        }
        if (isRequired) {
            return this.validate(inputObj,fieldLabel,isRequired,Validator.NOT_BLANK,arg0,arg1,arg2);
        }
        return true;

    case Validator.APOSTROPHE:
        var inputValue = inputObj.value;

        if (inputValue.indexOf('\'') != -1 ||
            inputValue.indexOf('"') != -1 ) {
        	this.showMessage(inputObj, validationType, [fieldLabel]);
            return false;
        }
        if (isRequired) {
            return this.validate(inputObj,fieldLabel,isRequired,Validator.NOT_BLANK,arg0,arg1,arg2);
        }
        return true;

    case Validator.DATE_ENTERED:
    	if (!isRequired && inputObj.value.trim() == '') {
    		return true;
    	}
    	var retVal = this.isDateValid(inputObj);
    	if (!retVal) {
    		this.showMessage(inputObj, validationType, [fieldLabel]);
    		return false;
    	} else {
    		inputObj.value = retVal;
    	}
        return true;

    case Validator.VALUE_MATCHES:
        var inputValue = inputObj.value;
        var inputValue2 = arg0.value;
        if (inputValue != inputValue2) {
        	this.showMessage(inputObj, validationType, [fieldLabel, arg1]);
            return false;
        }
        break;		
		
    case Validator.VALUE_DOESNT_MATCH:
        var inputValue = inputObj.value.toLowerCase();
        var inputValue2 = arg0.toLowerCase();
        if (inputValue == inputValue2) {
        	this.showMessage(inputObj, validationType, [fieldLabel]);
            return false;
        }
        break;		

    case Validator.VALUE_SELECTED:
        if (isRequired && (inputObj.selectedIndex == -1 || inputObj.options[inputObj.selectedIndex].value == '')) {
        	this.showMessage(inputObj, validationType, [fieldLabel]);
            return false;
        }
        break;
		
    case Validator.RADIO_SELECTED:
        if (isRequired) {
            for (var x=0;x<inputObj.length;x++) {
                if (inputObj[x].checked) {
                    return true;
                }
            }
            // if we're here, nothing was selected
        	this.showMessage(inputObj[0], validationType, [fieldLabel]);
        	//alert(this.buildMessage(validationType, fieldLabel));
            return false;
        }
        break;

    case Validator.CHECKBOX_ARR_CHECKED:
        var checkboxes = new Array();
        if(inputObj.length == undefined)
        {
            checkboxes[0] = inputObj;
        }
        else
        {
            for (var j=0; j<inputObj.length; j++)
            {
              checkboxes[j] = inputObj[j];
            }
        }

        if(arg0 != undefined)
        {
            if(arg0.length == undefined)
            {
                checkboxes[checkboxes.length] = arg0;
            }
            else
            {
                var cbLen = checkboxes.length;
                for (var j=0; j<arg0.length; j++)
                {
                  checkboxes[cbLen+j] = arg0[j];
                }
            }
        }

        if(arg1 != undefined)
        {
            if(arg1.length == undefined)
            {
                checkboxes[checkboxes.length] = arg1;
            }
            else
            {
                var cbLen = checkboxes.length;
                for (var j=0; j<arg1.length; j++)
                {
                  checkboxes[cbLen+j] = arg1[j];
                }
            }
        }

        for (var j=0; j<checkboxes.length; j++)
        {
          //alert(checkboxes[j].name + ' ' + checkboxes[j].value);
          if(checkboxes[j].checked)
          {
            return true;
          }
        }
    	this.showMessage(checkboxes[0], validationType, [fieldLabel]);
        //alert(this.buildMessage(validationType, fieldLabel));
        return false;		

    case Validator.EMAIL:
        var inputValue = inputObj.value;
        if (isRequired || '' != inputValue) {
            if (!inputValue.match(/^[_a-zA-Z0-9][_a-zA-Z0-9\'\w\.-]*@[_a-zA-Z0-9][_a-zA-Z0-9\w\.-]*\.[_a-zA-Z0-9\w\.-]*[_a-zA-Z0-9]$/)) {
                this.showMessage(inputObj, validationType, [fieldLabel]);
                return false;
            }
        }
        break;

    case Validator.EMAIL_MULTIPLE:
        var inputValue = inputObj.value;
        var valueArr = inputValue.split(',');

        for (var x=0; x<valueArr.length; x++) {
            if (!trim(valueArr[x]).match(/^[a-zA-Z0-9][a-zA-Z0-9\'\w\.-]*@[a-zA-Z0-9][a-zA-Z0-9\'\w\.-]*\.[a-zA-Z0-9\'\w\.-]*[a-zA-Z0-9]$/)) {
                this.showMessage(inputObj, validationType, [fieldLabel]);
                return false;
            }
        }
        break;
        
    case Validator.USERNAME:
        var inputValue = inputObj.value;
        if (isRequired || inputValue != '') {
            if (!(inputValue.length>=4 && inputValue.length<=15)) {
            	this.showMessage(inputObj, validationType, [fieldLabel]);
                return false;
            }
            return this.validate(inputObj,fieldLabel,isRequired,Validator.APOSTROPHE,arg0,arg1,arg2);
            return this.validate(inputObj,fieldLabel,isRequired,Validator.SPECIAL_CHARACTERS,arg0,arg1,arg2);
        }
        break;

    case Validator.PASSWORD:
        var inputValue = inputObj.value;
        if (isRequired || inputValue != '') {
            if (!(inputValue.length>=5 && inputValue.length<=15)) {
            	this.showMessage(inputObj, validationType, [fieldLabel]);
                return false;
            }
            return this.validate(inputObj,fieldLabel,isRequired,Validator.SPECIAL_CHARACTERS,arg0,arg1,arg2);
        }
        break;
		
    case Validator.VALID_FILE_TYPE:
        var theIndex = inputObj.value.lastIndexOf('.');
        if (theIndex <= 0 || theIndex == (inputObj.value.length + 1)) {
        	this.showMessage(inputObj, validationType, [fieldLabel]);
            return false;
        }		
        var fileExt = inputObj.value.substring(theIndex+1);
        var validExtensions = arg0.toLowerCase().split(/,[\s]*/);
		alert('fileExt: ' + fileExt + ' valid: ' + validExtensions);
        var isValid = false;
        for (var x=0;x<validExtensions.length;x++) {
            if (fileExt.toLowerCase() == validExtensions[x]) {
                isValid = true;
            }
        }
        if (!isValid) {
            //((fileExt == 'doc') ||
            //  (fileExt == 'txt') ||
            //  (fileExt == 'rtf') ||
            //  (fileExt == 'pdf') ||
            //  (fileExt == 'htm') ||
            //  (fileExt == 'html'))) {
        	this.showMessage(inputObj, validationType, [fieldLabel]);
            return false;
        }
        return true;

    default:
    	alert('Unknown Validation type: ' + validationType);
        return true;

    }
    // default to true
    return true;
}

Validator.prototype.showMessage = function(inputObj, validationType, arrMessageVars) {
	this.focusField(inputObj);	
	alert(this.buildMessage(validationType, arrMessageVars));
}

// any arguments passed in after validationType are substituted
Validator.prototype.buildMessage = function(validationType, arrMessageVars) {
	//alert('arrMessageVars:' + arrMessageVars + ' length: ' + arrMessageVars.length);
    var msgToReturn = Validator.messages[validationType];
    if (arrMessageVars) {
    //alert('msgToReturn: ' + msgToReturn + ' validationType: ' + validationType + ' args: ' + this.buildMessage.arguments.length);
	    for (var x=0; x<arrMessageVars.length; x++) {
	    	msgToReturn = msgToReturn.replace('{'+x+'}',arrMessageVars[x]);
	    }
    }
    return msgToReturn;
}

Validator.prototype.focusField = function(inputObj) {
    inputObj.focus();
}

/**
 * addValidation
 * adds the passed in validation call to the array of validations to perform on form submittal
 * strTestFunc: func to test, if true then perform the validation, otherwise not
 */
Validator.prototype.addValidation = function(strValidationCall,strTestFunc) {
    if (strTestFunc == null) {
    	strTestFunc = 'true';
    }
    var arrValidation = new Array();
    arrValidation[0] = strValidationCall;
    arrValidation[1] = strTestFunc;
    this.arrValidations[this.arrValidations.length] = arrValidation;
}

// iterates the validation array strings returning false at the first occurence of an invalid field
Validator.prototype.isFormValid = function() {
  for(var x=0;x<this.arrValidations.length;x++)
  {
      if (eval(this.arrValidations[x][1])) {
          if(!eval(this.arrValidations[x][0])) {
              return false;
          }
      }
  }
  return true;
}


/**
* checks if a date is entered in some reasonable format
* tries to make the date match the format 'mm/dd/yyyy', returns the formatted date
*/
Validator.prototype.isDateValid = function(objTxtInput) {
	var strDate = objTxtInput.value.trim();
    //alert('validating date: ' + strDate);
    if (!(
    	strDate.match(/^[0-9][0-9]?-[0-9][0-9]?-[0-9]+$/) || 
    	strDate.match(/^[0-9][0-9]?\/[0-9][0-9]?\/[0-9]+$/)
    	)) {
    	//alert('not a valid date');
        return false;
    }
    var delim = (strDate.indexOf('-') > 0 ? '-' : '/');
    var arrDate = strDate.split(delim);
    try {
    //if (arrDate.length == 3) {
    	var month = parseInt(arrDate[0],10);
    	var day = parseInt(arrDate[1],10);
    	var year = parseInt(arrDate[2],10);
    	//alert('year: ' + year + ' arrDate[2]: ' + arrDate[2] + ' parseInt: ' + parseInt('09'));
		return (month < 10 ? '0' : '') + month + (day < 10 ? '/0' : '/') + day + (year < 10 ? '/200' : (year < 100 ? '/20' : '/')) + year;    	
    } catch(err) {
    	return false;
    }
    //alert('good date');
	return true;
}

var Validator = new Validator();

