/*********************************************************************************
 * Script Name: CSFunction.js
 * 
 * Description: This contains common validation functions useful for client-side form validation.
 * 
 *********************************************************************************
 * !IMPORTANT NOTE! Remember to change server-side validation if you change client-side validation!
 *********************************************************************************
 *
 * Author: Kevin Tang
 * 
 * Change Log:
 * Date			Programmer		Notes
 * ----------	----------		-----
 * ?			Kevin Tang		Created script.
 * 26/07/2004	Drew Kilz		Added isABNorACN.
 *								Modified ForceEntry's message.
 * 27/07/2004	Drew Kilz		Modified IsPostCode to a regular expression as it was
 *								 catching invalid postcodes correctly. (wasn't catching
 *								 letters as invalid)
 * 27/08/2004	Drew Kilz		Added isDate(day, month, year) for calculating valid date when
 *								 given day, month, and year.
 * 
 * .: TODO :.
 * Nothing.
 *********************************************************************************/

/*********  Function Prototype *************************
function isEmpty(s);
function isWhitespace (s);
function isEmail (s);
function isABNorACN(s)
function ForceEntry(objField, name);
function ForceNumber(objField, FieldName);
function ForceAlpha(objField, FieldName);
function ForceMoney(objField, FieldName);
function RTrim(strTrim);
function isDateNumber(strNum,method);
function PromptErrorMsg(Field,strError);
function ForceDate(datefield,strField, datetime);
function IsPostCode(strZip);
function ForceLength(objField, nLength, strWarning);
function IsTime(strTime);
function IsWebAddress(objfield, fieldname);
function Forcevalidtypeentry(Field,FieldName, entrytype);
function Forcevalidentry(Field,FieldName, entrytype);
function isSelected(Fieldobj,FieldName);
function isChecked(Fieldobj,FieldName, fieldNumber);
function isTelephone(objField, FieldName)

****************************************************/

var whitespace = " \t\n\r";
var formok = false;
var noofvalidation = 0;

function isEmpty(s)
{   return ((s == null) || (s.length == 0))
}

function isWhitespace (s)
{   var i;
    if (isEmpty(s)) return true;
    for (i = 0; i < s.length; i++)
    {   
	var c = s.charAt(i);
	if (whitespace.indexOf(c) == -1) return false;
    }
    return true;
}

function isEmail (s)
{  
    var i = 1;
    var sLength = s.length;
	var numeric = new Array("1","2","3","4","5","6","7","8","9","0","~","`","!","@","#","$","%","^","&","*","(",")","_","=","+","[","{","}","]",";",":","<",">",".","/","?",",") //,"[","{","]","}","\","|",";",":","'","<",".",">","/","?")
	var k,kk;
    var value = s.charAt(sLength-1)
	for (var k = 0; k < 40; k++) {
		    if ((value.indexOf(numeric[k]) != "-1")){ 
			return false;                   
	        }	
		}
	if( s.indexOf(" ") > 0){
		for (var kk=s.indexOf(" ");kk<sLength ;kk++ )
		{
			if (s.charAt(kk)!=" ")
			{
				return false;
			}
		}
	}
		
    while ((i < sLength) && (s.charAt(i) != "@"))
    { i++
    }

    if ((i >= sLength) || (s.charAt(i) != "@")) return false;
    else i += 2;

    while ((i < sLength) && (s.charAt(i) != "."))
    { i++
    }
	
    if ((i >= sLength - 1) || (s.charAt(i) != ".")) return false;
    else return true;
}

/**
 * Checks whether a string is a valid ABN or ACN.
 *  A valid ACN consists of 9 digits.
 *  A valid ABN consists of 2 digits followed by a valid ACN for a total of 11 digits.
 * 
 * Parameters:	objField	the object that contains the value to validate as an ABN / ACN
 * Returns:		true if the string is a valid ABN or ACN, false otherwise
 */
function validABNorACN(objField) {
	var ABCN = new String(objField.value);
	ABCN=replaceSubstring(ABCN, " ", "")
	if(!(ABCN.length == 9 || ABCN.length == 11)) {
		alert("Invalid ABN / ACN.  The ABN / ACN must be 9 or 11 digits in length.");
		objField.focus();
		return false;
	}
		
	for (var i=0; i<ABCN.length; i++) {
		if(ABCN.charAt(i) < '0' || ABCN.charAt(i) > '9') {
			alert("Invalid ABN / ACN.  The ABN / ACN can contain only digits.");
			objField.focus();
			return false;
		}
	}
	
	return true;
}

