<!--
/*********************************************************
*	NAME:		ValidateForm
*
*	PURPOSE:	Generic form validation
*					Can validate form elements by type, length and value or
*					a combination of type, length and value.
*
*	USE:			Below is an example of how to use this function
*
*		//Include the FormValidation.JS include file
*		<Script LANGUAGE="JavaScript" src="/FormValidation.js"></Script>
*
*		<Script Language="JavaScript">
*		//Function call on the in the Form tag e.g. OnSubmit="return CheckForm();"
*		function CheckForm() {
*		
*			//Create an object of type ValidateForm
*			var objnewform = new ValidateForm();
*			
*			//Set the Error Message Header for both when there is one and more than one errors
*			objnewform.SetMessageHeader("Singular Error", "Plural Error");
*		
*			//Assign the form name to a variable.
*			var form = document.frmTest;
*
*			//Check the rad Button has been selected
*			objnewform.ValidateField("document.frmTest.radTest", "RadioButtonSelected", false, "", "", "Error Here");
*		
*			//Check the element TestString is of type string and it can be blank
*			objnewform.ValidateField(form.TestString.value, "String", true,  "", "", "Error on element TestString_String");
*
*			//Check the element TestStringLength is of type string, it can be blank and it has to be between 2-5 chars in length
*			objnewform.ValidateField(form.TestStringLength.value, "String", false, "2-5", "", "Error on element TestStringLength_String");
*
*			//Check the element TestNumber is of type number and is not one of the following values 1, 5 or 6
*			objnewform.ValidateField(form.TestNumber.value, "Number", false, "", "!1,5,6", "Error on element TestNumber");
*
*			//Check the element TestMoney is of type money and is greater than £100.00
*			objnewform.ValidateField(form.TestMoney.value, "Money", false, "", ">100.00", "Error on element TestMoney");
*
*			//Check the element TestNotEmpty is of no type but it has to be 5 chars long
*			objnewform.ValidateField(form.TestNotEmpty.value, "NotEmpty", false, "5", "", "Error on element NotEmpty");
*
*			//Check the element TestEmail is of type Email
*			objnewform.ValidateField(form.TestEmail.value, "Email", false, "", "", "Error on element TestEmail");
*
*			//Check the element TestDate is of type Date or blank
*			objnewform.ValidateField(form.TestDate.value, "Date", true, "", "", "Error on element TestDate");
*
*			//Check the radio button has been selected
*			objnewform.ValidateField("document.frmStandardLife.radPayment", "RadioButtonSelected", false, "", "", "Please fill in how often you wish to pay your contributions");
*
*			//Add error event
*			objnewform.AddErrorEvent("Please make sure that your employer regular payment is a valid amount (e.g. 300)");
*
*		
*			//Get the numbers of errors that have occurred
*			var errorcount = objnewform.ErrorCount();
*			if (errorcount > 0) {
*		
*				//Display the error message
*				objnewform.DisplayErrors();
*				return false;
*		
*			} else {
*		
*				return true;
*			}
*		
*			objnewform = null;
*		}
*
*    </Script>
*
*	TYPES: List of types that can be checked for:
*				- String
*				- Number
*				- Money
*				- NotEmpty
*				- Email
*				- Date
*				- RadioButtonSelected
*				- CheckBox
*
*	LENGTH CHECK : In the length parameter you can enter one of the following
*				- 5 (will check the input has 5 chars)
*				- <5 (will check the input has less than 5 chars)
*				- >5 (will check the input has greater than 5 chars)
*				- 1-5 (will check the input has between 1 and 5 chars)
*
*	VALUE CHECK:	In the value parameter you can enter one of the following
*				- 5 (will check the input is equal to 5)
*				- <5 (will check the input is equal to less than 5)
*				- >5 (will check the input is equal to greater than 5)
*				- 1-5 (will check the input has a value between 1 and 5)
*				- 1,5,6 (will check the input is equal to one of 1,5 and 6)
*				- !1,5,6 (will check the input is not equal to 1,5 or 6)
*
*	PARAMETERS :		Form Element Value
*							Element Type
*							Can the element be blank
*							The required length of the element
*							The values the element can be
*							Error message to display
*							
*							e.g
*							objnewform.ValidateField(form.TestNumber.value, "Number", false, "2", "!1,5,6", "Error on element TestNumber");
*
*	AUTHOR :	Owain Wragg
*
*************************************************************************************/


