
/******** Utility Functions For Validation *************/
function isLegal(txt) {
var invalids = "!@#$%^&*()-~,'<.>/?;:\|"
for(i=0; i<invalids.length; i++) {
if(txt.indexOf(invalids.charAt(i)) >= 0 ) {
return false;
}
        }
return true;
}

/* Concatenate two strings - wrapper function so JS and CF code can be identical */
function fv_concat(str1,str2) {
	return str1.concat(str2);
}

/* Remove whitespace from a string */
function fv_trimString(str) {
  return str.replace(/^\s+/g,'').replace(/\s+$/g,'');
}

/* Checks if a string contains only whitespace */
function fv_isBlank(str) {
	var re = /^[\s]*$/;
	return (re.test(str));
}

/* Get selected value from <select> not multiple */
function fv_selectedValue(formfield) {
	var index = formfield.options.selectedIndex;
	return (formfield.options[index].value);
}

/* Note these next functions are to compare numbers as strings so that numbers larger than 
	javascript can handle can be compared */

/* Compares 2 number strings, returns true if num1 >= num2 */
function fv_compareIntegers(num1, num2) {
	var num1neg = (num1.charAt(0) == '-') ? true : false;
	var num2neg = (num2.charAt(0) == '-') ? true : false;
	var i;
	if((num1 == num2) || (!num1neg && num2neg) || 
	   (num1neg && num2neg && num1.length < num2.length) ||
	   (!num1neg && !num2neg && num1.length > num2.length))
		return true;
	if((num1neg && !num2neg) || 
	   (num1neg && num2neg && num1.length > num2.length) ||
	   (!num1neg && !num2neg && num1.length < num2.length))
		return false;
	// if here then logic proves that they are same length and same parity
	for(i=0;i<num1.length;i++) {
		if(num1.charAt(i) < num2.charAt(i)) {
			if(num1neg) { return true; }
			else { return false; }
		} else if(num1.charAt(i) > num2.charAt(i)) {
			if(num1neg) { return false; }
			else { return true; }
		}
	}
	// if here then equal, just in case
	return true;
}

/* Compares 2 decimal number strings, returns true if num1 >= num2 */
function fv_compareDecimals(num1, num2) {
	var num1neg = (num1.charAt(0) == '-') ? true : false;
	var num2neg = (num2.charAt(0) == '-') ? true : false;
	var i;
	var int1 = 0;
	var int2 = 0;
	var dec1 = 0;
	var dec2 = 0;
	if (num1.indexOf('.') > -1) {
		int1 = num1.substring(0,num1.indexOf('.'));
		dec1 = num1.substring(num1.indexOf('.')+1,num1.length);
	} else {
		int1 = num1;
	}
	if (num2.indexOf('.') > -1) {
		int2 = num2.substring(0,num2.indexOf('.'));
		dec2 = num2.substring(num2.indexOf('.')+1,num2.length);
	} else {
		int2 = num2;
	}
	var minDecLen = Math.min(dec1.length,dec2.length);
	// compares the integers
	if (fv_compareIntegers(int1, int2) && int1 != int2) { return true; }
	if (!fv_compareIntegers(int1, int2) && int1 != int2) { return false; }
	// if here then logic proves that the decimals are same length and same parity
	for(i=0;i<minDecLen;i++) {
		if(dec1.charAt(i) < dec2.charAt(i)) {
			if(num1neg) { return true; }
			else { return false; }
		} else if(dec1.charAt(i) > dec2.charAt(i)) {
			if(num1neg) { return false; }
			else { return true; }
		}
	}
	// compares with different lengths of decimals if same parity on the top dec pls.
	if (dec1.length < dec2.length) { return false; }
	// if here then equal, just in case
	return true;
}

/* Checks a number is within a certain range, assumes all arguments are valid numbers as strings */
function fv_isIntegerInRange(num,low,high) {
	num = fv_trimString(num); low = fv_trimString(low); high = fv_trimString(high);
	if(low != "" && !fv_compareIntegers(num,low)) { return false; }
	if(high != "" && !fv_compareIntegers(high,num)) { return false; }
	return true;
}

/* Checks a decimal number is within a certain range, assumes all arguments are valid numbers as strings */
function fv_isDecimalInRange(num,low,high) {
	num = fv_trimString(num); low = fv_trimString(low); high = fv_trimString(high);
	if(low != "" && !fv_compareDecimals(num,low)) { return false; }
	if(high != "" && !fv_compareDecimals(high,num)) { return false; }
	return true;
}
	
