//Giving Game javascript
//Version: 1.0
//Date: 4/22/03
//Developer: V Tatko

//Places focus in the 1st text/textarea form element in the 1st form on any page
//	(This function will run successfully even if there is no form on a page.)
//onLoad event to put focus in first text or textarea field
//The Body tag must include the following parameter: onLoad="placeFocus();"
function placeFocus() {
	//is there a form on the page?
	if (document.forms[0]) {
		var form = document.forms[0];
	
		//iterate through all form elements in 1st form until find text or textarea
		for (var i=0; i < form.elements.length; i++) {
			if (form.elements[i].type == "text" || form.elements[i].type == "textarea") {
				//place focus in first text or textarea
				form.elements[i].focus();
			
				//return
				return;
			}
		}
	
		//if get down here, no text/textareas found: no focus

		//Write out event handler for autotab fields
					
	}	
}

//Function "validateForm(form)" validates form fields of any submitted form
//In order to call this function, the following must be included in the form
//	form tag: onSubmit="return validateForm(this.form);"
//
//Form elements within a form must be named (in the HTML) using the following convention:
//	1. All form elements must have a name="..." parameter specified in the HTML.
//		The name should translate to a friendly name, but using all lower case and
//		underscores where spaces are going to be.
//	2. Required Fields: All elements are assumed to be required unless the element has "_OPT" 
//		within the element name (e.g., "first_name_OPT").  The error message that appears
//		when fields(s) are incomplete will uppercase the first character of a field 
//		name, change any underscores to spaces, and strip out any key words (_OPT, _SET)
//	3. MaxLength - JS will not verify field value lengths: maxlength parameter in HTML for text elements
//		server side validation for TEXTAREA elements
//	4. Character restrictions - email (must have @ and .), phone (not yet), GG card (not yet)
//	5. SETs - when a form has two or more fields where only one of the fields can be completed,
//		but not multiple, the charatcter string "_SET#" must appear in the form element
//		name (where # is a single digit).  All field within a set should have the same
//		set digit.  Sets can be numbered 1-9 and can have up to 9 on a given page.
//	6. Submission pop-up - The text that will appear in a pop-up message after a form is
//		submitted, is pulled from the value of form's "submission_message" hidden field.
//		If there is no such field in the form, then no pop-up will appear upon submission.
//		Also, if the form name has "_THANK" in it and there is no "submission_message" field,
//		the pop-up will display "Thank you for your submission."