function ValidateForm() {
		
	this.errCount = 0;
	this.errMessage = "";
	this.errMessageHeaderSingular = "The Form has the following error\n";
	this.errMessageHeaderPlural  = "The Form has the following errors\n"
	this.ValidateField = CheckFieldValue;
	this.ErrorCount = ReturnErrorCount;
	this.AddErrorEvent = AddError;
	this.DisplayErrors = DisplayErrors;
	this.SetMessageHeader = SetMessageHeader;		
			
	this.ProcessString = ProcessStringElement;
	this.CheckIsString = IsString;
	this.CheckLength = CheckLength;
	this.ProcessNumber = ProcessNumberElement;
	this.CheckIsNumber = IsNumber;
	this.CheckNumberValue = CheckNumberValue;
	this.ProcessMoney = ProcessMoneyElement;
	this.CheckIsMoney = IsMoney
	this.CheckMoneyValue = CheckMoneyValue;
	this.ProcessNotEmpty = ProcessNotEmptyElement;
	this.ProcessEmail = ProcessEmailElement;
	this.CheckIsEmail = IsEmail;
	this.ProcessDate = ProcessDateElement;
	this.CheckIsDate = IsDate;
	this.Checky2k = y2k;
	this.ProcessRadioButton = ProcessRadioButton;
	this.ProcessCheckBox = ProcessCheckBox;
		
}
		
function SetMessageHeader(HeaderSingular, HeaderPlural) {
		
	this.errMessageHeaderSingular = HeaderSingular;
	this.errMessageHeaderPlural = HeaderPlural;
		
}
	
function AddError(ErrorMessage) {
		
	this.errCount++;
	this.errMessage = this.errMessage + "\n" + ErrorMessage;
}

function ReturnErrorCount() {

	return this.errCount;

}

function DisplayErrors() {

	if (this.errCount == 1) {
		alert(this.errMessageHeaderSingular + this.errMessage);
	} else {
		alert(this.errMessageHeaderPlural + this.errMessage);
	}
}

function CheckFieldValue (Value, Type, CanBeBlank, LengthCheck, ValueCheck, ErrMessage) {
		
	switch (Type) {
		case "String":
			this.ProcessString(Value, Type, CanBeBlank, LengthCheck, ErrMessage);
			break;
		case "Number":
			this.ProcessNumber(Value, Type, CanBeBlank, LengthCheck, ValueCheck, ErrMessage);
			break;
		case "Money":
			this.ProcessMoney(Value, Type, CanBeBlank, LengthCheck, ValueCheck, ErrMessage);
			break;
		case "NotEmpty":
			this.ProcessNotEmpty(Value, LengthCheck, ErrMessage);
			break;
		case "Email":
			this.ProcessEmail(Value, Type, CanBeBlank, ErrMessage);
			break;
		case "Date":
			this.ProcessDate(Value, Type, CanBeBlank, ErrMessage);
			break;
		case "RadioButtonSelected":
			this.ProcessRadioButton(Value, Type, ErrMessage);
			break;
		case "CheckBox":
			this.ProcessCheckBox(Value, Type, ErrMessage);
			break;
		}
}

function ProcessCheckBox(Value, Type, ErrMessage) {

	var blnChecked = eval(Value + '.checked');
	
	if (!blnChecked) {
		this.AddErrorEvent(ErrMessage);
	}

}
		
function ProcessRadioButton(Value, Type, ErrMessage) {
	
	var intlength;
	intlength = eval(Value + '.length');
	var blnIsChecked = false
	var i;
	
	if ( ((eval(Value + '.checked')) == false) || ((eval(Value + '.checked')) == true) ) {
		blnIsChecked = eval(Value + '.checked');
		
	} else {
	
		for (i = 0; i < intlength; i++) {
	
			if (eval(Value + '[' + i + '].checked')) {
				blnIsChecked = true;
			}
			
		}
		
	}
	
	if (!blnIsChecked) {
		this.AddErrorEvent(ErrMessage);
	}

}

function ProcessMoneyElement(Value, Type, CanBeBlank, LengthCheck, ValueCheck, ErrMessage) {
	
	var blnErrorAlready = false;
			
	if (!CanBeBlank || (CanBeBlank && Value.length != 0)) {
			
		if (Value.length == 0) {
				
			this.AddErrorEvent(ErrMessage);
			blnErrorAlready = true
				
		} else {
				
			var blnCheck = this.CheckIsMoney(Value, Type, ErrMessage);
					
			if (LengthCheck !="" && blnCheck) {
					
				blnCheck = this.CheckLength(Value, LengthCheck, ErrMessage);
						
			}
		
			if (ValueCheck != "" && blnCheck) {
					
				this.CheckMoneyValue(Value, ValueCheck, ErrMessage);
						
			}
					
		}
				
	}
			
	if (!blnErrorAlready) {
		if (!CanBeBlank && Value.length == 0) {
			
			this.AddErrorEvent(ErrMessage);
				
		}
	}
}
		
