//	SCRIPT:			/include/validation.js
//	CREATE DATE:	12/4/2000
//	AUTHOR:			Joe Leger, Digital Change Technologies
//	PURPOSE:		The functions in this script file contain high-level data validation
//					for form fields.
//  DISCLAIMER:		This set of functions was not developed for a specific client; as such
//					clients may not claim ownership of this file or functions therein.  They
//					are free to modify and/or add functions for their own puposes.

function LTrim(str) {
	//  Removes leading blanks from a string.
	//  IN: str - the string we want to RTrim
	// We don't want to trip JUST spaces, but also tabs,
	// line feeds, etc.  Add anything else you want to
	// "trim" here in Whitespace
	var whitespace = new String(" \t\n\r");
	var s = new String(str);

	if (whitespace.indexOf(s.charAt(0)) != -1) {
		// We have a string with leading blank(s)...
		var j=0, i = s.length;
		// Iterate from the far left of string until we
		// don't have any more whitespace...
		while (j < i && whitespace.indexOf(s.charAt(j)) != -1)
			j++;
			// Get the substring from the first non-whitespace
			// character to the end of the string...
			s = s.substring(j, i);
		}
	return s;
}

function RTrim(str) {
	//  Removes trailing blanks from a string.
	//  IN: str - the string we want to RTrim
    // We don't want to trip JUST spaces, but also tabs,
    // line feeds, etc.  Add anything else you want to
    // "trim" here in Whitespace
	var whitespace = new String(" \t\n\r");
	var s = new String(str);

	if (whitespace.indexOf(s.charAt(s.length-1)) != -1) {
		// We have a string with trailing blank(s)...
		var i = s.length - 1;       // Get length of string

		// Iterate from the far right of string until we
		// don't have any more whitespace...
		while (i >= 0 && whitespace.indexOf(s.charAt(i)) != -1)
			i--;
			// Get the substring from the front of the string to
			// where the last non-whitespace character is...
			s = s.substring(0, i+1);
		}
	return s;
}


function Trim(str) {
	// Removes leading and trailing spaces from a string
	return RTrim(LTrim(str));
}

function ZeroPadLeft(str,totalstrlen) {
	//Adds leading zeros to start of string
	var newstr = str;
	var returnstr = "";
	for (var i = 1; i <= totalstrlen; i++) {
		newstr = "0" + newstr;
	}
	//now take the Right of the string for totalstrlength chars.
	var j = newstr.length - 1;
	for (var k = 1; k <= totalstrlen; k++) {
		returnstr = newstr.charAt(j) + returnstr;
		j -= 1;
	}
	
	return returnstr;
}

function ZeroPadRight(str,totalstrlen) {
	//Adds leading zeros to end of string
	var newstr = str;
	var returnstr = "";
	for (var i = 1; i <= totalstrlen; i++) {
		newstr = newstr + "0";
	}
	//now take the Left of the string for totalstrlength chars.
	for (var j = 0; j < totalstrlen; j++) {
		returnstr = returnstr + newstr.charAt(j);
	}
	
	return returnstr;
}

function inRange(object_value, min_value, max_value) {
    // check minimum
    if (min_value != null) {
        if (object_value < min_value)
			return false;
    }
    // check maximum
    if (max_value != null) {
        if (object_value > max_value)
			return false;
	}
    //All tests passed, so...
    return true;
}

function isValidDate(theMonth, theDay, theYear) {	
	//this function must be called AFTER validating that fields contain
	//numbers.
	//This function takes the input vars, converts to a date, then
	//compares back with the submitted values.
	
	//the month is - 1 from the form value, b/c in JS months are zero-based.
	tmpMonth = theMonth - 1;
	
	theDate = new Date(theYear, tmpMonth, theDay);
	
	//add 1 back to month, b/c in JS months are zero-based.
	returnvalue = true;
	if ((theDate.getMonth() + 1) != theMonth)
		returnvalue = false;
	if (theDate.getDate() != theDay)
		returnvalue = false;
	if (theDate.getFullYear() != theYear)
		returnvalue = false;

	return returnvalue;
}

function isValidDateFULL(object_value)
    {
    //Returns true if value is a date in the mm/dd/yyyy format
	isplit = object_value.indexOf('/');

	if (isplit == -1 || isplit == object_value.length)
		return false;

	theMonth = object_value.substring(0, isplit);
	isplit = object_value.indexOf('/', isplit + 1);

	if (isplit == -1 || (isplit + 1 ) == object_value.length)
		return false;

	theDay = object_value.substring((theMonth.length + 1), isplit);
	theYear = object_value.substring(isplit + 1);

	if (!isValidDate(theMonth, theDay, theYear)) // check date
		return false
	else
		return true;
    }

