////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Script Name:         validation.js
// Description:         Collection of routines to validate user form input
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////
// Execute the form
// Author : Alvin
// Parameter :
// 	obj  : Image object where the value parameter contain name of the destination
// 	form : The action of this form going to change
// Return :
//	boolean : there is not any validation done here. So it alwyas going to 
//		   return true
// Example of Usage :
//	<INPUT type="image" name="check_out" border="0" onclick="return changeFormAction(this, document.forms['<Name of the Form>']);" src="/images/check_other_loc.gif" value="/servlet/CheckOutServlet?action=checkout">&nbsp; &nbsp; 
//	<INPUT type="image" name="check_in" border="0" onclick="return changeFormAction(this, document.forms['<Name of the Form>']);" src="/images/check_other_loc.gif" value="/servlet/CheckInServlet?action=checkin">
function formExecute(formName,actionTypeValue,bodyVariableValue,validateFlag)
{
	var formObject = document.forms[formName];

	// alert("actionTypeValue is " + actionTypeValue);

	// Initialize the actionType
	if(actionTypeValue != '') formObject.actionType.value=actionTypeValue;
	// alert("formObject.actionType.value is " + formObject.actionType.value);

	// Initialize the redirectPage
	if(bodyVariableValue !=null && bodyVariableValue!="") formObject.bodyVariable.value=bodyVariableValue;

	// Validate form, if requested
	if(validateFlag==1)
	{
		// Validate Form
		if(validateForm(formObject)) formObject.submit();
	}
	else
	{
	formObject.submit();
	}
}


/////////////////////////////////////////////////////////////
// Change the form Action
// Author : Duke ()
// Parameter :
// 	obj  : Image object where the value parameter contain name of the destination
// 	form : The action of this form going to change
// Return :
//	boolean : there is not any validation done here. So it alwyas going to 
//		   return true
// Example of Usage :
//	<INPUT type="image" name="check_out" border="0" onclick="return changeFormAction(this, document.forms['<Name of the Form>']);" src="/images/check_other_loc.gif" value="/servlet/CheckOutServlet?action=checkout">&nbsp; &nbsp; 
//	<INPUT type="image" name="check_in" border="0" onclick="return changeFormAction(this, document.forms['<Name of the Form>']);" src="/images/check_other_loc.gif" value="/servlet/CheckInServlet?action=checkin">
function changeFormAction(value, form){	
	form.action=value;
	form.submit();
	//return true;
}

// Return the selected radio button Value 
function getSelectedObj(obj){
	var returnVal;
	for(var cnt = 0; cnt < obj.length; cnt++){
		if (obj[cnt].checked){
			returnVal = obj[cnt];
			break;
		}
	}
	return returnVal;
}



////////////////////////////////////
//
// Function: stripCharsInBag()
//
// Description: Removes all characters which 
//              appear in string bag from string s.
//
// Arguments: s   - string - required
//            bag - string - required - contains a list
//            of the characters to strip
//
// Returns: string - returns a string without any 
//          instances of the bag characters in it
//
// Preconditions: N/A
//
function stripCharsInBag (s, bag)
{
  if (!s) {return null;}
  if (!bag) {return s;}

   var re=new RegExp("["+bag+"]","g");
   return s.replace(re,"");
}

////////////////////////////////////
//
// Function: isBlank()
//
// Description: checks a string for whitespaces
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find only
//          blank characters
//
// Preconditions: N/A
//
function isBlank(s)
{
  if (!s) {return true;}
  if (s.replace(" ","").length==0) {return true;}
  return s.match(/^\s$/);
}

////////////////////////////////////
//
// Function: isInteger()
//
// Description: checks a string for an integer
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find an integer
//
// Preconditions: N/A
//
function isInteger(s) {
  if (!s) {return false;}
  return s.match(/^[0-9]*$/);
}

////////////////////////////////////
//
// Function: isFloat()
//
// Description: checks a string for a float
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find a float
//
// Preconditions: N/A
//
function isFloat(s) {
  if (!s) {return false;}
  return s.match(/^\-{0,1}\d*\.\d*/);
}

////////////////////////////////////
//
// Function: isNumeric()
//
// Description: checks a string for a numeric string
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find a
//          numeric string
//
// Preconditions: N/A
//
function isNumeric (s) {
  if (!s) {return false;}
  return (isFloat(s) || isInteger(s));
}

