function Validator(frmname)
{
  this.formobj=document.forms[frmname];
	if(!this.formobj)
	{
	  alert("BUG: could not get Form object "+frmname);
		return;
	}
	if(this.formobj.onsubmit)
	{
	 this.formobj.old_onsubmit = this.formobj.onsubmit;
	 this.formobj.onsubmit=null;
	}
	else
	{
	 this.formobj.old_onsubmit = null;
	}
	this.formobj.onsubmit=form_submit_handler;	
	this.addValidation = add_validation;
	this.setAddnlValidationFunction=set_addnl_vfunction;
	this.clearAllValidations = clear_all_validations;
}

function set_addnl_vfunction(functionname)
{
  this.formobj.addnlvalidation = functionname;
}
function clear_all_validations()
{
	for(var itr=0;itr < this.formobj.elements.length;itr++)
	{
		this.formobj.elements[itr].validationset = null;
	}
}
function form_submit_handler()
{
	for(var itr=0;itr < this.elements.length;itr++)
	{
		if(this.elements[itr].validationset &&
	   !this.elements[itr].validationset.validate())
		{
		  return false;
		}
	}
	if(this.addnlvalidation)
	{
	  str =" var ret = "+this.addnlvalidation+"()";
	  eval(str);
    if(!ret) return ret;
	}
	return true;
}

function add_validation(itemname,descriptor,errstr)
{
  if(!this.formobj)
	{
	  alert("BUG: the form object is not set properly");
		return;
	}//if
	var itemobj = this.formobj[itemname];
  if(!itemobj)
	{
	  alert("BUG: Could not get the input object named: "+itemname);
		return;
	}
		
	if(!itemobj.validationset)
	{
	  itemobj.validationset = new ValidationSet(itemobj);
	}
  itemobj.validationset.add(descriptor,errstr);
}

function ValidationDesc(inputitem,desc,error)
{
	this.desc=desc;
	this.error=error;
	this.itemobj = inputitem;
	this.validate=vdesc_validate;
}

function vdesc_validate()
{
	if(!ValidateData(this.desc,this.itemobj,this.error))
	{
		this.itemobj.focus();
		return false;
	}
	return true;
}

function ValidationSet(inputitem)
{
	this.vSet=new Array();
	this.add= add_validationdesc;
	this.validate= vset_validate;
	this.itemobj = inputitem;
}

function add_validationdesc(desc,error)
{
	this.vSet[this.vSet.length]= 
	new ValidationDesc(this.itemobj,desc,error);
}

function vset_validate()
{
	for(var itr=0;itr<this.vSet.length;itr++)
	{
		if(!this.vSet[itr].validate())
		{
			return false;
		}
	}
	return true;
}

function validateEmailv2(email)
{
	// simple email validation checking. 
	if(email.length <= 0)
	{
		return true;
	}
	var splitted = email.match("^(.+)@(.+)$");
	if(splitted == null) return false;
	if(splitted[1] != null )
	{
		var regexp_user=/^\"?[\w-_\.]*\"?$/;
		if(splitted[1].match(regexp_user) == null) return false;
	}
	if(splitted[2] != null)
	{
		var regexp_domain=/^[\w-\.]*\.[A-Za-z]{2,4}$/;
		if(splitted[2].match(regexp_domain) == null) 
		{
			var regexp_ip =/^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/;
			if(splitted[2].match(regexp_ip) == null) return false;
		}// if
		return true;
    }
	return false;
}