function ForceEntry(objField, name)
{
	var strField = new String(objField.value);
	if (isWhitespace(strField)) {
		alert("Please enter the " + name + ".");
		objField.focus();
		objField.select();
		return false;
	}
	return true;
}
		
function ForceNumber(objField, FieldName)
{
	var strField = new String(objField.value);
	var i = 0;
	var subparts = strField.split(".");
	 
	if(subparts.length > 2){
		alert("\"" +FieldName +"\"" + " must be a valid \"NUMERIC\" entry.  Please do not use commas or dollar signs or any non-numeric symbols.");
		objField.select();
		objField.focus();
		return false;
	}

	for (i = 0; i < strField.length; i++)
		if ((strField.charAt(i) < '0' || strField.charAt(i) > '9') && strField.charAt(i) != '.') {
			alert("\"" +FieldName +"\"" + " must be a valid \"NUMERIC\" entry.  Please do not use commas or dollar signs or any non-numeric symbols.");
			objField.select();
			objField.focus();
			return false;
		}
	return true;
}

function isCreditCard(objField, FieldName)
{
	var strField = new String(objField.value);
	var i = 0; j = 0;
	for (i = 0; i < strField.length; i++)
		if ((strField.charAt(i) < "0" || strField.charAt(i) > "9") && strField.charAt(i) != " ") {
			return false;
		}
		else{if (strField.charAt(i)!=" ")
		{
			j++;
		}
	}
	if (j!=16)
	{
			return false;
	}
	return true;
}

function ForceAlpha(objField, FieldName)
{
        var i
		var value = objField.value;
	var numeric = new Array("1","2","3","4","5","6","7","8","9","0","~","`","!","@","#","$","%","^","&","*","(",")","_","=","+","[","{","}","]",";",":","<",">",".","/","?",",")
	for (var i = 0; i < 40; i++) {
		    if ((value.indexOf(numeric[i]) != "-1")){ 
			alert(FieldName+" field might not have numeric charactor.");
			return false;                   
	        }	
		}
		return true;
	}
 
function ForceMoney(objField, FieldName)
{
	var strField = new String(objField.value);
	
	if (isWhitespace(strField)) return true;

	var i = 0;

	for (i = 0; i < strField.length; i++)
		if ((strField.charAt(i) < '0' || strField.charAt(i) > '9') && (strField.charAt(i) != '.')) {
			alert("\"" + FieldName+"\"" + " must be a valid \"NUMERIC\" entry.  Please do not use commas or dollar signs or any non-numeric symbols.");
			objField.focus();
			return false;
		}

	return true;
}



function RTrim(strTrim)
{
	var str = new String(strTrim);
	var i = 0;
	var c = "";
	var endpos = 0

	for (i = str.length; i >= 0 && endpos == 0; i = i - 1) {
		c = str.charAt(i);
		if (whitespace.indexOf(c) == -1)
			endpos = i;
	}

	return str.substring(0,endpos+1);
}

// Method 2: Day
// Method 1: Month
// Method (anything else): Year
function isDateNumber(strNum,method)
{
	var str = new String(strNum);
	var i = 0;

	if (isNaN(parseInt(str)) || parseInt(str) < 0) return false;

	if (method == 2)
		if (parseInt(str) > 31)
			return false;
	if (method == 1)
		if (parseInt(str) > 12)
			return false;

	for (i = 0; i < str.length; i++)
		if (str.charAt(i) < '0' || str.charAt(i) > '9')
			return false;
	return true;
}

function PromptErrorMsg(Field,strError)
{
	alert("You have entered an invalid \"DATE\".  Please make sure your date format is in \"DD/MM/YYYY\" format.");
	Field.select();
	Field.focus();
}

function ForceDate(datefield,strField, datetime)
{
	var str = new String(datefield.value);
	var datestr, datetimearray;
	if(datetime = "Date_Time"){
		datetimearray = str.split(" ");
		str = datetimearray[0];
	}
		
	var i = 0, count = str.length, j = 0;
	while ((str.charAt(i) != "/" && str.charAt(i) != "-") && i < count)
		i++;

	if (i == count || i > 2) {
		PromptErrorMsg(datefield,strField);
		return false;
	}

	var addOne = false;
	if (i == 2) addOne = true;

	if (!isDateNumber(str.substring(0,i),2)) {
		PromptErrorMsg(datefield,strField);
		return false;
	}

	j = i+1;
	i = 0;

	while ((str.charAt(i+j) != "/" && str.charAt(j+i) != "-") && i+j < count)
		i++;

	if (i+j == count || i > 2) {
		PromptErrorMsg(datefield,strField);
		return false;
	}

	if (!isDateNumber(str.substring(j,i+j),1)) {
		PromptErrorMsg(datefield,strField);
		return false;
	}

	j = i+3;
	i = 0;

	if (addOne) j++;

	while (i+j < count)
		i++;


	if (i != 2 && i != 4) {
		PromptErrorMsg(datefield,strField);
		return false;
	}

	if (!isDateNumber(str.substring(j,i+j),3)) {
		PromptErrorMsg(datefield,strField);
		return false;
	}

	return true;
}


