/******************************* global vars *******************************/
/* QUESTION: how does all this work with Unicode characters??? */
/* global parameters */
var gstrSymbolChars = "!@#$%^*()=+{}[],.<>?/\\~`\"\:;";
var gdateNow = new Date();
var gintThisYear = gdateNow.getYear(); // use getFullYear() in JavaScript 1.2+

/******************************* debugging functions *******************************/
function showAll(obj) {
// use to view all properties of an object
	var names = "";
	for (var prop in obj) names += prop + ": " + obj[prop] + "$\n";
	alert (names);
}

/******************************* stub functions *******************************/
function fnFormInitiatise() {
// this function is called by body.onload() -- pages with actual initialisation to do will override this function
	return true;
}

/******************************* field-level functions *******************************/
function fnTextHint(theTextInput, state, normalClass, hintClass) {
//		showAll(theTextInput); 
//		alert("hint = " + theTextInput['hinttext'] + "\ndefault = " + theTextInput['default']);
//	alert('the hinttext is: ' + theTextInput.getAttribute('hinttext'));
	if (theTextInput.getAttribute('hinttext')==null) {
		theHintText = "";
	} else {
		theHintText = theTextInput.getAttribute('hinttext');
	}
	if (theTextInput.getAttribute('default')==null) {
		theDefaultText = "";
	} else {
		theDefaultText = theTextInput.getAttribute('default');
	}
	if (state == 1) {
		theTextInput.className = normalClass;
		if (theTextInput.value == theHintText) {
			theTextInput.value = theDefaultText;
		}
	} else {
		if ((theTextInput.value == theDefaultText) || (theTextInput.value == "")) {
			theTextInput.value = theHintText;
		}
		if (theTextInput.value == theHintText) {
			theTextInput.className = hintClass;
		}
	}
}


/******************************* validation toolbox functions *******************************/
/* each fnIsXxxx function takes a (string) value as its first parameter and returns boolean. */

function fnIsNumber(theValue) {
//	check whether the value is a valid float with no extra characters
	if (theValue == null) {
		return false;
	} else {
		myNum = parseFloat(theValue);
		if ( isNaN(myNum) || (myNum.toString() != theValue) ) {
			return false;
		} else {
			return true;
		}
		return true;
	}
}

function fnIsYear(theValue) {
//	check whether value is a 4-digit year from 1900 up to 2099
//	to check only to the present year, change 2099 to gintThisYear
	if (theValue == null) {
		return false;
	} else {
		myYear = parseInt(theValue);
		if ( isNaN(myYear) || (myYear < 1900) || (myYear > 2099) ) {
			return false;
		} else {
			return true;
		}
		return true;
	}
}

function fnIsDate(theValue) {
	return true;
}

function fnIsCleanText(theValue) {
	return true;
}

function fnIsPostalCode(theValue) {
	return true;
}

function fnIsZipCode(theValue) {
	return true;
}

function fnIsPhoneNumber(theValue) {
	return true;
}

/** A valid email address has exactly one '@' symbol, and a period '.' somewhere after it.
*/
function fnIsEmail(theValue) {
	if (
	(theValue.indexOf("@") >= 1) && 
	(theValue.indexOf("@") == theValue.lastIndexOf("@")) && 
	(theValue.lastIndexOf(".") > theValue.indexOf("@")+1)
	) {
		return true;
	} else {
//		alert('Please enter a valid email address.');
//		TheForm.elements[TheField].select();
//		TheForm.elements[TheField].focus();
		return false;
	}
}

function fnIsURL(theValue) {
	return true;
}

function fnIsMoney(theValue) {
	return true;
}

function fnIsDefaultOrEmpty(theValue) {
	return true;
}

