//*************************************************************************************************************
// Javascript Form Validation Functions
// vs 1.0
// Author: Randy Moller
// Email: rmoller@hyperxmedia.com
// Date: 01-08-2003
// Last Revised: 01-16-2004
//
// Integration Notes:
//
// 1. Make sure this file is a js include on the document which contains the form(s) to be tested!
//
// 2. Change the error message background color variables to suit style.
//     2a. bgColorErr will set the error background color for the form elements if there's an error.
//     2b. bgColorNorm sets the normal background color for the form elements when no error exists.
//
// 3. The aryNames variable is basically a name/value array which aids in returning a friendly name in
//    the error message alert. So, on the left of the colon (:) would be the input name (w/o the 
//		validation flag "|validator"), and on the right is the friendly name you want returned in the 
//		error message. These name value pairs are delimited by a comma (,).
//		(i.e. "input_name" : "friendly_name", etc.)
//
// 4. In your web document, use the following naming convention for your input names in the form:
//    4a. Required values - name|required - Checks for empty strings
//    4b. *Phone Numbers - name|phone - validates u.s. phone #'s and returns formatted.
//    4c. Email Addresses - name|email - checks for valid email address
//    4d. Select box (selected) - name|selected - validates that user selected (not index[0])
//    4e. Minimum Chars - name|minimum,num - validates input to be >= num chars.
//    4f. Maximum Chars - name|maximum,num - validates input to be <= num chars.
//    4g. **SSAN - name|ssan (*note - currently only validates single box input, not split) - valid ssn
//    4h. Dates - name|date (most any u.s. format acceptable) - validates any date (UNTESTED)
//		4i. Credit Card - name|cc - validates that value is a credit card number (non-specific).
//    4j. MasterCard - name|mc - validates that entry is a valid mastercard number
//    4k. Visa - name|visa - validates that entry is a valid visa number
//		4l. Amex - name|amex - validates that entry is a valid amex number
//    4m. Zip Codes - name|zip (currently only supports u.s. or canadian)
//    4n. Dates of Birth - name|dob (incl leap years. Pass in as concatenated if split)
//		4o. alpha - name|alpha - field contains only letters
//		4p. alphaspace - name|alphaspace - field contains either letters or spaces
//		4q. alphanumeric - name|alphanumeric - field contains either numbers or letters
//		4r. alphanumericspace - name|alphanumericspace - field contains letters, numbers or spaces
//		4s. numeric - name|numeric - field contains all numbers
//		4t. digit - name|digit - for single digit validation
//		4u. confirm - name|confirm - will verify that element.value matches first previous element's value.
//
//		example: <input type='text' name='fname|required' value=''>
//		example: <select name='country|selected'>
//
//		* Phone number return format is configurable by uncommenting/commenting the particular format you want
//			(see function formatPhone())
//
//		**SSAN return format is configurable by uncommenting/commenting the particular format you want
//			(see function formatSSAN())
//
//		5. In the onSubmit of your <form> to be tested, call onSubmit='return validate(this);' and it should work!
//
//*************************************************************************************************************

//variables that hold normal and error background colors - config as necessary.
var bgColorErr = "#FBFA7F";
var bgColorNorm = "";

//set up associative array of input/friendly err message names - add/remove as necessary.
var aryNames = {
							 "name" : "Your Name",
							 "fname" : "Your First Name",
							 "lname" : "Your Last Name",
							 "address1" : "Address line 1",
							 "comments" : "Comments",
							 "description" : "Description",
							 "contact" : "Contact name",
							 "subject" : "Subject",
							 "support_product" : "Support Product",
							 "phone" : "Phone Number",
							 "city" : "City",
							 "state" : "State",
							 "zip" : "Zip code",
							 "country" : "Country",
							 "username" : "Username",
							 "password" : "Password",
							 "password_verify" : "Confirm Password",
							 "email" : "Email Address",
							 "cctype" : "Credit Card Type",
							 "cardnumber" : "Credit Card Number",
							 "ccexpirmonth" : "Credit Card Expire Month",
							 "ccexpiryear" : "Credit Card Expire Year",
							 "cardname" : "Credit Card Name",
							 "tsa_link_location" : "TSAGroup Link location",
							 "site_url" : "Your site URL",
							 "valid" : "Validation characters"
							 };