function ValidateData(strValidateStr,objValue,strError, ErrOut) 
{ 
	var epos = strValidateStr.search("="); 
	var  command  = ""; 
	var  cmdvalue = ""; 	
	if(epos >= 0) 
	{ 
		command  = strValidateStr.substring(0,epos); 
		cmdvalue = strValidateStr.substr(epos+1); 		
	} 
    else 
    { 
		command = strValidateStr; 
    } 
    var objValue = document.getElementById(objValue);        
    if (objValue.type == "text")
    {
		objValue.value = TrimAll(objValue.value);
	}
    objValue.focus();
    
    if (ErrOut != null)
    {
        var ErrOutput = document.getElementById(ErrOut);         
        if (ErrOutput!=null && ErrOutput.tagName != "DIV" && ErrOutput.tagName != "SPAN")
        {
            ErrOutput == null;
        }
        else
        {
            ErrOutput.className = "ERROR";
        }
    }
    switch(command) 
    { 		
		case "req": 
		case "required": 
		{ 						
			if ((objValue.type == "checkbox" || objValue.type == "radio" ) && objValue.checked == false)
			{
				if(!strError || strError.length ==0) 
				{ 
				strError = objValue.id + " : is a required field"; 
				}//if
				if(ErrOutput == null)
				{   alert(strError);    }
				else
				{   ErrOutput.innerText = strError; }
				return false; 				
			}
			else
			{				
				if(eval(objValue.value.length) == 0) 
				{ 
					if(!strError || strError.length ==0) 
					{ 
						strError = objValue.id + " : is a required field"; 
					}//if 
				    if(ErrOutput == null)
				    {   alert(strError);    }
				    else
				    {   ErrOutput.innerText = strError; }
					return false; 
				}//if 
			}//else
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
			break;             
		}//case required 
		
        case "maxlength": 
        case "maxlen": 
		{ 
			if(eval(objValue.value.length) >  eval(cmdvalue)) 
			{ 
				if(!strError || strError.length ==0) 
				{ 
					strError = objValue.id + " : "+cmdvalue+" characters maximum "; 
				}//if 
			    if(ErrOutput == null)
			    {   alert(strError + "\n[Current length = " + objValue.value.length + " ]");   }
			    else
			    {   ErrOutput.innerText = strError + "\n[Current length = " + objValue.value.length + " ]"; }								
				return false; 
             }//if 
             break; 
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}             
		}//case maxlen 
          
		case "minlength": 
        case "minlen": 
		{ 
			if(eval(objValue.value.length) <  eval(cmdvalue)) 
			{ 
				if(!strError || strError.length ==0) 
				{ 
					strError = objValue.id + " : " + cmdvalue + " characters minimum  "; 
				}//if               
			    if(ErrOutput == null)
			    {   alert(strError + "\n[Current length = " + objValue.value.length + " ]");    }
			    else
			    {   ErrOutput.innerText = strError + "\n[Current length = " + objValue.value.length + " ]"; }				
				return false;                 
			}//if 
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}			
			break; 
		}//case minlen 
		
        case "alnum": 
        case "alphanumeric": 
		{ 
			var charpos = objValue.value.search("[^A-Za-z0-9]"); 
			if(objValue.value.length > 0 &&  charpos >= 0) 
			{ 
				if(!strError || strError.length ==0) 
				{ 
					strError = objValue.id+": Only alpha-numeric characters allowed "; 
				}//if 
			    if(ErrOutput == null)
			    {   alert(strError + "\n [Error character position " + eval(charpos+1)+"]");    }
			    else
			    {   ErrOutput.innerText = strError + "\n [Error character position " + eval(charpos+1)+"]"; }				
				return false; 
			}//if 
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}			
			break; 
		}//case alphanumeric 
		
        case "num": 
        case "numeric": 
		{ 
			var charpos = objValue.value.search("[^0-9]"); 
			if(objValue.value.length > 0 &&  charpos >= 0) 
			{ 
				if(!strError || strError.length ==0) 
				{ 
					strError = objValue.id+": Only digits allowed "; 
				}//if    
			    if(ErrOutput == null)
			    {   alert(strError + "\n [Error character position " + eval(charpos+1)+"]");     }
			    else
			    {
			       ErrOutput.innerText = strError ;
			    }
			    //+ "\n [Error character position " + eval(charpos+1)+"]"; }				           				
				return false; 
			}//if 
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}			
			break;               
		}//numeric 
		
        case "alphabetic": 
        case "alpha": 
		{ 
			var charpos = objValue.value.search("[^A-Za-z]"); 
			if(objValue.value.length > 0 &&  charpos >= 0) 
			{ 
				if(!strError || strError.length ==0) 
				{ 
					strError = objValue.id+": Only alphabetic characters allowed "; 
                }//if                             
			    if(ErrOutput == null)
			    {   alert(strError + "\n [Error character position " + eval(charpos+1)+"]");      }
			    else
			    {   ErrOutput.innerText = strError + "\n [Error character position " + eval(charpos+1)+"]"; }				           								
				return false; 
			}//if 
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
			break; 
		}//alpha 
		
		case "alnumhyphen":
		{
			var charpos = objValue.value.search("[^A-Za-z0-9\-_]"); 
			if(objValue.value.length > 0 &&  charpos >= 0) 
			{ 
				if(!strError || strError.length ==0) 
				{ 
					strError = objValue.id+": characters allowed are A-Z,a-z,0-9,- and _"; 
				}//if                             
			    if(ErrOutput == null)
			    {   alert(strError + "\n [Error character position " + eval(charpos+1)+"]");    }
			    else
			    {   ErrOutput.innerText = strError + "\n [Error character position " + eval(charpos+1)+"]"; }
				return false; 
			}//if 			
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
			break;
		}//alnumhyphen
		
		case "email": 
		{ 
			if(!validateEmailv2(objValue.value)) 
			{ 
				if(!strError || strError.length ==0) 
				{ 
					strError = objValue.id+": Enter a valid Email address "; 
				}//if                                               
			    if(ErrOutput == null)
			    {   alert(strError);    }
			    else
			    {   ErrOutput.innerText = strError; }				
				return false; 
			}//if 
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
			break; 
		}//case email 
		
        case "lt": 
        case "lessthan": 
		{ 
			if(isNaN(objValue.value)) 
			{ 
			    if(ErrOutput == null)
			    {   alert(objValue.id+": Should be a number ");     }
			    else
			    {   ErrOutput.innerText = objValue.id+": Should be a number "; }								
				return false; 
			}//if 
            if(eval(objValue.value) >=  eval(cmdvalue)) 
            { 
				if(!strError || strError.length ==0) 
				{ 
					strError = objValue.id + " : value should be less than "+ cmdvalue; 
				}//if
			    if(ErrOutput == null)
			    {   alert(strError);    }
			    else
			    {   ErrOutput.innerText = strError; }				
				return false;                 
			}//if             
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
            break; 
		}//case lessthan 
         
        case "gt": 
        case "greaterthan": 
		{ 
			if(isNaN(objValue.value)) 
			{ 
			    if(ErrOutput == null)
			    {   alert(objValue.id+": Should be a number ");    }
			    else
			    {   ErrOutput.innerText = objValue.id+": Should be a number "; }				
				return false; 
            }//if 
			if(eval(objValue.value) <=  eval(cmdvalue)) 
			{ 
				if(!strError || strError.length ==0) 
				{ 
					strError = objValue.id + " : value should be greater than "+ cmdvalue; 
				}//if               
			    if(ErrOutput == null)
			    {   alert(strError);    }
			    else
			    {   ErrOutput.innerText = strError; }				
				return false;                 
			}//if             
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
			break; 
		}//case greaterthan 
		
        case "regexp": 
		{ 
			if(objValue.value.length > 0)
			{
				if(!objValue.value.match(cmdvalue)) 
				{ 
					if(!strError || strError.length ==0) 
					{ 
						strError = objValue.id+": Invalid characters found "; 
					}//if                                                               
			        if(ErrOutput == null)
			        {   alert(strError);    }
			        else
			        {   ErrOutput.innerText = strError; }				
					return false;                   
				}//if 
			}
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
			break; 
		}//case regexp 
		
        case "dontselect": 
		{ 
			if(objValue.selectedIndex == null) 
			{ 
			    if(ErrOutput == null)
			    {   alert("BUG: dontselect command for non-select Item");     }
			    else
			    {   ErrOutput.innerText = "BUG: dontselect command for non-select Item"; }								
				return false; 
			} 
			if(objValue.selectedIndex == eval(cmdvalue)) 
			{ 
				if(!strError || strError.length ==0) 
				{ 
					strError = objValue.id+": Please Select one option "; 
				}//if                                                               
			    if(ErrOutput == null)
			    {   alert(strError);    }
			    else
			    {   ErrOutput.innerText = strError; }				
				return false;                                   
			} 
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
            break; 
		}//case dontselect 
		
        case "ssn":
        {	
			if (objValue.value.length > 0 )
			{			           
				var matchArr = objValue.value.match(/^(\d{3})-?\d{2}-?\d{4}$/);
				var numDashes = objValue.value.split('-').length - 1;
				if (matchArr == null || numDashes == 1) 
				{
			        if(ErrOutput == null)
			        {   alert("Invalid SSN. Must be 9 digits or in the form NNN-NN-NNNN.");    }
			        else
			        {   ErrOutput.innerText = "Invalid SSN. Must be 9 digits or in the form NNN-NN-NNNN."; }													
					msg = "does not appear to be valid";
					return false;				
				}
				else 
					if (parseInt(matchArr[1],10)==0) 
					{
			            if(ErrOutput == null)
			            {   alert("Invalid SSN: SSN's can't start with 000.");    }
			            else
			            {   ErrOutput.innerText = "Invalid SSN: SSN's can't start with 000."; }
						msg = "does not appear to be valid";
						return false;
					}
					else 
						return true;
				}
			    if(ErrOutput != null)
			    {			
			        ErrOutput.innerText = "";			    
			        ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			    }
			break;
         }//case ssn
         
         case "zip":
		 { 
			if (objValue.value.length > 0 )
			{
				var valid = "0123456789-";
				var hyphencount = 0;

				if (objValue.value.length!=5 && objValue.value.length!=10) 
				{
	                if(ErrOutput == null)
	                {   alert("Please enter your 5 digit or 5 digit+4 zip code.");    }
	                else
	                {   ErrOutput.innerText = "Please enter your 5 digit or 5 digit+4 zip code."; }					
					return false;
				}
				for (var i=0; i < objValue.value.length; i++) 
				{
					temp = "" + objValue.value.substring(i, i+1);
					if (temp == "-") hyphencount++;
						if (valid.indexOf(temp) == "-1") 
						{
                            if(ErrOutput == null)
                            {   alert("Invalid characters in your zip code.  Please try again.");    }
                            else
                            {   ErrOutput.innerText = "Invalid characters in your zip code.  Please try again."; }
							return false;
						}
					if ((hyphencount > 1) || ((objValue.value.length==10) && ""+objValue.value.charAt(5)!="-")) 
					{
                        if(ErrOutput == null)
                        {   alert("The hyphen character should be used with a properly formatted 5 digit+four zip code, like '12345-6789'.   Please try again.");    }
                        else
                        {   ErrOutput.innerText = "The hyphen character should be used with a properly formatted 5 digit+four zip code, like '12345-6789'.   Please try again."; }						
						return false;
					}
				}
			}              
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
			break;         
         }//case zip
         
         case "time":
		 {          
			// 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 = objValue.value.match(timePat);
			if (matchArray == null) 
			{
                if(ErrOutput == null)
                {   alert("Time is not in a valid format.");    }
                else
                {   ErrOutput.innerText = "Time is not in a valid format."; }
				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) 
			{
                if(ErrOutput == null)
                {   alert("Hour must be between 1 and 12. (or 0 and 23 for military time)");    }
                else
                {   ErrOutput.innerText = "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) 
			{
                if(ErrOutput == null)
                {   alert("You can't specify AM or PM for military time.");    }
                else
                {   ErrOutput.innerText = "You can't specify AM or PM for military time."; }								
				return false;
			}
			if (minute<0 || minute > 59) {
                if(ErrOutput == null)
                {   alert ("Minute must be between 0 and 59.");    }
                else
                {   ErrOutput.innerText = "Minute must be between 0 and 59."; }
				return false;
			}
			if (second != null && (second < 0 || second > 59)) {
                if(ErrOutput == null)
                {   alert ("Second must be between 0 and 59.");    }
                else
                {   ErrOutput.innerText = "Second must be between 0 and 59."; }				
				return false;
			}						              
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
			break;         
         }//case time
         
         case "date":
         {			
			if(!isDate(objValue.value)) 
               { 
                 if(!strError || strError.length ==0) 
                 { 
                    strError = objValue.id+": Enter a valid date "; 
                 }//if                                               
                if(ErrOutput == null)
                {   alert(strError);   }
                else
                {   ErrOutput.innerText = strError; }				                 
                 return false; 
               }//if 
			    if(ErrOutput != null)
			    {			
			        ErrOutput.innerText = "";			    
			        ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			    }
			break;			
         }
         
         case "phone":
         {
			if (objValue.value.length > 0 )
			{
				if (!checkInternationalPhone(objValue.value))
				{
					if(!strError || strError.length ==0) 
					{ 
						strError = objValue.id+": Enter a valid phone number"; 
					}//if                                               
                    if(ErrOutput == null)
                    {   alert(strError);   }
                    else
                    {   ErrOutput.innerText = strError; }				                 
					return false; 				
				}
			}
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
			break;         
         }//Case phone
         
         case "dec":
         case "decimal":
         {			
			if (objValue.value.length > 0 )
			{
				if (!isDecimal(objValue.value))
				{
					if(!strError || strError.length ==0) 
					{ 
						strError = objValue.id+": Enter a valid decimal"; 
					}//if                                               
                    if(ErrOutput == null)
                    {   alert(strError);   }
                    else
                    {   ErrOutput.innerText = strError; }				                 
					return false; 				
				}
			}
			if(ErrOutput != null)
			{			
			    ErrOutput.innerText = "";			    
			    ErrOutput.parentElement.innerHTML = ErrOutput.parentElement.innerHTML.replace("&nbsp;", "");
			}
			break;			
         }//case Decimal
    }//switch 
    return true; 
}