function validateForm(form) {
	//define incomplete error message array
	var incomplete = new Array();
	var errorList = new Array();
	var errorCount = 0;
	var formType;
	var valid = 0;
	var numSetElements = 0; // number of elements in a SET where only one field can be completed
	var setElements = new Array();
	var setIndex = new Array();
	var setMessage = new Array();
	var elementMessage = new Array();
	var state;
	var setInList = 0;

	// iterate through all form elements
	for (var i=0; i < form.elements.length; i++) {
		//Restrict elements for validation
		var elementType = form.elements[i].type;
		var validateField = 0;
		
		// Separate elements into Text/Textarea vs. Radio/Checkbox vs. Select
		if (elementType == "text" || elementType == "textarea") {	
			var formElementType = "TextualField";
			validateField = 1;
		}
		else if (elementType == "radio" || elementType == "checkbox") {
			var formElementType = "CheckedField";
			validateField = 1;
		}
		else if (elementType.indexOf("select") != -1) {
			var formElementType = "SelectField";
			validateField = 1;
		}			

		//Proceed with validation for flagged fields
		if (validateField == 1) {
			//Call a function to evaluate specific type of element
			//Store validity flags in array
			incomplete[i] = eval("validate"+formElementType+"Elements(form, i);");

			//Where element is part of a SET (where only 1 field can be completed of the SET)
			if (form.elements[i].name.indexOf("_SET") != -1) {

				//Create parallel array to track which sets are being used
				setIndex[numSetElements]=form.elements[i].name.substring(form.elements[i].name.indexOf("_SET")+4, form.elements[i].name.length);
				//Create parallel array to track which form elements are SETs
				setElements[numSetElements]=i;

				//Increment number of elements in form attributed to a set
				numSetElements++;
			}

		}

	}

	//Check for duplicate entries in a SET; if they exist, return false;
	state = validateSets(form,numSetElements,setIndex,setElements,incomplete);
	if (state == false) {

		return false;
	}

	//Validate phone fields
	state = validatePhone(form) 
	if (state == false) {

		return false;
	}		

	//Validate email fields
	state = validateEmail(form) 
	if (state == false) {

		return false;
	}	

	//Create parallel array to build error message for the SET

	if (numSetElements > 0) {
		
		for (var i=1; i <= 9; i++) {

			for (var j=0; j < numSetElements; j++) {
				
				if (setIndex[j] == i) {
					// Build error message
					if (setMessage[i]) {
						setMessage[i] = setMessage[i] + " OR ";
					} else {
						setMessage[i] = "";
					}
					setMessage[i] = setMessage[i] + form.elements[setElements[j]].name;
				}
			}
		}
	}
	
	//Iterate through incomplete array to identify which fields are missing values
	for (var i=0; i < form.elements.length; i++) {


		// Find incomplete entries
		if (incomplete[i] == 1) {
			//Set valid flag to 0: not valid
			valid = 0;
			
			//For radio & checkbox types, iterate through all elements
			if (form.elements[i].type == "radio" || form.elements[i].type == "checkbox") {

				for (var j=0; j < incomplete.length; j++) {
					if (form.elements[i].type==form.elements[j].type && i != j &&
					  form.elements[i].name==form.elements[j].name &&
					  	incomplete[j]==0) {
						valid = 1;						
					}
				}
				//Make sure that group has not already been added to errormessage array
				for (var k=0; k < errorList.length; k++) {
					if (form.elements[i].name == errorList[k])
						valid = 1;
				}
			}
			
			// iterate through SET elements, because only 1 value should be filled out
			//	and only one entry listed in the errorList
			if (form.elements[i].name.indexOf("_SET") != -1) {
			
				//grab setNumber of current element's set
				setNumber = form.elements[i].name.substring(form.elements[i].name.indexOf("_SET")+4,form.elements[i].name.indexOf("_SET")+5);
				
				//iterate through setIndex to find list of other elements in set
				for (var j=0; j < setIndex.length; j++) {
					//where another element in set is completed
					if (setElements[j] != i && setIndex[j] == setNumber
					    && incomplete[setElements[j]] == 0)
						//this field is valid because it is in a completed set
						valid = 1;
				}
				
			}
			
			// Field is incomplete, so build errormessage array
			if (valid == 0) {

				//For a SET element, add name of custom group
				if (form.elements[i].name.indexOf("_SET") != -1) {
					setInList = 0;
					setNumber = form.elements[i].name.substring(form.elements[i].name.indexOf("_SET")+4,form.elements[i].name.indexOf("_SET")+5);

					//Make sure that group has not already been added to errormessage array
					for (var k=0; k <= errorList.length; k++) {
								
						if (setMessage[setNumber] == errorList[k])
							setInList = 1;
					}		
					if (setInList == 0) {
						errorList[errorCount] = setMessage[setNumber];
						errorCount++;
					} 
					
				} else {
					//Add name of group to errormessage array

					errorList[errorCount] = form.elements[i].name;
					errorCount++;
				}

			}
		}
	}
	
	//If errors exist
	if (errorCount > 0) {

		//Iterate through error message array to populate alert
		var fullErrorMessage = "Please complete the following field";
		if (errorCount > 1) 
			fullErrorMessage = fullErrorMessage + "s";
		fullErrorMessage = fullErrorMessage + ":";
		for (var m=0; m < errorList.length; m++) {
			//Change field name to be user friendly
			errorList[m]=makeNameUserFriendly(errorList[m]);

			fullErrorMessage = fullErrorMessage + "\n  " + (m+1) + ". " + errorList[m];
		}
		alert(fullErrorMessage);

		//If validation fails, place focus
		placeFocus();
		return false;
	}
	
	//if the form got down here, it passes all validation
	//If form name includes "_THANK", then pop-up a thank you message.
	showSubmissionMessage(form);
	
	//Return to submit form
	return true;

}