/******************************* form validation functions down here??? *******************************/
/*	This general-purpose validation function checks whether all required fields have been filled in. The form elements validated by this function are INPUT (type = TEXT, TEXTAREA, HIDDEN, PASSWORD, CHECKBOX) and SELECT. 
	The javascript types are text, textarea, hidden, password, checkbox, select-one.
	How it works: we look at form elements for the attribute required="yes". 
		If a SELECT is required, the first option is a prompt and should generate a validation alert.
		If a CHECKBOX is required, it is one of a group (2 or more) of which at least one must be checked.
		If a text entry field is required, the submitted value cannot be empty string OR the value of the hinttext attribute (if any).
		A required HIDDEN field cannot be empty, but what do we do if it is?
	The validation message comes from the msg attribute, if present. If not, it is a generic message using the name attribute.
*/
function fnFormValidate(theForm) {
	var noOfReqdElements = 0;
	var noOfReqdCheckboxGroups = 0;
	var theReqdCheckboxNames = new Array();
	var noOfTypes = 0;
	var theTypes = new Array();
	var theType = "";
	for (j=0; j<theForm.elements.length; j++) {
		theType = theForm.elements[j].type;
/*
		isNewType = true;
		for (k=0; k<theTypes.length; k++) {
			isNewType = isNewType && (theTypes[k] != theType);
		}
		if (isNewType) {
			theTypes[noOfTypes++] = theType;
		}
*/
		if ((theForm.elements[j].getAttribute('required') != null) && (theForm.elements[j].getAttribute('required') != 'no')) {
			if (theType == 'text' || theType == 'textarea' || theType == 'password') {
				// if the element is INPUT type=TEXT, check whether the value is empty or equal to hinttext attribute (if any)
				if (theForm.elements[j].value == "" || theForm.elements[j].value == theForm.elements[j].getAttribute('hinttext')) {
					theForm.elements[j].focus();
					if (theForm.elements[j].getAttribute('msg') != null) {
						alert(theForm.elements[j].getAttribute('msg'));
					} else {
						alert('Required value is missing in element: ' + theForm.elements[j].name);
					}
					return false;
				}
			} else if (theForm.elements[j].type == 'select-one') {
				// if the element is a SELECT, check whether the 0th option is selected -- note: does not apply to select-multiple!
				if (theForm.elements[j].selectedIndex == 0) {
					theForm.elements[j].focus();
					if (theForm.elements[j].getAttribute('msg') != null) {
						alert(theForm.elements[j].getAttribute('msg'));
					} else {
						alert('A value must be selected for element: ' + theForm.elements[j].name);
					}
					return false;
				}
			} else if (theType == 'hidden') {
				// if the element is HIDDEN and fails here, a required value wasn't passed in...
				if (theForm.elements[j].value == "") {
					if (theForm.elements[j].getAttribute('msg') != null) {
						alert(theForm.elements[j].getAttribute('msg'));
					} else {
						alert('Required value is missing in element: ' + theForm.elements[j].name);
					}
					return false;
				}
			} else if (theType == 'checkbox') {
				// we can't validate multiple-selects element-by-element, so collect info to process at end of loop
				// NB: in future rev, only first checkbox of group might be labelled required=yes 
				theReqdCheckboxName = theForm.elements[j].name;
				isNewReqdCheckbox = true;
				for (k=0; k<theReqdCheckboxNames.length; k++) {
					isNewReqdCheckbox = isNewReqdCheckbox && (theReqdCheckboxNames[k] != theReqdCheckboxName);
				}
				if (isNewReqdCheckbox) {
					theReqdCheckboxNames[noOfReqdCheckboxGroups++] = theReqdCheckboxName;
				}
			} else {
				// let RADIO & other types pass through
			}
		}
	}
	// at this point, all elements pass validation except possibly the multi-selects e.g. CHECKBOX
	for (i=0; i < theReqdCheckboxNames.length; i++) {
		theReqdCheckboxArray = eval('theForm.' + theReqdCheckboxNames[i]);
		isChecked = false;
		for (m=0; m < theReqdCheckboxArray.length; m++) {
			isChecked = isChecked || theReqdCheckboxArray[m].checked;
		}
		if (!isChecked) {
			theReqdCheckboxArray[0].focus();
			if (theReqdCheckboxArray[0].getAttribute('msg') != null) {
				alert(theReqdCheckboxArray[0].getAttribute('msg'));
			} else {
				alert('Required value is missing in element: ' + theReqdCheckboxNames[i]);
			}
			return false;
		}
	}
/*
	alert('Form passes validation!');
	return false;
*/
	return true;
}