defaultEmptyOK = false;
var whitespace = " \t\n\r";
var phoneNumberDelimiters = "()- ";
var digits = "0123456789";
var digitsInUSPhoneNumber = 10;
var validUSPhoneChars = digits + phoneNumberDelimiters;
var reWhitespace = /^\s+$/
var reInteger = /^\d+$/
var reEmail = /^.+\@.+\..+$/


var iIP ="This field must be a valid IP address, that is not private."
var iEmail = "This field must be a valid email address (like johndoe@cox.net). 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 iInteger = "This field must be a number greater than zero.  Please reenter it now."
var iTime = "This field must be a valid time in the format HH:MM followed by AM or PM, such as 10:45 AM."
var iRequired = "You must check the box at the bottom before submitting, to indicate your acceptance of the Acceptable Use Policy."
var mPrefix = "You did not enter a value into the "
var mSuffix = " field. This is a required field. Please enter it now."


function warnInvalid (theField, s)
{   theField.focus()
    theField.select()
		if (warnInvalid.arguments.length == 2)
    	alert(s);
    return false
}

function warnEmpty (theField, s)
{   theField.focus()
    alert(mPrefix + s + mSuffix)
    return false
}


function checkIP(thefield,emptyOK)
{
 if(checkIP.arguments.length == 1) emptyOK = defaultEmptyOK;
 thefield.value=stripWhitespace(thefield.value);
 //if ((emptyOK==true)&&(isEmpty(thefield.value))) return true; 
 if(thefield.value.length ==0)
   return warnInvalid(thefield,iIP);
 if(!isIP(thefield.value))
    return warnInvalid (thefield,iIP);

 else return true;
 
}
 
 
function checkEmail (theField, emptyOK)
{   if (checkEmail.arguments.length == 1) emptyOK = defaultEmptyOK;
		theField.value = stripWhitespace(theField.value);
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;
    else if (!isEmail(theField.value, false)) 
       return warnInvalid (theField, iEmail);
    else return true;
}

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 
       {  // if you don't want to reformat as (123) 456-789, comment next line out
          theField.value = reformatUSPhone(normalizedPhone)
          return true;
       }
    }
}

function isEmail (s)

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

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)
}

function IsValidTime(timeStr) {
  // Checks if time is in HH:MM:SS AM/PM format.
  // The seconds and AM/PM are optional.
  
  var timePat = /^(\d{1,2}):(\d{2})(:(\d{2}))?(\s?(AM|am|PM|pm))?$/;
  
  var matchArray = timeStr.match(timePat);
  if (matchArray == null) {
  	alert(iTime);
  	return false;
  }
  hour = matchArray[1];
  minute = matchArray[2];
  second = matchArray[4];
  ampm = matchArray[6];
  
  if (second=="") { second = null; }
  if (ampm=="") { ampm = null }
  
  if (hour < 0  || hour > 23) {
  alert("Hour must be between 1 and 12. (or 0 and 23 for military time)");
  return false;
  }
  if (hour <= 12 && ampm == null) {
  if (confirm("Please indicate which time format you are using.  OK = Standard Time, CANCEL = Military Time")) {
  alert("You must specify AM or PM.");
  return false;
     }
  }
  if  (hour > 12 && ampm != null) {
  alert("You can't specify AM or PM for military time.");
  return false;
  }
  if (minute<0 || minute > 59) {
  alert ("Minute must be between 0 and 59.");
  return false;
  }
  if (second != null && (second < 0 || second > 59)) {
  alert ("Second must be between 0 and 59.");
  return false;
  }
  //return false;
	return true;
}




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;

    // Explicitly change type to integer to make code work in both
    // JavaScript 1.1 and JavaScript 1.2.
    var intYear = parseInt(year);
    var intMonth = parseInt(month);
    var intDay = parseInt(day);

    // catch invalid days, except for February
    if (intDay > daysInMonth[intMonth]) return false; 

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

    return true;
}

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 isDay (s)
{   if (isEmpty(s)) 
       if (isDay.arguments.length == 1) return defaultEmptyOK;
       else return (isDay.arguments[1] == true);   
    return isIntegerInRange (s, 1, 31);
}

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 isIntegerInRange (s, a, b)
{   if (isEmpty(s)) 
       if (isIntegerInRange.arguments.length == 1) return defaultEmptyOK;
       else return (isIntegerInRange.arguments[1] == true);

    // Catch non-integer strings to avoid creating a NaN below,
    // which isn't available on JavaScript 1.0 for Windows.
    if (!isInteger(s, false)) return false;

    // Now, explicitly change the type to integer via parseInt
    // so that the comparison code below will work both on 
    // JavaScript 1.2 (which typechecks in equality comparisons)
    // and JavaScript 1.1 and before (which doesn't).
    var num = parseInt (s);
    return ((num >= a) && (num <= b));
}



function isInteger (s)

{   var i;

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

    return reInteger.test(s)
}



function isPositiveInteger (s)
{   var secondArg = defaultEmptyOK;
		
    if (isPositiveInteger.arguments.length > 1)
        secondArg = isPositiveInteger.arguments[1];
    return (parseInt (s) > 0);
}

function checkInteger (theField, emptyOK)
{
	if (checkInteger.arguments.length == 2) emptyOK = defaultEmptyOK;
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;
	if (!isPositiveInteger(theField.value)) return warnInvalid (theField, iInteger)
		else return true;
}
function checkString (theField, s, emptyOK)
{   // Next line is needed on NN3 to avoid "undefined is not a number" error
    // in equality comparison below.
    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 checkTime (theField,emptyOK)
{
	if (checkTime.arguments.length == 2) emptyOK = defaultEmptyOK;
	if ((emptyOK == true) && (isEmpty(theField.value))) return true;
	if (!IsValidTime(theField.value)) return warnInvalid (theField)
		else return true;
}

function checkChoice (optionsarray, idx, s, otherField)
{
	//this function ensure that the "other" text field is not blank when "other"
	//is selected as a choice.
	if (optionsarray[idx].checked==true){
		if (isEmpty(otherField.value))
			return warnEmpty(otherField,s)
		else
			return true;
	}else{
		//clear the "other" blank if the "other" choice is not selected
		otherField.value = "";
		return true;
	}
}

function checkRequired(theField){
	//returns false if the field (checkbox) is not "checked."  
	if(!theField.checked) 
		return warnInvalid(theField,iRequired)
		else return true;
}

function isEmpty(s)
{   return ((s == null) || (s.length == 0))
}

function isWhitespace (s)
{   // Is s empty?
    return (isEmpty(s) || reWhitespace.test(s));
}

function isIP(IpValue)
{
 var pieces = IpValue.split('.');
 if(pieces.length < 4)
   return false;
 for(var i=0;i<4;i++)
 {
  if((isNaN(pieces[i]))||(pieces[i]>255))
	 return false;
 }
 if(pieces[0] == 10)
  return false;
 else if((pieces[0] == 192)&&(pieces[1]==168))
  return false;
 else return true;
}

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++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }

    return returnString;
}

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 reformatUSPhone (USPhone)
{   return (reformat (USPhone, "(", 3, ") ", 3, "-", 4))
}

function stripWhitespace (s)

{   return stripCharsInBag (s, whitespace)
}

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++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }

    return returnString;
}