////////////////////////////////////
//
// Function: isAlphaNumeric()
//
// Description: checks a string for an alphanumeric string
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find an
//          alphanumeric string
//
// Preconditions: N/A
//
function isAlphaNumeric (s) {
  if (!s) {return false;}
  return s.match(/^[A-Za-z0-9]*$/);
}

////////////////////////////////////
//
// Function: isAlphaNumeric()
//
// Description: checks a string for an alphanumeric string
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find an
//          alphanumeric string
//
// Preconditions: N/A
//
// Need to add options for _,-, and <space>
function isFolderName(s) {
  if (!s) {return false;}
  return s.match(/^[A-Za-z0-9]*$/);
}


////////////////////////////////////
//
// Function: isNowOrFutureDate(String s)
// Author  : Alvin
// Description: checks that a date is >= today
//
// Arguments: s - string - required (Format "MM/DD/YYYY")
//
// Returns: boolean - is the string today or in the future
//
// Preconditions: N/A
//
function isNowOrFutureDate(s) {
	var month 	= parseInt(s.substring(0,2));
	var day 	= parseInt(s.substring(3,5));
	var year	= parseInt(s.substring(6,10));
	
	var currentDate = new Date();
	var currentMonth= currentDate.getMonth() + 1;
	var currentDay	= currentDate.getUTCDate()-1;
	var currentYear	= currentDate.getYear();

	if (!s) {return false;}

	if (s=="//" || s=="--") {return false;}

	if (year < currentYear)
		return false;
	else if (year > currentYear)
		return true;
	else //year=currentYear
	{	
		if (month < currentMonth)
			return false;
		else if (month > currentMonth)
			return true;
		else
		{
			// alert("currentDate is " + currentDate);
			// alert("day is: " + day);
			// alert("currentDay is: " + currentDay);

			if (day < currentDay)
				return false;
			else if (day >= currentDay)
				return true;
		}
	}
}


////////////////////////////////////
//
// Function: stripNonDigits(str)
//
// Description: The function replaces all occurrences of any 
// character that's not 0-9 with a null string using the negated 
// character set ([^0-9]), and the global metacharacter (g):
//
// Arguments: str - string - required
//
// Returns: string - 
//
function stripNonDigits(str) {
	//alert("stripNonDigits str b4 is " + str);
        return str.replace(/[^0-9]/g,"")
} 


////////////////////////////////////
//
// Function: isCellPhoneNumber(object)
//
// Description: checks a string for a phone number
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find a
//          phone number in the string
//
// Preconditions: N/A
//
function isCellPhoneNumber (obj)
{
	// alert("in isCellPhoneNumber");
  var str = obj.value;

  // replace any non-numeric values
  s = stripNonDigits(str);
	// alert("s after stripNonDigits str is " + s);

  if (isEmptyString(s)) return false;

  if (s.charAt(0)=='1')	
  	{
  	s=s.substring(1,s.length);
  	obj.value=s
  	}

  if (isInteger(s)){
	if (s.length < 10)
		return false;
	else
		{
		obj.value = s;
		return true;
		}
  }
  else
  	return false;

  //return (s.match(/\d{3}[\-\.\ ]\d{3}[\-\.\ ]\d{4}/) ||
  //        s.match(/\(\d{3}\)[\ ]{0,1}\d{3}[\-\.\ ]\d{4}/));
}

////////////////////////////////////
//
// Function: isPhoneNumber(object)
//
// Description: checks a string for a phone number
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find a
//          phone number in the string
//
// Preconditions: N/A
//
function isPhoneNumber (obj)
{
  var str = obj.value;

  // replace any non-numeric values
  s = stripNonDigits(str);

  if (isEmptyString(s)) return false;
  if (isInteger(s)){
	if (s.length == 10) {
		obj.value = s;
		return true;
	}
	else
		return false;
  }
  //return (s.match(/\d{3}[\-\.\ ]\d{3}[\-\.\ ]\d{4}/) ||
  //        s.match(/\(\d{3}\)[\ ]{0,1}\d{3}[\-\.\ ]\d{4}/));
}

////////////////////////////////////
//
// Function: isEmailAddress2() OLD Function
//
// Description: checks a string for an email address
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find an
//          email address in the string
//
// Preconditions: N/A
//
function isEmailAddress2 (s)
{
  if (isEmptyString(s)) return false;
  return s.match(/\w{1,}[@]\w{1,}[\.]\w{1,}/);
}

