<!--
/* Copyright (c) 2003 Forty Two International Pty. Ltd.
   All Rights Reserved. */

//window.onerror = function () { return true; };

/* Purpose of this javascript is to perform form validation on items in a form. */

function ECM_hiddenFormValidate(theForm) {
	var inputs = theForm.getElementsByTagName("input");
	var textareas = theForm.getElementsByTagName("textarea");
	var selects = theForm.getElementsByTagName("select");
	var i,j;
	var returnval = true;
	var msg = "";
	var str;
	var objDesc
	var reqThis;
	var validThis;
	var checkedNames = new Array()

	// Check to see if collections are valid. If not, may be an odd browser; try grabbing
	// the objects using document.getElementsByTagName instead.
	if ((inputs == null)&&(textareas == null)&&(selects == null)) {
		inputs = document.getElementsByTagName("input");
		textareas = document.getElementsByTagName("textarea");
		selects = document.getElementsByTagName("select");
	}
	else if ((inputs.length == 0)&&(textareas.length == 0)&&(selects.length == 0)) {
		inputs = document.getElementsByTagName("input");
		textareas = document.getElementsByTagName("textarea");
		selects = document.getElementsByTagName("select");
	}

	// construct the array of objects we need to validate
	var objects = new Array();

	if (inputs != null) {
		for (i=0; i	< inputs.length; i++) {
			objects[i] = inputs[i];
		}
	}
	if (textareas != null) {
		for (j=0; j < textareas.length; j++, i++) {
			objects[i] = textareas[j];
		}
	}
	if (selects != null) {
		for (j=0; j < selects.length; j++, i++) {
			objects[i] = selects[j];
		}
	}

	// get the string describing the object.
	// use title if it exists, name if it doesn't, nothing if neither.
	for (i=0; i < objects.length; i++) {
		if ((objects[i].title == null)||(objects[i].title == "")) {
			if ((objects[i].name == null)||(objects[i].name == "")) {
				objDesc = ":";
			}
			else {
				objDesc = objects[i].name;
				objDesc = "\"" + objDesc + "\":";
			}
		}
		else {
			objDesc = objects[i].title
			objDesc = "\"" + objDesc + "\":";
		}

		// get the objects required and validation info
		// these are enforced to be lowercase, but some older forms may break if
		// there is no support for the upper case version as well; so both will work.
		if (objects[i].attributes["requireThis"]) {
			reqThis = objects[i].attributes["requireThis"].value;
		}
		else if (objects[i].requireThis) {
			reqThis = objects[i].requireThis.value;
		}
		else if (objects[i].attributes["requirethis"]) {
			reqThis = objects[i].attributes["requirethis"].value;
		}
		else if (objects[i].requirethis) {
			reqThis = objects[i].requirethis.value;
		}
		else {reqThis = null;}


		if (objects[i].attributes["validateThis"]) {
			validThis = objects[i].attributes["validateThis"].value;
		}
		else if (objects[i].validateThis) {
			validThis = objects[i].validateThis.value;
		}
		else if (objects[i].attributes["validatethis"]) {
			validThis = objects[i].attributes["validatethis"].value;
		}
		else if (objects[i].validatethis) {
			validThis = objects[i].validatethis.value;
		}
		else {validThis = null;}

		//check for required but empty
		if ((reqThis == "yes")&&((objects[i].value == "")||(objects[i].value == null))) {
			returnval = false;
			msg += "Required field " + objDesc.substr(0,objDesc.length - 1) + " is empty.\n";
		}
		//check for list box required values.
		if (objects[i] && objects[i].tagName && (objects[i].tagName.toLowerCase() == "select")) {
			if (reqThis == "yes") {
				// list box - is annoying. All we can do is chect that it's different from the default
				// value, really. If there is no default value? do nothing.
				var options = objects[i].getElementsByTagName("option");
				var q;
				for (q=0; q < options.length; q++) {
					if (options[q].defaultSelected) {
						if (options[q].selected) {
							returnval = false;
							msg += "Please change the value in list box " +
							objDesc.substring(0, objDesc.length - 1) +
							" to a value other than the default.\n";
						}
					}
				}
			}
		}


		if ((validThis != null)&&(validThis != "")) {
			if ((objects[i].type && objects[i].type.toLowerCase() == "radio")&&
				(validThis && validThis == "radio")) {
				// radio button validation.
				if ((objects[i].name != null)&&(objects[i].name != "")) {
					var r;
					var done = false;
					for (r=0; r < checkedNames.length; r++) {
						if (objects[i].name == checkedNames[r]) {
							done = true;
						}
					}
					if (!done) {
						// we know radio buttons of this name haven't been checked before.
						var rads;
						var oneChecked = false;
						rads = ECM_getFromFormByName(objects, objects[i].name);
						checkedNames[checkedNames.length] = objects[i].name;
						for (r=0; r < rads.length; r++) {
							if (rads[r].checked) {
								oneChecked = true;
							}
						}
						if (oneChecked == false) {
							returnval = false;
							msg += "In radio buttons: " + objDesc + " No radio button selected.\n"
						}
					}
				}
			}
			else {
				// If value is empty, do nothing; if the field was required the
				// error would be caught elsewhere
				if ((objects[i].value == null)||(objects[i].value == "")) {
					// Do nothing.
				}
				else if (validThis == "email") {
					str = ECM_validateEmail(objects[i])
					if (str != "") {
						returnval = false;
						msg += "In email field " + objDesc + " " + str + "\n";
					}
				}
				else if (validThis == "integer") {
					str = ECM_validateInteger(objects[i]);
					if (str != "") {
						returnval = false;
						msg += "In integer number field " + objDesc + " " + str + "\n";
					}
				}
				else if (validThis == "float") {
					str = ECM_validateFloat(objects[i])
					if (str != "") {
						returnval = false;
						msg += "In decimal number field " + objDesc + " " + str + "\n";
					}
				}
				else if (validThis == "date") {
					str = ECM_validateDate(objects[i])
					if (str != "") {
						returnval = false;
						msg += "In date field " + objDesc + " " + str + "\n";
					}
				}
			}
		}
	}
	if (msg != "") {
		alert(msg);
	}
	return(returnval);
}


