//	*********************************************************************
//	*	Generic javascript validation routine written by Ian Snailham.	*
//	*	This is the first version of these procedures - please address	*
//	*	any corrections / amendments to me.								*
//	*	Amendment 1 - Year check adjusted to accept a two digit date    *
//  *	if figures entered are between 00 and 19 then 20 is added to    *
//	*	the front otherwise 19 is added and correct three digit year	*
//  *	problem.														*
//	*********************************************************************

// Regular Expressions
var reAlphabetic = /^[a-zA-Z \-\/\&\.\,\']+$/					// Alphabetic - [a to z, A - Z, space, - , /] matches the preceding characters 1 or more times
var reAlphanumeric = /^[a-zA-Z 0-9\-\/\,\n\r\&\.\']+$/			// Alphanumeric - [a to z, A - Z, space, 0 to 9, -, /] matches the preceding characters 1 or more times
var reNumeric = /^[0-9 ]+$/								// Numeric - [0 to 9, space] matches the preceding characters 1 or more times
var reInteger = /^[0-9]+$/								// Integer - [0 to 9] matches the preceding characters 1 or more times
var reCurrency = /^[0-9]+(\.[0-9]?[0-9]?)?$/			// Currency - [0 to 9] matches the preceding characters 1 or more times, ., [0 to 9][0 to 9] matches the preceding character 0 or 1 time
var reEmail = /^.+\@.+\..+$/							// Email - must contain the @ symbol and a full stop
var reSortCode = /^[0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]$/ // SortCode - two digits, hyphen, two digits, hyphen, two digits
var reYear = /^[1-2]?[089]?[0-9][0-9]$/					// Year - beginning with 1 or 2, second digit 0, 8 or 9 and then any two digits
var reDate = /^[0-3]?[0-9]\/[0-3]?[0-9]\/[1-2]?[089]?[0-9][0-9]$/
var reAPR = /^[1-3]?[0-9](\.[0-9]?[0-9]?)?$/
var rePercentage = /^[0-9]+(\.[0-9]?[0-9]?)?$/
var dteNow = new Date();
var theYear = dteNow.getFullYear();

// isIntegerInRange tests whether an integer passed into the procedure as 's' is between the range
// greater than a and less than b. If 's' is not an integer the procedure returns false, if the value
// of 's' is preceded by 0 it is stripped from the value before testing if it lies between a and b.
function isIntegerInRange(s, a, b) {
	if (!reInteger.test(s)) return false;
		if ((s.length == 2) && (s.substring(0, 1) == '0')) {
			s = s.substring(1);
		}
	var num = parseInt (s);
	return ((num >= a) && (num <= b));
}

// isDate checks that the three values strDay, strMonth and strYear will form a valid date.
// If any of these values are preceded by 0 then it is first stripped from the value before
// the test is carried out.
function isDate(strDay, strMonth, strYear) {
	switch(strMonth)
	{
		case 'January':
			strMonth = '1';
			break;
		case 'February':
			strMonth = '2';
			break;
		case 'March':
			strMonth = '3';
			break;			
		case 'April':
			strMonth = '4';
			break;			
		case 'May':
			strMonth = '5';
			break;			
		case 'June':
			strMonth = '6';
			break;			
		case 'July':
			strMonth = '7';
			break;			
		case 'August':
			strMonth = '8';
			break;			
		case 'September':
			strMonth = '9';
			break;			
		case 'October':
			strMonth = '10';
			break;			
		case 'November':
			strMonth = '11';
			break;			
		case 'December':
			strMonth = '12';
			break;			
	}
	if (strDay.substring(0, 1) == '0') {
		strDay = strDay.substring(1);
	}
	if (strMonth.substring(0, 1) == '0') {
		strMonth = strMonth.substring(1);
	}
	var CheckDate = strDay;
	var CheckMonth = strMonth;
	var CheckYear = strYear;

	if (((isNaN(CheckDate)) || (isNaN(CheckMonth))) || (isNaN(CheckYear))) {
		return false;
	}
	var mydate = new Date(parseInt(CheckYear), (parseInt(CheckMonth) - 1), parseInt(CheckDate));

	if (mydate.getFullYear() != parseInt(CheckYear)) {
		return false;
	}
	if (mydate.getMonth() != (parseInt(CheckMonth) - 1)) {
		return false;
	}
	if (mydate.getDate() != parseInt(CheckDate)) {
		return false;
	}
	return true;
}


// Description: Trim the input value by removing spaces at the start and end of
//              the input string
// Author: Richard Leonard
// Date: 29/8/02
function trim(strInput) {
	//Declare temporary variable
	var tmpInput = strInput;
	if (tmpInput != "") {
		//Step through each character from the start until not equal to a space
		//Remove one character (space) each time round
		var ch = tmpInput.substring(0, 1);
		while (ch == " ") { // Check for spaces at the beginning of the string
		 	tmpInput = tmpInput.substring(1, tmpInput.length);
	 		ch = tmpInput.substring(0, 1);
		}
	
		//Step through each character from the end until not equal to a space
		//Remove one character (space) each time round
		ch = tmpInput.substring(tmpInput.length-1, tmpInput.length);
		while (ch == " ") { // Check for spaces at the end of the string
	 		tmpInput = tmpInput.substring(0, tmpInput.length-1);
	 		ch = tmpInput.substring(tmpInput.length-1, tmpInput.length);
		}
	}

	//Return the trimmed input value
	return tmpInput;
}


// isValid (STRING strInput, STRING strType)
// strType values -	Alphabetic, Alphanumeric, Numeric, Integer,
// 					Currency, Email, SortCode, Day, Month, Year
//					(checking year will also check the date!)
// If a field can be left blank then the element ID should be set to 'emptyOK'.
function isValid(strInput, strType)
{
	if ((validated == 'Yes') || (firstCheck == 'Yes')) {
		validating = strInput.name;
		firstCheck = 'No' 
	}
	if (validating == strInput.name) {
		if ((strInput.value == null) || (strInput.value.length == 0)) {
			if (strInput.id == 'emptyOK') {
				findElement(strInput.name);
				validated = 'Yes';
				return true;
			}
			else {
					validated = 'No';
					alert("This box cannot be left blank.");
					strInput.form.elements[strInput.name].focus();
					strInput.form.elements[strInput.name].select();
					return false;
			}
		}
		else
		{
    		switch (strType)
			{
				case 'Alphabetic':
					if (reAlphabetic.test(strInput.value) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No';
						alert("The value entered must only contain alphabetic characters.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'Alphanumeric':
					if (reAlphanumeric.test(strInput.value) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No';
						alert("The value entered must only contain alphabetic or numeric characters.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'Decimal':
					if (reCurrency.test(strInput.value) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No';
						alert("The value entered must only contain numeric characters or the full stop.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'Numeric':
					if (reNumeric.test(strInput.value) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No';
						alert("The value entered must only contain numeric characters or the space character.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'Integer':
					if (reInteger.test(strInput.value) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No';
						alert("The value entered must only contain numeric characters.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'Currency':
					if (reCurrency.test(strInput.value) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No';
						alert("The value entered must be a valid monetary figure.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'Email':
					if (reEmail.test(strInput.value) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No';
						alert("Please enter a valid e-mail address.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'SortCode':
					if (reSortCode.test(strInput.value) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No'
						alert("Please enter a valid sort code.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'Day':
					if (isIntegerInRange(strInput.value, 1, 31) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No';
						alert("The value entered must be a valid day of the month.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'Month':
					if (isIntegerInRange(strInput.value, 1, 12) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No';
						alert("The value entered must be a valid month in the year.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'Year':
					if (strInput.value.length == 2) {
						if ((strInput.value.substring(0, 1) == '0') || (strInput.value.substring(0, 1) == '1')) {
							strInput.value = '20' + strInput.value;
						}
						else {
							strInput.value = '19' + strInput.value;
						}
					}
					if ((reYear.test(strInput.value) == true) && (strInput.value.length != '3') && (!isIntegerInRange(strInput.value, 1900, parseInt(thisYear) + 5))) {
						var k = 0;
						while ((strInput.name != strInput.form.elements[k].name) && (k < strInput.form.elements.length)) {
							++k;
						}
						if (isDate(strInput.form.elements[k-2].value, strInput.form.elements[k-1].value, strInput.value)) {
							findElement(strInput.name);
							validated = 'Yes';
							return true;
						}
						else {
							validated = 'No';
							alert("Please enter a valid date.");
							strInput.form.elements[k-2].focus();
							strInput.form.elements[k-2].select();
							return false;
						}	
					}
					else {
						validated = 'No';
						alert("Please enter a valid four digit year.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'APR':
					if (reAPR.test(strInput.value) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No'
						alert("Please enter a valid interest rate.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;
				case 'Percentage':
					if (rePercentage.test(strInput.value) == true) {
						findElement(strInput.name);
						validated = 'Yes';
						return true;
					}
					else {
						validated = 'No'
						alert("Please enter a valid percentage.");
						strInput.form.elements[strInput.name].focus();
						strInput.form.elements[strInput.name].select();
						return false;
					}
					break;					
				case 'NoTypeCheck':
					validated = 'Yes';
					return true;
					break;
			}
		}
	}
}	

// initialise should be run in the 'body onLoad' event to set the values of the elementOK array
// to 'No' unless the elements already contain some text. 
function initialise() {
	elementOK = new Array();
	for (n = 0 ; n < document.forms[0].elements.length ; ++n) {
		if (document.forms[0].elements[n].value == "") {
			elementOK[n] = 'No';
		}
		else {
			elementOK[n] = 'Yes';
		}
	}
validated = 'No';
firstCheck = 'Yes';
}

// findElement finds the relevant element on the form and sets the value of elementOK to 'Yes'
// once the element has been validated through the onBlur event.
function findElement(strElement) {
var i = 0
	while ((strElement != document.forms[0].elements[i].name) && (i < document.forms[0].elements.length)) {
	++i;
	}
	elementOK[i] = 'Yes';
}

// submitCheck puts the focus on each element of the form in turn in order to trigger the onBlur event
// and hence validate the element.
function submitCheck() 
{
	document.forms[0].elements[0].focus();
	for (j = 1 ; j < document.forms[0].elements.length - 1 ; ++j) 
	{
		if (document.forms[0].elements[j-1].type == 'text') 
		{
			if((document.forms[0].elements[j-1].id != 'emptyOK') || (document.forms[0].elements[j-1].value.length>0))
			{
				document.forms[0].elements[j].focus();
				if (elementOK[j-1] == 'No') 
				{
					alert("Please enter or correct the selected data on this page.");
					return false;
				}
			}
		}
	}
	return true;
}

function isFieldValid(strInput, strType, blnAllowEmpty, strName, blnDisplayMessage)
{
  blnReturnValue = true;
  strMessage = "";
  
 	if(arguments.length<3)
	{
		allowEmpty = false;
	}

	if(arguments.length<4)
	{
		strName = strInput.name;
	}

	if(arguments.length<5)
  {
    blnDisplayMessage = true;
  }

  //Remove any leading or trailing spaces from the input string
  strInput.value = trim(strInput.value);

  if ((strInput.value == null) || (strInput.value.length == 0))
  {
  	blnReturnValue = blnAllowEmpty;

		if (!blnReturnValue)
    {
			alert(strName + " cannot be left blank.");
			return false;
		}
    else
    {
      return true;
    }
	}

	switch (strType)
	{
    case 'Alphabetic':
            blnReturnValue = (reAlphabetic.test(strInput.value) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must only contain alphabetic characters.";
  					}
            break;
    case 'Alphanumeric':
            blnReturnValue = (reAlphanumeric.test(strInput.value) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must only contain alphabetic or numeric characters.";
            }
					  break;
    case 'Decimal':
					  blnReturnValue = (reCurrency.test(strInput.value) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must only contain numeric characters or the full stop.";
  					}
	  				break;
    case 'Numeric':
					  blnReturnValue = (reNumeric.test(strInput.value) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must only contain numeric characters or the space character.";
            }
  					break;
		case 'Integer':
					  blnReturnValue = (reInteger.test(strInput.value) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must only contain numeric characters.";
            }
  					break;
		case 'Currency':
			{
				var strCurrency = strInput.value.replace(/,/g, "");
				strInput.value = strCurrency
			}
					  blnReturnValue = (reCurrency.test(strCurrency) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must be a valid monetary figure.";
            }
  					break;
		case 'Email':
					  blnReturnValue = (reEmail.test(strInput.value) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must be a valid e-mail address.";
  					}
	  				break;
		case 'SortCode':
					  blnReturnValue = (reSortCode.test(strInput.value) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must be a valid sort code.";
  					}
	  				break;
    case 'Date':
            blnReturnValue = (reDate.test(strInput.value) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must be a valid date. (e.g. 31/12/1999)";
  					}
            break;
		case 'Day':
					  blnReturnValue = (isIntegerInRange(strInput.value, 1, 31) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must be a valid day of the month.";
  					}
	  				break;
		case 'Month':
					  blnReturnValue = (isIntegerInRange(strInput.value, 1, 12) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must be a valid month in the year.";
            }
  					break;
        case 'MonthDuration':
                    blnReturnValue = (isIntegerInRange(strInput.value,0,11) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must be a valid number of months.";
            }
                    break;
		case 'Year':
  					if (strInput.value.length == 2)
            {
						  if ((strInput.value.substring(0, 1) == '0') || (strInput.value.substring(0, 1) == '1'))
              {
							  strInput.value = '20' + strInput.value;
						  }
  						else
              {
	  						strInput.value = '19' + strInput.value;
		  				}
					  }
						  if ((reYear.test(strInput.value) == true) && (strInput.value.length != '3') && (isIntegerInRange(strInput.value, 1900, parseInt(theYear) + 5)))
            {
						  var k = 0;
  						while ((strInput.name != strInput.form.elements[k].name) && (k < strInput.form.elements.length)) 
              {
	  						++k;
						  }
  						if (isDate(strInput.form.elements[k-2].value, strInput.form.elements[k-1].value, strInput.value)) 
              {
		  					blnReturnValue = true;
					  	}
						  else 
              {
		  					blnReturnValue = false;
				  			strMessage = strName + " must be a valid date.";
  						}	
	  				}
		  			else 
            {
						  blnReturnValue = false;
			  			strMessage = strName + " must be a valid four digit year.";
  					}
					break;
		case 'APR':
					  blnReturnValue = (reAPR.test(strInput.value) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must be a valid interest rate.";
  			}
	  				break;
		case 'Percentage':
					  blnReturnValue = (rePercentage.test(strInput.value) == true);
            if (!blnReturnValue)
            {
              strMessage = strName + " must be a valid percentage.";
  			}
	  				break;					
		case 'NoTypeCheck':
						blnReturnValue = true;
					break;
     default:
          blnReturnValue = false;
          strMessage = strType + " is not a valid validation type!";        
	}
  
  if (!blnReturnValue && blnDisplayMessage)
  {
    alert(strMessage);
  }
  return blnReturnValue;
}

function isFieldValidAndFocus(strInput, strType, blnAllowEmpty, strName)
{
  if (! strInput)
    return true;  //Return true if object doesn't exist.
    
  blnReturnValue = isFieldValid(strInput, strType, blnAllowEmpty, strName);
  if (!blnReturnValue)
  {
    strInput.select();
    strInput.focus();
  }
  return blnReturnValue;
}
  