////////////////////////////////////
//
// Function: isEmailAddress()
//
// Description: checks a string for an email address
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find an
//          email address in the string
//
// Preconditions: N/A
//
function isEmailAddress(emailStr) {
/* The following pattern is used to check if the entered e-mail address
   fits the user@domain format.  It also is used to separate the username
   from the domain. */
var emailPat=/^(.+)@(.+)$/
/* The following string represents the pattern for matching all special
   characters.  We don't want to allow special characters in the address. 
   These characters include ( ) < > @ , ; : \ " . [ ]    */
var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
/* The following string represents the range of characters allowed in a 
   username or domainname.  It really states which chars aren't allowed. */
var validChars="\[^\\s" + specialChars + "\]"
/* The following pattern applies if the "user" is a quoted string (in
   which case, there are no rules about which characters are allowed
   and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
   is a legal e-mail address. */
var quotedUser="(\"[^\"]*\")"
/* The following pattern applies for domains that are IP addresses,
   rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
   e-mail address. NOTE: The square brackets are required. */
var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
/* The following string represents an atom (basically a series of
   non-special characters.) */
var atom=validChars + '+'
/* The following string represents one word in the typical username.
   For example, in john.doe@somewhere.com, john and doe are words.
   Basically, a word is either an atom or quoted string. */
var word="(" + atom + "|" + quotedUser + ")"
// The following pattern describes the structure of the user
var userPat=new RegExp("^" + word + "(\\." + word + ")*$")
/* The following pattern describes the structure of a normal symbolic
   domain, as opposed to ipDomainPat, shown above. */
var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$")

var matchArray=emailStr.match(emailPat)
if (matchArray==null) {
  /* Too many/few @'s or something; basically, this address doesn't
     even fit the general mould of a valid e-mail address. */
	// alert("Email address seems incorrect (check @ and .'s)")
	return false
}
var user=matchArray[1]
var domain=matchArray[2]

// See if "user" is valid 
if (user.match(userPat)==null) {
    // user is not valid
    // alert("The username doesn't seem to be valid.")
    return false
}

/* if the e-mail address is at an IP address (as opposed to a symbolic
   host name) make sure the IP address is valid. */
var IPArray=domain.match(ipDomainPat)
if (IPArray!=null) {
    // this is an IP address
	  for (var i=1;i<=4;i++) {
	    if (IPArray[i]>255) {
	        alert("Destination IP address is invalid!")
		return false
	    }
    }
    return true
}

// Domain is symbolic name
var domainArray=domain.match(domainPat)
if (domainArray==null) {
	alert("The domain name doesn't seem to be valid.")
    return false
}

/* domain name seems valid, but now make sure that it ends in a
   three-letter word (like com, edu, gov) or a two-letter word,
   representing country (uk, nl), and that there's a hostname preceding 
   the domain or country. */

/* Now we need to break up the domain to get a count of how many atoms
   it consists of. */
var atomPat=new RegExp(atom,"g")
var domArr=domain.match(atomPat)
var len=domArr.length
if (domArr[domArr.length-1].length<2 || 
    domArr[domArr.length-1].length>3) {
   // the address must end in a two letter or three letter word.
   alert("The address must end in a three-letter domain, or two letter country.")
   return false
}

// Make sure there's a host name preceding the domain.
if (len<2) {
   var errStr="This address is missing a hostname!"
   // alert(errStr)
   return false;
}

// If we've gotten this far, everything's valid!
return true;
}

////////////////////////////////////
//
// Function: isDifferentEmailAddress()
//
// Description: checks a string for an email address
//
// Arguments: emailStr - string - required
//		origEmailStr - original email string - required
//
// Returns: boolean - did the function find the e-mails different?
//          
//
// Preconditions: N/A
//
function isDifferentEmailAddress(emailStr,origEmailStr) {
	// alert("in isDifferentEmailAddress( emailStr is " + emailStr + " origEmailStr is: " + origEmailStr);
	if(emailStr && origEmailStr) {
		// alert("in isDifferentEmailAddress if1");

		// alert("in isDifferentEmailAddress emailStr.toLowerCase() is [" + emailStr.toLowerCase() + "]");
		// alert("in isDifferentEmailAddress origEmailStr.toLowerCase() is [" + origEmailStr.toLowerCase() + "]");
		if(emailStr.toLowerCase()!=origEmailStr.toLowerCase()) {
			// alert("in isDifferentEmailAddress if2");
			return true; // emailstrings are different
		}
	}
	// alert("in isDifferentEmailAddress returning false");
	
	return false; // email strings are equal
}

