/* 
JavaScript Document
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Description:	functions for client side form validation
Author:			liz moyer	
Updated: 		2/26/2006

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/

/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Over ride submit - submit without validating
* submit form without cleint side validation
*/
function overrideSubmit(thisFormId,thisCheckBoxId) {
	if(document.getElementById(thisCheckBoxId).checked) {
		document.getElementById(thisFormId).setAttribute("onsubmit","return true");
	}	
	else {
		document.getElementById(thisFormId).setAttribute("onsubmit","return validateForm(this)");
	}
}

/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Email
* validate a field for the email
*/
function validateEmail(thisField) {
	
	//regular expression against which to validate email
	var re_mail = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z])+$/; 
	
	//if email doesn't validate invoke alert message, move cursor to form field, and return form = false
	if (!re_mail.test(thisField.value) || !thisField.value) {
		alert("Email address is invalid.");
		thisField.focus();	
		if (!thisField.value) {thisField.select(thisField.value);}
		return false;		
	}
	
	return true;	
}

/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Credit card
* validate credit card expiration date - format mm/dd
*/
function validateCardExpiration(thisField) {

	// Check credit expiry date is in valid format
	var cardExpiresOn = thisField.value;
	
	//empty value
	if (cardExpiresOn == "") {
		alert("Please enter the credit card expiration date."); 
		thisField.focus(); 
		return false;
	}
	//invalid format
	else {
		
		var arrayCardExpiresDate = cardExpiresOn.split("/");
		if ((arrayCardExpiresDate.length != 2) || (arrayCardExpiresDate[0] == "") || (isNaN(arrayCardExpiresDate[0])) || (arrayCardExpiresDate[1] == "") || (isNaN(arrayCardExpiresDate[1])) || (arrayCardExpiresDate[0] < 1) || (arrayCardExpiresDate[0] > 12)) {
			alert("Expiration date is not in correct format."); 
			thisField.focus(); 
			thisField.select(thisField.value);		
			return false;
		}
	}
	return true;

}

/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Credit card
* validate credit card number
*/
function validateCardNumber(thisField) {

	//remove white spaces	
	var ccRE=/\W/gi;
	var cardNumber = thisField.value.replace(ccRE, "");
	var cardNumberLen =	cardNumber.length;
	var c = 0;
	
	//value is not number
	if (isNaN(cardNumber)) {
		alert("Credit card number is not numeric."); 
		thisField.focus(); 
		if (!thisField.value) {thisField.select(thisField.value);}
		return false;
	}
	
	//card numbr is incorrect length
	if ((cardNumberLen != 13) && (cardNumberLen != 16)) {
		alert("Incorrect number of digits in credit card number."); 
		thisField.focus();
		if (!thisField.value) {thisField.select(thisField.value);}
		return false;
	}
	
	//invalid number - sum of card math calculation must be divisible by 10 
	var cardMath=0;
	
	for (x = cardNumberLen; x > 0; x--) {
		if (x % 2 == 1) {
			var doubled = "" + (parseInt(cardNumber.substring(x - 1, x)) * 2);
			if (doubled.length == 2) {
				doubled = parseInt(doubled.substring(0,1)) + parseInt(doubled.substring(1,2));
			}
			cardMath += parseInt(doubled);
		}
		else {
			cardMath += parseInt(cardNumber.substring(x - 1, x));
		}	
		
	}	
	if (cardMath % 10 != 0) {
		alert("Credit card number is invalid."); 
		thisField.focus(); 
		thisField.select(thisField.value);
		return false;
	}
	
	return true;
	
}


/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Numbers
* validate a field that contains numbers
*/
function validateNumber(thisField, thisFieldName, min, max) { 
	
	//if min or max are empty or null set some values
	if (!min) { min = 0 } 
	if (!max) { max = 255 } 
	
	//strip out acceptable non-numeric characters () - \ /.
	var strippedValue = thisField.value.replace(/[\(\)\.\-\ ]/g, '');
	
	//value is not number
	if(isNaN(strippedValue)) {
		alert("Invalid characters in " + thisFieldName + ". The " + thisFieldName + " only excepts numbers plus any characters as indicated in the formatting example.");
		thisField.focus();
		thisField.select(thisField.value);		
		return false;		
	}
	
	//too short or too long
	if(strippedValue.length < min  || strippedValue.length > max) {
		alert("Incorrect number of digits in " + thisFieldName + ".");
		thisField.focus();
		thisField.select(thisField.value);		
		return false;								
	}
	
	return true;
	
}