function ProcessNumberElement(Value, Type, CanBeBlank, LengthCheck, ValueCheck, ErrMessage) {
		
	var blnErrorAlready = false;
			
	if (!CanBeBlank || (CanBeBlank && Value.length != 0)) {
			
		if (Value.length == 0) {
				
			this.AddErrorEvent(ErrMessage);
			blnErrorAlready = true
				
		} else {
				
			var blnCheck = this.CheckIsNumber(Value, Type, ErrMessage);
					
			if (LengthCheck !="" && blnCheck) {
					
				blnCheck = this.CheckLength(Value, LengthCheck, ErrMessage);
						
			}
		
			if (ValueCheck != "" && blnCheck) {
					
				this.CheckNumberValue(Value, ValueCheck, ErrMessage);
						
			}
					
		}
				
	}
			
	if (!blnErrorAlready) {
		if (!CanBeBlank && Value.length == 0) {
			
			this.AddErrorEvent(ErrMessage);
				
		}
	}
				
}
		
function ProcessStringElement(Value, Type, CanBeBlank, LengthCheck, ErrMessage) {
		
	var blnErrorAlready = false;
			
	if (!CanBeBlank || (CanBeBlank && Value.length != 0)) {
			
		if (Value.length == 0) {
				
			this.AddErrorEvent(ErrMessage);
			blnErrorAlready = true;
					
		} else {
			var blnTypeCheck = this.CheckIsString(Value, Type, ErrMessage);

			if (LengthCheck != "" && blnTypeCheck) {
			
				this.CheckLength(Value, LengthCheck, ErrMessage);
			
			}
		}
	}
			
	if (!blnErrorAlready) {
		if (!CanBeBlank && Value.length == 0) {
			
			this.AddErrorEvent(ErrMessage);
				
		}
	}		
}

function ProcessEmailElement(Value, Type, CanBeBlank, ErrMessage) {
		
	var blnErrorAlready = false;
			
	if (!CanBeBlank || (CanBeBlank && Value.length != 0)) {
			
		if (Value.length == 0) {
				
			this.AddErrorEvent(ErrMessage);
			blnErrorAlready = true
				
		} else {
				
			var blnCheck = this.CheckIsEmail(Value, Type, ErrMessage);
		
		}
				
	}
			
	if (!blnErrorAlready) {
		if (!CanBeBlank && Value.length == 0) {
			
			this.AddErrorEvent(ErrMessage);
				
		}
	}
		
}
		
function ProcessNotEmptyElement(Value, LengthCheck, ErrMessage) {
			
	var blnAllBlank = true;
		
	if (Value.length == 0) {
		this.AddErrorEvent(ErrMessage);
	} else {
		for (var i = 0; i < Value.length; i++) {
			strChar = Value.charAt(i);
			if (strChar != " ") {
				blnAllBlank = false;
			}
		}
		
		if (blnAllBlank) {
			this.AddErrorEvent(ErrMessage);
			return false;
		}
		
		if (LengthCheck != "") {
			this.CheckLength(Value, LengthCheck, ErrMessage);
		}
	}			
}
		
function ProcessDateElement(Value, Type, CanBeBlank, ErrMessage) {
		
	var blnErrorAlready = false;
			
	if (!CanBeBlank || (CanBeBlank && Value.length != 0)) {
			
		if (Value.length == 0) {
				
			this.AddErrorEvent(ErrMessage);
			blnErrorAlready = true
				
		} else {
				
			var blnCheck = this.CheckIsDate(Value, Type, ErrMessage);
		
		}			
	}
			
	if (!blnErrorAlready) {
		if (!CanBeBlank && Value.length == 0) {
			
			this.AddErrorEvent(ErrMessage);
				
		}
	}		
}

function IsNumber(Value, Type, ErrMessage) {
			
	var blnIsNumber = isNaN(Value);
			
	if (blnIsNumber) {
		this.AddErrorEvent(ErrMessage);
		return false;
	} else {
		return true;
	}
}