////////////////////////////////////
//
// Function: isDifferentEmailAddressCSV()
//
// Description: checks a CSV string for an email address
//
// Arguments: emailStr - string - required
//		origEmailStr - original email string - required
//
// Returns: boolean - did the function find the e-mails different?
//          
//
// Preconditions: N/A
//
function isDifferentEmailAddressCSV(emailStr,origEmailStrCSV) {
	var valueToReturn=false;
	
	// alert("in isDifferentEmailAddress( emailStr is " + emailStr + " origEmailStrCSV is: " + origEmailStrCSV);
	if(origEmailStrCSV) {
		// alert("in isDifferentEmailAddress if1");

		// alert("in isDifferentEmailAddress emailStr.toLowerCase() is [" + emailStr.toLowerCase() + "]");
		// alert("in isDifferentEmailAddress origEmailStrCSV.toLowerCase() is [" + origEmailStrCSV.toLowerCase() + "]");
		// alert("origEmailStrCSV.toLowerCase().indexOf(, + emailStr.toLowerCase() + ,) is " + origEmailStrCSV.toLowerCase().indexOf("," + emailStr.toLowerCase() + ","))

		if(emailStr){
			if(("," + origEmailStrCSV + ",").toLowerCase().indexOf("," + emailStr.toLowerCase() + ",")<0) {
				// alert("in isDifferentEmailAddress if2");
				valueToReturn=true; // emailstrings are different
			}
		}
/**		
		// Compare strings to each other in CSV
		var emailArray=new Array();
		emailArray=origEmailStrCSV.split(",");

		for(e=0;e<emailArray.length;e++) {
			alert("emailArray["+ e + "] is " + emailArray[e]");
			if(emailArray[e]!="" && origEmailStrCSV.toLowerCase().indexOf(emailArray[e].toLowerCase())!=origEmailStrCSV.toLowerCase().lastIndexOf(emailArray[e].toLowerCase())
				return false;
			
		}
**/
	}
	// alert("in isDifferentEmailAddress returning false");
	return valueToReturn; // email string is present in CSV
}

////////////////////////////////////
//
// Function: isUrl()
//
// Description: checks a string for a url
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find a
//          url in the string (http://)
//
// Preconditions: N/A
//
function isUrl (s)
{
  if (isEmptyString(s)) return false;
  return s.match(/https?:\/\/\w{1,}[\.]\w{1,}/i);
}

////////////////////////////////////
//
// Function: isEmptyString()
//
// Description: checks a string for non-whitespace
//              characters
//
// Arguments: s - string - required
//
// Returns: boolean - did the function find a
//          non-whitespace string
//
// Preconditions: N/A
//
function isEmptyString (s)
{
  if (!s) {return true;}
  if (s == "") {return true;}
  if (isBlank(s)) {return true;}
  if (s.length<=0) {return true;}

  return false;
}

////////////////////////////////////
//
// Function: isValidPassword()
//
// Description: check for a valid password
//
// Arguments: s - string - required
//
// Returns: boolean
//
// Preconditions: the 
function isValidPassword (password)
{
 //  alert("in vp");
  return true;
}

////////////////////////////////////
//
// Function: isValidSecondPwd	    //
// Description: compare for string
//
// Arguments: password and confirm Password//
// Returns: boolean - if both match 
//
// Preconditions: N/A //
function isValidSecondPwd (pwd, confirmPwd)
{
	// alert("in v2p");
	if (pwd == confirmPwd)
		return true;
	else 
		return false;
}

/*  ================================================================
    FUNCTION:  isCreditCard(st)
 
    INPUT:     st - a string representing a credit card number

    RETURNS:  true, if the credit card number passes the Luhn Mod-10
		    test.
	      false, otherwise
    ================================================================ */

function isCreditCard(st) {
  // Encoding only works on cards with less than 19 digits
  if (st.length > 19)
    return (false);

  sum = 0; mul = 1; l = st.length;
  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 (mul == 1)
      mul++;
    else
      mul--;
  }
