var DEFAULT_MONETARY_DECIMAL_SYMBOL = ".";

// deprecated
function isDate(day, month, year)
{ 
	// checks if date passed is valid
	// will accept dates in following format:
	// isDate(dd,mm,ccyy), or
	// isDate(dd,mm) - which defaults to the current year, or
	// isDate(dd) - which defaults to the current month and year.
	// Note, if passed the month must be between 1 and 12, and the
	// year in ccyy format.
	var today = new Date();
	year = (!year)? y2k(today.getYear()) : year;
	month = (!month)? today.getMonth() : month - 1;
	if (!day) return false;

	var testDate = new Date(year, month, day);
	if ((y2k(testDate.getYear()) == year) &&
		(month == testDate.getMonth()) &&
		(day == testDate.getDate()))
	{
		return true;
	}
	else
	{
		return false
	}
}
 
function y2k(number)
{ 
	return (number < 1000) ? number + 1900 : number;
}
 
function timeDifferenceWithToday(laterDay, laterMonth, laterYear)
{
	var now = new Date();

	// return timeDifference(today, laterDate);
	return timeDifference(now.getDate(), now.getMonth() + 1, now.getYear(), laterDay, laterMonth, laterYear);
}

function timeDifference(earlierDay, earlierMonth, earlierYear, laterDay, laterMonth, laterYear)
{
	var earlierDate = new Date(earlierYear, earlierMonth, earlierDay);
	var laterDate = new Date(laterYear, laterMonth, laterDay);

	// return timeDifference(earlierDate, laterDate);
	var difference = laterDate.getTime() - earlierDate.getTime();
	var daysDifference = Math.floor(difference / 1000 / 60 / 60 / 24);

	if (daysDifference < 0)
	{
		// laterDate is earlier than earlierDate
		return false;
	}
	else
	{
		return true;
	}
}

// To remove leading spaces and trailing spaces for a string
function trim(string)
{
	// trim leading spaces
	var intCount = 0;
	for (var i = 0; i < string.length; i++)
	{
		if ((string.charAt(i)) != " ")
			break;
		else
			intCount++;
	}
	string = string.substring(intCount, string.length);

	// trim trailing spaces
	intCount = 0;
	for (var i = string.length - 1; i >= 0; i--)
	{
		if ((string.charAt(i)) != " ")
			break;
		else
			intCount++;
	}
	string = string.substring(0, string.length - intCount);

	return string;
}

// To remove white space from a value, irregardless of its position: leading, trailing or in-between
function removeWhiteSpace(value)
{
	var charValue = "";
	var formatedValue = "";

	// remove white space from content
	for (var i=0; i < value.length; i++)
	{
		charValue = value.charAt(i);
		if (charValue != " ")
		{
			formatedValue += charValue;
		}
	}

	return formatedValue;
}

function clearInnerSpaces(inputValue)
{
	var temp = inputValue;
	var obj = /^(\s*)([\W\w]*)(\b\s*$)/;
	if (obj.test(temp))
	{
		temp = temp.replace(obj, "$2");
	}
	var obj = / +/g;
	temp = temp.replace(obj, "");
	if (temp == " ")
	{
		temp = "";
	}

	return temp;
}

function invalidCharactersCheck(inputValue)
{
	// The following string represents the pattern for matching all special
	// characters. We don't want to allow special characters in the value.
	// These characters include < >  "  [ ] $ * ~ ` { }
	var specialChars="><\\'\\\"\\[\\]\\$\\~\\`\\*\\{\\}";

	//var specialChars="><\\\"\\[\\]\\$\\~\\`\\*\\{\\}\\%\\@";  -- remarked by marvin on 24/12/2003

	// The following string represents the range of characters allowed in a
	// value. It really states which chars aren't allowed.
	//var validChars="\[^\\s" + specialChars + "\]";
	var validChars="\[^" + specialChars + "\]";

	// The following string represents an atom (basically a series of non-special characters)
	var atom = validChars + "+";
	inputValue = clearInnerSpaces(inputValue);
	var atomPat = new RegExp("^" + atom + "$");
	if (inputValue.search(atomPat) == -1)
	{
		return true;
	}
 
}