function CheckNumberValue(Value, ValueCheck, ErrMessage) {
		
	var blnReturn = true;
	var intValue = parseInt(Value);
	var intTmpValue;
			
	if (ValueCheck.indexOf("-") != "-1" ) {
		//"Between"
		var intLowerBound = parseInt(ValueCheck.substr(0, ValueCheck.indexOf("-")));
		var intUpperBound = parseInt(ValueCheck.substr(ValueCheck.indexOf("-") + 1));
		if (intValue < intLowerBound || intValue > intUpperBound) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	} else if (ValueCheck.indexOf("<") != "-1" ) {
		intTmpValue = parseInt(ValueCheck.substr(ValueCheck.indexOf("<") + 1));
		if (intTmpValue <= intValue) {
			this.AddErrorEvent(ErrMessage);
			blnReturn =false
		}
	} else if (ValueCheck.indexOf(">") != "-1") {
		//"GreaterThan"
		intTmpValue = parseInt(ValueCheck.substr(ValueCheck.indexOf(">") + 1));
		if (intValue <= intTmpValue) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	} else if (ValueCheck.indexOf(",") != "-1") {
		//"One from a list e.g. 1,4,5"
		if (ValueCheck.indexOf("!") == "-1") {
			var arryValues = ValueCheck.split(",");
			var arryLength = arryValues.length;
			var blnValueMatched = false;
			var i;
				
			for (i = 0; i < arryLength; i++) {
				if (intValue == arryValues[i]) {
					blnValueMatched = true;
				}
			}
				
			if (!blnValueMatched) {
				this.AddErrorEvent(ErrMessage);
				blnReturn = false;
			}
					
		} else if (ValueCheck.indexOf("!") != "-1") {
			//"Note one from a list e.g. !1,2,5"
			intTmpValue = ValueCheck.substr(ValueCheck.indexOf("!") + 1);
			var arryValues = intTmpValue.split(",")
			var arryLength = arryValues.length;
			var blnValueMatched = false;
			var i;
				
			for (i = 0; i < arryLength; i++) {
				if (intValue == arryValues[i]) {
					blnValueMatched = true;
				}
			}

			if (blnValueMatched) {
				this.AddErrorEvent(ErrMessage);
				blnReturn = false;
			}
		}
				
	} else {
		//"Equals"
		if (intValue != parseInt(ValueCheck)) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	}
			
	return blnReturn;		
}
		
function IsMoney(Value, Type, ErrMessage) {
		
	var intDecimalPlace = Value.indexOf(".");
	var blnReturn = true;
	var blnIsNumber = false;
	var intTmpLength;
	var strPounds;
	var strPence;
	var intCommaCount = 0;
	
	for (var i = 1; i <= Value.length; i++) {
	
		if ( (Value.charAt(i - 1)) == ",") {
			intCommaCount++;
		}
	}
	
	if (intCommaCount > 1) {
		this.AddErrorEvent(ErrMessage);
		return false;
	}
			
	if (intDecimalPlace == "-1") {
		strPounds = removeCommas(Value);
		blnIsNumber = isNaN(strPounds);
		if (blnIsNumber) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	} else {
		strPounds = Value.substr(0, intDecimalPlace);
		strPence = Value.substr(intDecimalPlace + 1);
		strPounds = removeCommas(strPounds);
		blnIsNumber = isNaN(strPounds);
		if (blnIsNumber) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		} else {
			blnIsNumber = (!isNaN(strPence));
			intTmpLength = strPence.length;
			if (!(intTmpLength == 2 && blnIsNumber)) {
				this.AddErrorEvent(ErrMessage);
				blnReturn = false;
			}
		}
	}
			
	return blnReturn;
}
		
function CheckMoneyValue(Value, ValueCheck, ErrMessage) {

	var blnReturn = true;
	var intValue;
	var intDecimalPlace = Value.indexOf(".");

	intValue = parseInt((removeCommas(Value)) * 100);
	var intTmpValue;
	
	if (ValueCheck.indexOf("-") != "-1" ) {
		//"Between"
		var intLowerBound = parseInt(ValueCheck.substr(0, ValueCheck.indexOf("-")) * 100);
		var intUpperBound = parseInt(ValueCheck.substr(ValueCheck.indexOf("-") + 1) * 100);
		if (intValue < intLowerBound || intValue > intUpperBound) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	} else if (ValueCheck.indexOf("<") != "-1" ) {
		//"LessThan"
		intTmpValue = parseInt(ValueCheck.substr(ValueCheck.indexOf("<") + 1) * 100);
		if (intTmpValue <= intValue) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	} else if (ValueCheck.indexOf(">") != "-1") {
		//"GreaterThan"
		intTmpValue = parseInt(ValueCheck.substr(ValueCheck.indexOf(">") + 1) * 100);
		if (intValue <= intTmpValue) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	} else {
		//"Equals"
		intTmpValue = parseInt(ValueCheck * 100);
		if (intValue != intTmpValue) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	}
			
	return blnReturn;
}
		