// Uncomment the following line to help create credit card numbers
// 1. Create a dummy number with a 0 as the last digit
// 2. Examine the sum written out
// 3. Replace the last digit with the difference between the sum and
//    the next multiple of 10.

//  document.writeln("<BR>Sum      = ",sum,"<BR>");
//  alert("Sum      = " + sum);

  if ((sum % 10) == 0)
    return (true);
  else
    return (false);

} // END FUNCTION isCreditCard()


/*  ================================================================
    FUNCTION:  isVisa()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid VISA number.
		    
	      false, otherwise

    Sample number: 4111 1111 1111 1111 (16 digits)
    ================================================================ */

function isVisa(cc)
{
  if (((cc.length == 16) || (cc.length == 13)) &&
      (cc.substring(0,1) == 4))
    return isCreditCard(cc);
  return false;
}  // END FUNCTION isVisa()




/*  ================================================================
    FUNCTION:  isMasterCard()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid MasterCard
		    number.
		    
	      false, otherwise

    Sample number: 5500 0000 0000 0004 (16 digits)
    ================================================================ */

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;

} // END FUNCTION isMasterCard()





/*  ================================================================
    FUNCTION:  isAmericanExpress()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid American
		    Express number.
		    
	      false, otherwise

    Sample number: 340000000000009 (15 digits)
    ================================================================ */

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;

} // END FUNCTION isAmericanExpress()



