/*
USEAGE:

Create an array of required fields using the supplied function in this form:
arrRequiredFields[n] = new RequiredField("fieldname", "field_description", "field_type");
Where 
	1. "fieldname" is the name given the field (or in some cases the root field name, see phone type below)
	2. "field_description" is the user-friendly description that fits in the phrase "OOPS... field_description is required."
	3. "field_type" is the type of field to be validated, as described below

Field types:
	"text" - checks that field value is not null
	"email" - checks that field value conforms to general structure of an email address
	"zip" - checks that field value is a five-digit numerical zip code.
	"phone" - uses fieldname as a root and assumes that three fields are used: fieldname1, fieldname2, fieldname3
			checks that field value is a ten-digit numerical phone number
			AND it writes a formatted phone number to hidden field named fieldname 			
	"checkboxes" - uses fieldname as a root and assumes that N consecutively
			  numbered fields are used: fieldname1, fieldname2, ..., fieldnameN
			checks that at least one checkbox was selected
			AND it writes a comma separated list of all entries to hidden field named fieldname
	"selection" - checks that selected value is not null
		
EXAMPLE
<script language="JavaScript" src="FormValidation.js"></script>

// Create an array of required fields
var arrRequiredFields = new Array(); 

// Array should be in the order that you want fields validated		
arrRequiredFields[0] = new RequiredField("name", "Your Name", "text");
arrRequiredFields[1] = new RequiredField("email", "Valid E-mail Address", "email");
arrRequiredFields[2] = new RequiredField("zip", "Five-digit U.S. Zip Code", "zip");
arrRequiredFields[3] = new RequiredField("phone", "Phone Number Including Area Code", "phone");
arrRequiredFields[4] = new RequiredField("like", "What You Like", "checkboxes");
arrRequiredFields[4] = new RequiredField("truths", "What You Believe to be True", "selection");

END EXAMPLE
*/

// Object constructor 
function RequiredField(FieldName, ErrorString, FieldType) { 
   this.FieldName = FieldName;
   this.ErrorString = ErrorString; 
   this.FieldType = FieldType;
}

// Alert message components
var preAlert = 'OOPS...\n'
var postAlert = ' is required.'

// Background Colors
var strBackgroundNormal = "#FFFFFF";
var strBackgroundFlagged = "#FFFF80";
//for (var i=0;i<document.forms[0].elements.length;i++){
//	setElementBG(document.forms[0].elements[i], bgElementNormal );
//}