function isValidEmail(object_value)
    {
	/* The following variable tells the rest of the function whether or not
	to verify that the address ends in a two-letter country or well-known
	TLD.  1 means check it, 0 means don't. */
	
	var checkTLD=1;
	
	/* The following is the list of known TLDs that an e-mail address must end with. */
	
	var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;
	
	/* The following pattern is used to check if the entered e-mail address
	fits the user@domain format.  It also is used to separate the username
	from the domain. */
	
	var emailPat=/^(.+)@(.+)$/;
	
	/* The following string represents the pattern for matching all special
	characters.  We don't want to allow special characters in the address. 
	These characters include ( ) < > @ , ; : \ " . [ ] */
	
	var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
	
	/* The following string represents the range of characters allowed in a 
	username or domainname.  It really states which chars aren't allowed.*/
	
	var validChars="\[^\\s" + specialChars + "\]";
	
	/* The following pattern applies if the "user" is a quoted string (in
	which case, there are no rules about which characters are allowed
	and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
	is a legal e-mail address. */
	
	var quotedUser="(\"[^\"]*\")";
	
	/* The following pattern applies for domains that are IP addresses,
	rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
	e-mail address. NOTE: The square brackets are required. */
	
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	
	/* The following string represents an atom (basically a series of non-special characters.) */
	
	var atom=validChars + '+';
	
	/* The following string represents one word in the typical username.
	For example, in john.doe@somewhere.com, john and doe are words.
	Basically, a word is either an atom or quoted string. */
	
	var word="(" + atom + "|" + quotedUser + ")";
	
	// The following pattern describes the structure of the user
	
	var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
	
	/* The following pattern describes the structure of a normal symbolic
	domain, as opposed to ipDomainPat, shown above. */
	
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
	
	/* Finally, let's start trying to figure out if the supplied address is valid. */
	
	/* Begin with the coarse pattern to simply break up user@domain into
	different pieces that are easy to analyze. */
	
	var matchArray=object_value.match(emailPat);
	
	if (matchArray==null) {
	
	/* Too many/few @'s or something; basically, this address doesn't
	even fit the general mould of a valid e-mail address. */
	
	alert("Email address seems incorrect (check @ and .'s)");
	return false;
	}
	var user=matchArray[1];
	var domain=matchArray[2];
	
	// Start by checking that only basic ASCII characters are in the strings (0-127).
	
	for (i=0; i<user.length; i++) {
	if (user.charCodeAt(i)>127) {
	alert("The email username contains invalid characters.");
	return false;
	   }
	}
	for (i=0; i<domain.length; i++) {
	if (domain.charCodeAt(i)>127) {
	alert("The email domain name contains invalid characters.");
	return false;
	   }
	}
	
	// See if "user" is valid 
	
	if (user.match(userPat)==null) {
	
	// user is not valid
	
	alert("The email username doesn't seem to be valid.");
	return false;
	}
	
	/* if the e-mail address is at an IP address (as opposed to a symbolic
	host name) make sure the IP address is valid. */
	
	var IPArray=domain.match(ipDomainPat);
	if (IPArray!=null) {
	
	// this is an IP address
	
	for (var i=1;i<=4;i++) {
	if (IPArray[i]>255) {
	alert("The email destination IP address is invalid!");
	return false;
	   }
	}
	return true;
	}
	
	// Domain is symbolic name.  Check if it's valid.
	 
	var atomPat=new RegExp("^" + atom + "$");
	var domArr=domain.split(".");
	var len=domArr.length;
	for (i=0;i<len;i++) {
		var domTest = domArr[i].toLowerCase();
	if (domTest.search(atomPat)==-1) {
		alert("The email domain name does not seem to be valid.");
		return false;
	   }
	}
	
	/* domain name seems valid, but now make sure that it ends in a
	known top-level domain (like com, edu, gov) or a two-letter word,
	representing country (uk, nl), and that there's a hostname preceding 
	the domain or country. */
	//SINCE WE'VE ALREADY LOOPED OVER THE EMAIL EXTENSTION, the last split (and subsequently
	// lowercased) should be the TLD 
	if (checkTLD && domArr[domArr.length-1].length!=2 
		&& domTest.search(knownDomsPat)==-1) {
	alert("The email address must end in a well-known domain or two letter " + "country.");
	return false;
	}
	
	// Make sure there's a host name preceding the domain.
	
	if (len<2) {
	alert("The email address is missing a hostname!");
	return false;
	}
	
	// If we've gotten here, then it's ok.
	return true;
}

