// VARIABLE DECLARATIONS

// non-digit characters which are allowed in phone numbers
var phoneNumberDelimiters = "()- ext.:";

// characters which are allowed in US phone numbers
var validUSPhoneChars = digits + phoneNumberDelimiters;

// characters which are allowed in international phone numbers
// (a leading + is OK)
var validWorldPhoneChars = digits + phoneNumberDelimiters + "+";

// non-digit characters which are allowed in
// Social Security Numbers
var SSNDelimiters = "- ";

// characters which are allowed in Social Security Numbers
var validSSNChars = digits + SSNDelimiters;

// characters which are allowed in first, middle or last name
// !! NOTE: the used vars are defined in string_tools.js, which is a required .js collection to run the functions on this page
var validNameChars = lowercaseLetters + uppercaseLetters + digits + "&,'-. ";
var validNameCharsDisplay = "A-Z, 0-9 and " + "&,'-. ";

// characters which are allowed in a street address
// !! NOTE: the used vars are defined in string_tools.js, which is a required .js collection to run the functions on this page
var validStreetAddressChars = lowercaseLetters + uppercaseLetters + digits + ",./@#&()';:- " + String.fromCharCode(34); // 34 is a double quote
var validStreetCharsDisplay = "A-Z, 0-9 and " + ",./@#&()';:- " + String.fromCharCode(34);

// characters which are allowed in a city name
// !! NOTE: the used vars are defined in string_tools.js, which is a required .js collection to run the functions on this page
var validCityChars = lowercaseLetters + uppercaseLetters + digits + "&,'-. ";
var validCityCharsDisplay = "A-Z, 0-9 and " + "&,'-. ";

// U.S. Social Security Numbers have 9 digits.
// They are formatted as 123-45-6789.
var digitsInSocialSecurityNumber = 9;

// U.S. phone numbers have 10 digits.
// They are formatted as 123 456 7890 or (123) 456-7890.
var digitsInUSPhoneNumber = 10;

// non-digit characters which are allowed in ZIP Codes
var ZIPCodeDelimiters = "-";

// our preferred delimiter for reformatting ZIP Codes
var ZIPCodeDelimeter = "-"

// characters which are allowed in Social Security Numbers
var validZIPCodeChars = digits + ZIPCodeDelimiters;

// U.S. ZIP codes have 5 or 9 digits.
// They are formatted as 12345 or 12345-6789.
var digitsInZIPCode1 = 5;
var digitsInZIPCode2 = 9;

var digitsInCreditCard = 16;
var digitsInCreditCardAmex = 15;

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;

// Valid U.S. Postal Codes for State, territories, armed forces, etc.

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"


// either has to have no spaces, or has 2 hyphens
function isSSN(s)
	{
	var sAdj = stripCharsInBag(s, "- ")
    return (isInteger(sAdj) && sAdj.length == digitsInSocialSecurityNumber)
	}


// NOTE: Strip out any delimiters (spaces, hyphens, etc.) BELOW f's
// from string s before calling this function.

function isUSPhoneNumber(s)
	{
    if (isEmpty(s)) return true;
    var sAdj = stripCharsInBag(s, phoneNumberDelimiters)
	return (isInteger(sAdj) && sAdj.length >= digitsInUSPhoneNumber)
	}

function isZIPCode(s)
	{
	sAdj = stripCharsInBag(s, "- ");
	return (isInteger(sAdj) && ((sAdj.length == digitsInZIPCode1) || (sAdj.length == digitsInZIPCode2)))
	}

function isStateCode(s)
	{
    return ( (USStateCodes.indexOf(s) != -1) && (s.indexOf(USStateCodeDelimiter) == -1) )
	}


// failing.. try 204.rr
function __isNumeric(argString)
{
	return new RegExp('[0-9]+', 'g').test(argString);
}

function isNumeric(sText)

{
   var ValidChars = "0123456789.";
   var IsNumber=true;
   var Char;

 
   for (i = 0; i < sText.length && IsNumber == true; i++) 
      { 
      Char = sText.charAt(i); 
      if (ValidChars.indexOf(Char) == -1) 
         {
         IsNumber = false;
         }
      }
   return IsNumber;
   
   }




// isEmail (STRING s [, BOOLEAN emptyOK])
//
// Email address must be of form a@b.c -- in other words:
// * there must be at least one character before the @
// * there must be at least one character before and after the .
// * the characters @ and . are both required
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

