function fDisallowDefaultValue() { // v2.0.0 2006-09-12; like:; req:;
	if (!gbW3C) return gfW3C_Failed();

	bFormPassed = true;
	for (var i = 0; i < fDisallowDefaultValue.arguments.length; i=+2) {
		sFormField = fDisallowDefaultValue.arguments[i];
		bDisallowBlank = fDisallowDefaultValue.arguments[i+1];
	
		oFormField = document.getElementById(sFormField);
		if (!oFormField) return gfMissingObj(sFormField);

		if (oFormField.value == oFormField.defaultValue) {
			oFormField.className = 'inputFormFieldAlert'; /* could be improved, cuz will overwrite */
			bFormPassed = false;
		} else {
			if (oFormField.value == "" && bDisallowBlank) {
				oFormField.className = 'inputFormFieldAlert';
				bFormPassed = false;
			} else
				oFormField.className = 'inputFormField';
		}
	}
	return bFormPassed;
}
function fTextareaEnlargeAndMaxLen(oFormField,oEvent, iMaxLen, bShowWordCount) { /* v1.0.0 2006-11-01; like:; req:fEnlargeTextarea(v1.0),fTextareaMaxLen(v1.0); */
	fEnlargeTextarea(oFormField, oEvent)
	fTextareaMaxLen(oFormField, iMaxLen)
}
function fEnlargeTextarea(oTextarea, oEvent) { /* v1.0.1 2006-08-01; like:fTextareaEnlargeAndMaxLen(v1.0); req:; HTML row attribute required */
	var iKeyCode = oEvent.keyCode ? oEvent.keyCode : oEvent.which ? oEvent.which : oEvent.charCode;
	if (iKeyCode == 13) oTextarea.rows += 1; // enter key
}
function fFormFieldMinLen(oFormField, iMinLen) { // v1.0.0 2006-08-21; like:; req:;
	if (oFormField.value.length < iMinLen) {
		alert('Warning: Your ' + oFormField.name + ' is too short!  The minimum length is ' + iMinLen + ' characters.');
		return false;
	}
}
function fTextareaMaxLen(oFormField, iMaxLen) { // v1.0.0 2005-09-25; like:fTextareaEnlargeAndMaxLen(v1.0); req:;
	if (oFormField.value.length > iMaxLen) {
		alert('Warning: Your input has been truncated!  Please limit your entry to ' + iMaxLen + ' characters.');
		oFormField.value = oFormField.value.substring(0, iMaxLen);
	}
}
function fFreshFormField(oFormField) { // v1.0.0 2004-10-04; like:; req:;
	if (oFormField.value == oFormField.defaultValue) oFormField.value = "";
}
function fNonBlankFormField(oFormField) { // v1.4.10 2005-09-22; like:fValidateForm(v2.4),fValidateFormField(v1.3); req:;
	if (oFormField.type) {
		if (/text|file|password|hidden/.test(oFormField.type)) { // text and file and password
			return (oFormField.value.replace(/ /g, "").length != 0); // trim spaces
		} else if (/select/.test(oFormField.type)) { // select dropdown menu; both multiple and single
			if (oFormField.selectedIndex == -1) return false;
			else if (oFormField.selectedIndex == 0 && oFormField.options[oFormField.selectedIndex].value == "") // if first item selected AND blank value (meaning default value often instruction label)
				return false;
			else return true;
		} else if (/radio|checkbox/.test(oFormField.type)) { // single radio/checkbox
			return (oFormField.checked);
		} else alert('Note to Webmaster: Form type action not defined.');
	} else if (oFormField.length && oFormField[0].type && /radio|checkbox/.test(oFormField[0].type)) // multiple radio/checkbox
		for (var i=0; i<oFormField.length; i++)
			if (oFormField[i].checked) return true;
	return false;
}
function fValidDate(sDateFormat, oFormField) { // v1.3.30 2005-10-05; like:fValidateForm(v2.4),fValidateFormField(v1.3); req:;
	if (!sDateFormat) { alert('Note to Webmaster: Date format MUST be default value (i.e. yyyy-mm-dd).'); return; }
	sDateFormat_delimiter = sDateFormat.replace(/y|m|d/g, "").charAt(0); // find delimiter
	if (oFormField.value.indexOf(sDateFormat_delimiter) == -1) return false; // delimiters are different
	aDate = oFormField.value.split(sDateFormat_delimiter);
	aDateFormat = sDateFormat.split(sDateFormat_delimiter);

	for (i=0; i<aDateFormat.length; i++) {
		if (isNaN(aDate[i])) // ensure numbers only; if character found then cancel
			return false;
		if (aDateFormat[i].length > aDate[i].length) { // code does NOT remove ZERO, yet
			aDate[i] = (aDate[i].length == 1)?"0"+aDate[i]:aDate[i]; // add zero if single digit
			if (aDateFormat[i].toLowerCase().indexOf('y') != -1) // year length must match
				return false;
		}
		if (aDateFormat[i].toLowerCase().indexOf('y') != -1)
			iYear = parseInt(aDate[i]);
		else if (aDateFormat[i].toLowerCase().indexOf('m') != -1)
			iMonth = parseInt(aDate[i])-1;
		else if (aDateFormat[i].toLowerCase().indexOf('d') != -1)
			iDay = parseInt(aDate[i]);
	}
	var oTestDate=new Date(iYear, iMonth, iDay);
	return (iYear==oTestDate.getFullYear() && iMonth==oTestDate.getMonth() && iDay==oTestDate.getDate()) // prevent month wrap; Jan 33 = Feb 2
}
function fValidEmail(oFormField) { // v1.2.0 2006-10-20; like:fValidateFormField(v1.3); req:;
	if (!(/^.+@.+\..{2,6}$/.test(oFormField.value))) return false; /* test format; top-level: ca to museum */
	else if (oFormField.value.match(/[\(\)\<\>\,\;\:\\\"\[\]]/)) return false; //test for illegal characters
	return true;
}
function fValidPhone(oFormField) { v='v3.0.1 2007-04-16; like:fValidateFormField(v1.3); req:;';
	return (/^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})|(\(?\d{2,3}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$/.test(oFormField.value)); /* accepts phone number in both local format (eg. 02 1234 5678 or 123 123 4567) or international format (eg. +61 (0) 2 1234 5678 or +1 123 123 4567). It also accepts an optional extention of up to five digits prefixed by x or ext (eg. 123 123 4567 x89). */
}
function fValidPhoneOLD(oFormField) { // v2.0.0 2005-09-01; like:fValidateFormField(v1.3); req: fFormatValue(v1.0);
	var sPhoneNumbers = oFormField.value.replace(/[\(\)\.\-\ ]/g, ""); // strip out acceptable non-numeric characters
	if (isNaN(sPhoneNumbers) || (sPhoneNumbers.length != 10)) // contains no letters and check for 10 digits
		return false;
	else {
		oFormField.value = fFormatValue(sPhoneNumbers,"(",3,") ",3,"-",4)
		return true;
	}
}
function fValidPostal(oFormField) { /* v1.0.0 2006-11-01; like:; req:; */
	return (/^(\d{5}|\d{9}|\d{5}-\d{4}|[a-z]\d[a-z]\s*\d[a-z]\d)$/i.test(oFormField.value)); /* US and Canada */
}
function fValidateFormField(oFormField) { // CUSTOM v1.3.30 2005-10-05; like:fValidateForm(v2.4); req:fNonBlankFormField(v1.4),fValidDate(v1.2), fValidEmail(v1.1), fValidPhone(v1.0);
	if (!fNonBlankFormField(oFormField)) return false;
	if (oFormField.name) // radio,checkbox nameless
		if (oFormField.name.toLowerCase().indexOf('date') != -1)        /* check for valid Date */
			return fValidDate(oFormField.defaultValue,oFormField)         /* date format MUST be hardcoded as value */
		else if (oFormField.name.toLowerCase().indexOf('email') != -1)  /* check for valid E-Mail */
			return fValidEmail(oFormField)
		else if (oFormField.name.toLowerCase().indexOf('phone') != -1)  /* check for valid Telephone */
			return fValidPhone(oFormField)
/*		else if (oFormField.name.toLowerCase().indexOf('postal') != -1) // check for valid Postal Code 
			return fValidPostal(oFormField) */
	return true;
}
function fValidateForm() { // v2.4.3 2006-09-25; like:; req:fValidateFormField(v1.3);
	if (!gbW3C) return gfW3C_Failed();

	oForm = fValidateForm.arguments[0];
	if (!oForm)
		alert('Note to Webmaster: fValidateForm is missing Form object as first parameter!');

	var bFormPassed = true, oLabel, tLabels = document.getElementsByTagName('label');
	for (var i=0; (oLabel = tLabels[i]); i++) {
		if (oLabel.className == 'txtFormLabelRequired' || oLabel.className == 'txtFormLabelAlert') {
			if (!oLabel.htmlFor) alert('Note to Webmaster: JS validation label MUST have "for" attribute.');
			if (document.getElementById(oLabel.htmlFor))
				var oFormField = oForm[document.getElementById(oLabel.htmlFor).name]; /* take ID from label and learn name associated with form element */

			if (oFormField) {
				var oClarifyLabel = document.getElementById(oFormField.id+"Clarify");
				if (fValidateFormField(oFormField)) {
					oFormField.className = 'inputFormFieldRequired';
					oLabel.className = 'txtFormLabelRequired';
					if (oClarifyLabel) oClarifyLabel.style.display = 'none';
				} else {
					bFormPassed = false;
					oFormField.className = 'inputFormFieldAlert';
					oLabel.className = 'txtFormLabelAlert';
					if (oClarifyLabel) oClarifyLabel.style.display = 'block';
				}
			} else
				alert('Note to Webmaster: ' + oLabel.htmlFor + ' missing ID attribute.');
		}
	}

	if (fValidateForm.arguments.length > 0) { /* check for additional validate functions */
		for (var i = 1; i < fValidateForm.arguments.length; i++) {
			bAdditionalValidationPassed = fValidateForm.arguments[1];
			bFormPassed = (bAdditionalValidationPassed == false) ? false : bFormPassed;
		}
	}

	if (!bFormPassed) alert("Required fields are highlighted");
	return bFormPassed;
}
function fFormatValue(sRawString) { // v1.0.0 2005-09-01; like: fValidPhone(v2.0); req:;
	var arg, sPos = 0, sReturn = "";
	for (var i = 1; i < fFormatValue.arguments.length; i++) {
		arg = fFormatValue.arguments[i];
		if (i % 2 == 1) sReturn += arg;
		else {
			sReturn += sRawString.substring(sPos, sPos + arg);
			sPos += arg;
		}
	}
	return sReturn;
}