////////////////////////////////////
//
// Function: validateForm()
//
// Description: validates all text elements of
//              a form against their assigned
//              formatting rules
//
// Arguments: f - Form object - required
//
// Returns: boolean - true if no violations detected
//                    false if one or more violations detected
//
// Preconditions: N/A
//
function validateForm(f)
{
// alert("at 1");
  var requiredViolations = "";
  var numericViolations = "";
  var alphanumericViolations = "";
  var dateViolations = "";
  var emailViolations = "";
  var phoneViolations = "";
  var ccViolations="";
  var urlViolations = "";
  var pwdViolations= "";
  var confPwdViolations="";
  var confEmailViolations="";
  var matchViolations="";

  var myPassword = "%$#@";
  var myEmailAddress=""
  var originalMatchObject;
  
  var eNicename;
  var eSize = f.length;
  for (var i = 0; i < eSize; i++) {
    var e = f.elements[i];
    var eValue= e.value;

    if (e.match_original)
    	originalMatchObject = e;	
    else if (e.pwd)
    	myPassword = e.value;	
    else if (e.emailAddress1)
    	myEmailAddress = e.value;	
    
    // check type of field; assume a null type is of type text
    //
// alert("at 2");
    if (!e.type) {
      e.type = "text";
    }
    if ( (e.type == "text")     || 
         (e.type == "textarea") ||
         (e.type == "hidden") ||
         (e.type == "password") ||
	 (e.type == "radio") ||
	 (e.type == "select-one") ||
	 (e.type == "checkbox")) {

// alert("at 3");

	// If e is Select Object
	if (e.type == "select-one")
	   eValue = e.options[e.selectedIndex].value;
	else if ((e.type =="checkbox" || e.type=="radio" || e.multiplevalues) && e.name ) {
		//alert("eval field length is " + eval ("f." + e.name + ".length"));
		//alert("e.type is " + e.type);
		//alert("e.name is " + e.name);
		//alert("e.checked is " + e.checked);
	
		eValue="";
		checkboxCounterObject=eval("f." + e.name);
		eLength=checkboxCounterObject.length

		if(eLength) {
			eNicename=eval("f." + e.name + "[0].nicename")
			
			for (var checkboxCounter=0; checkboxCounter<eLength; checkboxCounter++) {
				if (e.multiplevalues)
					eValue=eValue + eval("f." + e.name + "[" + checkboxCounter + "].value");			
				else if(eval("f." + e.name + "[" + checkboxCounter + "].checked")==true)
					eValue="1";
			}
		}
		else if(e.checked)
			eValue = "1";

		//alert("e.required is " + e.required + " evalue is " + eValue);
	}

	// alert("e.originalEmailAddress is " + e.originalEmailAddress);
	// alert("e.originalEmailAddressCSV is " + e.originalEmailAddressCSV);

      // Must the field have a value; record field name
      // if this rule exists and is violated for this field
      //
      if (e.required && isEmptyString(eValue) ) {
         requiredViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      } 
      // if the field is empty, do not validate it
      //
      else if (isEmptyString(eValue)) {
        continue;
      } 
  
      // Must the field have a numeric value; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.numeric && !isNumeric(eValue) ) {
         numericViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      } 
  
      // Must the field have an alphanumeric value; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.alphanumeric && (!isAlphaNumeric(eValue)) ) {
         alphanumericViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      } 
  
      // Must the field have a valid directory name; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.foldername && (!isFolderName(eValue)) ) {
         alphanumericViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      } 

      // Must the field have an email value; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.emailaddress && (!isEmailAddress(eValue)) ) {
         emailViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      } 

      // Must the field have an email value; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.originalEmailAddressCSV && e.originalEmailAddressCSV!="" && (!isDifferentEmailAddressCSV(eValue,e.originalEmailAddressCSV)) ) {
	// alert("in originalEmailAddressCSV check");
         emailViolations += "\t" + (e.nicename ? e.nicename : e.name) + e.originalEmailAddressMessage + "\n";
      } 

      // Must the field have an now or future value; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.noworfuturedate && (!isNowOrFutureDate(eValue)) ) {
      	 // alert('e.nicename is' + e.nicename);
      	 // alert('e.name is' + e.name);
         dateViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      } 
  
      // Must the datefield have an now or past value; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.enddate && (!isValidStartAndEndDate(e.startdate,eValue,"M/d/yyyy")) ) {
         dateViolations += "\t" + (eNicename ? eNicename : e.name) + ": cannot be before Start Date.\n";
      } 

      // Must the datefield have an minimum verified age restriction; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.minimumage && (!isAgeVerified(eValue,e.minimumagelimit,null)) ) {
         dateViolations += "\t" + (e.nicename ? e.nicename : e.name) + ": You must be at least " + e.minimumagelimit + " years of age to become a member.\n";
      } 

      // Must the field be a valid Visa credit card number
      // if this rule exists and is violated for this field
      //
      else if ( e.isamex && (!isAmericanExpress(eValue)) ) {
         ccViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      } 

      // Must the field be a valid Visa credit card number
      // if this rule exists and is violated for this field
      //
      else if ( e.isvisa && (!isVisa(eValue)) ) {
         ccViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      } 

      // Must the field be a valid Visa credit card number
      // if this rule exists and is violated for this field
      //
      else if ( e.ismc && (!isMasterCard(eValue)) ) {
         ccViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      } 

      // Must the field have a url value; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.url && (!isUrl(eValue)) ) {
         urlViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      } 

      // Must the field have a phone number value; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.phonenumber && (!isPhoneNumber(e)) ) {
         phoneViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      }

      // Must the field have a cell phone number value; record field name
      // if this rule exists and is violated for this field
      //
      else if ( e.cellphonenumber && (!isCellPhoneNumber(e)) ) {
         phoneViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";
      }

      // Must the field have a valid password
      else if (e.pwd && (!isValidPassword(eValue))){
  	  pwdViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";	
	}

      // Must have identical passwords
      else if (e.confirmpwd && (!isValidSecondPwd(myPassword, eValue))){
	  confPwdViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";	
	}

      // Must have identical email addresses
      else if (e.confirmemail && (!isValidSecondPwd(myEmailAddress, eValue))){
	  confEmailViolations += "\t" + (e.nicename ? e.nicename : e.name) + "\n";	
	}

      // Must have identical values
      else if (e.matchValues && originalMatchObject && (!isValidSecondPwd(originalMatchObject.value, eValue))){
	  matchViolations += "\t" + (originalMatchObject.nicename ? originalMatchObject.nicename : originalMatchObject.name) + " : " + (e.nicename ? e.nicename : e.name) + "\n";
	}


    }
    
  } // end for loop 

  // construct error message
  var errors = " ";

  if (!isEmptyString(requiredViolations) ) {
     errors += "- The following fields are required:\n";
     errors += requiredViolations + "\n";
  }

  if (!isEmptyString(numericViolations) ) {
     errors += "- The following fields require numeric input:\n";
     errors += numericViolations + "\n";
  }

  if (!isEmptyString(alphanumericViolations) ) {
     errors += "- The following fields require alpha-numeric input:\n";
     errors += alphanumericViolations + "\n";
  }

  if (!isEmptyString(dateViolations) ) {
     errors += "- The following fields require a proper date:\n";
     errors += dateViolations + "\n";
  }

  if (!isEmptyString(emailViolations) ) {
     errors += "- The following fields require a valid email address:\n";
     errors += emailViolations + "\n";
  }

  if (!isEmptyString(ccViolations) ) {
     errors += "- The following fields require a valid credit card information:\n";
     errors += ccViolations + "\n";
  }

  if (!isEmptyString(urlViolations) ) {
     errors += "- The following fields require a valid url:\n";
     errors += urlViolations + "\n";
  }

  if (!isEmptyString(phoneViolations) ) {
     errors += "- The following fields require a valid phone number:\n";
     errors += (phoneViolations + "\n");
  }

  // Password
  if (!isEmptyString(pwdViolations) ) {
     errors += "- Password should be at least 4 characters\n  and only contain numbers and/or letters.\n";
     //errors += (pwdViolations + "\n");
  }

  // Confirm Password
  if (!isEmptyString(confPwdViolations) ) {
     errors += "- Confirm Password does not match with Password.\n";
     //errors += (confPwdViolations + "\n");
  }

  // Confirm E-mail
  if (!isEmptyString(confEmailViolations) ) {
     errors += "- Confirm E-mail does not match with E-mail.\n";
     //errors += (confEmailViolations + "\n");
  }

  // Confirm Equal Strings
  if (!isEmptyString(matchViolations) ) {
     errors += "- The following fields require an exact match:\n";
     errors += (matchViolations + "\n");
  }




  if (errors == " ") {
    // *** The following added by KG 2-1-2000
    // Prepare text inputs for storage
    for (var i = 0; i < eSize; i++) {
      var e = f.elements[i];
      if (eValue == null) continue;
      if (eValue.length == 0) continue;
      if ( (e.type == "text")     || 
           (e.type == "textarea") ) {
        e.value = trimString(e.value);
        if (e.dbquote)
          e.value = dbquote(e.value);
      }
    }
    // *** end KG add 2-1-2000
    return true;
  }
  else {
    // generate dialog box
    displayErrorMessage(errors);
    return false;
  }

}