function isValidPhone(object_value) {
    //Returns true if value is a phone number is all numbers and dashes
    //otherwise returns false   

    if (object_value.length == 0)
        return true;

    //Returns true if value is a phone defined as
    //   having a leading number and only containing
    //   numbers and dashes after that point.
        var start_format = "0123456789";
        var phone_format = "-0123456789";
        var check_char;
        var firstnum = false;

    	//The first character can be digit.
        check_char = start_format.indexOf(object_value.charAt(0))
	    //Was it a number?
        if (check_char < 0)
			return false;      

        //Remaining characters can be only . or a digit, but only one decimal.
		for (var i = 1; i < object_value.length; i++) {
			check_char = phone_format.indexOf(object_value.charAt(i))
			if (check_char < 0) {
				return false;
			}
		}       
    //All tests passed, so...
    return true
}

function isValidZip(object_value) {
    //Returns true if value is either 5-digit or zip+4 format (xxxxx-xxxx)
    //otherwise returns false   

    if (object_value.length == 0)
        return true;

	//if it's not 5 digits or 10 (including dash) then not valid
	if ((object_value.length != 5) && (object_value.length != 10))
		return false;
	
	var number_format = "0123456789";
	var checkchar;
	
	if (object_value.length == 5) {
		for (var i = 0; i < 5; i++) {
			check_char = number_format.indexOf(object_value.charAt(i));
			if (check_char < 0)
				return false;
		}
	}
	else {
		//greater than five digits.  make sure sixth char is a dash
		if (object_value.charAt(5) != "-") {
			return false;
		}
		//test the +4 designation.
		for (var i = 6; i < object_value.length; i++) {
			check_char = number_format.indexOf(object_value.charAt(i));
			if (check_char < 0)
				return false;
		}
	}
	
	//All tests passed, so...
	return true
}

function isNumber(obj) {
    //Returns true if value is a number or is NULL
    //otherwise returns false   

    if (obj.value.length == 0)
        return true;

    //Returns true if value is a number defined as
    //   having an optional leading + or -.
    //   having at most 1 decimal point.
    //   otherwise containing only the characters 0-9.
        var start_format = " .+-0123456789";
        var number_format = " .0123456789";
        var check_char;
        var decimal = false;
        var trailing_blank = false;
        var digits = false;

    //The first character can be + - .  blank or a digit.
        check_char = start_format.indexOf(obj.value.charAt(0))
    //Was it a decimal?
        if (check_char == 1)
            decimal = true;
        else if (check_char < 1)
                return false;      
        //Remaining characters can be only . or a digit, but only one decimal.
		for (var i = 1; i < obj.value.length; i++) {
			check_char = number_format.indexOf(obj.value.charAt(i))
			if (check_char < 0)
				return false;
			else if (check_char == 1) {
				if (decimal)            // Second decimal.
					return false;
				else
					decimal = true;
				}
			else if (check_char == 0){
				if (decimal || digits)  
					trailing_blank = true;
					// ignore leading blanks
				}
				else if (trailing_blank)
					return false;
				else
					digits = true;
			}       
    //All tests passed, so...
    return true
}

function isInteger(obj) {
    //Returns true if value is an integer or is NULL
    //otherwise returns false   

    if (obj.value.length == 0)
        return true;

    //Returns true if value is a number defined as
    //   having an optional leading + or -.
    //   having at most 1 decimal point.
    //   otherwise containing only the characters 0-9.
        var start_number = "+-0123456789";
		var valid_number = "0123456789";
        var check_char;
        var decimal = false;
        var trailing_blank = false;
        var digits = false;

    //The first character can be +, -, or a digit.
        check_char = start_number.indexOf(obj.value.charAt(0))
        if (check_char < 1)
                return false;      
        //Remaining characters can be only digits.
        for (var i = 1; i < obj.value.length; i++) {
			check_char = valid_number.indexOf(obj.value.charAt(i))
			if (check_char < 0)
				return false;
        }       
    //All tests passed, so...
    return true
}

function hasValue(obj, obj_type) {
   if (obj_type == "TEXT" || obj_type == "PASSWORD") {
       if (obj.value.length == 0) 
               return false;
       else if (Trim(obj.value) == "") 
               return false;
	   else
	   	  return true;
       }
   else if (obj_type == "SELECT") {
       for (i=0; i < obj.length; i++) {
               if (obj.options[i].selected)
                       return true;
               }
       return false;   
       }
   else if (obj_type == "SELECT_NODEFAULT") {
       //this one used if we have the first option like 'Pick One'
	   if (obj.options[0].selected) 
	   		return false;
	   else
	   		return true;
       }
   else if (obj_type == "SINGLE_VALUE_RADIO" || obj_type == "SINGLE_VALUE_CHECKBOX") {
		if (obj.checked)
			return true;
		else
			return false;   
       }
   else if (obj_type == "RADIO" || obj_type == "CHECKBOX") {
       for (i=0; i < obj.length; i++) {
		if (obj[i].checked)
			return true;
	}
    	return false;   
   }
}