function noHTMLCheck(inputValue)
{
	// The following string represents the pattern for matching all special
	// characters. We don't want to allow special characters in the value.
	// These characters include < >  "  [ ] $ * ~ ` { }
	var specialChars="><";
 

	// The following string represents the range of characters allowed in a
	// value. It really states which chars aren't allowed.
	//var validChars="\[^\\s" + specialChars + "\]";
	var validChars="\[^" + specialChars + "\]";

	// The following string represents an atom (basically a series of non-special characters)
	var atom = validChars + "+";
	inputValue = clearInnerSpaces(inputValue);
	var atomPat = new RegExp("^" + atom + "$");
	if (inputValue.search(atomPat) == -1)
	{
		return true;
	}
 
}

// To validate a set of mandatory fields as well as their valid types
function validateForm(formObj, param)
{ 
	var strFieldNm = "";
	var strFieldDscp = "";
	var strFieldType = "";
	var blnSpecialCheck = "false";
	var strErrMsgs = "";
	var strErrMsg = "";
	var strFieldDay = "";
	var strFieldMonth = "";
	var strFieldYear = "";
	var strLocale = "";

	for (var intCount = 0; intCount < param.length; intCount++)
	{
		strFieldNm = param[intCount][0];
		strFieldDscp = param[intCount][1];
		strFieldType = param[intCount][2];
		blnSpecialCheck = param[intCount][3];
		strErrMsg = ""; 
		if (strFieldType.indexOf("D") >= 0)
		{
			var index = strFieldNm.indexOf(":");

			var dayValue = "";
			var monthValue = "";
			var yearValue = "";

			strFieldDay  = strFieldNm.substr(0, index);
			strFieldNm = strFieldNm.substr(index + 1, strFieldNm.length);
			var objDay = formObj.elements[strFieldDay];
			if (objDay)
			{
				dayValue = trim(objDay.value);
			}
			else
			{
				dayValue = "";   
				//dayValue = " ";
			}

			index = strFieldNm.indexOf(":");
			strFieldMonth  = strFieldNm.substr(0, index);
			strFieldNm = strFieldNm.substr(index + 1, strFieldNm.length);

			var objMonth = formObj.elements[strFieldMonth];
			if (objMonth)
			{
				monthValue = trim(objMonth.value);
			}
			else
			{
				monthValue = "";    
				//monthValue = " ";
			}

			index = strFieldNm.indexOf(":");
			strFieldYear  = strFieldNm.substr(0, index);
			strLocale = strFieldNm.substr(index + 1, strFieldNm.length);

			var objMonth = formObj.elements[strFieldMonth];
			var objYear = formObj.elements[strFieldYear];
			if (objYear)
			{
				yearValue = trim(objYear.value);
			}
			else
			{
				yearValue = "";    
				//yearValue = " ";
			}

			switch (strFieldType)
			{
				case "MD":       // mandatory

					if ((objDay && dayValue == "") || (objMonth && monthValue == "") || (objYear && yearValue == ""))
					{
						// strErrMsg = strFieldDscp + " is a mandatory field.";
						strErrMsg = generateValidateMessage(fieldIsRequired, [strFieldDscp]);
					}
					else
					{
						strErrMsg = dateSelectedValidate(dayValue, monthValue, yearValue, strFieldDscp, strLocale);
					}
					break;

				case "D":

					if (dayValue == "" && monthValue == "" && yearValue == "")
					{
						// all field empty and not mandatory
					}
					else if ((objDay && dayValue == "") || (objMonth && monthValue == "") || (objYear && yearValue == ""))
					{
						strErrMsg = generateValidateMessage(invalidDateFormat, [strFieldDscp]);
					}
					else
					{
						strErrMsg = dateSelectedValidate(dayValue, monthValue, yearValue, strFieldDscp, strLocale);
					}
					break;
			}

		}
		else
		{
			var obj = formObj.elements[strFieldNm];

			if (!obj)
			{
				return strErrMsg;
			}

			strValue = "";

			if (obj.type != null && obj.type.indexOf("select") != -1)
			{
				index = obj.selectedIndex;
				if (index >= 0)
				{
					strValue = obj.options[index].value;
				}
				else
				{
					strValue = "";
				}
			}
			else if (obj.type != null && obj.type.indexOf("radio") != -1)
			{
				strValue = obj.value;
			}
			else if (obj[0] != null && obj[0].type.indexOf("radio") != -1)
			{
				strValue = "";
				for (var arrayCount = 0; arrayCount < obj.length; arrayCount++)
				{
					if (obj[arrayCount].checked)
					{
						strValue = obj[arrayCount].value;
					}
				}

				// no checking for this array object
				blnSpecialCheck = "false";
			}
			else if (obj[0] != null && typeof(obj[0]) == "object")
			{
				childList = new Array();
				for (var arrayCount = 0; arrayCount < obj.length; arrayCount++)
				{
					for (elementCount = 0; elementCount < formObj.elements.length; elementCount++)
					{
						if (formObj.elements[elementCount] == obj[arrayCount])
						{
							childList[arrayCount] = new Array( "" + elementCount,
								strFieldDscp + " " + (arrayCount + 1), strFieldType, blnSpecialCheck);
						}
					}
				}

				strErrMsg = validateForm(formObj, childList);

				// no checking for this array object
				blnSpecialCheck = "false";
				strFieldType = null;
			}
			else
			{
				strValue = obj.value;
			}

			if (blnSpecialCheck == "true")
			{
				if (strValue != "")
				{
					if (invalidCharactersCheck(strValue))
					{
						strErrMsg = generateValidateMessage(invalidCharacter, [strFieldDscp]);
					}
				}
			}
			else if (blnSpecialCheck == "html")
			{
				if (strValue != "")
				{
					if (noHTMLCheck(strValue))
					{
						strErrMsg = generateValidateMessage(invalidHTMLToken, [strFieldDscp]);
					}
				}
			} 
 
			switch (strFieldType)
			{
				case "M":       // mandatory
				case "MA":      // mandatory alphanumeric (refered to by maintenance module)

					if (trim(strValue) == "")
					{ 
						strErrMsg = generateValidateMessage(fieldIsRequired, [strFieldDscp]);
					}
					break;

				case "A":       // alphanumeric

					// no implementation
					break;

				case "ML":      // mandatory letter

					if (trim(strValue) == "")
					{
						strErrMsg = generateValidateMessage(fieldIsRequired, [strFieldDscp]);
					}
					else
					{
						for (i = 0; i < strValue.length; i++)
						{
							var c = strValue.charAt(i);
							if (!isRomanAlphabet(c))
							{
								strErrMsg = generateValidateMessage(invalidRomanAlphabet, [strFieldDscp]);
								break;
							}
						}
					}
					break;

				case "L":       // letter

					for (i = 0; i < strValue.length; i++)
					{
						var c = strValue.charAt(i);
						if (!isRomanAlphabet(c))
						{
							strErrMsg = generateValidateMessage(invalidRomanAlphabet, [strFieldDscp]);
							break;
						}
					}
					break;

				case "MN":      // mandatory numeric

					if (trim(strValue) == "")
					{
						strErrMsg = generateValidateMessage(fieldIsRequired, [strFieldDscp]);
					}
					else
					{
						strValue = removeGroupingSeparator(strValue);
						if (isNaN(strValue) || (strValue == null))
						{
							strErrMsg = generateValidateMessage(invalidNumericFormat, [strFieldDscp]);
						}
						else if ((strValue + 0) < 0)
						{
							strErrMsg = generateValidateMessage(numberTooSmall, [strFieldDscp, "0"]);
						}
					}
					break;

				case "N":       // numeric

					if (strValue != "")
					{
						strValue = removeGroupingSeparator(strValue);
						if (isNaN(strValue) || (strValue == null))
						{
							strErrMsg = generateValidateMessage(invalidIntFormat, [strFieldDscp]);
						}
					}
					break;

				case "MI":      // mandatory integer (only accept 0-9)

					if (trim(strValue) == "")
					{
						strErrMsg = generateValidateMessage(fieldIsRequired, [strFieldDscp]);
					}
					else
					{
						strValue = removeGroupingSeparator(strValue);
						if (isNaN(strValue) || (strValue == null) || isInvalidInteger(strValue))
						{
							strErrMsg = generateValidateMessage(invalidNumericFormat, [strFieldDscp]);
						}
						else if ((strValue + 0) < 0)
						{
							strErrMsg = generateValidateMessage(numberTooSmall, [strFieldDscp, "0"]);
						}
					}
					break;

				case "I":       // integer (only accept 0-9)

					if (strValue != "")
					{
						strValue = removeGroupingSeparator(strValue);
						if (isNaN(strValue) || (strValue == null) || isInvalidInteger(strValue))
						{
							strErrMsg = generateValidateMessage(invalidIntFormat, [strFieldDscp]);
						}
					}
					break;

				case "MP":      // mandatory positive (>0)
				case "MPI":     // DEPRECATED

					if (trim(strValue) == "")
					{
						strErrMsg = generateValidateMessage(fieldIsRequired, [strFieldDscp]);
					}
					else
					{
						strValue = removeGroupingSeparator(strValue);
						if (isNaN(strValue) || (strValue == null) || isInvalidInteger(strValue))
						{
							strErrMsg = generateValidateMessage(invalidIntFormat, [strFieldDscp]);
						}
						else
						{
							strValue = replaceWithDefaultMonetaryDecimalSeparator(strValue);
							if ((strValue + 0) <= 0)
							{
								strErrMsg = generateValidateMessage(numberMustLargerThan, [strFieldDscp, "0"]);
							}
						}
					}
					break;

				case "MPZ":     // mandatory positive inclusive of zero
				case "MNN":     // DEPRECATED
				case "MNNI":    // DEPRECATED

					if (trim(strValue) == "")
					{
						strErrMsg = generateValidateMessage(fieldIsRequired, [strFieldDscp]);
					}
					else
					{
						strValue = removeGroupingSeparator(strValue);
						if (isNaN(strValue) || (strValue == null) || isInvalidInteger(strValue))
						{
							strErrMsg = generateValidateMessage(invalidIntFormat, [strFieldDscp]);
						}
						else
						{
							strValue = replaceWithDefaultMonetaryDecimalSeparator(strValue);
							if ((strValue + 0) < 0)
							{
								strErrMsg = generateValidateMessage(numberMustLargerThanOrEqualTo, [strFieldDscp, "0"]);
							}
						}
					}
					break;

				case "P":       // positive (>0)
				case "PI":      // DEPRECATED

					if (strValue != "")
					{
						strValue = removeGroupingSeparator(strValue);
						if (isNaN(strValue) || (strValue == null) || isInvalidInteger(strValue))
						{
							strErrMsg = generateValidateMessage(invalidIntFormat, [strFieldDscp]);
						}
						else
						{
							strValue = replaceWithDefaultMonetaryDecimalSeparator(strValue);
							if ((strValue + 0) <= 0)
							{
								strErrMsg = generateValidateMessage(numberMustLargerThan, [strFieldDscp, "0"]);
							}
						}
					}
					break;

				case "PZ":      // positive inclusize of zero
				case "NN":      // DEPRECATED
				case "NNI":     // DEPRECATED

					if (strValue != "")
					{
						strValue = removeGroupingSeparator(strValue);
						if (isNaN(strValue) || (strValue == null) || isInvalidInteger(strValue))
						{
							strErrMsg = generateValidateMessage(invalidIntFormat, [strFieldDscp]);
						}
						else
						{
							strValue = replaceWithDefaultMonetaryDecimalSeparator(strValue);
							if ((strValue + 0) < 0)
							{
								strErrMsg = generateValidateMessage(numberMustLargerThanOrEqualTo, [strFieldDscp, "0"]);
							}
						}
					}
					break;

				case "MC":      // mandatory currency

					if (trim(strValue) == "")
					{
						strErrMsg = generateValidateMessage(fieldIsRequired, [strFieldDscp]);
					}
					else
					{
						strValue = removeGroupingSeparator(strValue);
						if (isInvalidCurrency(strValue) || (strValue == null))
						{
							strErrMsg = generateValidateMessage(invalidNumericFormat, [strFieldDscp]);
						}
					}
					break;

				case "C":       // currency

					strValue = removeGroupingSeparator(strValue);

					if (strValue != "")
					{
						if (isInvalidCurrency(strValue) || (strValue == null))
						{
							strErrMsg = generateValidateMessage(invalidNumericFormat, [strFieldDscp]);
						}
					}
					break;

				case "MCP":     // mandatory currency positive (>0)

					if (trim(strValue) == "")
					{
						strErrMsg = generateValidateMessage(fieldIsRequired, [strFieldDscp]);
					}
					else
					{
						strValue = removeGroupingSeparator(strValue);

						if (isInvalidCurrency(strValue) || (strValue == null))
						{
							strErrMsg = generateValidateMessage(invalidNumericFormat, [strFieldDscp]);
						}
						else
						{
							strValue = replaceWithDefaultMonetaryDecimalSeparator(strValue);
							if ((strValue + 0) <= 0)
							{
								strErrMsg = generateValidateMessage(numberMustLargerThan, [strFieldDscp, "0"]);
							}
						}
					}
					break;

				case "MCPZ":    // mandatory currency positive inclusize of zero (OLD VERSION is MCNN)
				case "MCNN":    // DEPRECATED
				case "VR":      // DEPRECATED

					if (trim(strValue) == "")
					{
						strErrMsg = generateValidateMessage(fieldIsRequired, [strFieldDscp]);
					}
					else
					{
						strValue = removeGroupingSeparator(strValue);

						if (isInvalidCurrency(strValue) || (strValue == null))
						{
							strErrMsg = generateValidateMessage(invalidNumericFormat, [strFieldDscp]);
						}
						else
						{
							strValue = replaceWithDefaultMonetaryDecimalSeparator(strValue);
							if ((strValue + 0) < 0)
							{
								strErrMsg = generateValidateMessage(numberMustLargerThanOrEqualTo, [strFieldDscp, "0"]);
							}
						}
					}
					break;

				case "CP":      // currency positive (>0)

					strValue = removeGroupingSeparator(strValue);

					if (strValue != "")
					{
						if (isInvalidCurrency(strValue) || (strValue == null))
						{
							strErrMsg = generateValidateMessage(invalidNumericFormat, [strFieldDscp]);
						}
						else
						{
							strValue = replaceWithDefaultMonetaryDecimalSeparator(strValue);
													if ((strValue + 0) <= 0)
						{
							strErrMsg = generateValidateMessage(numberMustLargerThan, [strFieldDscp, "0"]);
						}
					}
					}
					break;

				case "CPZ":     // currency positive inclusize of zero
				case "CNN":     // DEPRECATED

					strValue = removeGroupingSeparator(strValue);

					if (strValue != "")
					{
						if (isInvalidCurrency(strValue) || (strValue == null))
						{
							strErrMsg = generateValidateMessage(invalidNumericFormat, [strFieldDscp]);
						}
						else
						{
							strValue = replaceWithDefaultMonetaryDecimalSeparator(strValue);
							if ((strValue + 0) < 0)
							{
								strErrMsg = generateValidateMessage(numberMustLargerThanOrEqualTo, [strFieldDscp, "0"]);
							}
						}
					}
					break;
			}
		}

		if (strErrMsg != "")
		{
			if (strErrMsgs != "")
			{
				strErrMsgs += "\n";
			}

			strErrMsgs += strErrMsg;
		}
	}

	return strErrMsgs;
}

