var Screen = new Object();
var Screen = new Object();
var Screen = new Object();

//Checks whether a string is in the correct format
function verifyRegExString(strField, psMessage, psPattern) {
	alert('verifyRegExString not implemented correctly')
	var field = document.getElementById(strField);
	var loRegEx = new RegExp(psPattern);

	if (!loRegEx.test(field.value))
		alertFieldError(field, "The " + psMessage + " is in the incorrect format.");
}


//extend the string object
String.prototype.Trim = function() {
	//http://www.js-examples.com/javascript/?view=932

	// skip leading and trailing whitespace
	// and return everything in between
	var x = this;
	x = x.replace(/^\s*(.*)/, "$1");
	x = x.replace(/(.*?)\s*$/, "$1");
	return x;
}


String.prototype.xmlEncode = function()
{	//http://jroller.com/page/rayhon/Weblog?catname=/Java		xmlEncode and xmlDecode functions

    var retVal = "";
    var str = this;
    if (str != null)
    {
		retVal = str.toString();
		retVal = retVal.replace(/\&/g, "&amp;");
		retVal = retVal.replace(/\"/g, "&quot;");
		retVal = retVal.replace(/\'/g, "&apos;");
		retVal = retVal.replace(/\</g, "&lt;");
		retVal = retVal.replace(/\>/g, "&gt;");
    }
    return retVal;
}

String.prototype.xmlDecode = function()
{
	var retVal = "";
	var str = this;
	if (str)
	{
		retVal = str.toString();
		retVal = retVal.replace(/\&amp\;/g, "&");
		retVal = retVal.replace(/\&quot\;/g, '"');
		retVal = retVal.replace(/\&apos\;/g, "'");
		retVal = retVal.replace(/\&lt\;/g, "<");
		retVal = retVal.replace(/\&gt\;/g, ">");
	}
	return retVal;
}


function isInt(psNumber)
{	//Checks whether string contains only numeric 
	var re = new RegExp( "^([0-9]{1,})$", "ig" );
	var r = psNumber.match(re);

	if ( r==null )
		return false;
	else
		return true;
}


function isNumber(psNumber)
{
	var re = new RegExp( "^([0-9]{1,})(([.]?[0-9]{1,})?)$", "ig" );
	var r = psNumber.match(re);

	if ( r==null )
		return false;
	else
		return true;
}



function ComboBoxItemAdd(poComboBox, psId, psText)
{
	var loOption = new Option(psText, psId);
	poComboBox.options[poComboBox.length] = loOption;
}

function ComboBoxItemRemove(poComboBox, psId)
{
	for (var i=0; i < poComboBox.length; i++) 
		if (poComboBox.options[i].value == psId)
			poComboBox.remove(i);
}

function ComboBoxItemExists(poComboBox, psId)
{
	var lbExists = false;
	for (var i=0; i < poComboBox.length; i++) 
		if (poComboBox.options[i].value == psId)
			lbExists = true;

	return lbExists;
}

function ComboBoxSelectAll(poComboBox)
{
	for (var i=0; i < poComboBox.length; i++)
		poComboBox.options[i].selected = true;
}


function bIsValidCreditCardNumber(psCardNumber) 
{
	//Function performs a modulus 10 validation check on the card number and returns true or false
	// Encoding only works on cards with less than 19 digits

	if (psCardNumber.length > 19)
		return (false);

	sum = 0; mul = 1; l = psCardNumber.length;
	for (i = 0; i < l; i++) {
		digit = psCardNumber.substring(l-i-1,l-i);
		tproduct = parseInt(digit ,10)*mul;
		if (tproduct >= 10)
			sum += (tproduct % 10) + 1;
		else
			sum += tproduct;

		if (mul == 1)
			mul++;
		else
			mul--;
	}

	if ((sum % 10) == 0)
		return (true);
	else
		return (false);
}


function bIsValidExpiryDate(psExpiryDate)
{
	//This function validates the expiry date to see whether it conforms to the mmyy or mmyyyy format.

	var lbRet = true;
	var lsMonth = '';
	var lsYear = '';

	var liCurrentYearShort = new Date().getFullYear() - 2000;
	var liCurrentYearFull = new Date().getFullYear();
	var liCurrentMonth = new Date().getMonth();
	
	liCurrentMonth = liCurrentMonth + 1;

	if ((psExpiryDate.length == 4) || (psExpiryDate.length == 6 ))
	{
		lsMonth = psExpiryDate.substr(0, 2);
		lsYear = psExpiryDate.substr(2);	//copy from 3rd char to end of string
		
		if (parseInt(lsMonth, 10) == NaN)
			lbRet = false;
		else
		{
			if ( (parseInt(lsMonth, 10) < 1)  ||  (parseInt(lsMonth, 10) > 12) )
				lbRet = false;
		}


		if (parseInt(lsYear, 10) == NaN)
			lbRet = false;
		else
		{
			if (lsYear.length == 2)
			{
				if (liCurrentYearShort > 2000)
					liCurrentYearShort = liCurrentYearShort - 2000;
				
				//getYear returns values eg : 1999 = 99; 2000 = 100; check for entered value to be less than current + 10 years
				if ( (parseInt(lsYear, 10) < liCurrentYearShort)  ||  (parseInt(lsYear, 10) > (liCurrentYearShort + 10)) )
					lbRet = false;
			}
			else
			{
				//check for 4 digit year
				if ( (parseInt(lsYear, 10) < liCurrentYearFull)  ||  (parseInt(lsYear, 10) > (liCurrentYearFull + 10)) )
					lbRet = false;
			}
		}

		//check whether the date on the card has expired
		if ( (parseInt(lsYear, 10) == liCurrentYearShort )  || ( parseInt(lsYear, 10) == liCurrentYearFull ) )
		{
			//check if it is the same month
			if ( liCurrentMonth > parseInt(lsMonth, 10) )
				lbRet = false;
		}
		
	}
	else
		lbRet = false;

	return lbRet;
}



function bIsValidDateDMY(psDate)
{	//This function accepts a date in d/m/y format

	var days = [31,28,31,30,31,30,31,31,30,31,30,31];
	var d, m, y = new Number();
	var la_DMY = new Array();
	var lbRet = true;

	if ( psDate != '' )
	{
		var re = new RegExp( "^([0]?[1-9]|[1-2][0-9]|3[0-1])\/([0]?[1-9]|1[0-2])\/([1-2][0-9][0-9][0-9])$", "ig" );
		var r = psDate.match(re);

		if ( r==null )
			lbRet = false;
		else
		{
			//matched to dd/mm/yyyy format
			la_DMY = psDate.split("/");

			//check individual values
			d = la_DMY[0];
			m = la_DMY[1];
			y = la_DMY[2];

			if ((m < 1) || (m > 12))
				lbRet = false;

			if ((y % 4) == 0)
				days[1] = 29;
			else
				days[1] = 28;

			if ((y % 100) == 0) 
			{
				if ((y % 400) == 0)
					days[1] = 29;
				else
					days[1] = 28;
			}

			if (d > days[m - 1])
				lbRet = false;
				
			if (y<1900 || y>2100)
				lbRet = false;
		}
	}
	else
		lbRet = false;

	return lbRet;
}


function ddMMyyyyToDate(psDate, psSplitChar)
{//Convert a dd/MM/yyyy string to the native date format
	var lsDay = '';
	var lsMonth = '';
	var lsYear = '';
	var liMonth = 0;
	var larrDate = new Array();
	var ldtReturnDate = new Date();

	alert('ddMMyyyyToDate not fully tested');

	try
	{
		larrDate = psDate.split(psSplitChar);
		lsDay = larrDate[0];
		lsMonth = larrDate[1];
		liMonth = parseInt(lsMonth) - 1;
		lsYear = larrDate[2];

		ldtReturnDate = new Date(lsYear, liMonth, lsDay);
	}
	catch(e)
	{
		alert('Error converting string ' + psDate + ' to a date' );
		return;
	}

	return ldtReturnDate;
}




function ddMMMyyyyToDate(psDate)
{//Convert a dd MMM yyyy string to the native date format
	var lsDay = '';
	var lsMonth = '';
	var lsYear = '';
	var liMonth = 0;
	var larrDate = new Array();
	var ldtReturnDate = new Date();

	alert('ddMMyyyyToDate not fully tested');

	try
	{
		larrDate = psDate.split(' ');
		lsDay = larrDate[0];
		lsMonth = larrDate[1];
		liMonth = getMonthNumber(lsMonth) - 1;
		lsYear = larrDate[2];

		ldtReturnDate = new Date(lsYear, liMonth, lsDay);
	}
	catch(e)
	{
		alert('Error converting string ' + psDate + ' to a date' );
		return;
	}

	return ldtReturnDate;
}

function getMonthNumber(psMonthName)
{	//returns the month number (1 to 12) for a month name, or abbreviated name;
	//returns 0 if not found

	var liMonthNumber = 0;
	var lArrFullMonthNames = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
	var lArrAbbrMonthNames = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");

	//search the list of full month names
	var i = 0;
	while ( (liMonthNumber == 0) && (i < lArrFullMonthNames.length) )
	{
		if (lArrFullMonthNames[i].toString().toUpperCase() == psMonthName.toUpperCase())
			liMonthNumber = i + 1;

		i++;
	}

	// if not found, try searching the list of abbreviated month names
	if (liMonthNumber == 0)
	{
		i = 0;
		while ( (liMonthNumber == 0) && (i < lArrAbbrMonthNames.length) )
		{
			if (lArrAbbrMonthNames[i].toString().toUpperCase() == psMonthName.toUpperCase())
				liMonthNumber = i + 1;

			i++;
		}
	}

	if (liMonthNumber == 0)
	{
		alert("Unable to determine month name from the following string : " + psMonthName);
		return;
	}

	return liMonthNumber;
}




//This is a private function
//Checks whether the date is of the right format, but this is not part of form verification
function checkDateString(strDate)
{
	return bIsValidDateDMY(strDate);
}


function stringToDate(psDate)
{	//convert d/m/yyyy to native date format
	if (bIsValidDateDMY(psDate) == false) 
		return null;

	var dateArray = new Array();
	dateArray = psDate.split("/");

	var intDay = parseInt(dateArray[0], 10);
	var intMonth = parseInt(dateArray[1], 10);
	var intYear = parseInt(dateArray[2], 10);

	return new Date(intYear, intMonth - 1, intDay);
}





function DateDiff( start, end, interval, rounding )
{	//http://forums.asp.net/thread/1543883.aspx
    var iOut = 0;
    
    // Create 2 error messages, 1 for each argument. 
    var startMsg = "Check the Start Date and End Date\n"
        startMsg += "must be a valid date format.\n\n"
        startMsg += "Please try again." ;
	
    var intervalMsg = "Sorry the DateDiff function only accepts\n"
        intervalMsg += "d, h, m OR s intervals.\n\n"
        intervalMsg += "Please try again." ;

    var bufferA = Date.parse( start ) ;
    var bufferB = Date.parse( end ) ;
    	
    // check that the start parameter is a valid Date. 
    if ( isNaN (bufferA) || isNaN (bufferB) ) {
        alert( startMsg ) ;
        return null ;
    }
	
    // check that an interval parameter was not numeric. 
    if ( interval.charAt == 'undefined' ) {
        // the user specified an incorrect interval, handle the error. 
        alert( intervalMsg ) ;
        return null ;
    }
    
    var number = bufferB-bufferA ;
    
    // what kind of add to do? 
    switch (interval.charAt(0))
    {
        case 'd': case 'D': 
            iOut = parseInt(number / 86400000) ;
            if(rounding) iOut += parseInt((number % 86400000)/43200001) ;
            break ;
        case 'h': case 'H':
            iOut = parseInt(number / 3600000 ) ;
            if(rounding) iOut += parseInt((number % 3600000)/1800001) ;
            break ;
        case 'm': case 'M':
            iOut = parseInt(number / 60000 ) ;
            if(rounding) iOut += parseInt((number % 60000)/30001) ;
            break ;
        case 's': case 'S':
            iOut = parseInt(number / 1000 ) ;
            if(rounding) iOut += parseInt((number % 1000)/501) ;
            break ;
        default:
        // If we get to here then the interval parameter
        // didn't meet the d,h,m,s criteria.  Handle
        // the error. 		
        alert(intervalMsg) ;
        return null ;
    }
    
    return iOut ;
}




function isFormDirty(loFrm)
{
	var bFrmDirty = false;
	var oEls = loFrm.elements;
	var i=0;

	for (i=0; i < oEls.length; i++)
	{
		switch (oEls[i].type)
		{
			case 'select-one'	:
						// iterate through options
						for (j=0; j < oEls[i].options.length; j++)
							//ignore select statements that are changed by javascript
							if ((oEls[i].name != 'Type') && (oEls[i].name != 'PlantTree' ))
								if (oEls[i].options[j].selected != oEls[i].options[j].defaultSelected)
									bFrmDirty = true;
						break;

			case 'radio'		:
			case 'checkbox'		:
						if (oEls[i].defaultChecked != oEls[i].checked )
							bFrmDirty = true;
						break;

			case 'textarea'		:
			case 'text'			:
						if (oEls[i].value != oEls[i].defaultValue)
							bFrmDirty = true;
						break;
		}
	}

	return bFrmDirty;
}




function verifyTimeField(strField, strMessage)
{
	field = document.getElementById(strField);
	strInput = field.value;
	if (strInput == "")
		return false;

	re = new RegExp("^\\d{1,2}:\\d{2}$");
	if (!re.test(strInput)) 
	{
		alertFieldError(field, "The " + strMessage + " must be entered using the 24 hour time format, e.g. 14:30.");
		return false;
	}

	intHour = parseInt(strInput.substr(0, 2), 10);
	intMin = parseInt(strInput.substr(3, 2), 10);
	if ( (intHour < 0) || (intHour > 24)
		|| (intMin < 0) || (intMin > 59))
	{
		alertFieldError(field, "The " + strMessage + " value is incorrect please check hours and minutes.");
		return false;
	}
	return true;
}

function verifyDateField(strField, strMessage)
{
	field = document.getElementById(strField);
	strInput = field.value;
	if (strInput == "") 
		return false;

	if (bIsValidDateDMY(strInput) == false)
	{
		alertFieldError(field, "The " + strMessage + " must be in the format dd/mm/yyyy (e.g. 30/11/2006).")
		return false;
	}

	return true;
}


function verifyOptionalEmail(strField, strMessage)
{
	field = document.getElementById(strField)
	strInput = field.value

	if (strInput != "") {
		if (!verifyEmail(strInput)) {
			alertFieldError(field, "The email format is invalid.");
			return false;
		}
	}
	return true;
}


function verifyEmail(emailStr)
{
	if (emailStr == "") return true;
	var emailPat = /^(.+)@(.+)$/
	var specialChars = "\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
	var validChars = "\[^\\s" + specialChars + "\]"
	var firstChars = validChars
	var quotedUser = "(\"[^\"]*\")"
	var ipDomainPat = /^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
	var atom = "(" + firstChars + validChars + "*" + ")"
	var word = "(" + atom + "|" + quotedUser + ")"
	var userPat = new RegExp("^" + word + "(\\." + word + ")*$")
	var domainPat = new RegExp("^" + atom + "(\\." + atom +")*$")

	//Begin with the course pattern to simply break up user@domain
	var matchArray = emailStr.match(emailPat)
	if (matchArray == null) {
	return false
	}
	var user = matchArray[1]
	var domain = matchArray[2]
	if (user.match(userPat) == null) {
	return false
	}
	var IPArray = domain.match(ipDomainPat)
	if (IPArray != null) {
	for (var i = 1; i <= 4; i++) {
		if (IPArray[i] > 255) {
		return false
		}
	}
	return true
	}
	var domainArray = domain.match(domainPat)
	if (domainArray == null) {
	return false
	}

	var atomPat = new RegExp(atom, "g")
	var domArr = domain.match(atomPat)	//eg {"yahoo", "com"}
	var len = domArr.length				//eg 2
	//ensure that the last part of the domain string (eg "com" has length 2 or 3)
	if (domArr[domArr.length - 1].length < 2 || domArr[domArr.length - 1].length > 4) {
	return false
	}
	if (len < 2) {
	return false
	}
	return true;
}

//this is a copy of alertFieldError minus controlName.select(), which breaks when the control is, say, a combo...
function alertFieldErrorWithoutSelect(control, errorMessage)
{
	if (!Screen.Form_error) 
	{
		control.focus();
		Screen.Form_errorString = errorMessage;
		Screen.Form_error = true;
	}
}

function verifyMandatorySpecialCharsString(strField, strMessage, intMaxLength)
{
	if (verifyMandatoryField(strField, strMessage))
		return verifySpecialCharsString(strField, strMessage, intMaxLength);
	else
		return false;
	
	return true;
}

function verifySpecialCharsString(strField, strMessage, intMaxLength){
  //Relaxed requirements compared to verifyString
  field = document.getElementById(strField);
  strInput = field.value;
  if (strInput.charAt(0) == ' ') {
    field.focus();
    field.select();
    alert("The string contains leading spaces, it won't be displayed properly.");
    return false;
  }
  if (strInput.indexOf("  ") != -1) {
    field.focus();
    field.select();
    alert("The string contains consecutive spaces, it won't be displayed properly.");
    return false;
  }
  if (strInput.length > intMaxLength) {
  	alertFieldError(field, "A maximum of " + intMaxLength + " characters are allowed.");
  	return false;
  }

  return true;
}

function verifyMandatoryString(strField, strMessage, intMaxLength)
{
	if (verifyMandatoryField(strField, strMessage))
		return verifyString(strField, strMessage, intMaxLength);
	else
		return false;

	return true;
}

function verifyString(strField, strMessage, intMaxLength)
{
	field = document.getElementById(strField);
	strInput = field.value;

	if (strInput.length > intMaxLength) {
		alertFieldError(field, "A maximum of " + intMaxLength + " characters are allowed.");
		return false;
	}

	return true;
}


function verifyStringInvalidChars(psField, psMessage, psInvalidCharacters)
{
	var loField = document.getElementById(psField);
	var lsInput = loField.value;

	for (i = 0; i < psInvalidCharacters.length; ++i) {
		if (lsInput.indexOf(psInvalidCharacters.charAt(i)) != -1) {
			alertFieldError(loField, "The character '" + psInvalidCharacters.charAt(i) + "' is not allowed for " + psMessage + ".");
			return false;
		}
	}
	return true;
}

function verifyStringValidChars(psField, psMessage, psValidCharacters)
{
	var loField = document.getElementById(psField);
	var lsInput = loField.value;
	for (i = 0; i < lsInput.length; ++i) {
		if (psValidCharacters.indexOf(lsInput.charAt(i)) == -1) {
			alertFieldError(loField, "The character '" + lsInput.charAt(i) + "' is not allowed for " + psMessage + ".");
			return false;
		}
	}
	return true;
}

function verifyTelephoneNumber(psField, psMessage)
{
	return verifyStringValidChars(psField, psMessage, "0123456789");
}

function getSelectedRadio(buttonGroup) 
{
	// returns the array number of the selected radio button or -1 if no button is selected
	if (buttonGroup[0]) { // if the button group is an array (one button is not an array)
		for (var i=0; i<buttonGroup.length; i++) {
			if (buttonGroup[i].checked) {
			return i
			}
		}
	} else {
		if (buttonGroup.checked) { return 0; } // if the one button is checked, return zero
	}
	// if we get to this point, no radio button is selected
	return -1;
} // Ends the "getSelectedRadio" function

function getSelectedRadioValue(buttonGroup)
{
	// returns the value of the selected radio button or "" if no button is selected
	var i = getSelectedRadio(buttonGroup);
	if (i == -1) {
		return "";
	} else {
		if (buttonGroup[i]) { // Make sure the button group is an array (not just one button)
			return buttonGroup[i].value;
		} else { // The button group is just the one button, and it is checked
			return buttonGroup.value;
		}
	}
} // Ends the "getSelectedRadioValue" function

function verifyIDNumberField(psIDField, psIDTypeField, psIDMessage, psDOBField, psDOBMessage)
{
	if (Screen.Form_error)
		return false; ;

	var loCbxIDType = document.getElementById(psIDTypeField);
	// Check for RSA ID type
	if (loCbxIDType.options[loCbxIDType.selectedIndex].text.toLowerCase().search(/rsa/g) == -1)
		return false;

	var loTxtIDNumber = document.getElementById(psIDField);
	// Remove spaces

	var lsIDNumber = loTxtIDNumber.value.replace(/ /g, "");
	var lsDOB = psDOBField ? document.getElementById(psDOBField).value : "";
	// If the DOB is specified, it must be a valid date  
	if (lsDOB.length)
	{
		verifyDateField(psDOBField, psDOBMessage);
		if (Screen.Form_error)
			return false;
	}

	if (lsIDNumber.length)
	{
		var lsErrorMessage=verifyIDNumber(lsIDNumber)
		if (lsErrorMessage.length)
		{
			alertFieldError(loTxtIDNumber, "The " + psIDMessage + " should be a valid RSA ID number. (" + lsErrorMessage + ")");
			return false;
		}

		if (lsDOB.length)
		{
			// Extract DOB parts
			var liDOB_DD = parseInt(lsDOB.substr(0, 2), 10);
			var liDOB_MM = parseInt(lsDOB.substr(3, 2), 10);
			var liDOB_YY = parseInt(lsDOB.substr(8, 2), 10);  // NOTE: Ignores century
			// Extract ID DOB parts
			var liID_DD = parseInt(lsIDNumber.substr(4, 2), 10);
			var liID_MM = parseInt(lsIDNumber.substr(2, 2), 10);
			var liID_YY = parseInt(lsIDNumber.substr(0, 2), 10);

			if ((liDOB_DD != liID_DD) || (liDOB_MM != liID_MM) || (liDOB_YY != liID_YY))
			{
				var lsIDDOB = lsIDNumber.substr(4, 2) + "/" + lsIDNumber.substr(2, 2) + "/" + lsIDNumber.substr(0, 2);
				var lsDriverDOB = lsDOB.substr(0, 2) + "/" + lsDOB.substr(3, 2) + "/" + lsDOB.substr(8, 2);
				alertFieldError(loTxtIDNumber, "The date of birth from the " + psIDMessage + 
									" (" + lsIDDOB + ") and the " +
									psDOBMessage + " (" + lsDriverDOB + ") do not correspond.");
				return false;
			}
		}
	}
	return true;
}

function verifyIDNumber(psIDNumber)
{
	alert('verifyIDNumber not fully tested');
	if (psIDNumber.length != 13)
		return "Must contact exactly 13 characters";

	var liIDNumber = parseInt(psIDNumber, 10);
	if (isNaN(liIDNumber))
		return "Must contain numeric values only";

	var liSumOfDigits = 0
	for(i=1; i<=12; ++i)
	{
		switch (i)
		{
			case 1:
			case 3:
			case 5:
			case 7:
			case 9:
			case 11:
				liSumOfDigits += parseInt(psIDNumber.substr(i - 1, 1), 10);
				break;

			default:
				switch (parseInt(psIDNumber.substr(i - 1, 1), 10))
				{
					case 1: liSumOfDigits += 2; break;
					case 2: liSumOfDigits += 4; break;
					case 3: liSumOfDigits += 6; break;
					case 4: liSumOfDigits += 8; break;
					case 5: liSumOfDigits += 1; break;
					case 6: liSumOfDigits += 3; break;
					case 7: liSumOfDigits += 5; break;
					case 8: liSumOfDigits += 7; break;
					case 9: liSumOfDigits += 9; break;
				}
		}
	}

	var liCheckDigit = (liSumOfDigits%10) == 0 ? 0 : 10 - (liSumOfDigits%10);
	if (parseInt(psIDNumber.substr(12, 1), 10) == liCheckDigit)
		return "";
	else
		return "Check digit verification failed since the ID number is not valid";
}

function verifyInt(strField, strMessage)
{
	field = document.getElementById(strField)
	number = field.value
	if (number == "")
		return false; //we allow an empty string

	//General numeric check
	if (isNaN(parseInt(number, 10))) {
		alertFieldError(field, "The " + strMessage + " should be a number.");
		return false;
	}
	
	//The above check is not enough
	if (number - parseInt(number, 10) != 0) {
		alertFieldError(field, "The " + strMessage + " should be a number.");
		return false;
	}
	return true;
}

//Returns TRUE if the number is Empty or a valid number, FALSE otherwise
function verifyDouble(strField, strMessage)
{
	field = document.getElementById(strField)
	number = field.value

	if (number == "")
		return true;
	else //there is a number to be evaluated
	{
		if (isNaN(Number(number)))
		{
			alertFieldError(field, "The " + strMessage + " should be an amount.");
			return false;
		}
		else
			return true;
	}
	return true;
}

function verifyMoney(strField, strMessage)
{

	//First reuse the double function
	if (verifyDouble(strField, strMessage)) {
		//It seems to be a valid number, now check for negatives and high precision (more than 2 decimals)
		field = document.getElementById(strField);
		number = field.value;
		if (number != "") //ignore further validation if the string is empty!
		{
			aMoney = parseFloat(number);
			//Check for negative
			if (aMoney < 0) {
				alertFieldError(field, "The " + strMessage + " cannot be less than zero.");
				return false;
			}
			//Check for number of decimals
			if ((Math.round(aMoney * 100) / 100) != aMoney) {
				alertFieldError(field, "The " + strMessage + " cannot have more than 2 decimal places.");
				return false;
			}
		}
		else
			return false;
	}
	else
		return false;

	return true;
}

function verifyMandatoryEmail(strField, strMessage) {
  field = document.getElementById(strField)
  field.value = field.value.Trim();
  strInput = field.value;

  if (strInput == "") {
  	alertFieldError(field, "Please enter the " + strMessage + ".");
  	return false;
  }
  if (!verifyEmail(strInput)) {
  	alertFieldError(field, "Email format is invalid.");
  	return false;
  }
  return true;
}

function verifyMandatoryField(strField, strMessage) {
  field = document.getElementById(strField);
  field.value = field.value.Trim();
  value = field.value;
  if (value == "") {
  	alertFieldError(field, "The " + strMessage + " field is required.");
  	return false;
  }

  return true;
}

function verifyMandatoryDateField(strField, strMessage){
	if (verifyMandatoryField(strField, strMessage))
		return verifyDateField(strField, strMessage);
	else
		return false;

	return true;
}

//to be used for combo boxes that have a "Please Select" option.
function verifyMandatoryCombo(psControlName, psDescription) {
	var loControl = document.getElementById(psControlName);
	var lsValue = loControl.value;
	
	

	if (lsValue.length == 0){
		var lsMessage = "Please select an option in the " + psDescription + " list.";
		alertFieldErrorWithoutSelect(loControl, lsMessage);
		return false;
	} else
		return true;
}

function verifyMandatoryTimeField(strField, strMessage){
	if (verifyMandatoryField(strField, strMessage))
		return verifyTimeField(strField, strMessage);
	else
		return false;

	return true;
}

function verifyMandatoryInt(strField, strMessage){
  field = document.getElementById(strField)
  number = field.value
  if (number == "") {
  	alertFieldError(field, "Please enter the " + strMessage + ".");
  	return false;
  }

  //General numeric check
  if (isNaN(parseInt(number, 10))) {
  	alertFieldError(field, "The " + strMessage + " should be a number.");
  	return false;
  }

  //The above check is not enough
  if (number - parseInt(number, 10) != 0) {
  	alertFieldError(field, "The " + strMessage + " should be a number.");
  	return false;
  }

  return true;
}

function verifyMandatoryIntRange(strField, strMessage, lowerLimit, upperLimit){
  field = document.getElementById(strField)
  number = field.value
  
  //Ensure that the field is not Empty.
  if (number == ""){
    alertFieldError(field, "Please enter the " + strMessage + ".");
	  return false;
  }
  
  //Ensure that we have a Number
  if (!isInt(number))
  {
    alertFieldError(field, "The " + strMessage + " is not a valid integer.");
	  return false;
  }

  //Ensure number >= lowerLimit (is there is a limit)
  if (lowerLimit != "")
  {
  	if (number < lowerLimit)
	{
	  alertFieldError(field, "The " + strMessage + " must be greater than or equal to " + lowerLimit);
	  return false;
	}
  }

  //Ensure number <= upperLimit (is there is a limit)
  if (upperLimit != "")
  {
	  if (number > upperLimit){
		  alertFieldError(field, "The " + strMessage + " must be less than or equal to " + upperLimit);
		  return false; 
	  }
  }

  return true;
}

function verifyMandatoryStringRange(strField, strMessage, lowerLimit, upperLimit) {
	if (verifyMandatoryField(strField, strMessage))
		return false; 

  var field = document.getElementById(strField);
  var liLength = field.value.length;

  //Ensure number >= lowerLimit (if there is a limit)
  if (lowerLimit != "")
  {
	  if (liLength < lowerLimit){
		  alertFieldError(field, "The " + strMessage + " must be greater than or equal to " + lowerLimit + " characters in length.");
		  return false; 
	  }
  }

  //Ensure number <= upperLimit (is there is a limit)
	if (upperLimit != "")
	{
		if (liLength > upperLimit)
		{
		  alertFieldError(field, "The " + strMessage + " must be less than or equal to " + upperLimit + " characters in length.");
		  return false; ;
		}
	}

	return true;
}

function verifyMandatoryFloatRange(strField, strMessage, lowerLimit, upperLimit){
  verifyMandatoryField(strField, strMessage);
  
  var field = document.getElementById(strField)
  var number = parseFloat(field.value);
  
  // Parse as float.
  lowerLimit = parseFloat(lowerLimit);
  upperLimit = parseFloat(upperLimit);
    
  //Ensure that we have a Float/Double
  if (!isNumber(field.value)) {
    alertFieldError(field, "The " + strMessage + " is not a valid value.");
	  return false;
  }
	
  //Ensure number >= lowerLimit (is there is a limit)
  if (lowerLimit!=""){
	  if (number < lowerLimit){
		  alertFieldError(field, "The " + strMessage + " must be greater than or equal to " + lowerLimit);
		  return false;
	  }
  }

  //Ensure number <= upperLimit (is there is a limit)
  if (upperLimit!=""){
	  if (number > upperLimit){
		  alertFieldError(field, "The " + strMessage + " must be less than or equal to " + upperLimit);
		  return false;
	  }
	 }

	 return true;
}

function verifyMandatoryDateRange(strField, strMessage, psLowerLimit, psUpperLimit)
{
	if (!verifyMandatoryDateField(strField, strMessage))
		return false;

	if(Screen.Form_error == false)
	{

		var field = document.getElementById(strField);
		var loDate = stringToDate(field.value);

		// Parse as float.
		var loLowerLimit = stringToDate(psLowerLimit);
		var loUpperLimit = stringToDate(psUpperLimit);

		//Ensure number >= lowerLimit (is there is a limit)
		if (loLowerLimit)
		{
			if (loDate < loLowerLimit)
			{
				alertFieldError(field, "The " + strMessage + " must be greater than or equal to " + dateToString(loLowerLimit));
				return false; 
			}
		}

		//Ensure number <= upperLimit (is there is a limit)  
		if (loUpperLimit)
		{
			if (loDate > loUpperLimit)
			{
				alertFieldError(field, "The " + strMessage + " must be less than or equal to " + dateToString(loUpperLimit));	    
				return false;
			}
		}
	}
	return false;
}


function verifyMandatoryIntOver(strField, strMessage, lowerLimit)
{
	field = document.getElementById(strField)
	number = field.value

	//Ensure that the field is not Empty.
	if (number == "")
	{
		alertFieldError(field, "Please enter the " + strMessage + ".");
		return false;
	}

	//Ensure that we have a Number
	if (isNaN(parseInt(number,10))){
	alertFieldError(field, "The " + strMessage + " is not a valid integer.");
		return false;
	}

	//Ensure that we have an Integer
	if (number - parseInt(number,10) != 0)
	{
		alertFieldError(field, "The " + strMessage + " is not a valid integer.");
		return false;
	}

	//Ensure number > lowerLimit (is there is a limit)  
	if (number <= lowerLimit)
	{
		alertFieldError(field, "The " + strMessage + " must be greater than " + lowerLimit);
		return false;
	}
	return true;
}


function verifyMandatoryDouble(strField, strMessage)
{
	field = document.getElementById(strField)
	number = field.value
	if (number == "") {
		alertFieldError(field, "Please enter the " + strMessage + ".");
		return false;
	}

	//General numeric check
	aNumber = Number(number);
	if (isNaN(aNumber)) {
		alertFieldError(field, "The " + strMessage + " is invalid.");
		return false;
	}

	return true;
}

function verifyMandatoryMoney(strField, strMessage)
{
	//First reuse the double function
	if (!(verifyMandatoryDouble(strField, strMessage)))
		return false; 

	//It seems to be a valid number, now check for negatives and high precision (more than 2 decimals)
	field = document.getElementById(strField);
	number = field.value;
	aMoney = parseFloat(number);
	//Check for negative
	if (aMoney < 0) {
		alertFieldError(field, "The " + strMessage + " cannot be less than zero.");
		return false;
	}

	//Check for number of decimals
	if ((Math.round(aMoney * 100) / 100) != aMoney) {
		alertFieldError(field, "The " + strMessage + " cannot have more than 2 decimal places.");
		return false;
	}

	return true;
}


function verifyMandatoryPercentage(strField, strMessage)
{
	//First use the money function
	if (!(verifyMandatoryMoney(strField, strMessage)))
		return false;
		
	//Get the value
	field = document.getElementById(strField);
	number = field.value;
	aPercentage = parseFloat(number);
	//Check for 0% to 100%
	if (aPercentage < 0.0 || aPercentage > 100.0) {
		alertFieldError(field, "The " + strMessage + " must be between 0% to 100%.");
		return false;
	}

	return true;
}

function verifyMandatoryCalenderDay(strField, strMessage)
{
	field = document.getElementById(strField);
	number = field.value;
	if (number == "") {
		alertFieldError(field, "Please enter the " + strMessage + ". It should be between 0-28.");
		return false;
	}

	//General numeric check
	if (isNaN(parseFloat(number))) {
		alertFieldError(field, "The " + strMessage + " should be a amount between 0-28.");
		return false;
	}

	//The above check is not enough -> check for integer number
	if (number - parseInt(number, 10) != 0) {
		alertFieldError(field, "The " + strMessage + " should be a number.");
		return false;
	}

	//0-28 range check
	if (number < 1) {
		alertFieldError(field, "The " + strMessage + " should be a amount between 0-28.");
		return false; 
	}

	if (number > 28) {
		alertFieldError(field, "The " + strMessage + " should be a amount between 0-28.");
		return false;
	}

	return true;
}

function verifyMandatoryPositiveInt(strField, strMessage)
{
	field = document.getElementById(strField);
	number = field.value;
	if (number == "") {
		alertFieldError(field, "Please enter the " + strMessage + ". It should be a positive integer.");
		return false;
	}

	//General numeric check
	if (isNaN(parseFloat(number))) {
		alertFieldError(field, "The " + strMessage + " should be a positive integer.");
		return false;
	}

	//The above check is not enough -> check for integer number
	if (number - parseInt(number, 10) != 0) {
		alertFieldError(field, "The " + strMessage + " should be a positive integer.");
		return false;
	}

	//0-28 range check
	if (number < 1) {
		alertFieldError(field, "The " + strMessage + " should a positive integer.");
		return false;
	}

	return true;
}

function verifyCounter(field, countfield, maxlimit)
{
	if (field.value.length > maxlimit)
		field.value = field.value.substring(0, maxlimit);
	else 
		countfield.innerHTML = (maxlimit - field.value.length) + " characters left";
}

function verifyMandatoryRadioButton(strField, strMessage)
{
	field = document.getElementByName(strField);
	
	alert('this function does not work with radio button lists in asp.net')
	
	if (getSelectedRadio(field) == -1)
	{
		Screen.Form_errorString = "The " + strMessage + " field is required.";
		Screen.Form_error = true;
	}
}

function verifyMandatoryCheckBoxList(strField, psCheckBoxList)
{
	var laCheckFields = psCheckBoxList.split(',');
	var lsCheckString = '';

	for(i = 0; i < laCheckFields.length;i++)
	{
		if (document.getElementById(laCheckFields[i]).type == "checkbox")
		{
			if(document.getElementById(laCheckFields[i]).checked)
			{
				lsCheckString = '1';
				break;
			}
		}
	}

	if (lsCheckString.length == 0) {
		alertFieldError(document.getElementById(laCheckFields[0]), "The " + strField + " check box options require at least one value to be selected.");
		return false;
	}

	return true;
}


function verifyMandatoryIDNumberField(psIDField, psIDTypeField, psIDMessage, psDOBField, psDOBMessage)
{
	if (verifyMandatoryField(psIDField, psIDMessage))
		return verifyIDNumberField(psIDField, psIDTypeField, psIDMessage, psDOBField, psDOBMessage);
	else
		return false;

	return true;
}

//This is the general form validation framework
function alertError(perrorString)
{
	if (!Screen.Form_error)
	{
		Screen.Form_errorString = perrorString;
		Screen.Form_error = true;
	}
}

function alertFieldError(pfield, perrorString)
{
	if (!Screen.Form_error)
	{
		try
		{
			pfield.focus();
			//pfield.select();
		}
		catch(e) { }; // sometimes the control cannot be set to focus (it may be disabled), hence we are more forgiving here...)


		Screen.Form_errorString = perrorString;
		Screen.Form_error = true;
	}
}

function Screen_EncodeURL(s)
{
	//URL Encode the string
	s = escape(s);
	//URL Encode converts '+' as '+', but IIS takes '+' as ' '
	while (s.indexOf('+') != -1) s = s.replace(/\+/, "%2b");
		return s;
}

function isChecked(controlName){
	return document.getElementById(controlName).checked;
}
function enable(controlName){
	document.getElementById(controlName).disabled = false;
}
function disable(controlName){
	document.getElementById(controlName).disabled = true;
}

// Round the Amount to 2 decimals
function FormatAmount(pAmount)
{
	var mSign; 
	if (pAmount == 0)
		mSign = 1;
	else
		mSign = Math.abs(pAmount)/pAmount; // +1 or -1

	var intPart = mSign * Math.floor(Math.abs(pAmount));
	var decimalPart = pAmount - intPart;
	var decimalPart_Rounded = Math.round(decimalPart*100)/100;

	var sPrefix = "";
	var mAmount = parseFloat(intPart) + parseFloat(decimalPart_Rounded);
	if (mAmount < 0)
	{
		sPrefix = " Cr";
		mAmount = - mAmount;
		intPart = - intPart;
	}
	else
		sPrefix = " Dt";

	if (mAmount == 0)
		return " R 0";
	else 
		if (decimalPart_Rounded == 0)
			return sPrefix + " R " + intPart.toString();
		else
		{
			var sAmount = Math.round(mAmount*100)/100; // we need to round the amount AGAIN before displaying
			return sPrefix + " R " + sAmount;
		}
}






// Begin : Creates add method for date objects
//http://www.codingforums.com/showthread.php?t=3955
Date.prototype.add = function (psInterval, piNum)
{
  var ldTemp = this;
  if (!psInterval || piNum == 0) 
	return ldTemp;

  piNum = parseInt(piNum);

  switch (psInterval.toLowerCase())
  {
    case "ms":
      ldTemp.setMilliseconds(ldTemp.getMilliseconds() + piNum);
      break;
    case "s":
      ldTemp.setSeconds(ldTemp.getSeconds() + piNum);
      break;
    case "mi":
      ldTemp.setMinutes(ldTemp.getMinutes() + piNum);
      break;
    case "h":
      ldTemp.setHours(ldTemp.getHours() + piNum);
      break;
    case "d":
      ldTemp.setDate(ldTemp.getDate() + piNum);
      break;
    case "mo":
      ldTemp.setMonth(ldTemp.getMonth() + piNum);
      break;
    case "y":
      ldTemp.setFullYear(ldTemp.getFullYear() + piNum);
      break;
  }
  return ldTemp;
}
// End : Creates add method for date objects





function dateToString(poDate)
{
	if(poDate)
	{
		var intDay = poDate.getDate();
		var intMonth = poDate.getMonth() + 1;
		var intYear = poDate.getYear();

		if(intDay < 10)
			intDay = "0" + intDay;

		if(intMonth < 10)
			intMonth = "0" + intMonth;

		if(intYear < 2000)
			intYear += 1900;

		return intDay + "/" + intMonth + "/" + intYear;
	}
}


Date.prototype.toDateString = function (psFormatString)
{	//converts a native javascript date object to the formated output date
	var lsOutputDateString = psFormatString;

	var liDay = this.getDate();
	var lsDay = "";
	var liMonth = this.getMonth() + 1;
	var lsMonth = "";
	var liYear = this.getFullYear();
	var lsYear = "";
	

	//build the output string

	//dd - day with zero padding
	if (lsOutputDateString.indexOf("dd") >= 0)
	{	
		if (liDay < 10)
			lsDay = "0" + liDay.toString();
		else
			lsDay = liDay;
		lsOutputDateString = lsOutputDateString.replace("dd", lsDay);
	}

	//d - day without zero padding
	if (lsOutputDateString.indexOf("d") >= 0)
	{	
		lsOutputDateString = lsOutputDateString.replace("d", liDay.toString());
	}


	//MM - month with zero padding
	if (lsOutputDateString.indexOf("MM") >= 0)
	{
		if (liMonth < 10)
			lsMonth = "0" + liMonth.toString();
		else
			lsMonth = liMonth;
		lsOutputDateString = lsOutputDateString.replace("MM", lsMonth);
	}

	//M - month without zero padding
	if (lsOutputDateString.indexOf("M") >= 0)
	{	
		lsOutputDateString = lsOutputDateString.replace("M", liMonth.toString());
	}

	//yyyy - year
	if (lsOutputDateString.indexOf("yyyy") >= 0)
	{
		lsOutputDateString = lsOutputDateString.replace("yyyy", liYear.toString());
	}
	
	return lsOutputDateString;
}









/**
 * Taken from http://www.netspade.com/articles/2005/11/16/javascript-cookies/
 * Sets a Cookie with the given name and value.
 *
 * name       Name of the cookie
 * value      Value of the cookie
 * [expires]  Expiration date of the cookie (default: end of current session)
 * [path]     Path where the cookie is valid (default: path of calling document)
 * [domain]   Domain where the cookie is valid
 *              (default: domain of calling document)
 * [secure]   Boolean value indicating if the cookie transmission requires a
 *              secure transmission
 */
function setCookie(name, value, expires, path, domain, secure) {
    document.cookie= name + "=" + escape(value) +
        ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
}

/**
 * Gets the value of the specified cookie.
 *
 * name  Name of the desired cookie.
 *
 * Returns a string containing value of specified cookie,
 *   or null if cookie does not exist.
 */
function getCookie(name) {
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1) {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    } else {
        begin += 2;
    }
    var end = document.cookie.indexOf(";", begin);
    if (end == -1) {
        end = dc.length;
    }
    return unescape(dc.substring(begin + prefix.length, end));
}

/**
 * Deletes the specified cookie.
 *
 * name      name of the cookie
 * [path]    path of the cookie (must be same as path used to create cookie)
 * [domain]  domain of the cookie (must be same as domain used to create cookie)
 */
function deleteCookie(name, path, domain) {
    if (getCookie(name)) {
        document.cookie = name + "=" +
            ((path) ? "; path=" + path : "") +
            ((domain) ? "; domain=" + domain : "") +
            "; expires=Thu, 01-Jan-70 00:00:01 GMT";
    }
}




//To remember whether an error as occurred during form validation
Screen.Form_error = false;
//To remember the first error message
Screen.Form_errorString = "";
//To remember whether it's the first item being added to the query string
Screen.Form_blnFirstQuery = true;
//To construct the query string
Screen.Form_strQuery = "";