function validatePhone(form) {
	// iterate through all form elements
	for (var i=0; i < form.elements.length; i++) {

		// for each field named phone
		if (form.elements[i].name.indexOf("phone") != -1 && form.elements[i].name.indexOf("phone") != "") {
			// Field must be numeric
			if (form.elements[i].value != "" && isNaN(form.elements[i].value)) {
				errorMessage = "All phone fields must contain only numbers.";
				alert(errorMessage);
				return false;
			}

		}
	}

	return true;
}

function validateEmail(form) {
  //  Disable for now until the Mac is fixed
  return true;
	// iterate through all form elements
	for (var i=0; i < form.elements.length; i++) {

		// for each field named email
		if (form.elements[i].name.indexOf("email") != -1 && form.elements[i].name.indexOf("email") != "") {
			// Field must be only alphanumeric, periods, hyphens, underscores
			// where field is not blank
			if (form.elements[i].value != "" ) {
				// iterate through characters in value
				//for (var k=0; k < form.elements[i].value.length; k++) {
					// Must have @, .
					if (form.elements[i].value.indexOf("@") == -1 ||
						form.elements[i].value.indexOf(".") == -1) {
					//evaluate each character code to determine ok
					
						errorMessage = "All email fields must be complete\nand not contain any special characters.";
						alert(errorMessage);
						form.elements[i].focus();
						return false;
					}
				//}
			}

		}
	}

	return true;
}

//Change field name to be user friendly
function makeNameUserFriendly(fieldName) {

	var underscoreIndex;
	i=0;

	//strip out reserved strings in field names
	// _OPT
	// _SET
	while (fieldName.indexOf("_SET") != -1 ) {
		reservedIndex = fieldName.indexOf("_SET")
		beforeReserved = fieldName.substring(0,reservedIndex);
		beforeReserved = beforeReserved + fieldName.substring(reservedIndex+5,fieldName.length); 		
		fieldName = beforeReserved;

		//precautionary break statement in case old browsers don't like "while" loops
		i++;
		if (i > 100) {
			break;
		}
	}
	i=0;
	while (fieldName.indexOf("_OPT") != -1 ) {
		reservedIndex = fieldName.indexOf("_OPT")
		beforeReserved = fieldName.substring(0,reservedIndex);
		beforeReserved = beforeReserved + fieldName.substring(reservedIndex+5,fieldName.length); 		
		fieldName = beforeReserved;

		//precautionary break statement in case old browsers don't like "while" loops
		i++;
		if (i > 100) {
			break;
		}
	}
	i=0;
	//replacing underscore with spaces, using primitive javascript to be most old browser compatible
	while (fieldName.indexOf("_") != -1 && fieldName.indexOf("_") != "") {
		underscoreIndex = fieldName.indexOf("_");

		beforeUnderscore = fieldName.substring(0,underscoreIndex);
		beforeUnderscore = beforeUnderscore + " ";
		beforeUnderscore = beforeUnderscore + fieldName.substring(underscoreIndex+1,fieldName.length);
		
		fieldName=beforeUnderscore;
		
		//precautionary break statement in case old browsers don't like "while" loops
		i++;
		if (i > 100) {
			break;
		}
	}

	// Capitalize first letter
	fieldName = fieldName.substring(0,1).toUpperCase() + fieldName.substring(1,fieldName.length);

	return(fieldName);
	
}