/* Checks a date is within a certain range, assumes all arguments are valid dates in ODBC format */
function fv_isDateInRange(date,low,high) {
	date = fv_trimString(date); low = fv_trimString(low); high = fv_trimString(high);
	if(low <= date && date <= high) { return true; }
	else { return false; }
}

/* Manually checks a ODBC date for validity */
function fv_invalidDateCheck(string) {
	var year = string.substr(0,4);
	if (year == 0) { return true; }
	var month = string.substr(5,2);
    if (month < 1 || month > 12) { return true; }
	var day = string.substr(8,2);
	if (day < 1 || day > 31) { return true; }
	if (day > 30 && (month == "04" || month == "06" || month == "09" || month == "11")) { return true; }
	var leap = 0;
	if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) { leap = 1; }
    if (month == 2 && leap == 1 && day > 29) { return true; }
    if (month == 2 && leap != 1 && day > 28) { return true; }
	return false;
}

/* Convert Eurodate format (dd/mm/yyyy) to ODBC format (yyyy-mm-dd) */
function fv_eurodateToODBC(eurodate) {
	var re = /^(\d{2})\/(\d{2})\/(\d{4})$/;
	return eurodate.replace(re, "$3-$2-$1");
}

/* Convert Short Eurodate format (d/m/yyyy) to ODBC format (yyyy-mm-dd) */
function fv_shorteurodateToODBC(eurodate) {
	var re = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
	re.exec(eurodate);
	var day = RegExp.$1; 	if(day.length < 2) { day = "0" + day; }
	var month = RegExp.$2; 	if(month.length < 2) { month = "0" + month; }
	return (RegExp.$3 + "-" + month + "-" + day);
}

/* Convert Short Eurodate format (d/m/yyyy) to Eurodate format (dd/mm/yyyy) */
function fv_shorteurodateToEurodate(shorteurodate) {
	var re = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
	re.exec(shorteurodate);
	var day = RegExp.$1; 	if(day.length < 2) { day = "0" + day; }
	var month = RegExp.$2; 	if(month.length < 2) { month = "0" + month; }
	return (day + "/" + month + "/" + RegExp.$3);
}

/******** Basic Validation Functions *******************/

/* Required Form Field for <input type="text"> or <textarea> */
function fv_textRequired(form,fieldname,displayname) {
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	else { return ""; }
}

/* Required Form Field for <select> not multiple */
function fv_selectRequired(form,fieldname,displayname) {
	if(fv_selectedValue(form[fieldname]) == "") { return displayname + " must be selected\n"; }
	else { return ""; }
}

/* Integer validation for <input type="text"> or <textarea> */
function fv_integerFormat(form,fieldname,displayname,required,size,unsigned) {
	var hi,lo;
	if(arguments.length < 4) { required = false; }
	if(arguments.length < 5) { size = "integer"; }
	if(arguments.length < 6) { unsigned = false; }
	size = size.toLowerCase();
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var numberRE = /^\-?[\d]+$/; 
	if(!numberRE.test(form[fieldname].value)) { return displayname + " must be an integer\n"; }
	if(unsigned) { 
		lo = "0";
		switch (size) {
			case "tinyint":   hi = "255"; break;
			case "smallint":  hi = "65535"; break;
			case "mediumint": hi = "16777215"; break;
			case "int": 	  hi = "4294967295"; break;
			case "integer":   hi = "4294967295"; break;
			case "bigint":    hi = "18446744073709551615"; break;
			default : 
				return "Error occurred: "+size+" is not a valid size\n";
		}
	} else {
		switch (size) {
			case "tinyint":   hi = "127"; lo = "-128"; break;
			case "smallint":  hi = "32767"; lo = "-32768"; break;
			case "mediumint": hi = "8388607"; lo = "-8388608"; break;
			case "int": 	  hi = "2147483647"; lo = "-2147483648"; break;
			case "integer":   hi = "2147483647"; lo = "-2147483648"; break;
			case "bigint":    hi = "9223372036854775807"; lo = "-9223372036854775808"; break;
			default :
				return "Error occurred: "+size+" is not a valid size\n";
		}
	}
	//if(!fv_isIntegerInRange(form[fieldname].value,lo,hi)) { return displayname + " must be between " + lo + " and " + hi + "\n"; }
	return "";
}

