//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// VARIABLE DECLARATIONS
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
var digits = "0123456789";
var lowercaseLetters = "abcdefghijklmnopqrstuvwxyz";
var uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var whitespace = " \t\n\r";						// whitespace characters
var decimalPointDelimiter = ".";				// decimal point character differs by language and culture
var phoneNumberDelimiters = "( )-";				// non-digit characters which are allowed in phone numbers
var validUSPhoneChars = digits + phoneNumberDelimiters;
												// characters which are allowed in US phone numbers
var validWorldPhoneChars = digits + phoneNumberDelimiters + "+";
												// characters which are allowed in international phone numbers ( a leading + is OK )
var SSNDelimiters = "- ";						// non-digit characters which are allowed in  Social Security Numbers
var validSSNChars = digits + SSNDelimiters;
												// characters which are allowed in Social Security Numbers
var digitsInSocialSecurityNumber = 9;			// U.S. Social Security Numbers have 9 digits. They are formatted as 123-45-6789.
var digitsInUSPhoneNumber = 10;					// U.S. phone numbers have 10 digits. They are formatted as 123 456 7890 or ( 123 ) 456-7890.
var ZIPCodeDelimiters = "-";					// non-digit characters which are allowed in ZIP Codes
var ZIPCodeDelimeter = "-";						// our preferred delimiter for reformatting ZIP Codes
var validZIPCodeChars = digits + ZIPCodeDelimiters;
												// characters which are allowed in Social Security Numbers
var digitsInZIPCode1 = 5;						// U.S. ZIP codes have 5 or 9 digits.
var digitsInZIPCode2 = 9;						// They are formatted as 12345 or 12345-6789.

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// CONSTANT STRING DECLARATIONS
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// m is an abbreviation for "missing";
var mPrefix = "You did not enter a value into the ";
var mSuffix = " field. This is a required field. Please enter it now.";

// s is an abbreviation for "string"
var sUSLastName = "Last Name";
var sUSFirstName = "First Name";
var sWorldLastName = "Family Name";
var sWorldFirstName = "Given Name";
var sTitle = "Title";
var sCompanyName = "Company Name";
var sUSAddress = "Street Address";
var sWorldAddress = "Address";
var sCity = "City";
var sStateCode = "State Code";
var sWorldState = "State, Province, or Prefecture";
var sCountry = "Country";
var sZIPCode = "ZIP Code";
var sWorldPostalCode = "Postal Code";
var sPhone = "Phone Number";
var sFax = "Fax Number";
var sDateOfBirth = "Date of Birth";
var sExpirationDate = "Expiration Date";
var sEmail = "Email";
var sSSN = "Social Security Number";
var sOtherInfo = "Other Information";

// i is an abbreviation for "invalid"
var iStateCode = "This field must be a valid two character U.S. state abbreviation ( like CA for California ). Please reenter it now.";
var iZIPCode = "This field must be a 5 or 9 digit U.S. ZIP Code ( like 94043 ). Please reenter it now.";
var iUSPhone = "This field must be a 10 digit U.S. phone number ( like 415 555 1212 ). Please reenter it now.";
var iWorldPhone = "This field must be a valid international phone number. Please reenter it now.";
var iSSN = "This field must be a 9 digit U.S. social security number ( like 123 45 6789 ). Please reenter it now.";
var iEmail = "This field must be a valid email address ( like foo@bar.com ). Please reenter it now.";
var iDay = "This field must be a day number between 1 and 31.  Please reenter it now.";
var iMonth = "This field must be a month number between 1 and 12.  Please reenter it now.";
var iYear = "This field must be a 4 digit year number.  Please reenter it now.";
var iDatePrefix = "The Day, Month, and Year for ";
var iDateSuffix = " do not form a valid date.  Please reenter them now.";
var iNumber = "This field must be number.  Please reenter it now.";
var iMMDDYYYY = "Invalid date. (MM/DD/YYYY)";
var iGeneral = "The field content is invalid or empty.";

