<!--
//
// -- Various Validation Routines --
//
var whitespace = " \t\n\r";
var defaultEmptyOK = false; 
var decimalPointDelimiter = "."
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"
var ZIPCodeDelimiters = "-+";
var digitsInZipCode1 = 5
var digitsInZipCode2 = 9
var phoneNumberDelimiters = "()- ";
var digitsInUSPhoneNumber = 10;

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 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++) {
    var c = s.charAt(i);
    if ((c == decimalPointDelimiter) && !seenDecimalPoint) seenDecimalPoint = true;
    else if (!isDigit(c)) return false;
  }
  return true;
}

function isWhitespace (s) {
	  var i;
	  if (isEmpty(s)) return true;
	  for (i = 0; i < s.length; i++) {
	    var c = s.charAt(i);
	    if (whitespace.indexOf(c) == -1) return false;
	  }
	  return true;
}

function isEmail (s) {
	  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 isEmpty(s) {
 		return ((s == null) || (s.length == 0))
}

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) )
}

function isZipCode (s) {
  if (isEmpty(s)) 
    if (isZipCode.arguments.length == 1) return defaultEmptyOK;
    else return (isZipCode.arguments[1] == true);
  s = stripCharsInBag(s, ZIPCodeDelimiters);
  return (isInteger(s) && ((s.length == digitsInZipCode1) || (s.length == digitsInZipCode2)))
}

function isUSPhoneNumber (s) {
  if (isEmpty(s)) 
    if (isUSPhoneNumber.arguments.length == 1) return defaultEmptyOK;
    else return (isUSPhoneNumber.arguments[1] == true);
  s = stripCharsInBag(s, phoneNumberDelimiters);
  return (isInteger(s) && s.length == digitsInUSPhoneNumber)
}

//
// -- Credit Card Format Validations
//
function isCreditCard(st) {
  // - - - - - - - - - -- - - - - - - - - -
  // This is the Luhn Check Digit Algorithm.
  // - - - - - - - - - -- - - - - - - - - -
  //
  // None of the four cards we take are longer than 16 digits.
  if (st.length > 16)
    return (false);
  // It's not too long, so let's check it out.
  var sum = 0; 
  var mul = 1; 
  var l = st.length;
  var digit
  var tproduct
  // Loop through the card digits *right to left* and compute the checksum.
  for (i = 0; i < l; i++) 
  {
    digit = st.substring(l-i-1,l-i);
    tproduct = parseInt(digit,10)*mul;
    if (tproduct >= 10)
      sum += (tproduct % 10) + 1;
    else
      sum += tproduct;
    // If we were multiplying by 1 make it 2, else it was 2 so make it 1.
    if (mul == 1)
      mul = 2;
    else
      mul = 1;
  };
  // If the sum is evenly divisable by 10 then the checksum checks out.
  if ((sum % 10) == 0)
    return (true);
  else
    return (false);
}

function isVisa(cc) {
  if (((cc.length == 16) || (cc.length == 13)) && (cc.substring(0,1) == 4))
    return isCreditCard(cc);
  return false;
}

function isMasterCard(cc) {
  firstdig = cc.substring(0,1);
  seconddig = cc.substring(1,2);
  if ((cc.length == 16) && (firstdig == 5) && ((seconddig >= 1) && (seconddig <= 5)))
    return isCreditCard(cc);
  return false;
}

function isAmericanExpress(cc) {
  firstdig = cc.substring(0,1);
  seconddig = cc.substring(1,2);
  if ((cc.length == 15) && (firstdig == 3) && ((seconddig == 4) || (seconddig == 7)))
    return isCreditCard(cc);
  return false;
}

function isDiscover(cc) {
  first4digs = cc.substring(0,4);
  if ((cc.length == 16) && (first4digs == "6011"))
    return isCreditCard(cc);
  return false;
}

function isCardMatch (cardType, cardNumber) {
  cardType = cardType.toUpperCase();
  var doesMatch = true;
  if ((cardType == "VISA") && (!isVisa(cardNumber)))
    doesMatch = false;
  if ((cardType == "MASTERCARD") && (!isMasterCard(cardNumber)))
    doesMatch = false;
  if ( ( (cardType == "AMERICANEXPRESS") || (cardType == "AMEX") ) && (!isAmericanExpress(cardNumber)))
    doesMatch = false;
  if ((cardType == "DISCOVER") && (!isDiscover(cardNumber)))
    doesMatch = false;
  return doesMatch;
}

//
// -- Support Routines --
//
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 buildMessage(msg, errorText)
{
	var retVal = "";
	if (msg == "")
	{
		retVal = errorText;
	}
	else
	{
		retVal = errorText + "\n" + msg;    // bottom-up
	}
	return retVal;
}
-->