// To check whether the checkbox or array of checkboxes is selected
function isCheckboxSelected(checkboxObj)
{
	var isSelected = false;

	if (checkboxObj.length == null || checkboxObj.length == "undefined")
	{
		isSelected = checkboxObj.checked;
	}
	else
	{
		for (var i = 0; i < checkboxObj.length; i++)
		{
			if (checkboxObj[i].checked == true)
			{
				isSelected = true;
			}
		}
	}

	return isSelected;
}

// To support localization
function generateValidateMessage(message_template, strArray)
{ 
	try
	{
		var openIndex;
		var returnMsg = "";
		var closeIndex;
		var template = message_template;

		index = 0;
		while (template.indexOf("[") >= 0)
		{
			openIndex = template.indexOf("[");
			closeIndex = template.indexOf("]");

			returnMsg = returnMsg + template.substr(0, openIndex);
			returnMsg = returnMsg + strArray[index];
			index++;
			template = template.substr(closeIndex + 1, template.length);
		}
		if (template != "")
		{
			returnMsg = returnMsg + template;
		}
		return returnMsg;
	}
	catch (e)
	{
		return "Error, parameter was passed to method generateValidateMessage is invalid";
	}
}

// To check if a character is a letter
function isRomanAlphabet(character)
{
	return (((character >= "a") && (character <= "z")) || ((character >= "A") && (character <= "Z")));
}