function IsPostCode(strZip){
	//var s = new String(strZip);

	//if (s.length != 4)
	//	return false;

	//if(s.charAt(0) < '2' || s.charAt(0) > '8')
	//	return false;

	// Not working properly.  Replaced with regular expression below.
	//for (var i=1; i < s.length; i++)
	//	if (s.charAt(i) < '0' || s.charAt(s) > '9')
	//		return false;
	
	// Create a regular expression for validating postcodes - digits only
	var regEx = new RegExp("^[0-9]+$");
	var expFound = regEx.test(strZip);
	// If the string does not match the regular expression, invalid postcode
	if(!expFound)
		return false;
				
	return true;
}


function ForceLength(objField, nLength, strWarning){
	var strField = new String(objField.value);

	if (strField.length > nLength) {
		alert(strWarning);
		objField.focus();
		return false;
	} else
		return true;
}

/****************************************************************/

// PURPOSE:  Check to see if the string passed in is a valid time.
//	A valid time is defined as a string which is postfixed with either
//  "PM" or "AM".  Next it checks to see if there is a colon in the
//  string.  If there is, it makes sure that at least one digit preceeds
//  it and two proceed it.

function IsTime(strTime){
	var strTestTime1 = new String(strTime);
	strTestTime = strTestTime1.toUpperCase();

	var bolTime = false;

	if (strTestTime.indexOf("PM",1) != -1 || strTestTime.indexOf("AM",1))
		bolTime = true;
					
	if (bolTime && strTestTime.indexOf(":",0) == 0)
		bolTime = false;
			
	var nColonPlace = strTestTime.indexOf(":",1);
	if (bolTime && ((parseInt(nColonPlace) + 5) < (strTestTime.length - 1) || (parseInt(nColonPlace) + 4) > (strTestTime.length - 1)))
		bolTime = false;
		
	return bolTime;
}
	
function IsWebAddress(objfield, fieldname){
	var webadd = new String(objfield.value);
	var substrs = webadd.split(".");
	
	if((webadd.search("www.") != -1 || webadd.search("WWW.") != -1) && substrs.length >= 3){
		return true;
	}else{
		return false;
	}
}
		
function Forcevalidtypeentry(Field,FieldName, entrytype)
{
	alert("\"" + FieldName +"\"" +" is a REQUIRED field and must be a valid \"" + entrytype + "\" entry. ");
	Field.select();
	Field.focus();
	return true;
}

function Forcevalidentry(Field,FieldName, entrytype)
{
	alert("\"" + FieldName +"\"" +"  must have a valid \"" + entrytype + "\" entry. ");
	Field.select();
	Field.focus();
	return true;
}

function isSelected(Fieldobj,FieldName){
	var selopt =Fieldobj.options[Fieldobj.selectedIndex].value ;
      if(selopt == "0" || selopt == "")
	  {
			alert("Please select "+FieldName);
			Fieldobj.focus();
			return false;
			}
		else{
		return true;
		}
}

function isChecked(Fieldobj,FieldName,fieldnum){
	var i,flag;
	flag=0;
	for (i=0;i<fieldnum ; i++ )
	{
			if(Fieldobj[i].checked){
				flag=1;
			}
	}
	if (flag==0){
			//alert("Please check "+FieldName+"!");
			//Fieldobj.focus();
			return false;
	}
	else{
	return true;
	}
}

function isTelephone(objField, FieldName)
{
	var strField = new String(objField.value);
	var i = 0;
	for (i = 0; i < strField.length; i++)
		if ((strField.charAt(i) < '0' || strField.charAt(i) > '9') && strField.charAt(i) != '_'  && strField.charAt(i) != '(' && strField.charAt(i) != ')'  && strField.charAt(i) != ' '  && strField.charAt(i) != ';') {
			return false;
		}
	return true;
}