/*****************Trim a Value************************/

function TrimAll(TRIM_VALUE)
{
	if(TRIM_VALUE.length < 1)
	{	return"";	}
    
    TRIM_VALUE = RTrim(TRIM_VALUE);
    TRIM_VALUE = LTrim(TRIM_VALUE);

    if(TRIM_VALUE=="")	{	return "";	}
    else	{	return TRIM_VALUE;	}
}

function RTrim(VALUE)
{
	var w_space = String.fromCharCode(32);
    var v_length = VALUE.length;
	var strTemp = "";

	if(v_length < 0)
	{	return"";	}
	
	var iTemp = v_length -1;
			
	while(iTemp > -1)
	{
		if(VALUE.charAt(iTemp) == w_space)
		{}
		else
		{
			strTemp = VALUE.substring(0,iTemp +1);
            break;
        }
		iTemp = iTemp-1;
    }
    return strTemp;
            
}

function LTrim(VALUE)
{
	var w_space = String.fromCharCode(32);
	if(v_length < 1)
	{	return"";	}
			
	var v_length = VALUE.length;
    var strTemp = "";
    var iTemp = 0;
			
	while(iTemp < v_length)
	{
		if(VALUE.charAt(iTemp) == w_space)
		{}
		else
		{
			strTemp = VALUE.substring(iTemp,v_length);
			break;
		}
		iTemp = iTemp + 1;
    }
	return strTemp;
}			
/*****************Trim a Value************************/


