/*
author:Neocode
version Date:8/26/2002
about validate function:
Can handle validation of multiple forms on page.
USAGE: return validate(form,number)
WHERE form is either the name of the form or the keyword 'this' if if used inside the onsubmit handler of the form
and number is a reference number for that form. Tha number must be used to define the fields validation in the forms array.
DECLARATION OF FORMS ARRAY:
USAGE:
forms(number)=new Array(); 
forms(number)[0]="fieldname1[_req][;message][-validation]";
forms(number)[1]="fieldname2[_req][;message][-validation]";
.....
or could also be declared in one single line per form separating the elements by a comma:
forms(number)=new Array("fieldname1[_req][-validation][;message],fieldname2[_req][-validation][;message],...";
examples:
1-)
	forms1=new Array();
	forms1[0]="date3_req-date";
	forms1[1]="date4-date";
	forms1[2]="FirstName;Please Enter First Name";
	forms1[3]="phone-phone";
	forms2=new Array();
	forms2[0]="date5_req-date";
	forms2[1]="date6_req-date";
	forms2[2]="City;Please Enter Name of City";
	forms2[3]="CCN-cardnumber";
	forms2[4]="cctype-cardtype";
2-)
	forms1=new Array("date3_req-date","date4-date","FirstName;Please Enter First Name","phone-phone");
	forms2=new Array("date5_req-date","date6_req-date","City;Please Enter Name of City","CCN-cardnumber","cctype-cardtype");

Notes:
*If no message is specified the default for the type of validation will be shown
*If the fieldname is followed by _req the validation is required.
*On fields that has no validation type the validation is not empty and fieldname should not be followed by _req. The message parameter only works for this type of fields.
VALIDATION TYPES AVAILABLE IN THIS VERSION:phone,zip,cardnumber,cardtype,date,email

*/

var arrValidate = new Array();
var arrNames = new Array();
var doneCC=false;
var pp="";
//for (f=1;f<10;f++){
//  var thisform="forms"+f;
//  eval (thisform+"=''");
//}

var arrvalidations=new Array("-date","-email","-zip","-phone","-cardnumber","-password","-psswd","-cardtype");

function getval(str){
  //alert(str)
  var v="";
  for(z=0;z<arrvalidations.length;z++){
    if(str.indexOf(arrvalidations[z])>-1){v=arrvalidations[z].substring(1,arrvalidations[z].length);break;}
  }
  return v;
}

function vf(strparams){
	//alert(strparams);
	arrBad=new Array();
    arrBadM=new Array();
	var arrForm=strparams.split(",");
	var thisform=eval("document."+arrForm[0]);
	frmname=thisform.name;
	var thisfield="";
	var thisvalidation="";
	var thismessage="";
	var fldName="";
	for (i=1;i<arrForm.length;i++){
	  thisfield=(arrForm[i].indexOf("-") > -1)?arrForm[i].substring(0,arrForm[i].indexOf("-")):arrForm[i];
	  thisfield=(arrForm[i].indexOf(";") > -1)?thisfield.substring(0,arrForm[i].indexOf(";")):thisfield;
	  /*
	  if (arrForm[i].indexOf(";")){
	  	thisvalidation=(arrForm[i].indexOf("-") > -1)?arrForm[i].substring(arrForm[i].indexOf("-")+1,arrForm[i].indexOf(";")):"";
	  }else{
	    //alert(thisfield);
	  	thisvalidation=(arrForm[i].indexOf("-") > -1)?arrForm[i].substring(arrForm[i].indexOf("-")+1,arrForm[i].length):"";
	  }
	  */
	  thisvalidation=getval(arrForm[i]);
	  thismessage=(arrForm[i].indexOf(";") > -1)?arrForm[i].substring(arrForm[i].indexOf(";")+1,arrForm[i].length):"";
	  //alert(thismessage);
	  //alert("val: "+thisvalidation+" field:"+thisfield);
	  if(thisvalidation=="psswd"){pp=thisfield;}
	  if(doneCC==false){
	  	if(thisvalidation=="cardtype"){cardtype=thisfield;doneCC=true;}else{cardtype=null}
	  }
	  //alert(thisvalidation);
	  
	  if(thisfield.indexOf("_req")> -1){
	    fldName=thisfield.substring(0,thisfield.indexOf("_req"));
		objField=eval("document."+frmname+"."+fldName);
		doSubReq(objField,thisvalidation,thismessage);
	  }else{
	    fldName=thisfield;
		objField=eval("document."+frmname+"."+fldName);
		doSubNReq(objField,thisvalidation,thismessage);
	  }
	}
	
	if(cardtype != null){
    var CCyear=thisform.elements["CCexpyear"];
    var CCmonth=thisform.elements["CCexpmonth"];
    var CCyearValue=CCyear.options[CCyear.options.selectedIndex].value;
    var CCmonthValue=CCmonth.options[CCmonth.options.selectedIndex].value;
    var bool=validateExpiry(CCyearValue,CCmonthValue);
    if(!bool){arrBad[arrBad.length]="Credit Card Expiration";arrBadM[arrBadM.length]="(Card Expired)";}
  }
	
	var output=getoutput();
	return output;
}


