// Required variables - must be declared globally
var baseerror = "Please Note:\nThere are errors on the form preventing submittal\nPlease amend and resubmit\n\n"
var whitespace = " \t\n\r\f\b"
var validchars = "abcdefghijklmnopqrstuvwxyz"
var validnums = "0123456789"
var validstring = ""
var namestr ="'-"
var emailstr ="@._-"
var phonestr ="+() -"
var i // element number
var errcolor, origcolor
var formSeed

// Standard variables - can be overridden in local pages
formSeed = "document.forms[0]."

// Check error messages
var isRadioSelectedError ="You must select one of the options"
var isDropSelectedError ="You must choose an option from the list"
var isInError = "This field must contain one of the required values"
var isNotEmptyError = "This field cannot be blank"
var isAlphaNBError = "This field must contain at least one letter"
var isAlphaNumericNBError = "This field must contain at least one letter or number"
var isAlphaError = "This field must contain at least one letter or be blank"
var isAlphaNumericError = "This field must contain at least one letter or number or be blank"
var isCustomStringError = "This field can contain only valid characters"
var isCustomStringNBError = "This field can contain only valid characters"
var isCustomOnlyError = "This field can contain only valid characters"
var isCustomOnlyNBError = "This field can contain only valid characters"
var isAllAlphaNumNBError = "This field can contain only valid characters"
var isTimeError = "Must be a valid Time (24 hour format) or blank"
var isTimeNBError = "Must be a valid Time (24 hour format)"
var isDateError = "Must be a valid date or blank"
var isDateNBError = "Must be a valid date"
var isIntegerNBError = "This must be a whole number"
var isIntegerError = "This must be a whole number or blank"
var isPosIntegerNBError = "This must be a positive whole number"
var isPosIntegerError = "This must be a positive whole number or blank"
var isNumberError = "This must be a number or blank"
var isNumberNBError = "This must be a number"
var isCheckedError = "You must check the box"
var isNameError = "This name field can only contain valid characters or be blank"
var isNameNBError = "This name field can only contain valid characters"
var isPhoneError = "This phone number field can only contain valid characters or be blank"
var isPhoneNBError = "This phone number field can only contain valid characters"
var isEmailError = "This email field can only contain valid characters or be blank"
var isEmailNBError = "This email field can only contain valid characters"

// Create a check thingy for a field
function fieldcheck(fieldname,truename,checktype,custom,newmessage) {
	this.fieldname=fieldname
	this.truename=truename
	this.checktype=checktype
	this.custom=custom
	this.newmessage=newmessage
}

//Reset the form and all the colours
function resetForm(type) {
	if (type=="F") {eval(formSeed+"reset()")}

	for (i=0; i <= formChecks.length-1; i++) {
		if (typeof(eval(formSeed+formChecks[i].fieldname))=="object") {
			if (eval(formSeed+formChecks[i].fieldname+".type")==undefined) {
				if (eval(formSeed+formChecks[i].fieldname+"[0].type")=="radio")
				{
					setRadios("off")
				}
			} else if (eval(formSeed+formChecks[i].fieldname+".type")=="checkbox" && (formChecks[i].custom!="")) {
					eval(formSeed+formChecks[i].fieldname+".style.backgroundColor='"+formChecks[i].custom+"'")
			} else {
				eval(formSeed+formChecks[i].fieldname+".style.backgroundColor='"+origcolor+"'")
			}
		}
	}
}
function resetFields() {
	for (ctr=0;ctr<resetFields.arguments.length;ctr++) {
		eval(formSeed+resetFields.arguments[ctr]+".style.backgroundColor='"+origcolor+"'")
	}
}

//Main Function - loops through each form element
function validate(errstatus,ecolor,origcol) {
	// initialise error string
	errdisplay=errstatus
	errstr = baseerror
	if (errdisplay=='Y') {
		// Grab colours for general use
		errcolor=ecolor
		origcolor=origcol
		resetForm("x")
		}
	// Loop through check array and do stuff
	for (i=0; i <= formChecks.length-1; i++) {
		  if (typeof(eval(formSeed+formChecks[i].fieldname))=="object") {
		  //check for an error
		  if (! eval(formChecks[i].checktype+"('"+formSeed+formChecks[i].fieldname+"')")) { setErrors()} }
	}
	// if 2 strings are same length, we cannot have had an error
	if (errstr.length == baseerror.length) {return true}
	else {alert(errstr);return false}
}
// end of main function

// 'cos radio are different (don't know how many we have !!!)
function setRadios(action) {
	var loopCount, col
	if (action=="on") {
		col=errcolor
	} else {
		col=(formChecks[i].custom != "")?formChecks[i].custom:origcolor
	}
	no_rad_els=eval(formSeed+formChecks[i].fieldname+'.length')
	for (loopCount=0;loopCount<no_rad_els;loopCount++) {
		eval(formSeed+formChecks[i].fieldname+"["+loopCount+"].style.backgroundColor='"+col+"'")
	}
}