// To check if a character is a valid west arabic numerals (0-9), including symbol (locale-specific decimal separator)
// return true if it is, else false
function isWestArabicNumeralsOrValidSymbol(character)
{
	var acceptedSymbol = "";

	// if monetary decimal separator is not specified, default it to dot (.)
	if (typeof monetaryDecimalSeparator == "undefined")
	{
		acceptedSymbol = ".";
	}
	else
	{
		acceptedSymbol = monetaryDecimalSeparator;
	}

	return ((character == "1") || (character == "2") || (character == "3") || (character == "4") ||
		(character == "5") || (character == "6") || (character == "7") || (character == "8") ||
		(character == "9") || (character == "0") || (character == acceptedSymbol));
}

// To check if a character is a valid west arabic numerals (0-9)
// return true if it is, else false
function isWestArabicNumerals(character)
{
	return ((character == "1") || (character == "2") || (character == "3") || (character == "4") ||
		(character == "5") || (character == "6") || (character == "7") || (character == "8") ||
		(character == "9") || (character == "0"));
}

// To perform locale-sensitive currency amount checking with lenience of accepting decimal symbol;
// equivalent of isNaN() function applicable for numeric checking
// return true if input is found to contain invalid character, else false
// accept "monetaryDecimalSeparator"
function isInvalidCurrency(input)
{
	// negative sign is only acceptable at first position
	if (input.indexOf("-") > 0)
	{
		// have - other positon -> not accept
		return true;
	}

	var startPoint;
	if (input.indexOf("-") == 0)
	{
		// have - so, skip -
		startPoint = 1
	}
	else
	{
		startPoint = 0;
	}

	var counter = 0;
	for (i = startPoint; i < input.length; i++)
	{
		var c = input.charAt(i);
		if (!isWestArabicNumeralsOrValidSymbol(c))
		{
			return true;
		}
		if (c == ".")
		{
			counter++;
			if (counter == 2)
			{
				return true;
			}
		}
	}

	return false;
}