/*****************Init Cap************************/
function changeCase(frmObj) 
{
	var index;
	var tmpStr;
	var tmpChar;
	var preString;
	var postString;
	var strlen;
	tmpStr = frmObj.value.toLowerCase();
	strLen = tmpStr.length;
	if (strLen > 0)  {
		for (index = 0; index < strLen; index++)  {
			if (index == 0)  {
				tmpChar = tmpStr.substring(0,1).toUpperCase();
				postString = tmpStr.substring(1,strLen);
				tmpStr = tmpChar + postString;
			}
			else {
				tmpChar = tmpStr.substring(index, index+1);
				if (tmpChar == " " && index < (strLen-1))  {
					tmpChar = tmpStr.substring(index+1, index+2).toUpperCase();
					preString = tmpStr.substring(0, index+1);
					postString = tmpStr.substring(index+2,strLen);
					tmpStr = preString + tmpChar + postString;
				}
			}
		}
	}
	frmObj.value = tmpStr;
}

/*****************Init Cap************************/

/*****************Date Validation************************/
// Declaring valid date character, minimum year and maximum year
var dtCh= "/";
var minYear=1900;
var maxYear=2100;

function isInteger(s){
	var i;
    for (i = 0; i < s.length; i++){   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    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++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

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 DaysArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 31
		if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
		if (i==2) {this[i] = 29}
   } 
   return this
}