function IsString (Value, Type, ErrMessage) {
		
	var strChar;
	var blnCharsValid = true;
	var blnAllBlank = true;
	var i;
	
	for (i = 0; i < Value.length; i++) {
		strChar = Value.charAt(i);
		if (strChar != " ") {
			blnAllBlank = false;
		}
	}
	
	if (blnAllBlank) {
		this.AddErrorEvent(ErrMessage);
		return false;
	}
	
	for (i=0; i<Value.length; i++) {
		strChar = Value.charAt(i);
		if (((strChar < "a" || "z" < strChar) && (strChar < "A" || "Z" < strChar)) && strChar != ' ' && strChar != "'" && strChar != "-")  {
			blnCharsValid = false;
		}
		strChar = "";
	}
			
	if (Value.length == 0) {
		blnCharsValid = false;
	}
			
	if (!blnCharsValid) {
		this.AddErrorEvent(ErrMessage);
		return false;
	} else {
		return true;
	}	
}
		
function CheckLength(Value, LengthCheck, ErrMessage) {
		
	var intLength = Value.length;
	var strTypeOfCheck;
	var intTmpLength;
	var blnReturn = true;
			
	if (LengthCheck.indexOf("-") != "-1" ) {
		//"Between"
		var intLowerBound = LengthCheck.substr(0, LengthCheck.indexOf("-"));
		var intUpperBound = LengthCheck.substr(LengthCheck.indexOf("-") + 1);
		if (intLength < intLowerBound || intLength > intUpperBound) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	} else if (LengthCheck.indexOf("<") != "-1" ) {
		//"LessThan"
		intTmpLength = LengthCheck.substr(LengthCheck.indexOf("<") + 1);
		if (intTmpLength <= intLength) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	} else if (LengthCheck.indexOf(">") != "-1") {
		//"GreaterThan"
		intTmpLength = LengthCheck.substr(LengthCheck.indexOf(">") + 1);
		if (intLength <= intTmpLength) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	} else {
		//"Equals"
		if (intLength != LengthCheck) {
			this.AddErrorEvent(ErrMessage);
			blnReturn = false;
		}
	}
			
	return blnReturn;	
}	
		
function IsDate(Value, Type, ErrMessage) {
		
	var blnReturn = true;
	var arryDate = Value.split("/");
			
	var day = arryDate[0];
	var month = arryDate[1];
	var year = arryDate[2];
	
	var yearnew, monthnew, daynew;
	
	if (isNaN(year)) { blnReturn = false;}
	if (isNaN(month)) { blnReturn = false;}
	if (isNaN(day)) { blnReturn = false;}
	
	if (blnReturn) {
		//if we get here we have numbers, so strip off the leading zeros, and convert to integers
		yearnew = parseInt(parseFloat(year));
		monthnew = parseInt(parseFloat(month));
		daynew = parseInt(parseFloat(day));
	
		var today = new Date();
		yearnew = ((!yearnew) ? y2k(today.getYear()):yearnew);
		monthnew = ((!monthnew) ? today.getMonth():monthnew-1);
		if (!daynew) return false
		var test = new Date(yearnew,monthnew,daynew);
		if ( (y2k(test.getYear()) == yearnew) &&
		     (monthnew == test.getMonth()) &&
		     (daynew == test.getDate()) ) {
		    blnReturn = true;
		} else {
		    blnReturn = false;
		}
	}
	
	if (!blnReturn) {
		this.AddErrorEvent(ErrMessage);
	}
	
	return blnReturn;
			
}
		
function y2k(number) { 
	return (number < 1000) ? number + 1900 : number; 
}
		
function IsEmail(Value, Type, ErrMessage) {

	if (!(Value.search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) != -1)) {
		this.AddErrorEvent(ErrMessage);
	}
}

function removeCommas(strCurrency) {
	var arryParts;
	var strtmp = "";
	
	arryParts = strCurrency.split(',');
	for (i=0; i<arryParts.length; i++) {
		strtmp += arryParts[i];
	}
	
	return strtmp;
	
}
//-->