// validate an email address
function ECM_validateEmail(El) { 
	var s, sAddr, sDomain;
	var iErr=0;
	var msg = "";

	iPos = El.value.indexOf("@");
	if (iPos != -1 && iPos != El.value.length - 1) {
		sAddr = El.value.substring(0,iPos);
		sDomain = El.value.substring(iPos + 1, El.value.length);
		s = ECM_stringUtil(0, sAddr,1,1,1,"!#$%&'*+-/=?^_`{|}~.");
		if (s.length > 0) {
			if (s == "@")
				iErr = 2;
			else
				iErr = 3;
		} else {
			s = ECM_stringUtil(0, sDomain,1,1,1,"_-.");
			if (s.length > 0) {
				if (s == "@")
					iErr = 2;
				else 
					iErr = 3;
			} 
			iPos = sDomain.lastIndexOf(".");
			if (iPos == -1 || iPos == sDomain.length -1)
				iErr = 1;
		} 
	} else {
		iErr = 1;
	}
	
	if (iErr > 0) 
		msg="Invalid email address.";
	if (iErr == 2)
		msg += " Too many '@' characters.";
	else if (iErr == 3)
		msg += " '" + s + "' is not a valid character for this field.";

	return(msg);
}

function ECM_validateDate(El) {
//! Select the date Format for the server location: USA = mm-dd-yy; INT = dd-mm-yy
//////var dFormat = "USA";
	var dFormat = "INT";

	var date, dDate, sDate, sDay, sMonth, sYear, today, delim, i, c, mPos, m1, m2, pos1, pos2, leapYearInd, msg, ok;
	monthNames = new Array("JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC");
	monthDays = new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
	date = El.value;
	today = new Date();
	today = today.toString();
	msg = "";

	monthName = ""; mPos = 0
	delim = "";
	for (i=0; i < date.length; i++) {
		c = date.charAt(i);
		if (c < "0" || c > "9") {
			if (c < "A" || c > "Z") {
				if (c < "a" || c > "z") {
					delim = c;
				}
				else {
					if (mPos == 0 || mPos == i - 1) {monthName += c; mPos = i}
				}
			}
			else {
				if (mPos == 0 || mPos == i - 1) {monthName += c; mPos = i}
			}
		}
	}

	sMonth = "";
	if (monthName != "") {
		// This appears to be completely and utterly pointless;
		// why copy monthName out of the string, and then find the
		// index it is at and copy the same string out again?
		// I'm leaving it in, in case it does something I can't figure out.
		m1 = date.indexOf(monthName);
		m2 = m1 + monthName.length;
		monthName = date.substring(m1,m2);
		if (monthName.length > 3) {monthName = monthName.substring(0,3)}
		monthName = monthName.toUpperCase();
		for (i=0; i < 12; i++) {
			if (monthNames[i] == monthName) {
				sMonth = i + 1;
				break;
			}
		}

		if (sMonth == "") {msg = "Please enter date in dd/mm/yyyy format";};
		if (m1 > 0) {dFormat = "INT"}
	}

	if (delim == "") {
		// no delimiter
		if (dFormat == "USA") {
			if (sMonth == "") {
				sMonth = date.substring(0,2)
				sDay = date.substring(2,4);
				sYear  = date.substring(4,date.length);
			}
			else {
				sDay = date.substring(m2,m2 + 2);
				sYear  = date.substring(m2 + 2,date.length);
			}
		}
		else {
			if (sMonth == "") {
				sMonth = date.substring(2,4);
				sYear  = date.substring(4,date.length);
			}
			else {
				sYear  = date.substring(m2 + 2,date.length);
			}
			sDay = date.substring(0,2);
		}
	}
	else {
		// has  delimiter 
		pos1 = date.indexOf(delim);
		pos2 = date.lastIndexOf(delim);
		if (pos2 == pos1) {pos2 = date.length};

		if (dFormat == "USA") {
			if (sMonth == "") {sMonth = date.substring(0,pos1)}
			sDay   = date.substring(pos1 + 1, pos2);
		}
		else {
			sDay   = date.substring(0,pos1);
			if (sMonth == "") {sMonth = date.substring(pos1 + 1, pos2)}
		}
		sYear  = date.substring(pos2 + 1, date.length);
	}

	if (sYear.length < 4) {
		var yr = new Date();
		if (yr.getFullYear) {
			var str = "" + yr.getFullYear();
			sYear = str.substring(0, str.length - sYear.length) + sYear;
		}
		else {
			sYear = today.substring(today.length - 4,today.length - sYear.length) + sYear;
		}
	}

	// validate 
	if (msg == "") { 
		ok = 1;
		for (i = 0; i < sYear.length; i++) {
			c = sYear.substring(i, i + 1);
			if (c < "0" || c > "9") {
				ok = 0;
				break;
			}
		}

		if (ok == 0) {msg = "Year (" + sYear + ") must be between 0001 and 9999"} else {
			if (eval(sDay < 01 || sDay > 31)) {msg = "Day (" + sDay + ") must be between 1 and 31"} else {
				if (eval(sMonth - 1) < 0 || eval(sMonth - 12) > 0) {
					msg = "Month (" + sMonth + ") must be from 01 to 12";
				}
				else {
					if (eval(sDay - monthDays[sMonth]) > 0) {
						if (eval(sMonth) == 2 && sDay == 29) {
							leapYearInd = sYear / 4;
							leapYearInd = leapYearInd.toString();
							if (leapYearInd.indexOf(".") >= 0) {msg = leapYearInd.indexOf(".") + ", " + "29th is only valid for leap years"};
						}
						else {
							msg = monthNames[sMonth - 1] + " has only " + monthDays[sMonth] + " days";
						}
					}
				}
			}
		}
	}
	if (msg != "") {
		return(msg)
	}
	else {
		El.value = sDay + "-" + sMonth + "-" + sYear;
		return("");
	}
}