// Error Setting function: add the text, change color if needed
function setErrors(id) {
	if (id) {
		eval(formSeed+id+".style.backgroundColor='"+errcolor+"'")
	} else {
		if (formChecks[i].newmessage) { errmessage=formChecks[i].newmessage }
		else {errmessage = (eval(formChecks[i].checktype+"Error"))}
		errstr = errstr + formChecks[i].truename+ ": " + errmessage +"\n"

		if (errdisplay=='Y') {
			if (eval(formSeed+formChecks[i].fieldname+".type")==undefined) {
				if (eval(formSeed+formChecks[i].fieldname+"[0].type")=="radio")
				{
					setRadios("on")
				}
			} else {
				eval(formSeed+formChecks[i].fieldname+".style.backgroundColor='"+errcolor+"'")
			}
		}
	}
}
function setFields() {
	for (ctr=0;ctr<setFields.arguments.length;ctr++) {
		eval(formSeed+setFields.arguments[ctr]+".style.backgroundColor='"+errcolor+"'")
	}
}
// end of error setting function

// Start of Check types
// in any given group of radio buttons, is one selected
function isRadioSelected(objElName) {
	var loopCount
	no_rad_els=eval(formSeed+formChecks[i].fieldname+'.length')
	for (loopCount=0;loopCount<no_rad_els;loopCount++) {
		if (eval(formSeed+formChecks[i].fieldname+"["+loopCount+"].checked")){return true}
	}
	return false
}

// for any selection box, has a value been chosen
function isDropSelected(objElName) {
	if (! eval(objElName+".value")) {return false} else {return true}
}

// has the checkbox been checked ???
function isChecked(objElName) {
	if (! eval(objElName+".checked")) {return false} else {return true}
}

// field cannot contain blank or blank type (tab/return etc) characters
function checkString(objElName,checktype,theString) {
	var loopCount
	var CharatCurrPos
	theString=theString.toUpperCase()
	for (var loopCount=0;loopCount<eval(objElName+".value.length");loopCount++)
	{
		CharatCurrPos = eval(objElName+".value.charAt(loopCount).toUpperCase()")
		if (checktype == "O") {
			if (theString.indexOf(CharatCurrPos) == -1)  {return true}
		} else {
			if (theString.indexOf(CharatCurrPos) != -1) {return true}
		}
		
	}
	return false
}

// Check for null, blank, and must contain at least one alpha/num
function checkStringRange(objElName,alpha,blank) {
	var charfound="N"
	var lcstring,thisChar
	var loopCount
	if (checkString(objElName,"O",whitespace)==false) {
		if (blank=="Y") {objElName.value="";return true
		} else {return false}
	}

	lcstring = eval(objElName+".value.toLowerCase()")
	for (loopCount=0;loopCount<lcstring.length;loopCount++) {
		thisChar = lcstring.charAt(loopCount)
		if (thisChar >= "a" && thisChar <= "z") {
			return true
		}
		if (alpha=="Y" && (thisChar >= "0" && thisChar <= "9")) {
			return true
		}
	}
	return false
}

// Check for ranges of values - all characters must be part of this
function fullcheckStringRange(objElName,incchar,incnum,incblank,blank) {
	var lcstring,thisChar
	var loopCount
	//alert("in function")
	//alert(objElName+" "+incchar+" "+incnum+" "+incblank+" "+blank)
	if (checkString(objElName,"O",whitespace)==false) {
		if (blank=="Y") {
	//		alert("blanks allowed")
			objElName.value=""
			return true
		} else {
			return false
		}
	}
	//alert (validstring)

	// set up checking string
	if (incchar=="Y" ) {validstring = validstring + validchars}
	if (incnum=="Y" ) { validstring = validstring + validnums }
	if (incblank=="Y" ) { validstring = validstring + whitespace }
	//alert (validstring)
	lcstring = eval(objElName+".value.toLowerCase()")
	for (loopCount=0;loopCount<lcstring.length;loopCount++) {
		thisChar = lcstring.charAt(loopCount)
		if (validstring.indexOf(thisChar) == -1) {return false}
	}
	return true
}