function ValidateForm(objForm, arrReqFields, objSubmitButton){
// Format > Validate, Flag, Focus -or- Submit

	// reset all background field colors
	for (var i=0;i<arrReqFields.length;i++){
		var objField = objForm.elements[arrReqFields[i].FieldName];
		var objFieldN = objForm.elements[arrReqFields[i].FieldName+1];
		
		if (!(objField || objFieldN) ) {
			alert("FORMAT ALERT - Field Name Not Found in Form: " + arrReqFields[i].FieldName);
				return false;
		
		}
	
		switch ( arrReqFields[i].FieldType ){
			case "text":
				setElementBG(objField, strBackgroundNormal);
				break;
				
			case "num":
				setElementBG(objField, strBackgroundNormal);
				break;				

			case "email":			
				setElementBG(objField, strBackgroundNormal);
				break;
				
			case "zip5":			
				setElementBG(objField, strBackgroundNormal);
				break;

			case "phone":	
				setElementBG(objForm.elements[arrReqFields[i].FieldName+"1"], strBackgroundNormal);
				setElementBG(objForm.elements[arrReqFields[i].FieldName+"2"], strBackgroundNormal);
				setElementBG(objForm.elements[arrReqFields[i].FieldName+"3"], strBackgroundNormal);
				break;
				
			case "phone_num":
				setElementBG(objForm.elements[arrReqFields[i].FieldName+"1"], strBackgroundNormal);
				setElementBG(objForm.elements[arrReqFields[i].FieldName+"2"], strBackgroundNormal);
				setElementBG(objForm.elements[arrReqFields[i].FieldName+"3"], strBackgroundNormal);
				break;
				
			case "ssn_num":
				setElementBG(objForm.elements[arrReqFields[i].FieldName+"1"], strBackgroundNormal);
				setElementBG(objForm.elements[arrReqFields[i].FieldName+"2"], strBackgroundNormal);
				setElementBG(objForm.elements[arrReqFields[i].FieldName+"3"], strBackgroundNormal);
				break;
				
			case "checkboxes":
				var intCount = 1;
				while(objForm.elements[arrReqFields[i].FieldName+intCount]){
					setElementBG(objForm.elements[arrReqFields[i].FieldName+intCount], strBackgroundNormal);
					intCount++;
				}
				break;
	
			case "selection":
				setElementBG(objField, strBackgroundNormal);
				break;
	
			case "radio":		
				for(var k=0; k<objField.length; k++){
					setElementBG(objField[k], strBackgroundNormal);
				}
				break;
				
			default : 
				alert("FORMAT ALERT - Field Type Not Recognized: " + arrReqFields[i].FieldType);
				return false;
				
		} // end switch
	} // end for
	
	
	// validate form
	for (var i=0;i<arrReqFields.length;i++){
		var objField = objForm.elements[arrReqFields[i].FieldName];
		//alert (objField.value); return false;
	
		switch ( arrReqFields[i].FieldType ){
			// validate plain text fields: OK if not null
			case "text":
				// if field is null, change element bg color, set focus on field, alert user, and don't process form 
				if( !objField.value ){
					setElementBG(objField, strBackgroundFlagged);
					objField.focus();
					alert(preAlert + arrReqFields[i].ErrorString + postAlert );
					return false;
				} 
				break;
				
			case "num":			
				var strValidNum = "^[0-9]+$";
				var regValidNum = new RegExp(strValidNum);
  				
				// if zip code is not valid, change element bg color, set focus on field, alert user, and don't process form 
  				if (!regValidNum.test(objField.value)) {    				
					setElementBG(objField, strBackgroundFlagged);
					objField.focus();
					alert(preAlert + arrReqFields[i].ErrorString + postAlert );
					return false;
  				} 
				break;				
				
			// validate e-mail text fields
			case "email":			
				var strValidEmail = "^([._a-z0-9-]+[._a-z0-9-]*)@(([a-z0-9-]+\.)*([a-z0-9-]+)(\.[a-z]{2,3}))$";
				var regValidEmail = new RegExp(strValidEmail);
  				
				// if email is not valid, change element bg color, set focus on field, alert user, and don't process form 
  				if (!regValidEmail.test(objField.value)) {   				
					setElementBG(objField, strBackgroundFlagged);
					objField.focus();
					alert(preAlert + arrReqFields[i].ErrorString + postAlert );
					return false;
  				}
				break;
				
			// validate five-digit zip code text fields
			case "zip5":			
				var strValidZip = "^[0-9]{5}$";
				var regValidZip = new RegExp(strValidZip);
  				
				// if zip code is not valid, change element bg color, set focus on field, alert user, and don't process form 
  				if (!regValidZip.test(objField.value)) {    				
					setElementBG(objField, strBackgroundFlagged);
					objField.focus();
					alert(preAlert + arrReqFields[i].ErrorString + postAlert );
					return false;
  				} 
				break;
				
			// validate ten digit phone text fields and return a human-readable string
			case "phone":			
				var strValidPhone = "^[0-9]{10}$";
				var regValidPhone = new RegExp(strValidPhone);
				var objPhone1 = objForm.elements[arrReqFields[i].FieldName+"1"];
				var objPhone2 = objForm.elements[arrReqFields[i].FieldName+"2"];
				var objPhone3 = objForm.elements[arrReqFields[i].FieldName+"3"];
				var strPhone = objPhone1.value + objPhone2.value + objPhone3.value;
  				
				// if phone is not valid, change element bg color, set focus on field, alert user, and don't process form 
  				if (!regValidPhone.test(strPhone)) {    				
					setElementBG(objPhone1, strBackgroundFlagged);
					setElementBG(objPhone2, strBackgroundFlagged);
					setElementBG(objPhone3, strBackgroundFlagged);
					objPhone1.focus();
					alert(preAlert + arrReqFields[i].ErrorString + postAlert );
					return false;
  				} else {
					// check to see if hidden field exists and warn if is does not
					if(objField){
						objField.value = "(" + objPhone1.value + ") " + objPhone2.value + "-" + objPhone3.value;
					}
					else{
						alert("FORMAT ALERT - Missing hidden field: " + arrReqFields[i].FieldName);
					}
				}
				break;
				
				// validate ten digit phone text fields and return a numeric string
			case "phone_num":			
				var strValidPhone = "^[0-9]{10}$";
				var regValidPhone = new RegExp(strValidPhone);
				var objPhone1 = objForm.elements[arrReqFields[i].FieldName+"1"];
				var objPhone2 = objForm.elements[arrReqFields[i].FieldName+"2"];
				var objPhone3 = objForm.elements[arrReqFields[i].FieldName+"3"];
				var strPhone = objPhone1.value + objPhone2.value + objPhone3.value;
  				
				// if phone is not valid, change element bg color, set focus on field, alert user, and don't process form 
  				if (!regValidPhone.test(strPhone)) {    				
					setElementBG(objPhone1, strBackgroundFlagged);
					setElementBG(objPhone2, strBackgroundFlagged);
					setElementBG(objPhone3, strBackgroundFlagged);
					objPhone1.focus();
					alert(preAlert + arrReqFields[i].ErrorString + postAlert );
					return false;
  				} else {
					// check to see if hidden field exists and warn if is does not
					if(objField){
						objField.value = objPhone1.value + objPhone2.value + objPhone3.value;
					}
					else{
						alert("FORMAT ALERT - Missing hidden field: " + arrReqFields[i].FieldName);
					}
				}
				break;
				
			// validate nine digit SSN
			case "ssn_num":			
				var strValidSSN = "^[0-9]{9}$";
				var regValidSSN = new RegExp(strValidSSN);
				var objSSN1 = objForm.elements[arrReqFields[i].FieldName+"1"];
				var objSSN2 = objForm.elements[arrReqFields[i].FieldName+"2"];
				var objSSN3 = objForm.elements[arrReqFields[i].FieldName+"3"];
				var strSSN = objSSN1.value + objSSN2.value + objSSN3.value;
  				
				// if phone is not valid, change element bg color, set focus on field, alert user, and don't process form 
  				if (!regValidSSN.test(strSSN)) {    				
					setElementBG(objSSN1, strBackgroundFlagged);
					setElementBG(objSSN2, strBackgroundFlagged);
					setElementBG(objSSN3, strBackgroundFlagged);
					objSSN1.focus();
					alert(preAlert + arrReqFields[i].ErrorString + postAlert );
					return false;
  				} else {
					// check to see if hidden field exists and warn if is does not
					if(objField){
						objField.value = objSSN1.value + objSSN2.value + objSSN3.value;
					}
					else{
						alert("FORMAT ALERT - Missing hidden field: " + arrReqFields[i].FieldName);
					}
				}
				break;
				
			// validate that at least one of a set of check boxes has been selected
			case "checkboxes":
				var strAllValues;
				var intCount = 1;
				var boolCheckBoxValidated = false;
				// check each checkbox, from fieldname1 through fieldnameN
				while(objForm.elements[arrReqFields[i].FieldName+intCount]){
					if(objForm.elements[arrReqFields[i].FieldName+intCount].checked){
						boolCheckBoxValidated = true;
						// combine the values into one string
						strAllValues?strAllValues=strAllValues+", "+objForm.elements[arrReqFields[i].FieldName+intCount].value:strAllValues=objForm.elements[arrReqFields[i].FieldName+intCount].value;
					}
					intCount++;
				}
				
				// check to make sure there was more than one checkbox to validate
				if(intCount == 1){
					alert("FORMAT ALERT - No checkboxes of this form to validate: " + arrReqFields[i].FieldName + "N");
				}
  				
				// if no checkbox has been selected, change element bg color, set focus on field, alert user, and don't process form 
  				if (!boolCheckBoxValidated) { 
					for(var j=1; j<intCount; j++){
						setElementBG(objForm.elements[arrReqFields[i].FieldName+j], strBackgroundFlagged);
					}
					objForm.elements[arrReqFields[i].FieldName+"1"].focus();
					alert(preAlert + arrReqFields[i].ErrorString + postAlert );
					return false;
  				} else {
					// check to see if hidden field exists and warn if is does not
					if(objField){
						objField.value = strAllValues;
					}
					else{
						alert("FORMAT ALERT - Missing hidden field: " + arrReqFields[i].FieldName);
					}
				}
				break;
			
			// validate that the selection returns a non-null value	
			case "selection":
				// if no selection has been made or the selection has a null or 0 value, 
				//   change element bg color, set focus on field, alert user, and don't process form 	
				if( !objField.options[objField.selectedIndex].value || objField.options[objField.selectedIndex].value == '0'){
					setElementBG(objField, strBackgroundFlagged);
					objField.focus();
					alert(preAlert + arrReqFields[i].ErrorString + postAlert );
					return false;
				} 
				break;

			// validate that the radio selection returns a non-null value	
			case "radio":
				// check if a radio button was selected
				var boolRadioValidated = false;
				for(var k=0; k<objField.length; k++){
					if(objField[k].checked){
						boolRadioValidated = true;
						break;
					}
				}
				
				// if no radio button was selected, change element bg color, alert user, and don't process form 
				if( !boolRadioValidated ){
					for(var k=0; k<objField.length; k++){
						setElementBG(objField[k], strBackgroundFlagged);
					}
					setElementBG(objField, strBackgroundFlagged);
					objField[0].focus();
					alert(preAlert + arrReqFields[i].ErrorString + postAlert );
					return false;
				} 
				break;
				
		} // end switch
	} // end for

	// if the form has been validated and a button object submitted, disable the submit button and return true
	if (objSubmitButton){
		objSubmitButton.value = 'Please Wait ';
  		if (typeof objSubmitButton.disabled != 'undefined') {
    		objSubmitButton.disabled = true;
  		} else if (!objSubmitButton.buttonDisabled) {
    		objSubmitButton.onclick = cancelAction;
    		objSubmitButton.buttonDisabled = true;
		}  
	}
    return true;
	

}

function setElementBG(objElement, strColor) {
// sets element's color 
	if (document.images) {
		if (objElement.style) {
			objElement.style.backgroundColor = strColor;
		}
	}
}


// checks the value of a text input field
function checkMaximum(objField, floatValue, strErrorMsg){
	
	if( objField.value > (floatValue + 0) ){
		setElementBG(objField, strBackgroundFlagged);
		objField.focus();
		alert(preAlert + strErrorMsg + '.' );
		objField.value ='';
	} 
}
//onClick="disableSubmit(document.frmInKind, document.frmInKind.btnSubmit);return false;"