function isEmailOld(s)
	{

    // is s whitespace?
    if (isWhitespace(s)) return false;

    // there must be >= 1 character before @, so we
    // start looking at character position 1
    // (i.e. second character)
    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;
	}


// new function provided by doc jscript
function isEmail(str)
	{

	 if (isEmpty(str)) return true;

	if (hasSpace(str))
		{
		return false;
		}
	// are regular expressions supported?
	var supported = 0;
	if (window.RegExp)
		{
		var tempStr = "a";
		var tempReg = new RegExp(tempStr);
		if (tempReg.test(tempStr)) supported = 1;
		}
	if (!supported)
		{
		return (str.indexOf(".") > 2) && (str.indexOf("@") > 0);
		}

	var r1 = new RegExp("(@.*@)|(\\.\\.)|(@\\.)|(^\\.)");
	var r2 = new RegExp("^.+\\@(\\[?)[a-zA-Z0-9_\\-\\.]+\\.([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
	return (!r1.test(str) && r2.test(str));
}



function isDollarAmount(argString)
{
	return isNumericWithTwoDecimalPlaces(argString);
}


function isNumericWithTwoDecimalPlaces(argString)
{

	if (!isNumeric(argString))
	{
		return false;
	}
	
	
	
	var dotPosition = argString.indexOf('.');

	if (dotPosition == -1)
	{
		return false;
	}

	var lastDotPostion = argString.lastIndexOf('.');


	if((dotPosition!=-1) && ((dotPosition!=(argString.length-3)) || (dotPosition!=lastDotPostion)))
	{
		return false;
	}
	
	return true;
}



function isYear(s)
	{
    if (!isNonnegativeInteger(s)) return false;
    // removed acceptance of 2 digit year, mp, 02/19/2008
	return ((s.length == 4));
	}


function isMonth(s)
	{
    return isIntegerInRange (s, 1, 12);
	}


function isDay(s)
	{
    return isIntegerInRange (s, 1, 31);
	}

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 );
	}



function isDate(year, month, day)
	{
	// this f can handle both a date as MM/DD/YYYY or as 3 args... figure out what we've been handed and work with it

	if (isDate.arguments.length == 1) // we have probably been handed one arg with a date string in it
		{
		// split the date string up, the year arg should be the whole date string
		var splitDate = year.split('/');
		if (splitDate.length != 3) // not enough or too many slashes
			{
			// alert('Improperly formatted date.')
			return false;
			}
		// assign the month, day and year to vars so we can continue to validate
		var theMonth = splitDate[0];
		var theDay = splitDate[1];
		var theYear = splitDate[2];
		}
	else if	(isDate.arguments.length == 3)
		{
		var theMonth = month;
		var theDay = day;
		var theYear = year;
		}
	else
		{
		alert('The function isDate() accepts either 1 or 3 functions.\ Current call does not meet this criteria.')
		return false
		}

	// catch invalid years (not 2- or 4-digit) and invalid months and days.
    if (! (isYear(theYear, false) && isMonth(theMonth, false) && isDay(theDay, false))) return false;

    // Explicitly change type to integer to make code work in both
    // JavaScript 1.1 and JavaScript 1.2.
    var intYear = parseInt(theYear);
    var intMonth = parseInt(theMonth);
    var intDay = parseInt(theDay);

    // catch invalid days, except for February
    if (intDay > daysInMonth[intMonth]) return false;

    if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;

    return true;
	}



// written by mParnham 12/20/2000
// return the number of days from today as a signed integer
// -50 = date is 50 days into the past
// 50 = date is 50 days into the future
// make sure the day is legit before passing it to this function!

// !!! very important: this function flattens all potential differences in time zones-
// it does this by instantiating the 2 time objects with the same time (excluding milliseconds)
// if biz requirements require more sensitivity to time zones, then somebody will have to get smart.

function daysDifferent(dateToCheck,todaysDate)
	{

	// set the time object for the date to check
	var splitDateToCheck = dateToCheck.split('/');
	var theMonthToCheck = splitDateToCheck[0] - 1; // note month is indexed at 0
	var theDayToCheck = splitDateToCheck[1];
	var theYearToCheck = splitDateToCheck[2];

	var dateToCheck = new Date(theYearToCheck, theMonthToCheck, theDayToCheck);

	// set the time object for todays date
	var splitTodaysDate = todaysDate.split('/');
	var theMonthToday = splitTodaysDate[0] - 1; // note month is indexed at 0
	var theDayToday = splitTodaysDate[1];
	var theYearToday = splitTodaysDate[2];

	var todaysDate = new Date(theYearToday, theMonthToday, theDayToday);

	var difInMilliSecs = dateToCheck.getTime() - todaysDate.getTime();
	var difInDays = Math.floor(difInMilliSecs / (1000 * 60 * 60 * 24));

	return difInDays

	}