function isDate(objElName,notblank) {
	inputstr = eval(objElName+'.value.replace(/[-.]/g,"/")')
	var delim1 = inputstr.indexOf("/")
	var delim2 = inputstr.lastIndexOf("/")
	if (checkString(objElName,"O",whitespace)==false) {
		if (notblank=="Y") {objElName.value="";return false
		} else {return true}
	}	
	
	if (delim1 != -1 && delim1 == delim2) {
		//Only one delimiter - invalid
		return false
	}
	if (delim1 != -1) {
		//Delimited, so extract and process
		var dd = Number(inputstr.substring(0,delim1),10)
		var mm = Number(inputstr.substring(delim1+1,delim2),10)
		var yy = Number(inputstr.substring(delim2+1,inputstr.length),10)
	} else {
		//Not delimited, so extract and process
		if (inputstr.length != 6 && inputstr.length != 8) {
			// not right number of digits - invalid
			return false
		}
		var dd = parseInt(inputstr.substr(0,2),10)
		var mm = parseInt(inputstr.substr(2,2),10)
		var yy = parseInt(inputstr.substr(4,4),10)
	}

	// Reject if any non-numerics found
	if (isNaN(dd) || isNaN(mm) || isNaN(yy)) return false;
	// Reject if any obvious errors
	if (dd < 1 || dd > 31 || mm < 1 || mm > 12) return false;

	if (yy < 100) {
		// Sort out two digit years
		if (yy >= 50) {yy += 1900}
		else {yy += 2000}
	}

	var mymaxdays = 31
	switch (mm) {
		case 4,6,9,11:
			mymaxdays=30
			break
		case 2:
			lastfeb = new Date(yy,2,1)
			lastfeb.setDate(0)
			mymaxdays = lastfeb.getDate()
			break
	}

	if (dd > mymaxdays) {return false}
	// cannot assign values to function result, so create temp object
	objTemp=eval(objElName)
	if (dd<10) {dd = '0'+ dd}
	if (mm<10) {mm ='0' + mm}
	objTemp.value = dd + "/" + mm + "/" + yy

	return true
}

function isTime(objElName,notblank) {
	inputstr = eval(objElName+'.value.replace(/[-.]/g,":")')
	var delim = inputstr.indexOf(":")
	if (checkString(objElName,"O",whitespace)==false) {
		if (notblank=="Y") {objElName.value="";return false
		} else {return true}
	}	
	if (delim != -1) {
		//Delimited, so extract and process
		var hh = Number(inputstr.substring(0,delim),10)
		var mm = Number(inputstr.substring(delim+1,inputstr.length),10)
	} else {
		//Not delimited, so extract and process
		if (inputstr.length != 4) {
			// not right number of digits - invalid
			return false
		}
		var hh = parseInt(inputstr.substr(0,2),10)
		var mm = parseInt(inputstr.substr(2,2),10)
	}

	// Reject if any non-numerics found
	if (isNaN(hh) || isNaN(mm)) return false

	// Reject if any obvious errors
	if (hh < 0 || hh > 23 || mm < 0 || mm > 59) return false

	var tm = '0' + mm
	var th = '0' + hh
	objTemp=eval(objElName)
	objTemp.value = th.substr(th.length-2) + ':' + tm.substr(tm.length-2)

	return true
}

function checkNumber(objElName,intcheck,notblank,posneg) {
	if (checkString(objElName,"O",whitespace)==false) {
		if (notblank=="Y") {objElName.value="";return false
		} else {return true}
	}

	if (isNaN(Number(eval(objElName+".value")))) {
		return false
	} else {
		// Check for integer if required
		if (intcheck=="Y" && ((Number(eval(objElName+".value")) != parseInt(eval(objElName+".value"))))) {
			return false
		}
		// Check for pos / neg if required
		if ((posneg == "P") && (Number(eval(objElName+".value")) < 0)) {
			return false
		}
		if ((posneg == "N") && (Number(eval(objElName+".value")) > 0)) {
			return false
		}
	}
	return true
}

function CompareDates(date1,date2,ne) {
	// CAUTION - requires a date value, not a form field
	if (typeof date1 != 'string') {
		date1=date1.getDate()+"/"+(date1.getMonth()+1)+"/"+date1.getYear()
		}
	if (typeof date2 != 'string') {
		date2=date2.getDate()+"/"+(date2.getMonth()+1)+"/"+date2.getYear()
		}
	var delim1 = date1.indexOf("/")
	var delim2 = date1.lastIndexOf("/")
	var dd1 = parseInt(date1.substring(0,delim1),10)
	var mm1 = Number(date1.substring(delim1+1,delim2),10)
	var yy1 = parseInt(date1.substring(delim2+1,date1.length),10)
	var delim1 = date2.indexOf("/")
	var delim2 = date2.lastIndexOf("/")
	var dd2 = parseInt(date2.substring(0,delim1),10)
	var mm2 = Number(date2.substring(delim1+1,delim2),10)
	var yy2 = parseInt(date2.substring(delim2+1,date2.length),10)
	var date1val = new Date(yy1,mm1-1,dd1)
	var date2val = new Date(yy2,mm2-1,dd2)
	if (ne=="y") {
		if (date1val > date2val) return true
	} else if (date1val >= date2val) {
		return true
	}
	return false
}

