//
// Many of the below functions take an optional parameter eok (for "emptyOK")
// which determines whether the empty string will return true or false.
// Default behavior is controlled by global variable defaultEmptyOK.
//
// BASIC DATA VALIDATION FUNCTIONS:
//
// isWhitespace (s)                    Check whether string s is empty or whitespace.
// isLetter (c)                        Check whether character c is an English letter 
// isDigit (c)                         Check whether character c is a digit 
// isLetterOrDigit (c)                 Check whether character c is a letter or digit.
// isInteger (s [,eok])                True if all characters in string s are numbers.
// isNonnegativeInteger (s [,eok])     True if string s is an integer >= 0.
// isSignedInteger (s [,eok])          True if all characters in string s are numbers; leading + or - allowed.
// isAlphabetic (s [,eok])             True if string s is English letters 
// isAlphanumeric (s [,eok])           True if string s is English letters and numbers only.
// 
// isUSPhoneNumber (s [,eok])          True if string s is a valid U.S. Phone Number. 
// isInternationalPhoneNumber (s [,eok]) True if string s is a valid international phone number.
// isZIPCode (s [,eok])                True if string s is a valid U.S. ZIP code.
// isEmail (s [,eok])                  True if string s is a valid email address.
// isYear (s [,eok])                   True if string s is a valid Year number.
// isIntegerInRange (s, a, b [,eok])   True if string s is an integer between a and b, inclusive.
// isMonth (s [,eok])                  True if string s is a valid month between 1 and 12.
// isDay (s [,eok])                    True if string s is a valid day between 1 and 31.
// daysInFebruary (year)               Returns number of days in February of that year.
// isDate (year, month, day)           True if string arguments form a valid date.
// isFormattedDate (date)			   True if string is a formatted (00/00/00 or 00/00/0000) date
// isURL (s, [,eok])				   True if string s is a valid URL
// isEqual (s, s2)					   True is string s and s2 are identical
// isDateInOrder(s, s2)				   True if string s comes before s2


// FUNCTIONS TO REFORMAT DATA:
//
// stripCharsInBag (s, bag)            Removes all characters in string bag from string s.
// replaceCharsInBag (s, bag)          Replaces all characters in string bag with a space in string s.
// stripCharsNotInBag (s, bag)         Removes all characters NOT in string bag from string s.
// stripWhitespace (s)                 Removes all whitespace characters from s.
// stripInitialWhitespace (s)          Removes initial (leading) whitespace characters from s.
// reformat (TARGETSTRING, STRING,     Function for inserting formatting characters or
//   INTEGER, STRING, INTEGER ... )       delimiters into TARGETSTRING.                                       
// reformatZIPCode (ZIPString)         If 9 digits, inserts separator hyphen.
// reformatUSPhone (USPhone)           Reformats as (123) 456-789.
// reformatURL (URL)				   Reformats as http://URL
// reformatDate (DATE)				   Reformats as 00/00/0000
//




var digits = "0123456789";
var lowercaseLetters = "abcdefghijklmnopqrstuvwxyz"
var uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
var whitespace = " \t\n\r";
var decimalPointDelimiter = "."

var digitsInSocialSecurityNumber = 9;

var phoneNumberDelimiters = "()- ";
var validUSPhoneChars = digits + phoneNumberDelimiters;
var validWorldPhoneChars = digits + phoneNumberDelimiters + "+";
var digitsInUSPhoneNumber = 10;
var digitsInUSPhoneNumber2 = 7;

var ZIPCodeDelimiters = "-";
var digitsInZIPCode1 = 5
var digitsInZIPCode2 = 9

var defaultEmptyOK = false


var daysInMonth = new Array();
daysInMonth[1] = 31;
daysInMonth[2] = 29;   // must programmatically check this
daysInMonth[3] = 31;
daysInMonth[4] = 30;
daysInMonth[5] = 31;
daysInMonth[6] = 30;
daysInMonth[7] = 31;
daysInMonth[8] = 31;
daysInMonth[9] = 30;
daysInMonth[10] = 31;
daysInMonth[11] = 30;
daysInMonth[12] = 31;

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 stripCharsInBag (s, bag){
	var i;
	var returnString = "";
	for (i = 0; i < s.length; i++) {
		var c = s.charAt(i);
		if (bag.indexOf(c) == -1) returnString += c;
	}
	return returnString;
}

function replaceQuoteWithBlank (s){
	var i;
	var returnString = "";
	for (i = 0; i < s.length; i++) {
		var c = s.charAt(i);
		if (c == "'") returnString += " ";
		else returnString += c;
	}
	return returnString;
}

function stripCharsNotInBag (s, bag){
	var i;
	var returnString = "";
    for (i = 0; i < s.length; i++) {
		var c = s.charAt(i);
		if (bag.indexOf(c) != -1) returnString += c;
	}
	return returnString;
}

function stripWhitespace (s) {
	return stripCharsInBag (s, whitespace);
}