/* Integer validation (int, between from and to) for <input type="text"> or <textarea> */
function fv_integerFormatRange(form,fieldname,displayname,required,from,to) {
	if(arguments.length < 4) { required = false; }
	if(arguments.length < 5) { from = ""; }
	if(arguments.length < 6) { to = ""; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var numberRE = /^\-?[\d]+$/; 
	if(!numberRE.test(form[fieldname].value)) { return displayname + " must be an integer\n"; }
	if(!fv_isIntegerInRange(form[fieldname].value,from,to)) { return displayname + " must be between " + from + " and " + to + "\n"; }
	return "";
}

/* Decimal Format (precision specified) validation for <input type="text"> or <textarea> */
function fv_decimalFormat(form,fieldname,displayname,required,precision,scale) {
	if(arguments.length < 4) { required = false; }
	// if not defined use real range
	if(arguments.length < 5) { precision = 24; }
	if(arguments.length < 6) { scale = 7; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var decRE = /^\-?[\d]+(\.[\d]+)?$/;
	if(!decRE.test(form[fieldname].value)) { return displayname + " is not a decimal number\n"; }
	if(precision <= scale) { return "Error occurred: Precision must be greater than Scale\n"; }
	var preciseRE = new RegExp("^\\-?[\\d]{1,"+(precision-scale)+"}(\\.[\\d]{1,"+scale+"})?$");
	if(!preciseRE.test(form[fieldname].value)) { return displayname + " has a maximum precision of "+precision+" and a scale of "+scale+"\n"; }
	else { return ""; }
}

/* Date validation for <input type="text"> or <textarea> */
function fv_dateFormat(form,fieldname,displayname,required,type,format) {
	var ODBCdate;
	if(arguments.length < 4) { required = false; }
	if(arguments.length < 5) { type = ""; }
	if(arguments.length < 6) { format = "eurodate"; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	switch (format) {
		case "eurodate":
			var re = /^\d{2}\/\d{2}\/\d{4}$/;
			if(!re.test(form[fieldname].value)) { return displayname + " is not in dd/mm/yyyy format\n"; }
			ODBCdate = fv_eurodateToODBC(form[fieldname].value);
			break;
		case "shorteurodate":
			var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
			if(!re.test(form[fieldname].value)) { return displayname + " is not in d/m/yyyy format\n"; }
			ODBCdate = fv_shorteurodateToODBC(form[fieldname].value);
			break;
		case "odbcdate":
			var re = /^\d{4}\-\d{2}\-\d{2}$/;
			if(!re.test(form[fieldname].value)) { return displayname + " is not in yyyy-mm-dd format\n"; }
			ODBCdate = form[fieldname].value;
			break;
		default:
			return "Error occurred: "+format+" is not a valid format\n";
	}	
	if(fv_invalidDateCheck(ODBCdate)) { return displayname + " is not a valid date\n"; }
	switch (type) {
		case "SQLsmalldatetime":   
			if(!fv_isDateInRange(ODBCdate,"1900-01-01","2079-06-06")) { return displayname + " must be between 01/01/1900 and 06/06/2079\n"; } 
			break;
		case "SQLdatetime":  
			if(!fv_isDateInRange(ODBCdate,"1753-01-01","9999-12-31")) { return displayname + " must be between 01/01/1753 and 31/12/9999\n"; } 
			break;
		case "MySQLdate":  
			if(!fv_isDateInRange(ODBCdate,"1000-01-01","9999-12-31")) { return displayname + " must be between 01/01/1000 and 31/12/9999\n"; } 
			break;
	}
	return "";
}

/* Date Compare with Date validation (return error if Date 1 is not less than Date 2) for <input type="text"> or <textarea> */
function fv_dateFormatCompare(form,fieldname1,fieldname2,displayname1,displayname2,required,type,format) {
	var ODBCdate;
	var today;
	var dateObject = new Date();
	if(arguments.length < 6) { required = false; }
	if(arguments.length < 7) { type = ""; }
	if(arguments.length < 8) { format = "eurodate"; }
	form[fieldname1].value = fv_trimString(form[fieldname1].value);
	form[fieldname2].value = fv_trimString(form[fieldname2].value);
	if (required) {
		if(fv_isBlank(form[fieldname1].value)) { return displayname1 + " cannot be left blank\n"; }
		if(fv_isBlank(form[fieldname2].value)) { return displayname2 + " cannot be left blank\n"; }
	}
	else {
		today = fv_shorteurodateToEurodate(dateObject.getDay() + "/" + dateObject.getMonth() + "/" + dateObject.getYear());
		if(fv_isBlank(form[fieldname1].value)) { form[fieldname1].value = today; }
		if(fv_isBlank(form[fieldname2].value)) { form[fieldname2].value = today; }
	}
	switch (format) {
		case "eurodate":
			var re = /^\d{2}\/\d{2}\/\d{4}$/;
			if(!re.test(form[fieldname1].value)) { return displayname1 + " is not in dd/mm/yyyy format\n"; }
			ODBCdate1 = fv_eurodateToODBC(form[fieldname1].value);
			if(!re.test(form[fieldname2].value)) { return displayname2 + " is not in dd/mm/yyyy format\n"; }
			ODBCdate2 = fv_eurodateToODBC(form[fieldname2].value);
			break;
		case "shorteurodate":
			var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
			if(!re.test(form[fieldname1].value)) { return displayname1 + " is not in d/m/yyyy format\n"; }
			ODBCdate1 = fv_shorteurodateToODBC(form[fieldname1].value);
			if(!re.test(form[fieldname2].value)) { return displayname2 + " is not in d/m/yyyy format\n"; }
			ODBCdate2 = fv_shorteurodateToODBC(form[fieldname2].value);
			break;
		case "odbcdate":
			var re = /^\d{4}\-\d{2}\-\d{2}$/;
			if(!re.test(form[fieldname1].value)) { return displayname1 + " is not in yyyy-mm-dd format\n"; }
			ODBCdate1 = form[fieldname1].value;
			if(!re.test(form[fieldname2].value)) { return displayname2 + " is not in yyyy-mm-dd format\n"; }
			ODBCdate2 = form[fieldname2].value;
			break;
		default:
			return "test Error occurred: "+format+" is not a valid format\n";
	}	
	if(fv_invalidDateCheck(ODBCdate1)) { return displayname1 + " is not a valid date\n"; }
	if(fv_invalidDateCheck(ODBCdate2)) { return displayname2 + " is not a valid date\n"; }
	switch (type) {
		case "SQLsmalldatetime":   
			if(!fv_isDateInRange(ODBCdate1,"1900-01-01","2079-06-06")) { return displayname1 + " must be between 01/01/1900 and 06/06/2079\n"; } 
			if(!fv_isDateInRange(ODBCdate2,"1900-01-01","2079-06-06")) { return displayname2 + " must be between 01/01/1900 and 06/06/2079\n"; }
			break;
		case "SQLdatetime":
			if(!fv_isDateInRange(ODBCdate1,"1753-01-01","9999-12-31")) { return displayname1 + " must be between 01/01/1753 and 31/12/9999\n"; } 
			if(!fv_isDateInRange(ODBCdate2,"1753-01-01","9999-12-31")) { return displayname2 + " must be between 01/01/1753 and 31/12/9999\n"; }
			break;
		case "MySQLdate":
			if(!fv_isDateInRange(ODBCdate1,"1000-01-01","9999-12-31")) { return displayname1 + " must be between 01/01/1000 and 31/12/9999\n"; } 		
			if(!fv_isDateInRange(ODBCdate2,"1000-01-01","9999-12-31")) { return displayname2 + " must be between 01/01/1000 and 31/12/9999\n"; } 
			break;
	}
	if (ODBCdate1 < ODBCdate2) { return ""; }
	else { return displayname1 + " must come before " + displayname2 + "\n"; }
}

/* Bit format validation */
function fv_bitFormat(form,fieldname,displayname,required,inputtype) {
	if(arguments.length < 4) { required = false; }
	if(arguments.length < 5) { inputtype = "text"; }
	var bitRE = /^[01]$/;
	if(inputtype == "text" || inputtype == "textarea" || inputtype == "") {
		form[fieldname].value = fv_trimString(form[fieldname].value);
		if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
		if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
		if(!bitRE.test(form[fieldname].value)) { return displayname + " is not a bit (0 or 1)\n"; }
	}
	else if(inputtype == "select") {
		if(fv_selectedValue(form[fieldname]) == "" && !required) { return ""; }
		if(fv_selectedValue(form[fieldname]) == "") { return displayname + " must be selected\n"; }
		if(!bitRE.test(fv_selectedValue(form[fieldname]))) { return displayname + " is not a bit (0 or 1)\n"; }
	}
	else if(inputtype == "radio" || inputtype == "checkbox") {
 		if(form[fieldname].length == null) {
			if(!form[fieldname].checked && !required) { return ""; }
			if(!form[fieldname].checked) { return displayname + " must be checked\n"; }
			if(!bitRE.test(form[fieldname].value)) { return displayname + " is not a bit (0 or 1)\n"; }
		} else {
			var checkedValue = ""
			for(j=0;j<form[fieldname].length;j++)
				if(form[fieldname][j].checked) { checkedValue = form[fieldname][j].value; }	
			if(checkedValue == "" && !required) { return ""; }
			if(checkedValue == "") { return displayname + " must be checked\n"; }
			if(!bitRE.test(checkedValue)) { return displayname + " is not a bit (0 or 1)\n"; }
		} 
	}
	else { return "Error occurred: "+inputtype+" is not a valid input type\n"; }
	return "";
}

/* checkbox or radio  validation */
function fv_checkboxRequired(form,fieldname,displayname,required,inputtype) {
	if(arguments.length < 4) { required = false; }
	if(arguments.length < 5) { inputtype = "text"; }
	var bitRE = /^[01]$/;
	if(inputtype == "text" || inputtype == "textarea" || inputtype == "") {
		form[fieldname].value = fv_trimString(form[fieldname].value);
		if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
		if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
		if(!bitRE.test(form[fieldname].value)) { return displayname + " is not a bit (0 or 1)\n"; }
	}
	else if(inputtype == "select") {
		if(fv_selectedValue(form[fieldname]) == "" && !required) { return ""; }
		if(fv_selectedValue(form[fieldname]) == "") { return displayname + " must be selected\n"; }
	}
	else if(inputtype == "radio" || inputtype == "checkbox") {
 		if(form[fieldname].length == null) {
			if(!form[fieldname].checked && !required) { return ""; }
			if(!form[fieldname].checked) { return displayname + " must be checked\n"; }
		} else {
			var checkedValue = ""
			for(j=0;j<form[fieldname].length;j++)
				if(form[fieldname][j].checked) { checkedValue = form[fieldname][j].value; }	
			if(checkedValue == "" && !required) { return ""; }
			if(checkedValue == "") { return displayname + " must be checked\n"; }
		} 
	}
	else { return "Error occurred: "+inputtype+" is not a valid input type\n"; }
	return "";
}
/* Money validation for <input type="text"> or <textarea> */
function fv_moneyFormat(form,fieldname,displayname,required, size) {
	if(arguments.length < 4) { required = false; }
	if(arguments.length < 5) { size = "money"; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var moneyRE = /^\-?[\d]+(\.[\d]+)?$/;
	if(!moneyRE.test(form[fieldname].value)) { return displayname + " must be a monetary unit\n"; }
	switch (size) {
			case "money":   hi = "922337203685477.5807"; lo = "-922337203685477.5808"; break;
			case "smallmoney":  hi = "214748.3647"; lo = "-214748.3648"; break;
			default : 
				return "Error occurred: "+size+" is not a valid size\n";
	}
	if(!fv_isDecimalInRange(form[fieldname].value,lo,hi)) { return displayname + " must be between " + lo + " and " + hi + "\n"; }
	return "";
}

/* Form Field Maximum length check for <textarea> */
function fv_textMaxlength(form,fieldname,displayname,length) {
	if(form[fieldname].value.length > length) { return displayname + " cannot have more than " + length + " characters\n"; }
	else { return ""; }
}
/******** Special Case Validation Functions ************/

/* Email Address format validation for <input type="text"> or <textarea> */
function fv_emailFormat(form,fieldname,displayname,required) {
	if(arguments.length < 4) { required = false; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var reg1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/; // not valid
	var reg2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,6}|[0-9]{1,3})(\]?)$/; // valid
	if(reg1.test(form[fieldname].value) || !reg2.test(form[fieldname].value)) { return displayname + " is not a valid email address format\n"; }
	else { return ""; }
}

/* Alphanumeric validation (letters, numbers and underscores only, useful for Usernames,Passwords,Variable Names) for <input type="text"> or <textarea> */
function fv_alphanumericFormat(form,fieldname,displayname,required) {
	if(arguments.length < 4) { required = false; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var re = /^[\w]+$/;
	if(!re.test(form[fieldname].value)) { return displayname + " can only contain letters, numbers and underscores\n"; }
	else { return ""; }
}

/* Percentage validation (unsigned int, 0 to 100) for <input type="text"> or <textarea> */
function fv_percentageFormat(form,fieldname,displayname,required) {
	return fv_integerFormatRange(form,fieldname,displayname,required,"0","100");
}

/* Tax File Number (nine digits) validation for <input type="text"> or <textarea> */
function fv_taxFileNumberFormat(form,fieldname,displayname,required) {
	if(arguments.length < 4) { required = false; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var re = /^\d{9}$/;
	if(!re.test(form[fieldname].value)) { return displayname + " must be a 9 digit number\n"; }
	else { return ""; }
}

/* Australian Business Number (eleven digits) validation for <input type="text"> or <textarea> */
function fv_ABNFormat(form,fieldname,displayname,required) {
	if(arguments.length < 4) { required = false; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var re = /^\d{11}$/;
	if(!re.test(form[fieldname].value)) { return displayname + " must be a 11 digit number\n"; }
	else { return ""; }
}

/* Dollar validation for <input type="text"> or <textarea> */
function fv_dollarFormat(form,fieldname,displayname,required) {
	if(arguments.length < 4) { required = false; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var re = /^\-?[\d]+(\.[\d]{1,2})?$/;
	if(!re.test(form[fieldname].value)) { return displayname + " is not a dollar value\n"; }
	else { return ""; }
}

/* Postcode validation for <input type="text"> or <textarea> */
function fv_postcodeFormat(form,fieldname,displayname,required,country) {
	if(arguments.length < 4) { required = false; }
	if(arguments.length < 5) { country = "Australia"; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	switch (country) {
			case "Australia":  var re = /^[\d]{3,4}$/;  break;
			case "Austria":  var re = /^[\d]{4}$/;  break;	
			case "Belgium":  var re = /^[\d]{4}$/;  break;	
			case "Denmark":  var re = /^[\d]{4}$/;  break;	
			case "Finland":  var re = /^[\d]{5}$/;  break;	
			case "France":  var re = /^[\d]{5}$/;  break;	
			case "Germany":  var re = /^[\d]{5}$/;  break;	
			case "Greece":  var re = /^[\d]{3}[\s]{1}[\d]{2}$/; break;
			case "Italy":  var re = /^[\d]{5}$/;  break;
			case "Luxembourg":  var re = /^[\d]{4}$/;  break;
			case "Netherlands":  var re = /^[\d]{4}[\s]{1}[A-Z]{2}$/; break;
			case "Norway":  var re = /^[\d]{4}$/;  break;
			case "Portugal":  var re = /^([\d]{4}|[\d]{4}\-[\d]{3})$/;  break;
			case "Spain":  var re = /^[\d]{5}$/;  break;
			case "Sweden":  var re = /^[\d]{3}[\s]{1}[\d]{2}$/;  break;			
			case "Switzerland":  var re = /^[\d]{4}$/;  break;
			case "UK":  var re = /^([A-Z]{1}[\d]{1,2}|[A-Z]{2}[\d]{1,2}|[A-Z]{1,2}[\d]{1}[A-Z]{1}|[A-Z]{3})[\s]{1}[\d]{1}[A-Z]{2}$/; break;
			case "US":  var re = /^([\d]{5}|[\d]{5}\-[\d]{4})$/; break;
			default : 
				return "Error occurred: "+country+" is not a valid country\n";
	}
	if(!re.test(form[fieldname].value)) { return displayname + " is not a valid postcode\n"; }
	else { return ""; }
}

/* Expiry Date validation for <input type="text"> or <textarea> */
function fv_expiryDateFormat(form,fieldname,displayname,required) {
	if(arguments.length < 4) { required = false; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var re = /^\d{2}\/\d{2}$/;
	if(!re.test(form[fieldname].value)) { return displayname + " is not in mm/yy format\n"; }
	var month = form[fieldname].value.substr(0,2);
    if (month < 1 || month > 12) { return displayname + " is not a valid month\n"; }
	else { return ""; }
}

/* Credit Card Number validation for <input type="text"> or <textarea> */
function fv_creditCardNumberFormat(form,fieldname,displayname,required) {
	if(arguments.length < 4) { required = false; }
	form[fieldname].value = fv_trimString(form[fieldname].value);
	if(fv_isBlank(form[fieldname].value) && !required) { return ""; }
	if(fv_isBlank(form[fieldname].value)) { return displayname + " cannot be left blank\n"; }
	var re = /^\d{16}$/;
	if(!re.test(form[fieldname].value)) { return displayname + " is not a valid credit card number\n"; }
	else { return ""; }
}