function ECM_validateInteger (El) {
	var val;
	var str;

	// exempt a "-" sign at the start from being detected as a bad value.
	if (El.value.charAt(0) == "-") {
		str = ECM_stringUtil(0, El.value.substr(1), 1, 0, 0, "");
	}
	else {
		str = ECM_stringUtil(0, El.value, 1, 0, 0, "");
	}
	if (str != "") {
		return("Non numeric character \"" + str + "\"");
	}

	val = parseInt(El.value, 10);

	if 	((El.attributes["validatemin"])&&(El.attributes["validatemin"].value != "")) {
		var min = parseInt(El.attributes["validatemin"].value, 10);
		if (val < min) {
			return("Number less than minimum of " + min);
		}
	}
	if ((El.attributes["validatemax"])&&(El.attributes["validatemax"].value != "")) {
		var max = parseInt(El.attributes["validatemax"].value, 10);
		if (val > max) {
			return("Number greater than maximum of " + max);
		}
	}

	return("");
}

function ECM_validateFloat (El) {
	var val;
	var str;

	if (El.value.charAt(0) == "-") {
		str = ECM_stringUtil(0, El.value.substr(1), 1, 0, 0, ".");
	}
	else {
		str = ECM_stringUtil(0, El.value, 1, 0, 0, ".");
	}

	if (str != "") {
		return("Non numeric character: \"" + str + "\"");
	}
	// check there is at most one decimal point

	if (El.value.indexOf(".") != El.value.lastIndexOf(".")) {
		return("More than one decimal point");
	}

	val = parseFloat(El.value);

	if 	((El.attributes["validatemin"])&&(El.attributes["validatemin"].value != "")) {
		var min = parseFloat(El.attributes["validatemin"].value);
		if (val < min) {
			return("Number less than minimum of " + min);
		}
	}
	if ((El.attributes["validatemax"])&&(El.attributes["validatemax"].value)) {
		var max = parseFloat(El.attributes["validatemax"].value);
		if (val > max) {
			return("Number greater than maximum of " + max);
		}
	}

	return("");
}

function ECM_stringUtil(iMode, sString, fNumeric, fUAlpha, fLAlpha, sSpecial) { 
	var iLen, i;
	var s, c;
	var fFlag=1;

	s = ""; c = "";
	iLen = sString.length;
	for (i=0; i < iLen; i++) {
		c = sString.charAt(i);
		if (fNumeric && c >= "0" && c <= "9")
			fFlag = 1;
		else if (fUAlpha && c >= "A" && c <= "Z")
			fFlag = 1;
		else if (fLAlpha && c >= "a" && c <= "z")
			fFlag = 1;
		else if (sSpecial.indexOf(c) != -1)
			fFlag = 1;
		else
			fFlag = 0;

		if (!fFlag) {
			if (iMode == 0)
				break;
			else
				s += c;
		}
	}
	if (iMode == 0) {
		if (fFlag)
			s = "";
		else
			s = c;
	}

	return s;
}

function ECM_getFromFormByName (objects, givenName) {
	var i;
	var ret = new Array()
	var j;

	j=0;
	for (i=0; i < objects.length ; i++) {
		if (objects[i].name && (objects[i].name == givenName)) {
			ret[j] = objects[i];
			j++;
		}
	}
	return(ret);
}


-->