function stripInitialWhitespace (s) {
	var i = 0;

	while ((i < s.length) && (whitespace.indexOf(s.charAt(i)) != -1))
		i++;
	return s.substring (i, s.length);
}

function isLetter (c){
	return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) );
}

function isDigit (c){
	return ((c >= "0") && (c <= "9"));
}

function isLetterOrDigit (c) {
	return (isLetter(c) || isDigit(c));
}

function isInteger (s){
	var i;
	if (isEmpty(s))
		if (isInteger.arguments.length == 1) return defaultEmptyOK;
		else return (isInteger.arguments[1] == true);
	for (i = 0; i < s.length; i++){
		var c = s.charAt(i);
		if (!isDigit(c)) return false;
	}
	return true;
}

function isNonnegativeInteger (s){
	var secondArg = defaultEmptyOK;
	if (isNonnegativeInteger.arguments.length > 1) secondArg = isNonnegativeInteger.arguments[1];
	return (isSignedInteger(s, secondArg) && ( (isEmpty(s) && secondArg)  || (parseInt (s) >= 0) ) );
}

function isSignedInteger (s){
	if (isEmpty(s))
		if (isSignedInteger.arguments.length == 1) return defaultEmptyOK;
		else return (isSignedInteger.arguments[1] == true);
	else {
		var startPos = 0;
		var secondArg = defaultEmptyOK;
		if (isSignedInteger.arguments.length > 1) secondArg = isSignedInteger.arguments[1];
		if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") ) startPos = 1;
		return (isInteger(s.substring(startPos, s.length), secondArg))
	}
}

function isAlphabetic (s) {
	var i;
	if (isEmpty(s))
		if (isAlphabetic.arguments.length == 1) return defaultEmptyOK;
		else return (isAlphabetic.arguments[1] == true);
	for (i = 0; i < s.length; i++) {   
		var c = s.charAt(i);
		if (!isLetter(c)) return false;
	}
	return true;
}

function isAlphanumeric (s) {
	var i;
	if (isEmpty(s))
		if (isAlphanumeric.arguments.length == 1) return defaultEmptyOK;
		else return (isAlphanumeric.arguments[1] == true);
	for (i = 0; i < s.length; i++) {
		var c = s.charAt(i);
		if (! (isLetter(c) || isDigit(c) ) ) return false;
	}
	return true;
}

// EXAMPLE:
// reformat ("123 456 7890","(", 3, ") ", 3, "-", 4)
function reformat (s){
	var arg;
	var sPos = 0;
	var resultString = "";
	for (var i = 1; i < reformat.arguments.length; i++) {
		arg = reformat.arguments[i];
		if (i % 2 == 1) resultString += arg;
		else {
			resultString += s.substring(sPos, sPos + arg);
			sPos += arg;
		}
	}
	return resultString;
}

function isUSPhoneNumber (s){
	if (isEmpty(s))
		if (isUSPhoneNumber.arguments.length == 1) return defaultEmptyOK;
		else return (isUSPhoneNumber.arguments[1] == true);
	return (isInteger(s) && (s.length == digitsInUSPhoneNumber || s.length == digitsInUSPhoneNumber2));
}

function isInternationalPhoneNumber (s){
	if (isEmpty(s))
		if (isInternationalPhoneNumber.arguments.length == 1) return defaultEmptyOK;
		else return (isInternationalPhoneNumber.arguments[1] == true);
	return (isPositiveInteger(s));
}

function isZIPCode (s){
//	if (isEmpty(s))
//		if (isZIPCode.arguments.length == 1) return defaultEmptyOK;
//		else return (isZIPCode.arguments[1] == true);
	return (isInteger(s) && ((s.length == digitsInZIPCode1) || (s.length == digitsInZIPCode2)));
}

function isEmail (s) {
	if (isEmpty(s))
		if (isEmail.arguments.length == 1) return defaultEmptyOK;
		else return (isEmail.arguments[1] == true);
	if (isWhitespace(s)) return false;
	var i = 1;
	var sLength = s.length;
	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;
}

function isURL (s){
	if (isEmpty(s))
		if (isURL.arguments.length == 1) return defaultEmptyOK;
		else return (isURL.arguments[1] == true);
	if (isWhitespace(s)) return false;
	var i = 1;
	var sLength = s.length;
	while ((i < sLength) && (s.charAt(i) != ".")){ i++ }
	if ((i >= sLength - 1) || (s.charAt(i) != ".")) return false;
	else return true;
}

function isEqual (s, s2){
	if (isEmpty(s) && isEmpty(s2))
		return true;
	var i = 0;
	var sLength = s.length;
	var s2Length = s2.length;
	if (sLength != s2Length) return false;
	while (i < sLength) {
		if (s.charAt(i) != s2.charAt(i)) return false;
		i++
	}
	return true;
}