// To perform integer checking (each character of input is stritctly a west arabic numeral)
// return true if input is found to contain unexpected character, else false
// not accept "monetaryDecimalSeparator"
function isInvalidInteger(input)
{
	for (i = 0; i < input.length; i++)
	{
		var c = input.charAt(i);
		if (!isWestArabicNumerals(c))
		{
			return true;
		}
	}

	return false;
}

function isNumber(value)
{
	if (isBlank(value))
	{
		return false;
	}
	else
	{
		var strValue = value.toString();
		strValue = strValue.replace(/,/g, "");
		return !isNaN(strValue);
	}
}

function isBlank(text)
{
	if (text == null)
		return true;
	else
		return (trim(text) == "");
}

function addErrorMessage(errorMessage, message)
{
	if (errorMessage == null) errorMessage = "";
	if (message != "")
	{
		if (errorMessage != "") errorMessage += "\n";
		errorMessage += message;
	}
	return errorMessage;
}

// Email address validation function
function checkEmail(email)
{
	// returns error message if validation fails, else return empty string
	if (!isEmailAddress(email))
	{
		field = new Array();
		field[0] = labelEmail;
		return generateValidateMessage(invalidEmailFormat, field);
	}
	else
	{
		return "";
	}
}

// Email address with localization function
function checkEmail(email, labelEmail)
{
    // returns error message if validation fails, else return empty string
	if (!isEmailAddress(email))
	{
		field = new Array();
		field[0] = labelEmail;
		return generateValidateMessage(invalidEmailFormat, field);
	}
	else
	{
		return "";
	}
}