function validate (oForm)	{
	var elem;
	var val;
	var style;
	var firstError = -1;
	var errName;
	var errMsg = "";
	var validator;

	for (var i=0; i<oForm.length; i++)	{
		elem = oForm.elements[i];
		name = oForm.elements[i].name;
		errName = lookUp(name);
		val = oForm.elements[i].value;
		style = oForm.elements[i].style;
		
		//parse out the validator from elem name
		var aTmp = name.split("|");
		if (aTmp[1])	{
			strInput = aTmp[1];
			if (strInput.indexOf(",") == -1)	{
				switch (strInput)	{
					case "required":
						if (!required(val))	{
							errMsg += errName + " is missing\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "email":
						if (!validEmail(val))	{
							errMsg += errName + " is missing or incorrectly formatted\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "phone":
						if (!validPhone(val))	{
							errMsg += errName + " missing or not valid\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							elem.value = formatPhone(val);
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "confirm":
						if (val != oForm.elements[i-1].value)	{
							errMsg += errName + " does not match " + lookUp(oForm.elements[i-1].name) + "\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "zip":
						if (!validZip(val))	{
							errMsg += errName + " missing or incorrectly formatted\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "ssan":
						if (!validSSAN(val))	{
							errMsg += errName + " is not a valid Social Security Number\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							elem.value = formatSSAN(val);
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "selected":
						if (!validSelected(elem))	{
							errMsg += errName + " has not been selected\n";
							firstError = ((firstError > -1)	? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);				
						}
						break;
					case "cc":
						var regex = /\D+/gi;
						var tmp = val.replace(regex, "");
						if (!validCreditCard(tmp) || (tmp.length < 15))	{
							errMsg += errName + " is not a valid credit card number\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem,bgColorErr);
						} else {
							elem.value = tmp;
							setBackgroundStyle(elem,bgColorNorm);
						}
						break;
					case "mc":
						if (!validMasterCard(val))	{
							errMsg += errName + " is not a valid MasterCard number\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "visa":
						if (!validVisa(val))	{
							errMsg += errName + " is not a valid Visa number\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "amex":
						if (!validAmex(val))	{
							errMsg += errName + " is not a valid American Express number\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "alpha":
						if (!validAlpha(val))	{
							errMsg += errName + " must contain only letter characters\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "alphaspace":
						if (!validAlphaSpace(val))	{
							errMsg += errName + " must contain only letter or space characters\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "alphanumeric":
						if (!validAlphaNumeric(val))	{
							errMsg += errName + " must contain only letter or number characters\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "alphanumericspace":
						if (!validAlphaNumericSpace(val))	{
							errMsg += errName + " must contain only letters, numbers, or the space character\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "numeric":
						if (!validNumeric(val))	{
							errMsg += errName + " must contain number characters\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "digit":
						if (!validDigit(val))	{
							errMsg += errName + " must be a single digit character\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					default:
						break;
				}			
			} else {
				//split comma and process
				var t = strInput.split(",");
				var valid = t[0];
				var x = t[1];
				switch (valid)	{
					case "minimum_chars":
						if (!minimumChars(valid, x))	{
							errMsg += errName + " must contain at least " + x + "characters\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
					case "maximum_chars":
						if (!maximumChars(valid, x))	{
							errMsg += errName + " must contain at least " + x + "characters\n";
							firstError = ((firstError > -1) ? firstError : i);
							setBackgroundStyle(elem, bgColorErr);
						} else {
							setBackgroundStyle(elem, bgColorNorm);
						}
						break;
				}
			} 
		}
	}
	if (errMsg.length == 0)	{
		return true;
	} else {
		alert(errMsg);
		oForm.elements[firstError].focus();
		return false;
	}
}

//returns friendly name for input to display error msg
function lookUp (iput)	{
	for (i in aryNames)	{
		if (iput.indexOf("|") > -1)	{
			tmp = iput.split("|");
			if (tmp[0] == i)	{
				return aryNames[i];
			}
		}
	}
}

//returns false if country selectedIndex is 0
function validSelected (e)	{
	if (!e.selectedIndex > 0)	{
		return false;
	}
	return true;
}

//sets the background style of the element when an error occurs
function setBackgroundStyle	(elem, color)	{
	elem.style.backgroundColor = color;
	return;
}

//resets the form element background style when reset is clicked
function resetForm(frm)	{
	for(var i=0; i<frm.length; i++)	{
		setBackgroundStyle(frm.elements[i], bgColorNorm);
		type = frm.elements[i].type;
		if ((type != "submit") && (type != "reset") && (type != "button"))	{
			if (type == "checkbox")	{
				frm.elements[i].checked = false;
			} else {
				frm.elements[i].value = "";
			}
		}
	}
	return;
}

function required (sVal)	{	
	if (sVal.length == 0)	{
		return false;
	}
	return true;
}

//allows minimum of (num) number of chars
function minimumChars (v, num)	{
	if (v.length < num)	{
		return false;
	}
	return true;
}

// allows maximum of (num) number of chars
function maximumChars (v, num)	{
	if (v.length > num)	{
		return false;
	}
	return true;
}


//email
function validEmail (strEmail)	{
	var regex = /^[a-z0-9]([a-z0-9_\-\.]*)@([a-z0-9_\-\.]*)(\.[a-z]{2,3}(\.[a-z]{2}){0,2})$/i;
	return regex.test(strEmail);
}

//ssn (freeform)
function validSSAN (num)	{
	var regex = /\D+/gi;
	var tmp = num.replace(regex, "");
	if ((tmp.length == 9) && (validNumeric(tmp))) {
		return true;
	}
	return false;
}

//ssn - 3 part
function validSplitSSN (strPart1, strPart2, strPart3) 	{
	var regex1 = /^\d{3}/gi;
	var regex2 = /^\d{2}/gi;
	var regex3 = /^\d{4}/gi;
	if (!regex1.test(strPart1))	{
		return false;
	}
	if (!regex2.test(strPart2))	{
		return false;
	}
	if (!regex3.test(strPart3))	{
		return false;
	} else {
		return strPart1 + "-" + strPart2 + "-" + strPart3;
	}
}

//formats valid SSAN for return
function formatSSAN (num)	{
	var regex = /\D+/gi;
	if (tmp = num.replace(regex, ""))	{
	
		//create the substrings
		var ssn1 = tmp.substring(0,3);
		var ssn2 = tmp.substring(4,5);
		var ssn3 = tmp.substring(6,9);
		
		//format substrings (uncomment the format you want to return
		var fssan = ssn1 + "-" + ssn2 + "-" + ssn3;
		//var fssan = ssn1 + " " + ssn2 + "-" + ssn3;
		//var fssan = ssn1 + "." + ssn2 + "-" + ssn3;
		
		return fssan;
	}
	return false;
}

//u.s. phone number incl area code (freeform)
function validPhone (strNum)	{
	var regex = /\D+/gi;
	var tmp = strNum.replace(regex, "");
	if (tmp.length == 10)	{
		return true; 
	} else {
		return false;
	}
}

//u.s. phone number incl area code (split entry)
function validSplitPhone (strNum1, strNum2, strNum3)	{
	var regex = /^[\d{3}]/i;
	var regex2 = /^[\d{4}$]/i;
	if (!regex.test(strNum1))	{
		return false;
	}
	if (!regex.test(strNum2))	{
		return false;
	}
	if (!regex2.test(strNum3))	{
		return false;
	} else {
		return strNum1 + "-" + strNum2 + "-" + strNum3;
	}
}

//strips non digit characters and returns formatted phone number
function formatPhone (num)	{
	var regex = /\D+/gi;
	var tmp = num.replace(regex, "");
	if (tmp.length == 10)	{
	
		//format for return
		var tmp_ac = tmp.substring(0,3);
		var tmp_pre = tmp.substring(3,6);
		var tmp_num = tmp.substring(6,10);
		
		//uncomment the format you want returned
		var fphone = tmp_ac + "-" + tmp_pre + "-" + tmp_num; 								//returns xxx-xxx-xxxx
		//var fphone = "(" + tmp_ac + ") " + tmp_pre + "-" + tmp_num;				//returns (xxx) xxx-xxxx
		//var fphone = tmp_ac + "." + tmp_pre + "." + tmp_num;							//returns xxx.xxx.xxxx
		//var fphone = tmp_ac + tmp_pre + tmp_num;													//returns xxxxxxxxxx
		return fphone; 
	}
	return;
}

//validates dates in u.s. format (i.e. mm/dd/yyyy or mm.dd.yyyy) (freeform)
function validDate (strDate) {
	
	var formatted;
	var regex = /^\d{1,2}([\D|\s])\d{1,2}[\D|\s]\d{4}$/gi;
 
  if(!regex.test(strDate))	{
    return false;
  } else {
    var arrayDate = strDate.split(RegExp.$1);
    var intMonth = parseInt(arrayDate[0]);
		var intDay = parseInt(arrayDate[1]);
		var intYear = parseInt(arrayDate[2]);

		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 formatted = formatDate(arrayDate);
			}
  	}
		
  	//check for February
		var bLeapYear = (intYear % 4 == 0 && (intYear % 100 != 0 || intYear % 400 == 0));
  	if( ((bLeapYear && intDay <= 29) || (!bLeapYear && intDay <=28)) && intDay !=0)	{
    	return true;
  	}
  	return false;
	}
}

//validates dates in u.s. format (i.e. mm/dd/yyyy or mm.dd.yyyy) (split)
function validSplitDate (strMonth, strDay, strYear) {

	var formatted;
  var regexMo = /^[\d{1,2}]/i;
	var regexDay = /[\d{1,2,3}\1]/i;
	var regexYear = /[\d{4}$]/i;
 
  if (!regexMo.test(strMonth))	{
    return false;
  } else if (!regexDay.test(strDay))	{
		return false;
	} else if (!regexYear.test(strYear))	{
		return false;
	} else {
	
	if(strMonth > 12 || strMonth < 1) {
		return false;
	} else if (strDay > 31 || strDay < 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[strMonth] != null) {
    if(strDay <= arrayLookup[strMonth] && strDay != 0)	{
      return formatted = strMonth + "-" + strDay + "-" + strYear;
		}
  }
		
  //check for February
	var bLeapYear = (strYear % 4 == 0 && (strYear % 100 != 0 || strYear % 400 == 0));
  if( ((bLeapYear && strDay <= 29) || (!bLeapYear && strDay <=28)) && strDay !=0)
    return formatted = strMonth + "-" + strDay + "-" + strYear;
  }
  return false;
}

//validates a u.s. zip code (5 or 5+4) returns a formatted zip if 9char using hyphen as seperator (or false)
function validZip (strZip)	{
	var formatted;
	var regex = /(^\d{5}$|^\d{5}[\s-\.]?\d{4}$)/gi;
	if (!regex.test(strZip))	{
		return false;
	} else {
		if (strZip.length == 9) {
			return formatted = strZip.substring(0,5) + "-" + strZip.substring(5);
		} else {
			return formatted = strZip.replace(/[.\s]/, "-");
		}
	}
}

//validates a u.s. zip code (5+4 split) returns a formatted zip if 9char using hyphen as seperator (or false)
function validSplitZip (strZip1, strZip2)	{
	var formatted;
	var regex1 = /^\d{5}$/gi;
	var regex2 = /^\d{4}$/gi;
	if ((regex1.test(strZip1)) && (regex2.test(strZip2)))	{
		return formatted = strZip1 + "-" + strZip2;
	} else {
		return false;
	}
}

//validates Date of Birth dates in u.s. format (i.e. mm/dd/yyyy or mm.dd.yyyy) (freeform)
function validDOB (strDate) {
	
	var formatted;
	var regex = /^\d{1,2}([\D|\s])\d{1,2}[\D|\s]\d{4}$/gi;
 
  if(!regex.test(strDate))	{
    return false;
  } else {
    var arrayDate = strDate.split(RegExp.$1);
    var intMonth = parseInt(arrayDate[0]);
		var intDay = parseInt(arrayDate[1]);
		var intYear = parseInt(arrayDate[2]);
		var now = new Date();
		var intTodayDay = now.getDay();
		var intTodayMonth = now.getMonth();
		var intTodayYear = now.getYear();

		if(intMonth > 12 || intMonth < 1) {
			return false;
		} else if (intYear < 1800)	{
			return false;
		} else if ((intDay > (intTodayDay + 1)) && (intMonth > intTodayMonth) && (intYear >= intTodayYear))	{
			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 formatted = formatDate(arrayDate);
			}
  	}
		
  	//check for February
		var bLeapYear = (intYear % 4 == 0 && (intYear % 100 != 0 || intYear % 400 == 0));
  	if( ((bLeapYear && intDay <= 29) || (!bLeapYear && intDay <=28)) && intDay !=0)	{
    	return formatted = formatDate(arrayDate);
  	}
  	return false;
	}
}

//validates dates in u.s. format (i.e. mm/dd/yyyy or mm.dd.yyyy) (split)
function validSplitDOB (strMonth, strDay, strYear) {

	var formatted;
  var regexMo = /^[\d{1,2}]/i;
	var regexDay = /[\d{1,2,3}\1]/i;
	var regexYear = /[\d{4}$]/i;
	
  if (!regexMo.test(strMonth))	{
    return false;
  } else if (!regexDay.test(strDay))	{
		return false;
	} else if (!regexYear.test(strYear))	{		
		return false;
	} 

 	var now = new Date();
	var intTodayMonth = now.getMonth();
	var intTodayDay = now.getDay();
	var intTodayYear = now.getYear();
	var intMonth = parseInt(strMonth, 10);
	var intDay = parseInt(strDay, 10);
	var intYear = parseInt(strYear, 10);
	
	if (strMonth > 12 || strMonth < 1) {
		return false;
	} else if (strDay > 31 || strDay < 1)	{
		return false;
	} else if ((intDay > (intTodayDay + 1)) && (intMonth > intTodayMonth) && (intYear >= intTodayYear))	{
		return false;
	}	else if (intYear < 1800)	{
		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[strMonth] != null) {
    if(strDay <= arrayLookup[strMonth] && strDay != 0)	{
      return formatted = intMonth + "-" + intDay + "-" + intYear;
		}
  }
		
  //check for February
	var bLeapYear = (strYear % 4 == 0 && (strYear % 100 != 0 || strYear % 400 == 0));
  if( ((bLeapYear && strDay <= 29) || (!bLeapYear && strDay <=28)) && strDay !=0)	{
    return formatted = intMonth + "-" + intDay + "-" + intYear;
  }
  return false;
}

//credit card functions
//visa
function validVisa (num)	{
	var regex = /\D+/gi;
	var tmp = num.replace(regex, "");
  if ((tmp.length == 16) && (tmp.substring(0,1) == 4)) {
    return validCreditCard(tmp);
	}
  return false;
}

//mastercard
function validMasterCard (num)	{
	var regex = /\D+/gi;
	var tmp = num.replace(regex, "");
  firstdig = tmp.substring(0,1);
  seconddig = tmp.substring(1,2);
  if ((tmp.length == 16) && (firstdig == 5) && ((seconddig >= 1) && (seconddig <= 5))) {
    return validCreditCard(tmp);
	}
  return false;
}

//american express
function validAmex (num)	{
	var regex = /\D+/gi;
	var tmp = num.replace(regex, "");
	fdigit = tmp.substring(0,1);
	if ((tmp.length == 15) && (fdigit == 3)) {
		return validCreditCard(tmp);
	}
	return false;
}

//general credit card
function validCreditCard(cnum) {
  // Encoding only works on cards with less than 19 digits
  if (cnum.length > 19)
    return (false);

  sum = 0; mul = 1; l = cnum.length;
  for (i = 0; i < l; i++) {
    digit = cnum.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--;
  }
  if ((sum % 10) == 0)
    return (true);
  else
    return (false);
}

//matches alpha characters only
function validAlpha (v)	{
	var regex = /^[a-zA-Z]+$/;
	if (!regex.test(v))	{
		return false;
	}
	return true;
}

//matches alphabetic or space characters only
function validAlphaSpace (v)	{
	var regex = /[a-zA-Z\s]+$/;
	if (!regex.test(v))	{
		return false;
	}
	return true;
}

//matches alpha numeric characters only
function validAlphaNumeric (v)	{
	var regex = /[a-zA-Z0-9]+$/;
	if (!regex.test(v))	{
		return false;
	}
	return true;
}

//matches either alphabetic, numeric, or space characters only
function validAlphaNumericSpace (v)	{
	var regex = /[a-zA-Z0-9\s]+$/;
	if (!regex.test(v))	{
		return false;
	}
	return true;
}

//matches numbers only
function validNumeric (v)	{
	var regex = /[0-9]+$/;
	if (!regex.test(v))	{
		return false;
	}
	return true;
}

//matches any single digit only
function validDigit (v)	{
	var regex = /^[0-9]$/;
	if (!regex.test(v))	{
		return false;
	}
	return true;
}

//end validation functions
