/*----------------------------------------------------
/   SECURE SERVER JAVASCRIPT OBJECTS
/-----------------------------------------------------
/   CREATED: 8/9/02
/   LAST EDITED: 3/7/03
/-----------------------------------------------------*/
/*---------------------------------------------------------
/	FORM VALIDATOR OBJECT
/	OBJECT USED TO STORE FORM INFORMATION AND VALIDATION
/	METHODS FOR VALIDATION OF HTTPS FORMS
/--------------------------------------------------------*/
function FormValidator(form,id) {
	if (!form) {
		alert("A form identifier is required to create a FormValidator object. Specifiy either a form object or name string.");
		return false;
	} else if (!id) {
		alert("A Form Validator Object ID is required to create a FormValidator object. Be sure to specify the variable name of this Form Validator object.");
		return false;
	} else {
		this.id = id;
		// FORM NAME FOR VALIDATION
		// ACCEPTS BOTH A FORM OBJECT AS WELL AS A FORM NAME STRING
		var util = new UtilityObj();
		this.name = util.validateVarTypeOf(form,"object") ? form.name : form;
		delete util;	// FREE OBJECT FROM MEMORY 
		this.form = eval("document." + this.name);
		// USER DEFINED ARRAYS AND PROPERTIES 
		this.customValidate = null;
		// FORM FIELD ARRAY
		// ITEMS ADDED THROUGH addfieldsArr() METHOD
		// FORMAT: [index] = ['Name', 'Label', Required(0 = no, 1 = yes),'Type'(4 validation) 'Misc']
		this.fieldsArr = new Array();	
		
		// VALIDATION PROPERTIES
		this.regEx = (window.RegExp);
		this.stndErrorMess = "A problem was found with your submission.\n\n";
		
		// METHODS
		this.validate = validate;
		this.addfield = addfield;
		this.getRegExData = getRegExData;
		this.makeFieldObject = makeFieldObject;
		this.reset = reset;
		
		// ZERO LENGTH METHODS
		this.textChecking = textChecking;
		this.checkLength = checkLength;
		this.checkRadio = checkRadio;
		this.checkCheckbox = checkCheckbox;
		this.checkSelect = checkSelect;
		// FIELD VALIDATION METHODS
		this.validateField = validateField;	
		
		// ERROR HANDLING
		this.errors = new ErrorObj(this.id + ".errors");
	}
}
	function validate(subType) {
		var err = false;
		for (var i = 0; i < this.fieldsArr.length; i++) {
			if (!err) {
				var field = new Object(), thisType = "undefined";
				// FILTER OUT THE NON RADIO FIELD TYPES FROM THE fieldsArr LIST
				// RADIOS HAVE NUMBER ARGUMENTS FOR THE 'misc' PROPERTY
				if (typeof this.fieldsArr[i]['misc'] != "number") {
					// FILTER OUT CHECKBOXES AS THEIR NAME NEEDS TO BE SPLIT INTO AN ARRAY
					if (this.fieldsArr[i]["name"].indexOf("|") > -1) {
						field = this.fieldsArr[i]["name"];
						thisType = "checkboxGroup";
					// CREATE FIELD OBJECT FOR ALL TEXT BASED AND SELECT FIELD TYPES
					} else {
						field = eval("this.form." + this.fieldsArr[i]["name"]);
						thisType = field.type;
					}
				// RADIO OBJECTS
				} else {
					field = this.fieldsArr[i]["name"];
					thisType = "radio";
				}
				// ASSURE A FIELD TYPE WAS IDENTIFIED, QUIT AND THROW ERROR IF NOT
				if (thisType != "undefined") {
					switch (thisType) {
						/*-----------------------------------------------
						/	TEXT FIELD CHECKING
						/-----------------------------------------------*/
						case "text":
							err = this.textChecking(field,this.fieldsArr[i]["label"],this.fieldsArr[i]["required"],this.fieldsArr[i]["type"]);
							break;
						case "textarea":
							err = this.textChecking(field,this.fieldsArr[i]["label"],this.fieldsArr[i]["required"],this.fieldsArr[i]["type"]);
							break;
						case "file":
							err = this.textChecking(field,this.fieldsArr[i]["label"],this.fieldsArr[i]["required"],this.fieldsArr[i]["type"]);
							break;
						case "password":
							err = this.textChecking(field,this.fieldsArr[i]["label"],this.fieldsArr[i]["required"],this.fieldsArr[i]["type"]);
							break;
						/*-----------------------------------------------
						/	RADIO FIELD CHECKING
						/-----------------------------------------------*/
						case "radio":
							err = this.checkRadio(field,this.fieldsArr[i]["label"],this.fieldsArr[i]['misc']);
							break;
						/*-----------------------------------------------
						/	CHECKBOX FIELD CHECKING
						/-----------------------------------------------*/
						case "checkbox":
							err = this.checkCheckbox(field,this.fieldsArr[i]["label"]);
							break;
						case "checkboxGroup":
							err = this.checkCheckbox(field,this.fieldsArr[i]["label"]);
							break;
						/*-----------------------------------------------
						/	SELECT BOX CHECKING
						/-----------------------------------------------*/
						case "select-one":
							err = this.checkSelect(field,this.fieldsArr[i]["label"],this.fieldsArr[i]['misc']);
							break;
						case "select-multiple":
							err = this.checkSelect(field,this.fieldsArr[i]["label"],this.fieldsArr[i]['misc']);
							break;
						/*-----------------------------------------------
						/	ANY OTHER TYPES, LET THEM PASS THROUGH
						/-----------------------------------------------*/
						default:
							break;
					}
				} else {
					this.errors.handleErr("The field object could not be created.","Form field name invalid.",1,this.errors.name,"Validate->Switch");
				}
			}
		}
		// CUSTOM ERROR HANDLING AND VALIDATION CHECK AND EXECUTION
		if (!err && this.customValidate != null) {
			err = eval(this.customValidate + "()");
		}
		if (err) {
			return false;
		} else {
			if (subType == 1) {
				//finish();
				this.form.submit();
			} else {
				return true;
			}
		}
	}
	
	function reset() {
		this.form.reset();
	}
	
	function textChecking(field,label,req,type) {
		// IF REQUIRED FIELD, TEST FOR VALID LENGTH
		if (req == 1) {
			// ZERO LENGTH FIELD CHECK & ERROR HANDLING
			var thisErr = this.checkLength(field);
			if (thisErr) {
				this.errors.handleErr(this.stndErrorMess + "The " + label.toUpperCase() + " field had the following error: ",thisErr,0,this.errors.name);
				field.focus();
				field.select();
				return true;
			}
		}
		// FIELD VALUE VALIDATION & ERROR HANDLING - PERFORM IF TYPE IS SPECIFIED AND FIELD HAS A VALUE
		if(type && field.value != '') {
			var thisErr = this.validateField(field,type);
			if(thisErr != "" && thisErr != null) {
				this.errors.handleErr(this.stndErrorMess + "The " + label.toUpperCase() + " field had the following error: ",thisErr,0,this.errors.name);
				field.focus();
				field.select();
				return true;
			}
		}
		return false;
	}
	// FIELD LENGTH TEST
	// TEST TO ASSURE THE VALUE OF THE SPECIFIED FIELD IS NOT EMPTY
	function checkLength(field) {
		if (field.value == "") {
			return "A required value is missing.";
		} else {
			return "";
		}
	}
	// TEXT FIELD VALIDATION
	function validateField(field,fieldType) {
		// REGULAR EXPRESSION VALIDATION. MORE POWERFUL THAN REGUALR FIELD CHECKING,
		// BUT ONLY SUPPORTED BY 4.0+ BROWSERS
		if (this.regEx) {
			// GET THE CORRECt REG EXP PATTERN
			var regExPattern = this.getRegExData(fieldType,1);
			// TEST THE FIELD VALUE, AND GET THE CORRESPONDING ERROR IF THE TEST FAILS
			if (!regExPattern.test(field.value))
				return this.getRegExData(fieldType,0);
		}
	}
	
	// SELECT FIELD AND TEXT FIELD COMBO CHECKING
	// CHECK FOR ZERO LENGTH FOR BOTH AS WELL AS VALUES FOR BOTH
	// USERS MUST SELECT ONE OR THE OTHER
	function testSelectCombo(selField,defaultValue,textField,comboLabel) {
		if ((selField.options[selField.selectedIndex].value == defaultValue) && textField.value == "") {
			alert("You must choose an option from the " + comboLabel.toUpperCase() + " field or enter a value in the OTHER field provided.");
			selField.focus();
			selField.select();
			return true;
		} else if ((selField.options[selField.selectedIndex].value != defaultValue) && textField.value != "") {
			alert("You must choose only ONE option from either the " + comboLabel.toUpperCase() + " field or OTHER field provided.");
			selField.focus();
			selField.select();
			return true;
		} else {
			return false;
		}
	}
	
	// REMOVE ILLEGAL CHARACTERS FROM A STRING
	function removeBadCharacters(string) {
		if (string.replace) {
			string.replace(/[<>\"\'%;\)\(&\+]/, '');
		}
		return string;
	}
	
	// REMOVE SPACES FROM A STRING
	function removeSpaces(string) {
		var newString = '';
		for (var i = 0; i < string.length; i++) {
			if (string.charAt(i) != ' ') newString += string.charAt(i);
		}
		return newString;
	}
	// RADIO BUTTON TEST
	function checkRadio(field,label,count) {
		checked = false;
		for (j = 0; j < count; j++) {
			if (eval("this.form." + field + "[" + j + "]").checked == true) {
				checked = true;
				break;
			}
		}
		if (!checked)
			this.errors.handleErr(this.stndErrorMess,"You must select at least one option from the " + label.toUpperCase() + " group",0,this.errors.name);
			eval("this.form." + field + "[0]").focus();
		return !checked;
	}
	// SELECT BOX TEST
	// TEST TO ASSURE THE VALUE OF THE SPECIFIED FIELD IS NOT  EQUAL TO IT's DEFAULT VALUE
	function checkSelect(field,label,defaultValue) {
		if (field.options[field.selectedIndex].value == defaultValue) {
			this.errors.handleErr(this.stndErrorMess,"You must select at least one option from the " + label.toUpperCase() + " list.",0,this.errors.name);
			// MULTIPLE SELECTS THROW AN ERROR FOR Focus(), SO SKIP THEM 
				field.focus();
			return true;
		} else {
			return false;
		}
	}
	// CHECKBOX TEST
	function checkCheckbox(field,label) {
		if ((eval("this.form." + field.name)).checked != true) {
			this.errors.handleErr(this.stndErrorMess,"You must select the " + label.toUpperCase() + " checkbox to continue",0,this.errors.name);
			field.focus();
			return true;
		} else {
			return false;
		}
	}
	// CHECKBOX GROUP TEST
	function checkCheckboxGroup(fields,label) {
		var groupChecked = false
		var checkArray = fields.split("|");
		for (k = 0; k < checkArray.length; k++) {
			if ((eval("this.form." + checkArray[k])).checked == true) {
				groupChecked = true;
				break;
			}
		}
		if (!groupChecked)
			this.errors.handleErr(this.stndErrorMess,"You must select at least one option from the " + label.toUpperCase() + " group",0,this.errors.name);
			eval("this.form." + checkArray[0]).focus();
		return !groupChecked;
	}
	// ADD FIELD ITEMS TO THE fieldsArr ARRAY
	function addfield(fName,fLabel,fReq,fType,fMisc) {
		var inArray = new Array(5);
		inArray["name"] = fName;
		inArray["label"] = fLabel;
		inArray["required"] = fReq == "" ? 0 : fReq;
		inArray["type"] = fType == "" ? "" : fType;
		inArray["misc"] = fMisc == "" ? "" : fMisc;
		var currLen = 0;
		if (this.fieldsArr.length > 0)
			currLen = this.fieldsArr.length;
		this.fieldsArr[currLen] = inArray;
	}
	function getRegExData(type,rType) {
		var pattern = new RegExp("\w");
		var errMess = null;
		switch (type) {
			// SHORT DATE
			case "date":
				pattern = /^\d?\d\/\d?\d\/[0-9]{4}$/;
				errMess = "Please enter all dates in MM/DD/YYYY format.";
				break;
			// US PHONE NUMBER
			case "usPhone":
				pattern = /^\([0-9]{3}\)\s?[0-9]{3}\-[0-9]{4}$/;
				errMess = "US Phone Numbers must be contain an area code and 7 digits. (e.g., (123) 345-6789).";
				break;
			// GENERAL PHONE NUMBER - ACCEPTS US AND INTERNATIONAL PHONE NUMBERS
			case "genPhone": // ADDED 5/21/02
				pattern = /^[0-9\-\(\)\+\s]+$/;
				errMess = "Valid Phone Numbers can only include numbers, hyphens(-), parenthese () or spaces.";
				break;	
			// E-MAIL ADDRESS
			case "email":
				pattern = /^[a-z_0-9\.\-\_]+@[a-z_0-9\.\-]+\.[a-z_0-9\.\-]*[a-z]{2,3}$/i;
				errMess = "Please enter the e-mail address in recipient@hostname.com format.";
				break;
			// WORDS WITH SPACES
			case "word":
				pattern = /^[a-z\s]+$/i;
				errMess = "Please enter only words with spaces and without punctuation or numbers.";
				break;
			// NUMBER WITH COMMAS
			case "number":
				pattern = /^[0-9\,]+$/;
				errMess = "Please enter only a number values without letters or punctuation.";
				break;
			//	EIGHT dot THREE FILE NAME
			case "filename":
				pattern = /^\w{1,8}\.[a-z]{1,3}$/;
				errMess = "The name of this file must conform to the 8.3. naming convention with one to eight letters as the file name and one to three letters for a file extension. (e.g., filename.ext).";
				break;
			// INTERNET URL
			case "url":		// NEW 2/28/02
				pattern = /^https?\:\/\/[a-z_0-9\_\-]+\.[a-z_0-9\_\-]+\.?[a-z_0-9\.\_\-\/\?\&\%\=]+$/i;
				errMess = "Web site URLs must contain the http:// or https:// prefix";
				break;
			// US DOLLARS
			case "usdollars":	// NEW 2/28/02
				pattern = /^\$?[0-9\,]+\.[0-9]{2}$/i;
				errMess = "The dollar amount specified is not in the correct format. Enter dollar values as $###,###.## format.";
				break;
			// US POSTAL CODE
			case "zipcode":	// NEW 3/1/02
				pattern = /^[0-9]{5}\-?([0-9]{4})?$/i;
				errMess = "US Zip Codes must be entered in either 12345 or 12345-6789 format.";
				break;
			// US SOCIAL SECURITY NUMBER
			case "socSecurity":	// NEW 4/5/02
				pattern = /^[0-9]{3}\-[0-9]{2}\-[0-9]{4}$/;
				errMess = "Social Security Numbers must be entered in 123-45-6789 format.";
				break;
			// NAME - CAN CONTAIN -,. CHARS AS WELL AS LETTERS
			case "name":	// NEW 5/21/02
				pattern = /^[a-zA-Z\s\.\-\,]+$/i;
				errMess = "Names must be made up of letters wihout mubers and can contain only hyphns(-), commas (,) or periods(.).";
				break;	
			case "domain":	// NWS 8/30/02
				pattern = /^[a-z_0-9\-\_]{3,}\.[a-z_0-9\-\_]+\.[a-zA-Z]{2,4}(\.[\w\-]{2,})?$/;
				errMess = "You must specify domain names in the format: www.domainname.ext or subdomain.domain.co.uk";
				break;
			case "alphanumeric": // ALPHA NUMBERIC 1/22/03
				pattern = /^[a-z_0-9]*$/;
				errMess = "You can only enter alphanumeric characters without punctuation or special characters in this field.";
				break;
			default:
				break;
				return false;
		}
		if (rType == 1)
			return pattern;
		else
			return errMess;
	}
	// MAKE FIELD OBJECT - RETURNS A FIELD OBJECT FOR THE CURRENT FORM
	// BEST USED IN CUSTOMER VALIDATION FUNCTIONS
	function makeFieldObject(fieldName) {
		return eval("this.form." + fieldName);
	}