function CompareDateTime(datetime1,datetime2) {
	// CAUTION - assumes string of format "dd/mm/yyyy hh:mm"
	// Only use after full validation of dates and times
	var delim1 = datetime1.indexOf("/")
	var delim2 = datetime1.lastIndexOf("/")
	var delim3 = datetime1.indexOf(" ")
	var delim4 = datetime1.indexOf(":")
	var dd1 = parseInt(datetime1.substring(0,delim1),10)
	var mm1 = parseInt(datetime1.substring(delim1+1,delim2),10)
	var yy1 = parseInt(datetime1.substring(delim2+1,delim3),10)
	var hh1 = parseInt(datetime1.substring(delim3+1,delim4),10)
	var nn1 = parseInt(datetime1.substring(delim4+1,datetime1.length),10)
	var dt1val = new Date(yy1,mm1-1,dd1,hh1,nn1)
	var delim1 = datetime2.indexOf("/")
	var delim2 = datetime2.lastIndexOf("/")
	var delim3 = datetime2.indexOf(" ")
	var delim4 = datetime2.indexOf(":")
	var dd2 = parseInt(datetime2.substring(0,delim1),10)
	var mm2 = parseInt(datetime2.substring(delim1+1,delim2),10)
	var yy2 = parseInt(datetime2.substring(delim2+1,delim3),10)
	var hh2 = parseInt(datetime2.substring(delim3+1,delim4),10)
	var nn2 = parseInt(datetime2.substring(delim4+1,datetime2.length),10)
	var dt2val = new Date(yy2,mm2-1,dd2,hh2,nn2)
	if (dt1val > dt2val) { return true} else { return false }
}

// intermediate functions: special circumstances
function isIn(objElName) {
	return (checkString(objElName,"I",formChecks[i].custom))
}
function isAlphaNB(objElName) {
	return (checkStringRange(objElName,"N","N"))
}
function isAlpha(objElName) {
	return (checkStringRange(objElName,"N","Y"))
}
function isAlphaNumericNB(objElName) {
	return (checkStringRange(objElName,"Y","N"))
}
function isAlphaNumeric(objElName) {
	return (checkStringRange(objElName,"Y","Y"))
}
function isNotEmpty(objElName) {
	return (checkString(objElName,"O",whitespace))
}
// Number checks
// options are : integer check, not blank, pos/neg/all
function isIntegerNB(objElName) {
	return (checkNumber(objElName,"Y","Y","A"))
}
function isInteger(objElName) {
	return (checkNumber(objElName,"Y","N","A"))
}
function isPosIntegerNB(objElName) {
	return (checkNumber(objElName,"Y","Y","P"))
}
function isPosInteger(objElName) {
	return (checkNumber(objElName,"Y","N","P"))
}
function isNumberNB(objElName) {
	return (checkNumber(objElName,"N","Y","A"))
}
function isNumber(objElName) {
	return (checkNumber(objElName,"N","N","A"))
}
// Date / Time intermediates - only for "NB"
function isTimeNB(objElName) {
	return (isTime(objElName,"Y"))
}
function isDateNB(objElName) {
	return (isDate(objElName,"Y"))
}
// String functions ; optional values are :
// include characters, include nos, include whitespace, allow blanks
function isAllAlphaNumNB(objElName) {
	validstring=""
	return (fullcheckStringRange(objElName,"Y","Y","N","N"))
}
function isNameNB(objElName) {
	validstring=namestr
	return (fullcheckStringRange(objElName,"Y","N","Y","N"))
}
function isName(objElName) {
	validstring=namestr
	return (fullcheckStringRange(objElName,"Y","N","Y","Y"))
}
function isEmailNB(objElName) {
	validstring=emailstr
	return (fullcheckStringRange(objElName,"Y","Y","N","N"))
}
function isEmail(objElName) {
	validstring=emailstr
	return (fullcheckStringRange(objElName,"Y","Y","N","Y"))
}
function isPhoneNB(objElName) {
	validstring=phonestr
	return (fullcheckStringRange(objElName,"N","Y","N","N"))
}
function isPhone(objElName) {
	validstring=phonestr
	return (fullcheckStringRange(objElName,"N","Y","N","Y"))
}
function isCustomStringNB(objElName) {
	validstring=formChecks[i].custom
	return (fullcheckStringRange(objElName,"Y","Y","Y","N"))
}
function isCustomString(objElName) {
	validstring=formChecks[i].custom
	return (fullcheckStringRange(objElName,"Y","Y","Y","Y"))
}
function isCustomOnlyNB(objElName) {
	validstring=formChecks[i].custom
	return (fullcheckStringRange(objElName,"N","N","N","N"))
}
function isCustomOnly(objElName) {
	validstring=formChecks[i].custom
	return (fullcheckStringRange(objElName,"N","N","N","Y"))
}