////////////////////////////////////
//
// Function: displayErrorMessage()
//
// Description: displays an error message appropriate
//              for communicating input violations
//              produced by the user
//
// Arguments: msg - string - required
//
// Returns: N/A
//
// Preconditions: N/A
//
function displayErrorMessage(msg)
{
  var errorMsg;
  errorMsg  = "______________________________________________________\n\n";
  errorMsg += "The form was not submitted because of the following error(s).\n";
  errorMsg += "Please correct these error(s) and re-submit.\n";
  errorMsg += "______________________________________________________\n\n";
  errorMsg += msg;

  alert(errorMsg);
}

//////////////////////////////////////
//
// Function: validateDate()
//
// Author: Kurt Gabrick
//
// Description: For use with the startup (server-side)
//		function dateFields() (see /include/sdc_pageUtils.js)
//		This function ensures that either a valid date (MM/DD/YYYY) 
//		or a blank date is maintained in the hidden field created by dateFields().
//		It also maintains the state of the date controls seen by the
//		client. No one should need to explicity call this method.
//
// Arguments:
//		f - <object reference> - the form on which the date controls exist
//		ctrlField - <object reference> - the control causing the function call
//		dateField - <object reference> - the hidden date field of interest
//
// Returns: N/A
//
// Preconditions: No params can be null
//
function validateDate(f, ctrlField, dateField, month, day, year) {

  monthSelected = month.selectedIndex;
  daySelected   = day.selectedIndex;
  yearSelected  = year.selectedIndex;

  // support for blanking out the fields after editing
  // -------------------------------------------------
  if ((ctrlField == month) && (ctrlField.selectedIndex == 0) && ((day.selectedIndex != 0) || (year.selectedIndex != 0)) ) {
    day.selectedIndex = 0;
    year.selectedIndex = 0;
    dateField.value = "";
    return;
  } else if ((ctrlField == day) && (ctrlField.selectedIndex == 0) && ((month.selectedIndex != 0) || (year.selectedIndex != 0)) ) {
    month.selectedIndex = 0;
    year.selectedIndex = 0;
    dateField.value = "";
    return;
  } else if ((ctrlField == year) && (ctrlField.selectedIndex == 0) && ((day.selectedIndex != 0) || (month.selectedIndex != 0)) ) {
    day.selectedIndex = 0;
    month.selectedIndex = 0;
    dateField.value = "";
    return;
  }

  if (monthSelected > 0) {
    if (daySelected == 0) day.selectedIndex = 1; 	// set to 1st of month
    else { 
      switch (monthSelected) {
        case 2:
          if (daySelected == 29) {	
            if ( (yearSelected == 0) || 
                 ((year.options[yearSelected].value % 4) != 0) ||
                 ( ((year.options[yearSelected].value % 100) == 0) && ((year.options[yearSelected].value % 400) != 0) )
            ) {
              // find the first leap year in the year list
	      var firstLeapYear = -1;
              for (i = 1; i < year.options.length; i++) {
                currYr = year.options[i].value;
                if ((currYr % 4) == 0) 
                  firstLeapYear = i;
		  break;
              }
              // assign first leap year in list or set day to 28
              if (firstLeapYear > 0)
                year.selectedIndex = firstLeapYear;
              else 
                day.selectedIndex = 28; 
            }
          } else if (daySelected > 28) day.selectedIndex = 28;
          break;
	case 4:
	case 6:
	case 9:
	case 11:
	  if (daySelected > 30) day.selectedIndex = 30;
          break;
      } 
    }
    if (year.selectedIndex == 0) year.selectedIndex = 1;
  } else if (daySelected > 0) {
    month.selectedIndex = 1;
    year.selectedIndex = 1;
  } else if (yearSelected > 0) {
    month.selectedIndex = 1;
    day.selectedIndex = 1;
  } else {
    dateField.value = "";
  }

  // now, write the date to the hidden field
  // ---------------------------------------
  var validDate = month.options[month.selectedIndex].value;
  validDate += "/";
  validDate += day.options[day.selectedIndex].value;
  validDate += "/";
  validDate += year.options[year.selectedIndex].value;
//  alert("Writing validDate: " + validDate);
  dateField.value = validDate; 

}