function isDate(dateStr) 
{
	
	var datePat = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
	var matchArray = dateStr.match(datePat); // is the format ok?
		
	if (matchArray == null) {
	return false;
	}

	month = matchArray[3]; // p@rse date into variables
	day = matchArray[1];
	year = matchArray[5];

	if (month < 1 || month > 12) { // check month range
	alert("Month must be between 1 and 12.");
	return false;
	}

	if (day < 1 || day > 31) {
	alert("Day must be between 1 and 31.");
	return false;
	}

	if ((month==4 || month==6 || month==9 || month==11) && day==31) {
	alert("Month "+ month +" doesn`t have 31 days!")
	return false;
	}

	if (month == 2) { // check for february 29th
	var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
	if (day > 29 || (day==29 && !isleap)) {
	alert("February " + year + " doesn`t have " + day + " days!");
	return false;
	}
	}
	
	return true; // date is valid
}

/**
 * Checks for a valid date with the field parameters of day, month, and year.
 * 
 * Parameters:	day		the day field of the date to verify
 *				month	the month field of the date to verify
 *				year	the year field of the date to verify
 * Returns:		true if the string is a valid date, false otherwise
 */
function isDate(day, month, year){
	
	// Standard error messages
	var day_err = "Invalid day value.  The day value must be an integer in the range 1-31.";
	var month_err = "Invalid month value.  The month value must be an integer in the range 1-12.";
	var year_err = "Invalid year value.  The year value must be an integer in the range 1900-9999.";
	
	// Array of days in each month, 0=January, 1=February, ..., 11=December
	var days_array = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
	
	// Day, month, and year values must be numeric
	if(isNaN(parseInt(day.value))){
		alert(day_err);
		day.focus();
		return false;
	}
	else if(isNaN(parseInt(month.value))){
		alert(month_err);
		month.focus();
		return false;
	}
	else if(isNaN(parseInt(year.value))){
		alert(year_err);
		year.focus();
		return false;
	}
	
	// Day, month, and year values are numeric.  Check they are within a valid range.
	// Year must be between 1900 and 9999
	if(!(year.value >= 1900 && year.value <= 9999)){
		alert(year_err);
		year.focus();
		return false;
	}
	// Month must be between 1 and 12
	else if(!(month.value >= 1 && month.value <= 12)){
		alert(month_err);
		month.focus();
		return false;
	}
	// Determine how many days should be in the month of this year and check that day is within range.
	else{
		// Check for leap year and set days_array February entry appropriately
		if(year.value % 4 == 0 && (year.value % 100 != 0 || year.value % 400 == 0))
			days_array[1] = 29;
		
		// Check that day falls within range
		if(!(day.value >= 1 && day.value <= days_array[month.value-1])){
			alert("Invalid day value (" + day.value + ").  There are only " + days_array[month.value-1] + " days in that month of that year.");
			day.focus();
			return false;
		}
	}
	return true;
}

function replaceSubstring(inputString, fromString, toString) {
   // Goes through the inputString and replaces every occurrence of fromString with toString
   var temp = inputString;
   if (fromString == "") {
      return inputString;
   }
   if (toString.indexOf(fromString) == -1) { // If the string being replaced is not a part of the replacement string (normal situation)
      while (temp.indexOf(fromString) != -1) {
         var toTheLeft = temp.substring(0, temp.indexOf(fromString));
         var toTheRight = temp.substring(temp.indexOf(fromString)+fromString.length, temp.length);
         temp = toTheLeft + toString + toTheRight;
      }
   } else { // String being replaced is part of replacement string (like "+" being replaced with "++") - prevent an infinite loop
      var midStrings = new Array("~", "`", "_", "^", "#");
      var midStringLen = 1;
      var midString = "";
      // Find a string that doesn't exist in the inputString to be used
      // as an "inbetween" string
      while (midString == "") {
         for (var i=0; i < midStrings.length; i++) {
            var tempMidString = "";
            for (var j=0; j < midStringLen; j++) { tempMidString += midStrings[i]; }
            if (fromString.indexOf(tempMidString) == -1) {
               midString = tempMidString;
               i = midStrings.length + 1;
            }
         }
      } // Keep on going until we build an "inbetween" string that doesn't exist
      // Now go through and do two replaces - first, replace the "fromString" with the "inbetween" string
      while (temp.indexOf(fromString) != -1) {
         var toTheLeft = temp.substring(0, temp.indexOf(fromString));
         var toTheRight = temp.substring(temp.indexOf(fromString)+fromString.length, temp.length);
         temp = toTheLeft + midString + toTheRight;
      }
      // Next, replace the "inbetween" string with the "toString"
      while (temp.indexOf(midString) != -1) {
         var toTheLeft = temp.substring(0, temp.indexOf(midString));
         var toTheRight = temp.substring(temp.indexOf(midString)+midString.length, temp.length);
         temp = toTheLeft + toString + toTheRight;
      }
   } // Ends the check to see if the string being replaced is part of the replacement string or not
   return temp; // Send the updated string back to the user
} // Ends the "replaceSubstring" function