// Postcode validation function
function checkPostcode(postcode, length, labelPostcode)
{
	// returns error message if validation fails, else return empty string
	if (postcode.value.length != length)
	{
		field = new Array();
		field[0] = labelPostcode;
		return generateValidateMessage(invalidPostcodeLength, field);
	}
	else
	{
		return "";
	}
}

// Field fix length validation function
function checkFixLength(element, length, labelElement)
{
    var errMsg = "";

    field = new Array();
	field[0] = labelElement;
	field[1] = parseInt(length,10);

    if (element.value != "")
    {
        //element.value = removeGroupingSeparator(element.value);
        if (isNaN(element.value) || (element.value == null) || isInvalidInteger(element.value))
        {
            errMsg = addErrorMessage(errMsg, generateValidateMessage(invalidIntFormat, field));
        }
    }
	if (element.value.length != length)
	{
	    errMsg = addErrorMessage(errMsg, generateValidateMessage(invalidFixLength, field));
	}
	return errMsg;
}

// Sub-function invoked by checkEmail(String email)
function isEmailAddress(input)
{
	var addressPattern = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
	return addressPattern.test(input);
}

// Remove grouping separator from input
function removeGroupingSeparator(amount)
{
	var number = "";
	var absoluteNumber = "";
	var decimal = "";
	var decimalSeperatorPosition = -1;
	var formattedNumber = "";

	// extract number, decimal, absolute number
	amount = removeWhiteSpace(amount);

	try
	{
		// check it has this variable in scope
		monetaryDecimalSeparator = monetaryDecimalSeparator;
	}
	catch(e)
	{
		alert('Please add this line in your JSP:\n\n' +
			  'var monetaryDecimalSeparator = "<solution-web:numericSymbol locale="${YourActionForm.locale}" type="monetaryDecimalSeparator"/>";');
		monetaryDecimalSeparator = ".";
	}

	decimalSeperatorPosition = amount.indexOf(monetaryDecimalSeparator);
	if (decimalSeperatorPosition > -1)
	{
		number = amount.substring(0, decimalSeperatorPosition);
		decimal = amount.substring(decimalSeperatorPosition + 1, amount.length);
	}
	else
	{
		number = amount;
	}

	// remove grouping seperator
	for (; number.length >= 4;)
	{
		// -999 does not contain grouping seperator, therefore append it
		var temp = number.substring((number.length - 4), number.length);
		if (!isNaN(temp))
		{

		}
		// ,999 need extraction
		else
		{
			temp = number.substring((number.length - 3), number.length);
			var currentGroupingSeparator = number.substring((number.length - 4), (number.length - 3));
			if (temp.indexOf(groupingSeparator) > -1)
			{
				// fail to format
				return amount;
			}
			if (currentGroupingSeparator != groupingSeparator)
			{
				// fail to format
				return amount;
			}
		}
		formattedNumber = temp + formattedNumber;
		number = number.substring(0, (number.length - 4));
	}
	if (number.length > 0)
	{
		formattedNumber = number + formattedNumber;
	}

	// combine formatted number and decimal
	if (decimalSeperatorPosition > -1)
	{
		formattedNumber += monetaryDecimalSeparator + decimal;
	}

	return formattedNumber;
}

// Replace monetary decimal separator with default one (.)
function replaceWithDefaultMonetaryDecimalSeparator(input)
{
	var comma = ',';

	if (input.indexOf(comma) > 0)
	{
		input = input.replace(comma, DEFAULT_MONETARY_DECIMAL_SYMBOL);
	}

	return input;
}

// Check textarea max length
function checkTextAreaMaxLength(field, maxlimit, e)
{
	if (field.value.length >= maxlimit)
	{
		// accept the following keystrokes
		if (e.keyCode == 45 ||    // Insert
			e.keyCode == 46 ||    // Delete
			e.keyCode == 8  ||    // Backspace
			e.keyCode == 9  ||    // Tab
			e.keyCode == 33 ||    // PageUp
			e.keyCode == 34 ||    // PageDown
			e.keyCode == 35 ||    // End
			e.keyCode == 36)      // Home
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}

function textareaCheck(field, maxlength) {
	if (field.value.length > maxlength) 
		field.value = field.value.substring(0, maxlength);
}