function isDate(dtStr){
	var daysInMonth = DaysArray(12)
	var pos1=dtStr.indexOf(dtCh)
	var pos2=dtStr.indexOf(dtCh,pos1+1)
	var strMonth=dtStr.substring(0,pos1)
	var strDay=dtStr.substring(pos1+1,pos2)
	var strYear=dtStr.substring(pos2+1)
	strYr=strYear
	if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
	if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
	for (var i = 1; i <= 3; i++) {
		if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
	}
	month=parseInt(strMonth)
	day=parseInt(strDay)
	year=parseInt(strYr)
	if (pos1==-1 || pos2==-1){
		alert("The date format should be : mm/dd/yyyy")
		return false
	}
	if (strMonth.length<1 || month<1 || month>12){
		alert("Please enter a valid month")
		return false
	}
	if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
		alert("Please enter a valid day")
		return false
	}
	if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
		alert("Please enter a valid 4 digit year between "+minYear+" and "+maxYear)
		return false
	}
	if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
		alert("Please enter a valid date")
		return false
	}
return true
}
/*****************Date Validation************************/

/*****************Phone Validation************************/

// Declaring required variables
//example 801-943-5700
var digits = "0123456789";
// non-digit characters which are allowed in phone numbers
var phoneNumberDelimiters = "()- ";
// characters which are allowed in international phone numbers
// (a leading + is OK)
var validWorldPhoneChars = phoneNumberDelimiters + "+";
// Minimum no of digits in an international phone no.
var minDigitsInIPhoneNumber = 10;