function isDateInOrder(s, s2){
	var year;
	var year2;
	if ((s.length == 0) || (s2.length == 0)) return true;
	if (!(isFormattedDate(s) && isFormattedDate(s2))) return false;
	if (s.length == 10) year = s.charAt(6) + s.charAt(7) + s.charAt(8) + s.charAt(9);
	else year = '20' + s.charAt(6) + s.charAt(7);
	if (s2.length == 10) year2 = s2.charAt(6) + s2.charAt(7) + s2.charAt(8) + s2.charAt(9);
	else year2 = '20' + s2.charAt(6) + s2.charAt(7);
	if (year2 < year) return false;
	else if (year2 == year){
		if ((s2.charAt(0) + s2.charAt(1)) < (s.charAt(0) + s.charAt(1))) return false;
		else if  ((s2.charAt(0) + s2.charAt(1)) == (s.charAt(0) + s.charAt(1)))	{
			if ((s2.charAt(3) + s2.charAt(4)) < (s.charAt(3) + s.charAt(4))) {
				return false;
			} else return true;
		} else return true;
	} else return true;
}


function isYear (s){
	if (isEmpty(s))
		if (isYear.arguments.length == 1) return defaultEmptyOK;
		else return (isYear.arguments[1] == true);
	if (!isNonnegativeInteger(s)) return false;
	return ((s.length == 2) || (s.length == 4));
}

function isIntegerInRange (s, a, b) {
	if (isEmpty(s))
		if (isIntegerInRange.arguments.length == 1) return defaultEmptyOK;
		else return (isIntegerInRange.arguments[1] == true);
	if (!isInteger(s, false)) return false;
	var num = parseInt (s);
	return ((num >= a) && (num <= b));
}

function isMonth (s) {
	if (isEmpty(s))
		if (isMonth.arguments.length == 1) return defaultEmptyOK;
		else return (isMonth.arguments[1] == true);
	return isIntegerInRange (s, 1, 12);
}

function isDay (s) {
	if (isEmpty(s))
		if (isDay.arguments.length == 1) return defaultEmptyOK;
		else return (isDay.arguments[1] == true);
	return isIntegerInRange (s, 1, 31);
}

function daysInFebruary (year) {
	return (  ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 );
}

function isDate (year, month, day){
	if (! (isYear(year, false) && isMonth(month, false) && isDay(day, false))) return false;
	var intYear = parseInt(year);
	var intMonth = parseInt(month);
	var intDay = parseInt(day);
	if (intDay > daysInMonth[intMonth]) return false;
	if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;
	return true;
}

function isFormattedDate(DATE){
	var day;
	var month;
	var year;
	var tmpstring;
	tmpstring = stripCharsInBag(DATE,"-/ ");
	if ((tmpstring.length != 6) && (tmpstring.length != 8)) return false;
	day = tmpstring.charAt(2) + tmpstring.charAt(3);
	month = tmpstring.charAt(0) + tmpstring.charAt(1);
	if (tmpstring.length == 8) year = tmpstring.charAt(4) + tmpstring.charAt(5) + tmpstring.charAt(6) + tmpstring.charAt(7);
	else year = tmpstring.charAt(4) + tmpstring.charAt(5);
	if (! (isYear(year, false) && isMonth(month, false) && isDay(day, false))) return false;
	var intYear = parseInt(year);
	var intMonth = parseInt(month);
	var intDay = parseInt(day);
	if (intDay > daysInMonth[intMonth]) return false;
	if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;
	return true;
}

function checkString (theField, s, emptyOK) {
	if (checkString.arguments.length == 2) emptyOK = defaultEmptyOK;
	if ((emptyOK == true) && (isEmpty(theField.value))) return true;
	if (isWhitespace(theField.value)) return warnEmpty (theField, s);
	else return true;
}

function reformatZIPCode (ZIPString){
	if (ZIPString.length == 5) return ZIPString;
	else return (reformat (ZIPString, "", 5, "-", 4));
}

function reformatUSPhone (USPhone){
	return (reformat (USPhone, "(", 3, ") ", 3, "-", 4));
}

function reformatURL(URL) {
	var i = 1;
	var URLLength = URL.length;
	if (URLLength < 1) return URL;
	while ((i < URLLength) && (URL.charAt(i) != "/")){ i++ }
	if ((i >= URLLength) || (URL.charAt(i) != "/")) {
		return (reformat (URL, "http://", URLLength + 1))
	} else {
		return URL;
	}
}

function reformatDate(DATE){
	var DateLength = DATE.length;
	if ((DATE.charAt(1) == "/") || (DATE.charAt(1) == "-")) {
		DATE = reformat (DATE, "0", DateLength);
		DateLength += 1;
	}
	if ((DATE.charAt(4) == "/") || (DATE.charAt(4) == "-")) {
		DATE = reformat (DATE, "", 3, "0", DateLength - 3);
	}
	DATE = stripCharsInBag(DATE,"-/");
	DATE = reformat (DATE, "", 2, "/", 2, "/", DATE.length - 4);
	return DATE;
}

function getRadioButtonValue (radio) {
	for (var i = 0; i < radio.length; i++) {
		if (radio[i].checked) { break }
	}
	return radio[i].value;
}