function fixSSN(theSSN)
	{
	return reformat (stripCharsInBag(theSSN, "- "), "", 3, "-", 2, "-", 4)
	}

// some HOBS API's need leading zeros in day and month- great design eh?
// !! assumes the date is valid
function enforceLeadingZerosOnDate(theDateString)
	{

	var theDateAsArray = theDateString.split('/');
	var theMonth = theDateAsArray[0];
	var theDay = theDateAsArray[1];
	var theYear = theDateAsArray[2];

	if (theMonth.length < 2)
		{
		theMonth = "0" + theMonth;
		}

	if (theDay.length < 2)
		{
		theDay = "0" + theDay;
		}

	return (theMonth + "/" + theDay + "/" + theYear)

	}




// returns true if theNameString contains only validNameChars
function isValidName(theNameString, returnOffending)
	{
	var charsLeft = stripCharsInBag(theNameString, validNameChars);

	if (isEmpty(charsLeft))
		{
		return true;
		}
	if (returnOffending)
		{
		return charsLeft;
		}
	else
		{
		return false;
		}
	}

// returns true if theAddressString contains only validAddressChars
function isValidStreetAddress(theStreetAddressString, returnOffending)
	{
	var charsLeft = stripCharsInBag(theStreetAddressString, validStreetAddressChars)

	if (isEmpty(charsLeft))
		{
		return true;
		}
	if (returnOffending)
		{
		return charsLeft;
		}
	else
		{
		return false;
		}
	}


// returns true if theCityString contains only validCityChars
function isValidCity(theCityString, returnOffending)
	{
	var charsLeft = stripCharsInBag(theCityString, validCityChars)

	if (isEmpty(charsLeft))
		{
		return true;
		}
	if (returnOffending)
		{
		return charsLeft;
		}
	else
		{
		return false;
		}
	}



// written by mParnham 12/27/2000
// returns false if value of the passed select object is "" or the $ noneSelected
// else returns true
// !! make sure "" is the option that indicates nothing has been selected. ie "Select One"
function isSelectionMade(theSelector)
	{
	if (selectionValue(theSelector).toLowerCase() == "noneselected" || selectionValue(theSelector).toLowerCase() == "")
		{
		return false;
		}
	else
		{
		return true;
		}
	}


function getYear(dateString) // dateString needs to be in format MM/DD/YYYY
	{
	var splitDate =  dateString.split('/');
	return splitDate[2];
	}

function getMonth(dateString) // dateString needs to be in format MM/DD/YYYY
	{
	var splitDate =  dateString.split('/');
	return splitDate[0];
	}

function getDay(dateString) // dateString needs to be in format MM/DD/YYYY
	{
	var splitDate =  dateString.split('/');
	return splitDate[1];
	}

function isValidCreditCardNumber(s)
	{
	if (isEmpty(s)) return false;
    var sAdj = stripCharsInBag(s, " ");

	if (!isInteger(sAdj))
	{
		return false;
	}

	return (sAdj.length == digitsInCreditCard || sAdj.length == digitsInCreditCardAmex)

	}

function onTextAreaChange(element, remainingCharactersElementId, maxCharactersAllowed)
{

	var elementId = element.id;
	var numberOfCharacters = element.value.length + 1;

	var charactersLeft = maxCharactersAllowed - numberOfCharacters;

	if (charactersLeft < 0)
	{
		charactersLeft = 0;
	}

	if (charactersLeft == 0)
	{
		document.getElementById(remainingCharactersElementId).innerHTML = charactersLeft + "&nbsp;&nbsp;&nbsp;&nbsp;<span style='color:red; text-weight:bold;'>Maximum Limit Met</span>";
		var trimElementValue = element.value.substring(0, maxCharactersAllowed -1);
		element.value = trimElementValue;
	}
	else
	{
		document.getElementById(remainingCharactersElementId).innerHTML = charactersLeft;
	}

}