function isInteger(s)
{   var i;
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    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 checkInternationalPhone(strPhone){
	s=stripCharsInBag(strPhone,validWorldPhoneChars);
	return (isInteger(s) && s.length >= minDigitsInIPhoneNumber);
}

/*****************Phone Validation************************/

/*****************Decimal Validation************************/
function isDecimal(strValue)
{
	var err=0;
	var psj=0; 
	var ch = "";
	var checkOK = "1234567890.";
	var icheckNumr = strValue;
	var iPeriodcnt = 0;

	for (var i = 0;  i < icheckNumr.length;  i++)
	{
		ch = icheckNumr.charAt(i);
		if (ch == ".")
			iPeriodcnt++ ;
	    
		if (checkOK.search(ch) == -1)
		{  
			err = 1; 
		}
		if (iPeriodcnt > 1)
		{  
			err = 1; 
		}  	        
	}             
 		if (err==1)
		    return false;
		else
		    return true;
} 
/*****************Decimal Validation************************/

/*****************Credit Card Validation************************/

var Cards = new makeArray(8);
Cards[0] = new CardType("MasterCard", "51,52,53,54,55", "16");
var MasterCard = Cards[0];
Cards[1] = new CardType("VisaCard", "4", "13,16");
var VisaCard = Cards[1];
Cards[2] = new CardType("AmExCard", "34,37", "15");
var AmExCard = Cards[2];
Cards[3] = new CardType("DinersClubCard", "30,36,38", "14");
var DinersClubCard = Cards[3];
Cards[4] = new CardType("DiscoverCard", "6011", "16");
var DiscoverCard = Cards[4];
Cards[5] = new CardType("enRouteCard", "2014,2149", "15");
var enRouteCard = Cards[5];
Cards[6] = new CardType("JCBCard", "3088,3096,3112,3158,3337,3528", "16");
var JCBCard = Cards[6];
var LuhnCheckSum = Cards[7] = new CardType();

/*************************************************************************\
CheckCardNumber(form)
function called when users click the "check" button.
\*************************************************************************/
function CheckCardNumber(form) {
var tmpyear;
if (form.CardNumber.value.length == 0) {
alert("Please enter a Card Number.");
form.CardNumber.focus();
return;
}
if (form.ExpYear.value.length == 0) {
alert("Please enter the Expiration Year.");
form.ExpYear.focus();
return;
}
if (form.ExpYear.value > 96)
tmpyear = "19" + form.ExpYear.value;
else if (form.ExpYear.value < 21)
tmpyear = "20" + form.ExpYear.value;
else {
alert("The Expiration Year is not valid.");
return;
}
tmpmonth = form.ExpMon.options[form.ExpMon.selectedIndex].value;
// The following line doesn't work in IE3, you need to change it
// to something like "(new CardType())...".
// if (!CardType().isExpiryDate(tmpyear, tmpmonth)) {
if (!(new CardType()).isExpiryDate(tmpyear, tmpmonth)) {
alert("This card has already expired.");
return;
}
card = form.CardType.options[form.CardType.selectedIndex].value;
var retval = eval(card + ".checkCardNumber(\"" + form.CardNumber.value +
"\", " + tmpyear + ", " + tmpmonth + ");");
cardname = "";
if (retval)



// comment this out if used on an order form
alert("This card number appears to be valid.");


else {
// The cardnumber has the valid luhn checksum, but we want to know which
// cardtype it belongs to.
for (var n = 0; n < Cards.size; n++) {
if (Cards[n].checkCardNumber(form.CardNumber.value, tmpyear, tmpmonth)) {
cardname = Cards[n].getCardType();
break;
   }
}
if (cardname.length > 0) {
alert("This looks like a " + cardname + " number, not a " + card + " number.");
}
else {
alert("This card number is not valid.");
      }
   }
}
/*************************************************************************\
Object CardType([String cardtype, String rules, String len, int year,
                                        int month])
cardtype    : type of card, eg: MasterCard, Visa, etc.
rules       : rules of the cardnumber, eg: "4", "6011", "34,37".
len         : valid length of cardnumber, eg: "16,19", "13,16".
year        : year of expiry date.
month       : month of expiry date.
eg:
var VisaCard = new CardType("Visa", "4", "16");
var AmExCard = new CardType("AmEx", "34,37", "15");
\*************************************************************************/
function CardType() {
var n;
var argv = CardType.arguments;
var argc = CardType.arguments.length;

this.objname = "object CardType";

var tmpcardtype = (argc > 0) ? argv[0] : "CardObject";
var tmprules = (argc > 1) ? argv[1] : "0,1,2,3,4,5,6,7,8,9";
var tmplen = (argc > 2) ? argv[2] : "13,14,15,16,19";

this.setCardNumber = setCardNumber;  // set CardNumber method.
this.setCardType = setCardType;  // setCardType method.
this.setLen = setLen;  // setLen method.
this.setRules = setRules;  // setRules method.
this.setExpiryDate = setExpiryDate;  // setExpiryDate method.

this.setCardType(tmpcardtype);
this.setLen(tmplen);
this.setRules(tmprules);
if (argc > 4)
this.setExpiryDate(argv[3], argv[4]);

this.checkCardNumber = checkCardNumber;  // checkCardNumber method.
this.getExpiryDate = getExpiryDate;  // getExpiryDate method.
this.getCardType = getCardType;  // getCardType method.
this.isCardNumber = isCardNumber;  // isCardNumber method.
this.isExpiryDate = isExpiryDate;  // isExpiryDate method.
this.luhnCheck = luhnCheck;// luhnCheck method.
return this;
}

/*************************************************************************\
boolean checkCardNumber([String cardnumber, int year, int month])
return true if cardnumber pass the luhncheck and the expiry date is
valid, else return false.
\*************************************************************************/
function checkCardNumber() {
var argv = checkCardNumber.arguments;
var argc = checkCardNumber.arguments.length;
var cardnumber = (argc > 0) ? argv[0] : this.cardnumber;
var year = (argc > 1) ? argv[1] : this.year;
var month = (argc > 2) ? argv[2] : this.month;

this.setCardNumber(cardnumber);
this.setExpiryDate(year, month);

if (!this.isCardNumber())
return false;
if (!this.isExpiryDate())
return false;

return true;
}
/*************************************************************************\
String getCardType()
return the cardtype.
\*************************************************************************/
function getCardType() {
return this.cardtype;
}
/*************************************************************************\
String getExpiryDate()
return the expiry date.
\*************************************************************************/
function getExpiryDate() {
return this.month + "/" + this.year;
}
/*************************************************************************\
boolean isCardNumber([String cardnumber])
return true if cardnumber pass the luhncheck and the rules, else return
false.
\*************************************************************************/
function isCardNumber() {
var argv = isCardNumber.arguments;
var argc = isCardNumber.arguments.length;
var cardnumber = (argc > 0) ? argv[0] : this.cardnumber;
if (!this.luhnCheck())
return false;

for (var n = 0; n < this.len.size; n++)
if (cardnumber.toString().length == this.len[n]) {
for (var m = 0; m < this.rules.size; m++) {
var headdigit = cardnumber.substring(0, this.rules[m].toString().length);
if (headdigit == this.rules[m])
return true;
}
return false;
}
return false;
}

/*************************************************************************\
boolean isExpiryDate([int year, int month])
return true if the date is a valid expiry date,
else return false.
\*************************************************************************/
function isExpiryDate() {
var argv = isExpiryDate.arguments;
var argc = isExpiryDate.arguments.length;

year = argc > 0 ? argv[0] : this.year;
month = argc > 1 ? argv[1] : this.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;
}

/*************************************************************************\
boolean luhnCheck([String CardNumber])
return true if CardNumber pass the luhn check else return false.
Reference: http://www.ling.nwu.edu/~sburke/pub/luhn_lib.pl
\*************************************************************************/
function luhnCheck() {
var argv = luhnCheck.arguments;
var argc = luhnCheck.arguments.length;

var CardNumber = argc > 0 ? argv[0] : this.cardnumber;

if (! isNum(CardNumber)) {
return false;
  }

var no_digit = CardNumber.length;
var oddoeven = no_digit & 1;
var sum = 0;

for (var count = 0; count < no_digit; count++) {
var digit = parseInt(CardNumber.charAt(count));
if (!((count & 1) ^ oddoeven)) {
digit *= 2;
if (digit > 9)
digit -= 9;
}
sum += digit;
}
if (sum % 10 == 0)
return true;
else
return false;
}

/*************************************************************************\
ArrayObject makeArray(int size)
return the array object in the size specified.
\*************************************************************************/
function makeArray(size) {
this.size = size;
return this;
}

/*************************************************************************\
CardType setCardNumber(cardnumber)
return the CardType object.
\*************************************************************************/
function setCardNumber(cardnumber) {
this.cardnumber = cardnumber;
return this;
}

/*************************************************************************\
CardType setCardType(cardtype)
return the CardType object.
\*************************************************************************/
function setCardType(cardtype) {
this.cardtype = cardtype;
return this;
}

/*************************************************************************\
CardType setExpiryDate(year, month)
return the CardType object.
\*************************************************************************/
function setExpiryDate(year, month) {
this.year = year;
this.month = month;
return this;
}

/*************************************************************************\
CardType setLen(len)
return the CardType object.
\*************************************************************************/
function setLen(len) {
// Create the len array.
if (len.length == 0 || len == null)
len = "13,14,15,16,19";

var tmplen = len;
n = 1;
while (tmplen.indexOf(",") != -1) {
tmplen = tmplen.substring(tmplen.indexOf(",") + 1, tmplen.length);
n++;
}
this.len = new makeArray(n);
n = 0;
while (len.indexOf(",") != -1) {
var tmpstr = len.substring(0, len.indexOf(","));
this.len[n] = tmpstr;
len = len.substring(len.indexOf(",") + 1, len.length);
n++;
}
this.len[n] = len;
return this;
}

/*************************************************************************\
CardType setRules()
return the CardType object.
\*************************************************************************/
function setRules(rules) {
// Create the rules array.
if (rules.length == 0 || rules == null)
rules = "0,1,2,3,4,5,6,7,8,9";

var tmprules = rules;
n = 1;
while (tmprules.indexOf(",") != -1) {
tmprules = tmprules.substring(tmprules.indexOf(",") + 1, tmprules.length);
n++;
}
this.rules = new makeArray(n);
n = 0;
while (rules.indexOf(",") != -1) {
var tmpstr = rules.substring(0, rules.indexOf(","));
this.rules[n] = tmpstr;
rules = rules.substring(rules.indexOf(",") + 1, rules.length);
n++;
}
this.rules[n] = rules;
return this;
}
/*****************Credit Card Validation************************/


/****************************************************************/