// p is an abbreviation for "prompt"
var pEntryPrompt = "Please enter ";
var pStateCode = "2 character code ( like CA ).";
var pZIPCode = "5 or 9 digit U.S. ZIP Code ( like 94043 ).";
var pUSPhone = "10 digit U.S. phone number ( like 415 555 1212 ).";
var pWorldPhone = "international phone number.";
var pSSN = "9 digit U.S. social security number ( like 123 45 6789 ).";
var pEmail = "valid email address ( like foo@bar.com ).";
var pDay = "day number between 1 and 31.";
var pMonth = "month number between 1 and 12.";
var pYear = "2 or 4 digit year number.";
var defaultEmptyOK = false;
var daysInMonth = new Array( 12 );
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;
var USStateCodeDelimiter = "|";
var USStateCodes = "AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY|AE|AA|AE|AE|AP";

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Check whether string s is empty.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isEmpty( s )
{   
	return ( ( s == null ) || ( s.length == 0 ) )
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Returns true if string s is empty or whitespace characters only.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isWhitespace ( s )
{   
	var i;

	// Is s empty?
	if ( isEmpty( s ) ) 
		return true;

	// Search through string's characters one by one
	// until we find a non-whitespace character.
	// When we do, return false; if we don't, return true.

	for ( i = 0; i < s.length; i++ )
	{   
		// Check that current character isn't whitespace.
		var c = s.charAt( i );
		if ( whitespace.indexOf( c ) == -1 ) 
			return false;
	}

	// All characters are whitespace.
	return true;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Removes all characters which appear in string bag from string s.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function stripCharsInBag ( s, bag )
{   
	var i;
	var returnString = "";

	// Search through string's characters one by one.
	// If character is not in bag, append to returnString.
	for ( i = 0; i < s.length; i++ )
	{   
		var c = s.charAt( i );
		if ( bag.indexOf( c ) == -1 ) 
			returnString += c;
	}
	return returnString;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Removes all characters which do NOT appear in string bag from string s.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function stripCharsNotInBag ( s, bag )
{
	var i;
	var returnString = "";

	// Search through string's characters one by one.
	// If character is in bag, append to returnString.
	for ( i = 0; i < s.length; i++ )
	{   
		// Check that current character isn't whitespace.
		var c = s.charAt( i );
		if ( bag.indexOf( c ) != -1 ) 
			returnString += c;
	}
	return returnString;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Removes all whitespace characters from s.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function stripWhitespace ( s )
{
	return stripCharsInBag ( s, whitespace )
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Removes initial ( leading ) whitespace characters from s.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function stripInitialWhitespace ( s )
{
	var i = 0;

	while ( ( i < s.length ) && ( whitespace.indexOf( s.charAt( i ) ) > -1 ) )
		i++;
	
	return s.substring ( i, s.length );
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Returns true if character c is an English letter ( A .. Z, a..z ).
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isLetter ( c )
{
	if ( lowercaseLetters.indexOf( c ) > -1 )
		return true;
	else if ( uppercaseLetters.indexOf( c ) > -1 )
		return true;
	else
		return false;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Returns true if character c is a digit ( 0 .. 9 ).
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isDigit ( c )
{
	if ( digits.indexOf( c ) > -1 )
		return true;
	else
		return false;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Returns true if character c is a letter or digit.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isLetterOrDigit ( c )
{
	return ( isLetter( c ) || isDigit( c ) )
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Returns true if all characters in string s are numbers.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isInteger ( s )
{
	var i;

	if ( isEmpty( s ) ) 
	{
		if ( isInteger.arguments.length == 1 )
			return defaultEmptyOK;
		else
			return ( isInteger.arguments[1] == true );
	}

	// Search through string's characters one by one
	// until we find a non-numeric character.
	// When we do, return false; if we don't, return true.
	for ( i = 0; i < s.length; i++ )
	{   
		// Check that current character is number.
		var c = s.charAt( i );

		if ( !isDigit( c ) )
			return false;
	}

	// All characters are numbers.
	return true;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isSignedInteger ( STRING s [, BOOLEAN emptyOK] )
// Returns true if all characters are numbers; 
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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];

		// skip leading + or -
		if (  ( s.charAt( 0 ) == "-" ) || ( s.charAt( 0 ) == "+" )  )
			 startPos = 1;	
		return ( isInteger( s.substring( startPos, s.length ), secondArg ) )
	}
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isPositiveInteger ( STRING s [, BOOLEAN emptyOK] )
// Returns true if string s is an integer > 0.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isPositiveInteger ( s )
{
	var secondArg = defaultEmptyOK;

	if ( isPositiveInteger.arguments.length > 1 )
		secondArg = isPositiveInteger.arguments[1];

	return ( isSignedInteger( s, secondArg ) && (  ( isEmpty( s ) && secondArg )  || ( parseInt ( s, 10 ) > 0 )  )  );
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isNonnegativeInteger ( STRING s [, BOOLEAN emptyOK] )
// Returns true if string s is an integer >= 0.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isNonnegativeInteger ( s )
{
	var secondArg = defaultEmptyOK;

	if ( isNonnegativeInteger.arguments.length > 1 )
		secondArg = isNonnegativeInteger.arguments[1];

	return ( isSignedInteger( s, secondArg ) && (  ( isEmpty( s ) && secondArg )  || ( parseInt ( s, 10 ) >= 0 )  )  );
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isNegativeInteger ( STRING s [, BOOLEAN emptyOK] )
// Returns true if string s is an integer < 0.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isNegativeInteger ( s )
{
	var secondArg = defaultEmptyOK;

	if ( isNegativeInteger.arguments.length > 1 )
		secondArg = isNegativeInteger.arguments[1];

	return ( isSignedInteger( s, secondArg ) && (  ( isEmpty( s ) && secondArg )  || ( parseInt ( s, 10 ) < 0 )  )  );
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isNonpositiveInteger ( STRING s [, BOOLEAN emptyOK] )
// Returns true if string s is an integer <= 0.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isNonpositiveInteger ( s )
{
	var secondArg = defaultEmptyOK;

	if ( isNonpositiveInteger.arguments.length > 1 )
		secondArg = isNonpositiveInteger.arguments[1];

	return ( isSignedInteger( s, secondArg ) && (  ( isEmpty( s ) && secondArg )  || ( parseInt ( s, 10 ) <= 0 )  )  );
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isFloat ( STRING s [, BOOLEAN emptyOK] )
// True if string s is an unsigned floating point ( real ) number. 
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isFloat ( s )
{
	var i;
	var seenDecimalPoint = false;

	if ( isEmpty( s ) ) 
	{
		if ( isFloat.arguments.length == 1 )
			return defaultEmptyOK;
		else
			return ( isFloat.arguments[1] == true );
	}

	if ( s == decimalPointDelimiter )
		return false;

	for ( i = 0; i < s.length; i++ )
	{   
		// Check that current character is number.
		var c = s.charAt( i );

		if ( ( c == decimalPointDelimiter ) && !seenDecimalPoint )
			seenDecimalPoint = true;
		else if ( !isDigit( c ) )
			return false;
	}

	// All characters are numbers.
	return true;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isSignedFloat ( STRING s [, BOOLEAN emptyOK] )
// True if string s is a signed or unsigned floating point ( real ) number. First character is allowed to be + or -.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isSignedFloat ( s )
{
	if ( isEmpty( s ) ) 
	{
		if ( isSignedFloat.arguments.length == 1 )
			return defaultEmptyOK;
		else
			return ( isSignedFloat.arguments[1] == true );
	}
	else
	{
		var startPos = 0;
		var secondArg = defaultEmptyOK;

		if ( isSignedFloat.arguments.length > 1 )
			secondArg = isSignedFloat.arguments[1];

		// skip leading + or -
		if (  ( s.charAt( 0 ) == "-" ) || ( s.charAt( 0 ) == "+" )  )
			 startPos = 1;	
		return ( isFloat( s.substring( startPos, s.length ), secondArg ) )
	}
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isAlphabetic ( STRING s [, BOOLEAN emptyOK] )
// Returns true if string s is English letters ( A .. Z, a..z ) only.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isAlphabetic ( s )
{
	var i;

	if ( isEmpty( s ) )
	{
		if ( isAlphabetic.arguments.length == 1 )
			return defaultEmptyOK;
		else
			return ( isAlphabetic.arguments[1] == true );
	}

	// Search through string's characters one by one
	// until we find a non-alphabetic character.
	// When we do, return false; if we don't, return true.
	for ( i = 0; i < s.length; i++ )
	{   
		// Check that current character is letter.
		var c = s.charAt( i );

		if ( !isLetter( c ) )
			return false;
	}

	// All characters are letters.
	return true;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isAlphanumeric ( STRING s [, BOOLEAN emptyOK] )
// Returns true if string s is English letters ( A .. Z, a..z ) and numbers only.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isAlphanumeric ( s )
{
	var i;

	if ( isEmpty( s ) ) 
	{
		if ( isAlphanumeric.arguments.length == 1 ) 
			return defaultEmptyOK;
		else 
			return ( isAlphanumeric.arguments[1] == true );
	}

	// Search through string's characters one by one
	// until we find a non-alphanumeric character.
	// When we do, return false; if we don't, return true.
	for ( i = 0; i < s.length; i++ )
	{   
		// Check that current character is number or letter.
		var c = s.charAt( i );

		if ( ! ( isLetter( c ) || isDigit( c )  )  )
			return false;
	}

	// All characters are numbers or letters.
	return true;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// reformat ( TARGETSTRING, STRING, INTEGER, STRING, INTEGER ...  )			
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isSSN ( STRING s [, BOOLEAN emptyOK] )
// isSSN returns true if string s is a valid U.S. Social Security Number.  Must be 9 digits.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isSSN ( s )
{
	if ( isEmpty( s ) ) 
	{
		if ( isSSN.arguments.length == 1 )
			return defaultEmptyOK;
		else
			return ( isSSN.arguments[1] == true );
	}
	return ( isInteger( s ) && s.length == digitsInSocialSecurityNumber )
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isUSPhoneNumber ( STRING s [, BOOLEAN emptyOK] )
// isUSPhoneNumber returns true if string s is a valid U.S. Phone Number.  Must be 10 digits.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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 )
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isInternationalPhoneNumber ( STRING s [, BOOLEAN emptyOK] )
// isInternationalPhoneNumber returns true if string s is a valid  international phone number.  Must be digits only; any length OK.
// May be prefixed by + character.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isInternationalPhoneNumber ( s )
{
	if ( isEmpty( s ) ) 
	{
		if ( isInternationalPhoneNumber.arguments.length == 1 ) 
			return defaultEmptyOK;
		else 
			return ( isInternationalPhoneNumber.arguments[1] == true );
	}
	return ( isPositiveInteger( s ) )
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isZIPCode ( STRING s [, BOOLEAN emptyOK] )
// isZIPCode returns true if string s is a valid U.S. ZIP code.  Must be 5 or 9 digits only.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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 ) ) )
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isStateCode ( STRING s [, BOOLEAN emptyOK] )
// Return true if s is a valid U.S. Postal Code ( abbreviation for state ).
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isStateCode( s )
{   
	if ( isEmpty( s ) ) 
	{
		if ( isStateCode.arguments.length == 1 ) 
			return defaultEmptyOK;
		else 
			return ( isStateCode.arguments[1] == true );
	}
	return (  ( USStateCodes.indexOf( s ) != -1 ) && ( s.indexOf( USStateCodeDelimiter ) == -1 )  )
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isEmail ( STRING s [, BOOLEAN emptyOK] )
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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;

	// look for @
	while ( ( i < sLength ) && ( s.charAt( i ) != "@" ) )
	{ 
		i++;
	}
	if ( ( i >= sLength ) || ( s.charAt( i ) != "@" ) ) 
		return false;
	else 
		i += 2;

	// look for .
	while ( ( i < sLength ) && ( s.charAt( i ) != "." ) )
	{ 
		i++;
	}

	// there must be at least one character after the .
	if ( ( i >= sLength - 1 ) || ( s.charAt( i ) != "." ) ) 
		return false;
	else 
		return true;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isYear ( STRING s [, BOOLEAN emptyOK] )
// isYear returns true if string s is a valid Year number.  Must be 2 or 4 digits only.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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 == 4 ) );
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isIntegerInRange ( STRING s, INTEGER a, INTEGER b [, BOOLEAN emptyOK] )
// isIntegerInRange returns true if string s is an integer within the range of integer arguments a and b, inclusive.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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, 10 );
	return ( ( num >= a ) && ( num <= b ) );
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isMonth ( STRING s [, BOOLEAN emptyOK] )
// isMonth returns true if string s is a valid month number between 1 and 12.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isMonth ( s )
{   
	if ( isEmpty( s ) ) 
	{
		if ( isMonth.arguments.length == 1 ) 
			return defaultEmptyOK;
		else 
			return ( isMonth.arguments[1] == true );
	}
	return isIntegerInRange ( s, 1, 12 );
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isDay ( STRING s [, BOOLEAN emptyOK] )
// isDay returns true if string s is a valid day number between 1 and 31.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isDay ( s )
{   
	if ( isEmpty( s ) ) 
	{
		if ( isDay.arguments.length == 1 ) 
			return defaultEmptyOK;
		else 
			return ( isDay.arguments[1] == true );   
	}
	return isIntegerInRange ( s, 1, 31 );
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// daysInFebruary ( INTEGER year )
// Given integer argument year, returns number of days in February of that year.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function daysInFebruary ( year )
{
	// February has 29 days in any year evenly divisible by four,
	// EXCEPT for centurial years which are not also divisible by 400.
	return (   ( ( year % 4 == 0 ) && (  ( !( year % 100 == 0 ) ) || ( year % 400 == 0 )  )  ) ? 29 : 28  );
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// isDate ( STRING year, STRING month, STRING day )
// isDate returns true if string arguments year, month, and day form a valid date.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function isDate ( year, month, day )
{   
	// catch invalid years ( not 2- or 4-digit ) and invalid months and days.
	if ( ! ( isYear( year, false ) && isMonth( month, false ) && isDay( day, false ) ) ) 
		return false;

	var intYear = parseInt( year, 10 );
	var intMonth = parseInt( month, 10 );
	var intDay = parseInt( day, 10 );

	if ( intDay > daysInMonth[intMonth] ) 
		return false; 

	if ( ( intMonth == 2 ) && ( intDay > daysInFebruary( intYear ) ) ) 
		return false;
	return true;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Display prompt string s in status bar.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function prompt ( s )
{   
	window.status = s;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Display data entry prompt string s in status bar.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function promptEntry ( s )
{   
	window.status = pEntryPrompt + s;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Notify user that required field theField is empty.
// String s describes expected contents of theField.value.
// Put focus in theField and return false.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function warnEmpty ( theField, s )
{   
	alert( s );
	theField.focus(  );
	return false;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Notify user that contents of field theField are invalid.
// String s describes expected contents of theField.value.
// Put select theField, put focus in it, and return false.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function warnInvalid ( theField, s )
{   
	alert( s );
	theField.focus(  );
	theField.select(  );
	return false;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// checkString ( TEXTFIELD theField, STRING s, [, BOOLEAN emptyOK==false] )
// Check that string theField.value is not all whitespace.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// checkCurrency ( TEXTFIELD theField, STRING s, )
// Check that string theField.value is a valid currency value
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkCurrency( theField, s, emptyOK)
{
	if ((emptyOK == true ) && ( isEmpty( theField.value ) ) )
		return true;
	if (! isCurrency(theField.value))
		return warnInvalid ( theField, s );
	return true;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// checkNumber ( TEXTFIELD theField, STRING s, [, BOOLEAN emptyOK==false, Int minValue, Int maxValue] )
// Check that string theField.value is a valid number.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkNumber( theField, s, emptyOK, minValue, maxValue )
{
	if ( checkNumber.arguments.length == 2 ) 
		emptyOK = defaultEmptyOK;
	if ( ( emptyOK == true ) && ( isEmpty( theField.value ) ) ) 
		return true;
	theField.value = stripWhitespace ( theField.value );
	if ( isInteger( theField.value ) )
	{
		if ( minValue != null && parseInt( theField.value, 10 ) < minValue )
		{
			if ( maxValue != null )
				return warnInvalid ( theField, s+ " Range=[" + minValue + "..." + maxValue + "]" );
			else
				return warnInvalid ( theField, s+ " Value >= " + minValue );
		}
		if ( maxValue != null && (parseInt( theField.value, 10 ) > maxValue) )
		{
			if ( minValue != null )
				return warnInvalid ( theField, s+ " Range=[" + minValue + "..." + maxValue + "]" );
			else
				return warnInvalid ( theField, s+ " Value <= " + maxValue );
		}
		return true;
	}
	else 
		return warnInvalid ( theField, s );
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// checkStateCode ( TEXTFIELD theField [, BOOLEAN emptyOK==false] )
// Check that string theField.value is a valid U.S. state code.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkStateCode ( theField, emptyOK )
{   
	if ( checkStateCode.arguments.length == 1 ) 
		emptyOK = defaultEmptyOK;
	if ( ( emptyOK == true ) && ( isEmpty( theField.value ) ) ) 
		return true;
	else
	{  
		theField.value = theField.value.toUpperCase(  );
		if ( !isStateCode( theField.value, false ) ) 
			return warnInvalid ( theField, iStateCode );
		else 
			return true;
	}
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// checkZIPCode ( TEXTFIELD theField [, BOOLEAN emptyOK==false] )
// Check that string theField.value is a valid ZIP code.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkZIPCode ( theField, emptyOK )
{   
	if ( checkZIPCode.arguments.length == 1 ) 
		emptyOK = defaultEmptyOK;
	if ( ( emptyOK == true ) && ( isEmpty( theField.value ) ) ) 
		return true;
	else
	{ 
		var normalizedZIP = stripCharsInBag( theField.value, ZIPCodeDelimiters )
		if ( !isZIPCode( normalizedZIP, false ) ) 
			return warnInvalid ( theField, iZIPCode );
		else 
			return true;
	}
}



//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// checkUSPhone ( TEXTFIELD theField [, BOOLEAN emptyOK==false] )
// Check that string theField.value is a valid US Phone.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkUSPhone ( theField, emptyOK )
{   
	if ( checkUSPhone.arguments.length == 1 ) 
		emptyOK = defaultEmptyOK;
	if ( ( emptyOK == true ) && ( isEmpty( theField.value ) ) ) 
		return true;
	else
	{
		var normalizedPhone = stripCharsInBag( theField.value, phoneNumberDelimiters )
		if ( !isUSPhoneNumber( normalizedPhone, false ) ) 
			return warnInvalid ( theField, iUSPhone );
		else 
			return true;
	}
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// checkPhone
// Check that string value is a valid Phone number
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkPhone ( theField )
{
	if ( !isInteger( getNumericPhone( theField ) ) ) 
		return false
	else 
		return true
}

function getNumericPhone( theField )
{
	return stripCharsInBag( theField.value, phoneNumberDelimiters )
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// checkInternationalPhone ( TEXTFIELD theField [, BOOLEAN emptyOK==false] )
// Check that string theField.value is a valid International Phone.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkInternationalPhone ( theField, emptyOK )
{   
	if ( checkInternationalPhone.arguments.length == 1 ) 
		emptyOK = defaultEmptyOK;
	if ( ( emptyOK == true ) && ( isEmpty( theField.value ) ) ) 
		return true;
	else
	{  
		if ( !isInternationalPhoneNumber( theField.value, false ) ) 
			return warnInvalid ( theField, iWorldPhone );
		else 
			return true;
	}
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// checkEmail ( TEXTFIELD theField, STRING s, [, BOOLEAN emptyOK==false] )
// Check that string theField.value is a valid Email.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkEmail ( theField, s, emptyOK )
{   
	if ( checkEmail.arguments.length == 2 ) 
		emptyOK = defaultEmptyOK;
	if ( ( emptyOK == true ) && ( isEmpty( theField.value ) ) ) 
		return true;
	else if ( !isEmail( theField.value, false ) ) 
		return warnInvalid ( theField, s );
	else 
		return true;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Check that string theField.value is a valid SSN.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkSSN ( theField, emptyOK )
{   
	if ( checkSSN.arguments.length == 1 ) 
		emptyOK = defaultEmptyOK;
	if ( ( emptyOK == true ) && ( isEmpty( theField.value ) ) ) 
		return true;
	else
	{  
		var normalizedSSN = stripCharsInBag( theField.value, SSNDelimiters )
		if ( !isSSN( normalizedSSN, false ) ) 
			return warnInvalid ( theField, iSSN );
		else 
			return true;
	}
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Check that string theField.value is a valid Year.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkYear ( theField, emptyOK )
{   
	if ( checkYear.arguments.length == 1 ) 
		emptyOK = defaultEmptyOK;
	if ( ( emptyOK == true ) && ( isEmpty( theField.value ) ) ) 
		return true;
	if ( !isYear( theField.value, false ) ) 
		return warnInvalid ( theField, iYear );
	else 
		return true;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Check that string theField.value is a valid Month.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkMonth ( theField, emptyOK )
{   
	if ( checkMonth.arguments.length == 1 ) 
		emptyOK = defaultEmptyOK;
	if ( ( emptyOK == true ) && ( isEmpty( theField.value ) ) ) 
		return true;
	if ( !isMonth( theField.value, false ) ) 
		return warnInvalid ( theField, iMonth );
	else 
		return true;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Check that string theField.value is a valid Day.
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkDay ( theField, emptyOK )
{   
	if ( checkDay.arguments.length == 1 ) 
		emptyOK = defaultEmptyOK;
	if ( ( emptyOK == true ) && ( isEmpty( theField.value ) ) ) 
		return true;
	if ( !isDay( theField.value, false ) ) 
		return warnInvalid ( theField, iDay );
	else 
		return true;
}


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// checkDate ( yearField, monthField, dayField, STRING labelString [, OKtoOmitDay==false] )
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkDate ( yearField, monthField, dayField, labelString, OKtoOmitDay )
{
	if ( checkDate.arguments.length == 4 )
		OKtoOmitDay = false;
	if ( !isYear( yearField.value ) ) 
		return warnInvalid ( yearField, iYear );
	if ( !isMonth( monthField.value ) ) 
		return warnInvalid ( monthField, iMonth );
	if (  ( OKtoOmitDay == true ) && isEmpty( dayField.value )  ) 
		return true;
	else if ( !isDay( dayField.value ) ) 
		return warnInvalid ( dayField, iDay );
	if ( isDate ( yearField.value, monthField.value, dayField.value ) )
		return true;
	alert ( iDatePrefix + labelString + iDateSuffix );
	return false;
}

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//	checkDateStr ( dateField, STRING errorMessage [, emptyOK==false] )
//	Parameters:	dateField - format must be mm/dd/yyyy
//				errorMessage - Message to be displayed in case of error
//				emptyOK - true if field can be empty, false if it must contain a value
//	Returns:	true if valid date, false otherwise
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function checkDateStr( dateField, errorMessage, emptyOK )
{
	if ( checkDateStr.arguments.length == 2 )
		emptyOK = false;
		
	dateStr = dateField.value;
	if ( ( emptyOK == true ) && ( isEmpty( dateField.value ) ) ) 
		return true;

	// check for first forward slash in string
	s1 = dateStr.indexOf( "/" );
	if ( s1 == -1 )
		return warnInvalid ( dateField, errorMessage )

	// check for second forward slash in string
	s2 = dateStr.indexOf( "/", s1+1 );
	if ( s2 == -1 )
		return warnInvalid ( dateField, errorMessage )

	// check if values are a valid date
	if ( !isDate ( dateStr.substring( s2+1 ), dateStr.substring( 0, s1 ), dateStr.substring( s1+1, s2 ) ) )
		return warnInvalid ( dateField, errorMessage )
	else if ( dateStr.substring( s2+1 ).length != 4 )
		return warnInvalid ( dateField, "Please enter a 4-digit year" )
	else
		return true;
}

function NonSpace(str)
{
	if(typeof(str)=='undefined' || !str)
		return 0;
	var n = 0
	for (var i=0;i<str.length;i++)
	{
		if (str.charAt(i) != " ")
			n++
	}
	return n
}

var theMonth = new Array()
	theMonth["january"]		= 1
	theMonth["february"]	= 2
	theMonth["march"]		= 3
	theMonth["april"]		= 4
	theMonth["may"]			= 5
	theMonth["june"]		= 6
	theMonth["july"]		= 7
	theMonth["august"]		= 8
	theMonth["september"]	= 9
	theMonth["october"]		= 10
	theMonth["november"]	= 11
	theMonth["december"]	= 12
	theMonth[1]		= "January"
	theMonth[2]		= "February"
	theMonth[3]		= "March"
	theMonth[4]		= "April"
	theMonth[5]		= "May"
	theMonth[6]		= "June"
	theMonth[7]		= "July"
	theMonth[8]		= "August"
	theMonth[9]		= "September"
	theMonth[10]	= "October"
	theMonth[11]	= "November"
	theMonth[12]	= "December"

function getDteDifference(dateOne,dateTwo)
{
	d1 = new Date( dateOne )
	d2 = new Date( dateTwo )
	diff = (d2.getTime() - d1.getTime()) /(365*24*60*60*1000)
	return diff
}

function checkEmailAddress( strEmail)
{
	var x = strEmail;
	var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9])+$/;
	if (!filter.test(x)) {
		alert('Incorrect email address');
		return false;
	}
	return true;
}

function checkFutureDate( dateField )
{
	today = new Date()
	theDate = new Date(dateField.value)
	 
	diff = (today.getTime() - theDate.getTime()) /(365*24*60*60*1000)  //javascript does date in milliseconds
	if (diff > 0 )
		return false
	return true	
}

function isCurrency(str) 
{ 
	isAmount = /(^\d+\.\d{2}$)|(^\.\d{2}$)/; 
	return isAmount.test( str ); 
} 