function getoutput(){
  //alert(arrBad.length);
  if(arrBad.length>0){
    str="";
    for (i=0;i<arrBad.length;i++){
      str+=arrBad[i]+" "+arrBadM[i]+"\n";
	}
	alert("Revise the following fields:\n"+str);
	return false;
  }
  return true;
}



function doSubReq(theField,validation,m){
  //alert("requiered field:"+theField.name + " validation:"+validation );
  //alert(m);
  if((theField.length)&&(theField[0].type != undefined)){
  	if(theField[0].type=="radio"){
	  for(z=0;z<theField.length;z++){
	    if(theField[z].checked){var thisValue=theField[z].value;break}
	  }
	}
  }else{
  	var thisValue=theField.value;
  }
  var thismsg="";
  thismsg=(m!="")?m:theField.name;
  var bool=(thisValue=="" || thisValue== null)?true:false;
  if (bool){arrBad[arrBad.length]=thismsg;arrBadM[arrBadM.length]="(Empty)";return;
  }else{
    //alert("not Empty, now check if valid");
	var bool=isValid(thisValue,validation,theField);
	if(!bool){
	  arrBad[arrBad.length]=thismsg;
	  //arrBad[arrBad.length]=arrNames[theElem];
	  arrBadM[arrBadM.length]="(Wrong Entry)";
	}
	return;
  }
  return;
}


function doSubNReq(theField,validation,m){
  //alert("Not Req field:"+theField.name + " validation:"+validation );
  //alert(m);
  if((theField.length)&&(theField[0].type != undefined)){
  	if(theField[0].type=="radio"){
	  for(z=0;z<theField.length;z++){
	    if(theField[z].checked){var thisValue=theField[z].value;break}
	  }
	}
  }else{
  	var thisValue=theField.value;
  }
  var thismsg="";
  thismsg=(m!="")?m:theField.name;
  var bool=(thisValue=="" || thisValue== null)?true:false;
  if (!bool){
    //alert("check if valid");
	var isV=isValid(thisValue,validation,theField);
	if (!isV){
	  arrBad[arrBad.length]=thismsg;
	  //arrBad[arrBad.length]=arrNames[theElem];
	  arrBadM[arrBadM.length]="(Wrong Entry)";
	}
	return;
  }
  return;
}


function isValid(fieldValue,valType,fld){
  var bool=false;
  //alert(fieldValue+" \nvalidation:"+valType);
  switch (valType)
  {
  case "zip":
    bool=validateUSZip(fieldValue);
	break;
  case "phone":
    bool=validateUSPhone(fieldValue);
    break;
  case "email":
    bool=validateEmail(fieldValue);
	break;
  case "date":
    bool=validateUSDate(fieldValue);
	break;
  case "password":
    var thepass2=eval("document.theForm."+pp+".value");
	//alert(fieldValue+"::"+thepass2)
	bool=validatePassword(fieldValue,thepass2);
	break;
  case "cardnumber":
	//alert(fieldValue);
	//alert(fld);
	CrdType=eval("document."+frmname+"."+cardtype+".value");
	//CrdType=document.theForm.CCtype.value;
	//alert(CrdType);
	bool=isCardMatch(CrdType,fieldValue);
	break;
  default:
    bool=validateNotEmpty(fieldValue);
	break;
  }
  return bool;
}

function getCType(FName){
  var thisvalue=eval("thisForm.elements['"+FName+"'].value");
  return thisvalue;
}


function validateUSZip( strValue ) {
/************************************************
DESCRIPTION: Validates that a string a United
  States zip code in 5 digit format or zip+4
  format. 99999 or 99999-9999
    
PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.

*************************************************/
var objRegExp  = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
 
  //check for valid US Zipcode
  return objRegExp.test(strValue);
}