/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* String
* validate a field that can contains a string of any characters
*/
function validateString(thisField, thisFieldName, min, max) { 
	
	//if min or max are empty or null set some values
	if (!min) { min = 1 } 
	if (!max) { max = 255 } 
	
	//empty value
	if (thisField.value == "") { 
		alert("Please enter a " + thisFieldName); 
		thisField.focus(); 	
		return false;		
	}
	
	//too short or too long
	if (thisField.value.length < min || thisField.value.length > max) { 
		alert("Incorrect number of characters in " + thisFieldName); 
		thisField.focus(); 
		thisField.select(thisField.value); 		
		return validated = false;		
	}
	
	return true;
	
} 

/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Dropdown
* validate a user selected a drop down option
*/
function validateDropdown(thisSelectedIndex, thisFieldName, thisField) {
    
	//no option selected 
    if (thisSelectedIndex == 0) {
		alert("Select an option from the " + thisFieldName + " drop down menu.");
		thisField.focus();
		return (false); 
    }    
	
	return true;
	
} 

/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* URL
* validate url begins with http://
*/
function checkURL(thisField, thisFieldName) {
	//regular expression against which to validate email
	var re_url = /^http:\/\//; 
	
	//if email doesn't validate invoke alert message, move cursor to form field, and return form = false
	if (!re_url.test(thisField.value)) {
		alert(thisFieldName + " must begin with - http:\/\/");
		thisField.focus();	
		thisField.select(thisField.value);
		return false;		
	}
	
	return true;	
}