//Validate Select elements
function validateSelectFieldElements(form,i) {

	var incomplete = 0;
	var tempName = form.elements[i].name;
	var selectList = form.elements[i];

	//Where field is not optional
	if (tempName.indexOf("_OPT") == -1) {
		
		//set incomplete flag if field has first value selected	
		// or if a choice begins with "--"
		if (selectList.selectedIndex == 0 ||
		    selectList.options[selectList.selectedIndex].text.indexOf("--") == 0)
			incomplete = 1;
			
	}
	
	//return incomplete code
	return(incomplete);

}
	

//Validate Checked Field elements (radio, checkbox)
function validateCheckedFieldElements(form, i) {
	radioGroup = form.elements[i];
	var tempName = radioGroup.name;
	var incomplete = 0;

	//Where field is not optional
	if (tempName.indexOf("_OPT") == -1) {
		
		//set incomplete flag if field has no value
		if (!(form.elements[i].checked))
			incomplete = 1;
			
	} 

	//return incomplete code
	return(incomplete);	
}



//Validate text elements
function validateTextualFieldElements(form, i) {

	var tempName = form.elements[i].name;
	var incomplete = 0;

	//Where field is not optional
	if (tempName.indexOf("_OPT") == -1) {
		
		//set incomplete flag if field has no value
		if (form.elements[i].value == "") {
			incomplete = 1;
		}
	
	} 

	return(incomplete);
	
}

//Validate SET elements for duplicate entries
function validateSets(form,numSetElements,setIndex,setElements,incomplete) {

	var errorMessage;
	var duplicateFields = 0;
	var duplicateSetIndex;

	//iterate through elements that have been identified as being in a SET
	for (var i=0; i < numSetElements; i++) {
		
		//where a field in a SET is completed
		if (incomplete[setElements[i]] == 0) {

			//loop through to check that no other members of that SET are completed
			for (var j=0; j < numSetElements; j++) {

				if (i != j && setIndex[j] == setIndex[i] 
					&& incomplete[setElements[j]] == 0) {
					
					//set duplicateFields flag
					duplicateFields=1;
					duplicateSetIndex = setIndex[j];
				}
			}
		}
	}
	
	if (duplicateFields == 1) {
		
		errorMessage = "Only 1 of the following fields can be completed:\n";
		
		for (var k=0; k < numSetElements; k++) {
			
			if (duplicateSetIndex == setIndex[k]) {
				fieldName = makeNameUserFriendly(form.elements[(setElements[k])].name);
				errorMessage = errorMessage + " * "+fieldName +"\n";
				form.elements[setElements[k]].focus();
				if (form.elements[setElements[k]].type == "text" || form.elements[setElements[k]].type == "textarea") {
					//clear text values 
					form.elements[setElements[k]].value="";
				}	
				
			}
		}
		
		alert(errorMessage);
		return false;
	}

}

function showSubmissionMessage(form) {

	//if submission_message hidden field exists
	
	if (form.submission_message) {
		alert(form.submission_message.value);
	} 
	// There is a bug in the below if statement, but to save on time, I am just commenting out.
	else if (form.name.indexOf("_THANK") != -1 && form.name.indexOf("_THANK") != "") {
		alert("Thank you for your submission.");
	} 
	return true;
}

function showPopupMessage(message) {

	// if message is defined, popup this message
	if (message) {
		alert(message);
	} 
	return true;
}


//Submitting form with enter key

//Phone autotab based 

//validate email WIP

	// This function could be called to streamline printing from some browsers (IE)
	function printWindow(){
		if (window.print){
			window.print()
		}
		else{
			alert("Your browser does not support this function. Please click the Print button in your browser's toolbar.");
			}
		}

	//This is a basic function that opens a new window
	function openNewWindow (file) {
		windowVar=window.open(file,
					'new_print_window',
					'toolbar=no,location=no,directories=no, status=no,menubar=no,scrollbars=no,resizable=no, copyhistory=no,width=400,height=400');
		windowVar.focus();
		
		return false;
	}	 
	var windowVar; // global variable for new window