function validateUSPhone( strValue ) {
/************************************************
DESCRIPTION: Validates that a string contains valid
  US phone pattern. 
  Ex. (999) 999-9999 or (999)999-9999
  
PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
*************************************************/
  var objRegExp  = /^[1-9]\d{2}\-\d{3}\-\d{4}$/;
 
  //check for valid us phone with or without space between 
  //area code
  return objRegExp.test(strValue); 
}


function validateEmail( strValue) {
/************************************************
DESCRIPTION: Validates that a string contains a 
  valid email pattern. 
  
 PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
   
REMARKS: Accounts for email with country appended
  does not validate that email contains valid URL
  type (.com, .gov, etc.) and optionally,
  a valid country suffix.  Since email has many
  forms this expression only tests for near valid
  address.  Some additional validation may be
  required.
*************************************************/
var objRegExp  = /^[a-z0-9]([a-z0-9_\-\.]*)@([a-z0-9_\-\.]*)(\.[a-z]{2,3}(\.[a-z]{2}){0,2})$/i;
  //check for valid email
  return objRegExp.test(strValue);
}



function validateUSDate( strValue ) {
/************************************************
DESCRIPTION: Validates that a string contains only 
    valid dates with 2 digit month, 2 digit day, 
    4 digit year. Date separator can be ., -, or /.
    Uses combination of regular expressions and 
    string parsing to validate date.
    Ex. mm/dd/yyyy or mm-dd-yyyy or mm.dd.yyyy
    
PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
   
REMARKS:
   Avoids some of the limitations of the Date.parse()
   method such as the date separator character.
*************************************************/
  var objRegExp = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/
 
  //check to see if in correct format
  if(!objRegExp.test(strValue))
    return false; //doesn't match pattern, bad date
  else{
    var arrayDate = strValue.split(RegExp.$1); //split date into month, day, year
	var intDay = parseInt(arrayDate[1],10); 
	var intYear = parseInt(arrayDate[2],10);
    var intMonth = parseInt(arrayDate[0],10);
	
	//check for valid month
	if(intMonth > 12 || intMonth < 1) {
		return false;
	}
	
    //create a lookup for months not equal to Feb.
    var arrayLookup = { '01' : 31,'03' : 31, '04' : 30,'05' : 31,'06' : 30,'07' : 31,
                        '08' : 31,'09' : 30,'10' : 31,'11' : 30,'12' : 31}
  
    //check if month value and day value agree
    if(arrayLookup[arrayDate[0]] != null) {
      if(intDay <= arrayLookup[arrayDate[0]] && intDay != 0)
        return true; //found in lookup table, good date
    }
		
    //check for February
	var booLeapYear = (intYear % 4 == 0 && (intYear % 100 != 0 || intYear % 400 == 0));
    if( ((booLeapYear && intDay <= 29) || (!booLeapYear && intDay <=28)) && intDay !=0)
      return true; //Feb. had valid number of days
  }
  return false; //any other values, bad date
}


function getRadioButtonValue (radio)
{   for (var i = 0; i < radio.length; i++)
    {   if (radio[i].checked) { break }
    }
    return radio[i].value
}

/*  ================================================================
    FUNCTION:  isCardMatch()
 
    INPUT:    cardType - a string representing the credit card type
	      cardNumber - a string representing a credit card number

    RETURNS:  true, if the credit card number is valid for the particular
	      credit card type given in "cardType".
		    
	      false, otherwise
    ================================================================ */