////////////////////////////////////
//
// Function: dbquote()
//
// Description: escapes all single quotes within a string
//
// Arguments: s   - string - required
//
// Returns: string
//
// Preconditions: N/A
//
function dbquote(s) {
  return s.replace(/'/g,"''");
}

////////////////////////////////////
//
// Function: trimStringLeft()
//
// Description: removes leading whitespaces from a string
//
// Arguments: s   - string - required
//
// Returns: string
//
// Preconditions: N/A
//
function trimStringLeft(s) {
 return ((typeof(s) != "string") ? s : s.replace(/^\s+/, ""));
}

////////////////////////////////////
//
// Function: trimStringRight()
//
// Description: removes trailing whitespaces from a string
//
// Arguments: s   - string - required
//
// Returns: string
//
// Preconditions: N/A
//
function trimStringRight(s) {
  return ((typeof(s) != "string") ? s : s.replace(/\s+$/, ""));
}

////////////////////////////////////
//
// Function: trimString()
//
// Description: removes leading and trailing whitespaces from a string
//
// Arguments: s   - string - required
//
// Returns: string
//
// Preconditions: N/A
//
function trimString(s) {
  return trimStringRight(trimStringLeft(s));
}

/////////////////////////////////////////////////////////////
//
// Function: checkTextAreaLength()
//
// Description: Checks the maximum length of a textarea
//              control and sets the text area to the
//              maximum character count - 2 so when the
//              character is inserted, the string at the
//              maximum length. For use with the 
//              onKeyUp and or onChange event of a
//              text area control. onChange only fires
//              when the text is committed but
//              onKeyUp works when the user is typing.
//              onChange seems to work well if the user
//              cuts and pastes text into the control.
//
// Arguments: control - a textarea control object that
//                      you want to check
//            maxlen - the maximum allowable number of
//                     characters.
//
// Return value: N/A
//
// Preconditions: N/A
//
function checkTextAreaLength(control, maxlen)
{
  if ( control.value.length >= maxlen )
  {
    alert("You have reached the maximum limit this input box can handle.");
    control.value = control.value.substr(0, maxlen - 2);
  }
}