/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Whole form
* validate form
*/
function validateForm(thisForm) {
		
	//debugging message - calling form
	//alert("call form validator loop");
	
	//initiate variables for radio group	
	previousRadio = "";
	currentRadio = "";
	uncheckedRadios = 0;
	checkedRadio = 0;
	radioItems = 0;	
	
	//initiate variables for checkbox group
	currentBox = "";
	previousBox = "";
	uncheckedBoxes = 0;
	checkedBox = 0;
	boxItems = 0;	
		
	//initiate some variables for field type
	currentFieldType = "";
	previousFieldType = "";
	
	//loop thru the form
	for(i=0; i < thisForm.length; i++) {
		
		//create some variables for the field, value, name and type of field	
		formField = thisForm.elements[i]; 
		fieldValue = thisForm.elements[i].value; 
		fieldName = thisForm.elements[i].name;
		fieldType = thisForm.elements[i].type;		
		
		//create variable for name of form field for alert message		
		messageName = "";
		if(fieldType != null || typeof(fieldName) != "undefined") {	
						
			//test for underscore in field name
			if (fieldName.indexOf("_") > 0) {
				underscore = fieldName.indexOf("_");
				nameOne = fieldName.substring(0,underscore);
				nameTwo = fieldName.substring(underscore+1, fieldName.length);
				if (nameTwo == "dd") {nameTwo = "";}
				messageName = nameOne + " " + nameTwo;/**/
			}
			else {
				//regular expression for testing for upper case letters in field name
				reMixedCase = /\B[A-Z]/;
				if(reMixedCase.test(fieldName)) {
					//get array from splitting field name at upper case letters
					nameArray = fieldName.split(reMixedCase);						
					//get array of upper case letters
					ucLettersArray = fieldName.match(/\B[A-Z]/g);
					for(c=0; c < nameArray.length; c++) {
						if(c > 0) { 
							u = parseInt(c)-1;
							messageName += ucLettersArray[u];
						}
						messageName += nameArray[c]+" ";
					}
				
				}
				else {
					messageName = fieldName;
				}
			}
			//messageName =  messageName.toLowerCase(); 
		}
		
		//validate fields where class = validate
		if (thisForm.elements[i].className == "validate") {	
			
			//debug message - valid field name
			//alert("validate " + messageName)
			
			//conditional validation based on the name of field
			switch (fieldName) {
								
				//credit card number
				case "Card_number" :					
					//invoke routine to validate credit card 
					if (!validateCardNumber(formField)) { return false; }
					break;
				
				//credit card expiration
				case "Card_expires" :
					//invoke routine to validate credit card 
					if (!validateCardExpiration(formField)) { return false; }						
					break;
				
				//email
				case "Email" :	
					//invoke routine to validate email
					if(!validateEmail(formField)) { return false; }					
					break;
				
				//telephone					
				case "Telephone" :	
					// invoke routine to validate number - 10 digits
					if(!validateNumber(formField, messageName, 10, 10)) { return false; }					
					break;
				
				//zip code
				case "Zipcode" :
					//invoke routine to validate a number at least 5 digits and no longer than 9 digits
					if(!validateNumber(formField, messageName, 5, 9)) { return false; }						
					break;
				
				//Other fields
				default :
					
					//conditional validation based on the type of field
					switch(fieldType) {
					
						//text
						case "text" :	
							//invoke routine to validate string	input
							if(!validateString(formField, messageName, 1, 255)) { return false; }
							break;
						
						//drop downs	
						case "select-one" :
							if(!validateDropdown(thisForm.elements[i].selectedIndex, messageName, formField)) { return false; }
							break;
						
						//radio buttons
						case "radio" :
							
							//current box equal current field 
							currentRadio = fieldName;	
							if (fieldName.indexOf("_end") > 1) {
								currentRadio = messageName.substring(0, (messageName.length-4));
							}						
							currentRadio = currentRadio.toLowerCase(); 							
							
							//first or new instance of a radio group
							if (previousRadio == "" || currentRadio != previousRadio) {
								uncheckedRadios = 0;
								radioItems = 0;	
								checkedRadio = 0;
								if (currentRadio != previousRadio) { previousRadio = currentRadio; }
							}
							
							/* 	track Radio as part of group as long as the status of checked Radio = 0 
							* radioItems increases by increment of 1 							
							* uncheckedRadioes increases by increment of 1 
							* at the last Radio (name_end) 
 							  if number of radioItmes == number of uncheckedradioes, return false
							*/
							if ((currentRadio == previousRadio) && (checkedRadio == 0)) {
								
								//count number of radio buttons
								radioItems += 1;	
								
								//check status of radio
								if (!formField.checked) {
									uncheckedRadios += 1;			
									//alert("boxItems = " + boxItems + " || uncheckedBoxes = " + uncheckedBoxes)
								}
								else {
									 checkedRadio += 1;
								}
								
								//this is the radio button and number of box items is the same as number of unchecked boxes
								if ((fieldName.indexOf("_end") > 1) && (parseFloat(radioItems) == parseFloat(uncheckedRadios))) {	
									alert("Check at least one " + messageName.substring(0, (messageName.length-4)) + " boxes.");
									return false;									
								}
							}						
							break;
						
						//check boxes
						case "checkbox" :
							
							//current box equal current field 
							currentBox = fieldName;	
							if (fieldName.indexOf("_end") > 1) {
								currentBox = messageName.substring(0, (messageName.length-4));
							}
							currentBox = currentBox.toLowerCase(); 
														
							//first or new instance of a check box
							if (previousBox == "" || currentBox != previousBox) {
								uncheckedBoxes = 0;
								boxItems = 0;	
								checkedBox = 0;
								if (currentBox != previousBox) { previousBox = currentBox; }
							}
							
							/* 	track box as part of group as long as the status of checked box = 0 
							* boxItems increases by increment of 1 							
							* uncheckedBoxes increases by increment of 1 
							* at the last box (name_end) 
 							  if number of boxItmes == number of uncheckedBoxes, return false
							*/
							if ((currentBox == previousBox) && (checkedBox == 0)) {
								
								//count then number of box items
								boxItems += 1;	
								
								//check status of box
								if (!formField.checked) {
									uncheckedBoxes += 1;			
									//alert("boxItems = " + boxItems + " || uncheckedBoxes = " + uncheckedBoxes)
								}
								else {
									 checkedBox += 1;
								}
								
								reNameArray = /\[\]/; 					
								if(reNameArray.test(messageName)) {
									//alert(fieldname + " has array []";);
									messageName = messageName.replace(reNameArray,"");
								}
								//this is the last box and number of box items is the same as number of unchecked boxes
								if ((fieldName.indexOf("_end") > 1) && (parseFloat(boxItems) == parseFloat(uncheckedBoxes))) {	
									alert("Check at least one " + messageName.substring(0, (messageName.length-4)) + " boxes.");
									return false;									
								}
								
							}						
							break;
							
					//end field type condition
					}
					break;
					
			//end field name control
			}				
			
		//end validation condition
		}				
		
		//make sure urls are valid
		else {
			
			//validate web address is valid
			if(fieldType != null || typeof(fieldName) != "undefined") {	
				if ((fieldName.indexOf("_url") > 1) && formField.value != "") {
					messageName = messageName.substring(0, (messageName.length-3)) + "web address";
					if(!checkURL(formField, messageName)) { return false; }	
				}
			}
		}
		
	//end form loop
	}	
	
	//debug message - form valid
	//alert("All valid");
	
	return true;
}