function isCardMatch (cardType, cardNumber){
  if (cardType==null){return false;}
    if (cardType != ""){
      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;
	if ((cardType == "JCB") && (!isJCB(cardNumber)))
		doesMatch = false;
	if ((cardType == "DINERS") && (!isDinersClub(cardNumber)))
		doesMatch = false;
	if ((cardType == "CARTEBLANCHE") && (!isCarteBlanche(cardNumber)))
		doesMatch = false;
	if ((cardType == "ENROUTE") && (!isEnRoute(cardNumber)))
		doesMatch = false;
	if ((cardType=="") || (cardType==null))
	    doesMatch = false;
	return doesMatch;
}  
// END FUNCTION CardMatch()
/*  ================================================================
    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:  isDinersClub()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid Diner's
		    Club number.
		    
	      false, otherwise

    Sample number: 30000000000004 (14 digits)
    ================================================================ */

function isDinersClub(cc)
{
  firstdig = cc.substring(0,1);
  seconddig = cc.substring(1,2);
  if ((cc.length == 14) && (firstdig == 3) &&
      ((seconddig == 0) || (seconddig == 6) || (seconddig == 8)))
    return isCreditCard(cc);
  return false;
}



/*  ================================================================
    FUNCTION:  isCarteBlanche()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid Carte
		    Blanche number.
		    
	      false, otherwise
    ================================================================ */

function isCarteBlanche(cc)
{
  return isDinersClub(cc);
}




/*  ================================================================
    FUNCTION:  isDiscover()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid Discover
		    card number.
		    
	      false, otherwise

    Sample number: 6011000000000004 (16 digits)
    ================================================================ */

function isDiscover(cc)
{
  first4digs = cc.substring(0,4);
  if ((cc.length == 16) && (first4digs == "6011"))
    return isCreditCard(cc);
  return false;

} // END FUNCTION isDiscover()





/*  ================================================================
    FUNCTION:  isEnRoute()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid enRoute
		    card number.
		    
	      false, otherwise

    Sample number: 201400000000009 (15 digits)
    ================================================================ */

function isEnRoute(cc)
{
  first4digs = cc.substring(0,4);
  if ((cc.length == 15) &&
      ((first4digs == "2014") ||
       (first4digs == "2149")))
    return isCreditCard(cc);
  return false;
}



/*  ================================================================
    FUNCTION:  isJCB()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid JCB
		    card number.
		    
	      false, otherwise
    ================================================================ */

function isJCB(cc)
{
  first4digs = cc.substring(0,4);
  if ((cc.length == 16) &&
      ((first4digs == "3088") ||
       (first4digs == "3096") ||
       (first4digs == "3112") ||
       (first4digs == "3158") ||
       (first4digs == "3337") ||
       (first4digs == "3528")))
    return isCreditCard(cc);
  return false;

} // END FUNCTION isJCB()


/*  ================================================================
    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);

}


/*************************************************************************\
boolean isExpiryDate([int year, int month])
return true if the date is a valid expiry date,
else return false.
\*************************************************************************/
function validateExpiry(year,month) {

if (!isNum(year+""))
return false;
if (!isNum(month+""))
return false;
today = new Date();
expiry = new Date(year, month);
if (today.getTime() > expiry.getTime())
return false;
else
return true;
}

/*************************************************************************\
boolean isNum(String argvalue)
return true if argvalue contains only numeric characters,
else return false.
\*************************************************************************/
function isNum(argvalue) {
argvalue = argvalue.toString();

if (argvalue.length == 0)
return false;

for (var n = 0; n < argvalue.length; n++)
if (argvalue.substring(n, n+1) < "0" || argvalue.substring(n, n+1) > "9")
return false;

return true;
}

 // END FUNCTION isCreditCard()


//Check Empty functions start here

function validateNotEmpty( strValue ) {
   var strTemp = strValue; 
   strTemp = trimAll(strTemp);
   if(strTemp.length > 0){
     return true;
   }  
   return false;
}

function trimAll( strValue ) {
 var objRegExp = /^(\s*)$/;

    //check for all spaces
    if(objRegExp.test(strValue)) {
       strValue = strValue.replace(objRegExp, '');
       if( strValue.length == 0)
          return strValue;
    }
    
   //check for leading & trailing spaces
   objRegExp = /^(\s*)([\W\w]*)(\b\s*$)/;
   if(objRegExp.test(strValue)) {
       //remove leading and trailing whitespace characters
       strValue = strValue.replace(objRegExp, '$2');
    }
  return strValue;
}
//Check Empty functions End here

function validatePassword(val1,val2){
  if (val1 != val2){alert("Passwords don't Match");return false}else{
  return true;}
}

function validate(obj,which){
    thisform="forms"+which;
	if(eval(thisform)!=""){
	  thislength=eval("forms"+which+".length");
	  jsstr=obj.name+",";
	  for (k=0;k<thislength;k++){
	    data=eval("forms"+which+"["+k+"]");
		jsstr+=data;
		if(k != thislength-1){
		  jsstr+=",";
		}
      }
	  //alert(jsstr);
	  //testform=eval("jsValidate("+jsstr+")");
	  var testform=vf(jsstr);
	  if (testform){return true}
	  return false;
    
  }
}

function IsDigit()
{
  return ((event.keyCode >= 48) && (event.keyCode <= 57))
}
