
	var strCCType = '';
	var itemCount = 0;
	var strMinute = '00';
	var strHour = '00';
	var strDay = '0';
	var strMonth = '0';
	var strYear = '0000';
	var objStored;

	/***************************
		FUNCTION: validateForm
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function takes a form and looks at all of the input fields it contains.  For each input field,
			the function looks at the 'tag' attribute for pipe-delimited information about how to check the data.  It uses
			the masterValidation function to validate the data, and displays an error message if it cannot be validated.
			In the error message, it uses the 'friendlyName' attribute of the input field and the focus method to indicate
			where the error is located.  If all the validation works, the form submits

		PARAMETERS:
				theForm:		The form to be checked.  This function works on any form with input fields that use the 'tag'
									and 'friendlyName' attributes.

		RETURN:
				true			if the entire form is valid
				false			if an input in the form is invalid
	 ***************************/
	function validateForm_alt(theForm) {
		var tag, tagAttr, i, n;
		n = 0;
		for (i = 0; i < theForm.elements.length; i++) {
			tagAttr = theForm.elements[i].attributes.getNamedItem("tag");
			if (tagAttr == null)
				tag = '';
			else
				tag = tagAttr.value;
			if ((tag != "") && (tag != undefined)) {
				isHidden = false;													// See if the input field is visible, going up to its parent panel
				if (theForm.elements[i].disabled == true)
					isHidden = true;
				if (theForm.elements[i].style.display == "none")
					isHidden = true;
				p = theForm.elements[i].parentNode;
				while ((p.id != "panel") && (p != theForm)) {
					p = p.parentNode;
				}
				if ((p != theForm) && (p.style.display == "none"))
					isHidden = true;
				if (!isHidden) {
					var tempArr = tag.split("|");
					for (j = 0; j < tempArr.length; j++) {
						var result = "";
						result = masterValidation(theForm.elements[i], tempArr[j], theForm, false);
						if (result == "ignore") {
							return true;
						} else {
							if (result != "") {
								alert(result);
								if ((theForm.elements[i].type != "hidden") && (theForm.elements[i].parentNode.style.display != "none")) {
									theForm.elements[i].focus();
								} else {
									if ((theForm.elements[i].type == "hidden") && (i > 1))
										var iTemp;
										if (theForm.elements[i - 1].type == "hidden")
											iTemp = i - 2;
										else
											iTemp = i - 1;
										theForm.elements[iTemp].focus();
								}
								return false;
							}
						}
					}
				}
			}
		}
		return true;
	}
	
	// I renamed this function to validateForm_alt because the Opt-Intelligence script also defined a validateForm function.
	// This here will be overwritten in that case, but validateForm_alt will still be available (and used below in submitForm).
	// I included this here in case validateForm is used anywhere directly (without submitForm).
	function validateForm(theForm) {
		return validateForm_alt(theForm);
	}




	function getTagElement(theForm, strTag) {
		var tag, tagAttr, i;
		var arrReturn = new Array();
		n = 0;
		for (i = 0; i < theForm.elements.length; i++) {
			tagAttr = theForm.elements[i].attributes.getNamedItem("tag");
			if (tagAttr == null)
				tag = '';
			else
				tag = tagAttr.value;
			if ((tag != "") && (tag != undefined)) {
				isHidden = false;													// See if the input field is visible, going up to its parent panel
				if (theForm.elements[i].style.display == "none")
					isHidden = true;
				p = theForm.elements[i].parentNode;
				while ((p.id != "panel") && (p != theForm)) {
					p = p.parentNode;
				}
				if ((p != theForm) && (p.style.display == "none"))
					isHidden = true;
				if (!isHidden) {
					var tempArr = tag.split("|");
					for (j = 0; j < tempArr.length; j++) {
						if (tempArr[j] == strTag)
							arrReturn[n++] = theForm.elements[i];
					}
				}
			}
		}
		return arrReturn;
	}





	/***************************
		FUNCTION: masterValidation
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks some data against a given type.  The types are listed below and can be increased as needed.
									0:		not null
									1:		valid email
									2:		valid phone number
									3:		drop-down has been selected
									4:		max 500 characters
									5:		test for escape chars
									6:		numeric
									7:		state abbreviation
									8:		website
									9:		radio button or checkbox has been checked
									10:		valid zip code (numeric and has 5 digits)
									11:		valid credit card
									12:		valid date
									13:		valid phone number
									30:		start counting items
									31:		end counting items, with a min int
									32:		end counting items, with a max int
									33:		count checked item
									34:		end counting items, with an exact int
									35:		Store Credit Card Type
									40:		max 255 characters
									41:		max 200 characters
									42:		max 500 characters
									50:		ignore if certain tag is okay
									60:		Store Minute
									61:		Store Hour
									62:		Store Day
									63:		Store Month
									64:		Store Year
									65:		Check Stored date valid
									66:		Check Stored date in future
									67:		Check Stored date in past
									70:		Store element
									71:		Check element value against stored element value

		PARAMETERS:
				theElement:		The element to be validated.  It can be an <input>, <textarea>, or <button>.  Note that it is the element, not the value.
				type:				An integer, as listed abve.
				theForm:		The form in which the element lives
				validatingIgnore:	True if trying to validate an ignore request; false is normal validation

		RETURN:
				null				if the field is valid
				error string	if the field is invalid
	 ***************************/
	function masterValidation(theElement, type, theForm, validatingIgnore) {
		var result = "", i, friendlyName, friendlyNameAttr, errorText, errorTextAttr;

		friendlyNameAttr = theElement.attributes.getNamedItem("friendlyName")
		if (friendlyNameAttr == null)
			friendlyName = '';
		else
			friendlyName = friendlyNameAttr.value;
		errorTextAttr = theElement.attributes.getNamedItem("errorText")
		if (errorTextAttr == null)
			errorText = '';
		else
			errorText = errorTextAttr.value;
		i = 0;
		switch (type) {
			case "0":									// Test not null
				result = validNotNull(theElement.value, friendlyName, errorText);
				break;
			case "1":									// Test for valid e-mail address
				result = validEmailAddr(theElement.value, friendlyName, errorText);
				break;
			case "2":									// Test for valid phone number
				result = validPhone(theElement.value, friendlyName, errorText);
				break;
			case "3":									// Test for selection in drop-down
				result = isDropDownSelected(theElement.value, friendlyName, errorText);
				break;
			case "4":									// Set max length on a textarea to 500
				result = maxChars(theElement.value, 500, friendlyName, errorText);
				break;
			case "5":									// Test for escape chars
				theElement.value = addEscapeChars(theElement.value);
				break;
			case "6":									// Test for numeric
				result = validNumber(theElement.value, friendlyName, errorText);
				break;
			case "7":									// Test for valid state abbreviation
				result = validState(theElement.value, friendlyName, errorText);
				break;
			case "8":									// Test for valid e-mail address
				result = validWebsite(theElement.value, friendlyName, errorText);
				break;
			case "9":									// Test for selection in drop-down
				result = isChecked(theElement.checked, friendlyName, errorText);
				break;
			case "10":									// Test valid zip code
				result = validZipCode(theElement.value, friendlyName, errorText);
				break;
			case "11":									// Test valid credit card
				result = validCC(theElement.value, strCCType);
				break;
			case "12":									// Test valid date
				result = validDate(theElement.value, friendlyName, errorText);
				break;
			case "13":									// Test for valid international phone number
				result = validInternationalPhone(theElement.value, friendlyName, errorText);
				break;
			case "30":								// Start counting items
				startCount();
				break;
			case "31":								// End counting items, check against the value
				result = endCount(theElement.value, 0, friendlyName, errorText);
				break;
			case "32":								// End counting items, check against the value
				result = endCount(theElement.value, 1, friendlyName, errorText);
				break;
			case "33":								// Count an item if selected
				countItem(theElement.checked);
				break;
			case "34":								// End counting items, check against the value
				result = endCountExact(theElement.value, friendlyName, errorText);
				break;
			case "35":								// Store the type of credit card, for the credit card check
				strCCType = theElement.value;
				break;
			case "40":									// Set max length on a textarea to 255
				result = maxChars(theElement.value, 255, friendlyName, errorText);
				break;
			case "41":									// Set max length on a textarea to 200
				result = maxChars(theElement.value, 200, friendlyName, errorText);
				break;
			case "42":									// Set max length on a textarea to 500
				result = maxChars(theElement.value, 500, friendlyName, errorText);
				break;
			case "50":									// ignore if certain tag is okay
				result = ignoreIfTag(theForm, theElement.value);
				break;
			case "51":									// flag to look at for ignoring
				result = '';
				if (validatingIgnore)
					result = isChecked(theElement.checked, friendlyName, errorText);
				break;
			case "60":								// Store the minute, for the date check
				strMinute = theElement.value;
				break;
			case "61":								// Store the hour, for the date check
				strHour = theElement.value;
				break;
			case "62":								// Store the day, for the date check
				strDay = theElement.value;
				break;
			case "63":								// Store the month, for the date check
				strMonth = theElement.value;
				break;
			case "64":								// Store the year, for the date check
				strYear = theElement.value;
				break;
			case "65":								// Check stored date for validity
				result = validDate2(strYear, strMonth - 1, strDay, friendlyName, errorText);
				break;
			case "66":								// Check stored date is in future
				result = dateInFuture(strYear, strMonth - 1, strDay, strHour, strMinute, true, friendlyName, errorText);
				break;
			case "67":								// Check stored date is in past
				result = dateInFuture(strYear, strMonth - 1, strDay, strHour, strMinute, false, friendlyName, errorText);
				break;
			case "70":								// Store the year, for the date check
				objStored = {Value: theElement.value, FriendlyName: friendlyName};
				break;
			case "71":									// Test valid credit card
				if ((objStored != undefined) && (objStored != null)) {
					result = valuesMatch(theElement.value, friendlyName, errorText, objStored.Value, objStored.FriendlyName);
				} else {
					result = "";
				}
				break;
			default:
				result = "";
				break;
		}
		return result;
	}


	/***************************
		FUNCTION: validNotNull
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is null.

		PARAMETERS:
				str:					The string to be validated.
				friendlyName:	A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is valid
				error string	if the string is invalid
	 ***************************/
	function validNotNull(str, friendlyName, errorText) {
		var result = "";
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "Please fill in the " + friendlyName + " field.";

		if ((str == "") || (str == null) || (str == undefined)) {
			result = errorText;
		}
		return result;
	}


	/***************************
		FUNCTION: validNumber
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 11.29.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is a number.

		PARAMETERS:
				str:				The string to be validated.
				friendlyName:		A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is a number
				error string		if the string is not a number
	 ***************************/
	function validNumber(str, friendlyName, errorText) {
		var result = "";
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "The " + friendlyName + " field must be a number.";

		if (!IsNumeric(str)) {
			result = errorText;
		}
		return result;
	}




	/***************************
		FUNCTION: validDate
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 05.04.2005

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is a date.

		PARAMETERS:
				str:				The string to be validated.
				friendlyName:		A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is a date
				error string		if the string is not a date
	 ***************************/
	function validDate(str, friendlyName, errorText) {
		var result = "";
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "The " + friendlyName + " field must be a date (MM/DD/YYYY).";

		//re = /^[0-1]*\d[\/-\-][0-3]*\d[\/-\-]\d\{2\}|\d\{4\}$/;
		re = /^[0-1]{0,1}\d[\/\-][0-3]{0,1}\d[\/\-](\d{2}|\d{4})$/;
		if ((!re.test(str)) && (str != "")) {
			result = errorText;
		}
		return result;
	}



	/***************************
		FUNCTION: validDate2
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 11.14.2005

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is a date.

		PARAMETERS:
				strY:				The year
				strM:				The month
				strD:				The day
				friendlyName:		A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is a valid date
				error string		if the string is not a valid date
	 ***************************/
	function validDate2(strY, strM, strD, friendlyName, errorText) {
		var result = "";
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "The " + friendlyName + " field must be a date (MM/DD/YYYY).";

		var theDate = new Date(strY, strM, strD);
		if (!((theDate.getDate() == strD) && (theDate.getMonth() == strM) && (theDate.getYear() == strY))) {
			result = errorText;
		}
		return result;
	}	



	/***************************
		FUNCTION: validDate2
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 11.14.2005

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is a date.

		PARAMETERS:
				strY:				The year
				strM:				The month
				strD:				The day
				strH:				The hour
				strMin:				The minute
				bolCheckFuture:		True to check if the date is in the future, False to check if the date is in the past.
				friendlyName:		A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is a valid date
				error string		if the string is not a valid date
	 ***************************/
	function dateInFuture(strY, strM, strD, strH, strMin, bolCheckFuture, friendlyName, errorText) {
		var result = "";
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined)) {
			if (bolCheckFuture) {
				errorText = "The " + friendlyName + " field must be in the future.";
			} else {
				errorText = "The " + friendlyName + " field must be in the past.";
			}
		}
		var theDate = new Date(strY, strM, strD, strH, strMin);
		var today = new Date();
		if (bolCheckFuture) {
			if (!(theDate > today)) {
				result = errorText;
			}
		} else {
			if (!(theDate < today)) {
				result = errorText;
			}
		}
		return result;
	}



	/***************************
		FUNCTION: validZipCode
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 11.29.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is a valid zip code (5-digit number).

		PARAMETERS:
				str:				The string to be validated.
				friendlyName:		A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is a number
				error string		if the string is not a number
	 ***************************/
	function validZipCode(str, friendlyName, errorText) {
		var result = "";
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";

		if (!IsNumeric(str)) {
			if ((errorText == "") || (errorText == null) || (errorText == undefined))
				errorText = "The " + friendlyName + " field must be a number.";
			result = errorText;
		}
		if (str.length != 5) {
			if ((errorText == "") || (errorText == null) || (errorText == undefined))
				errorText = "The " + friendlyName + " field must be 5 digits.";
			result = errorText;
		}

		return result;
	}





	/***************************
		FUNCTION: validState
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 11.30.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is a valid state abbreviation.

		PARAMETERS:
				str:				The string to be validated.
				friendlyName:		A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is a valid state abbreviation
				error string		if the string is not a valid state abbreviation
	 ***************************/
	function validState(str, friendlyName, errorText) {
		var i;
		var result = "";
		var arrStates = new Array("AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY", "");
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "The " + friendlyName + " field is not a valid state.";

		str = str.toUpperCase();
		for (i = 0; i < arrStates.length; i++) {
			if (str == arrStates[i])
				return result;
		}
		result = errorText;

		return result;
	}





	/***************************
		FUNCTION: validWebsite
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 11.30.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is a valid website.  It uses RegExp to look for an 'http://' or 'https://',
				followed by a '.' somewhere in the string.

		PARAMETERS:
				str:				The string to be validated.
				friendlyName:		A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is valid
				error string		if the string is invalid
	 ***************************/
	function validWebsite(str, friendlyName, errorText) {
		var result = "";
		var re;

		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "Please enter a complete website (http://www.domain.com) in the " + friendlyName + " field.";

		re = /^(http|https):\/\/.+\..+$/;
		if ((!re.test(str)) && (str != ""))
			result = errorText;

		return result;
	}	
	
	
	

	/***************************
		FUNCTION: validEmailAddr
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is a valid email address.  It uses RegExp to look for an '@',
				followed by a '.', followed by at least 3 characters.

		PARAMETERS:
				email:				The string to be validated.
				friendlyName:	A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is valid
				error string	if the string is invalid
	 ***************************/
	function validEmailAddr(email, friendlyName, errorText) {
		var result = "";

		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "Please enter a complete email address (yourname@yourdomain.com) in the " + friendlyName + " field.";

		re = /^[\w+\.\-]+@[\w\-\.]+\.[a-zA-Z]{2,3}$/;
		if ((!re.test(email)) && (email != ""))
			result = errorText;

		return result;
	}


	/***************************
		FUNCTION: validPhone
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is a valid phone number.  It first strips out all non-numeric
				characters, then checks for a length of either 10 or 11 numbers.  If 11, it checks the first number for a 1.

		PARAMETERS:
				phone:				The string to be validated.
				friendlyName:	A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is valid
				error string	if the string is invalid
	 ***************************/
	function validPhone(phone, friendlyName, errorText) {
		var result = "";
		var str = new String(phone), temp;
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "Please enter a vaild phone number (##########) in the " + friendlyName + " field.";

		re = /\D/g;
		temp = str.replace(re, "");
		re = /^1?\d{10}$/
		if (!re.test(temp) && (phone.length != 0))
			result = errorText;

		return result;
	}

	/***************************
		FUNCTION: validInternationalPhone
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 12.13.2005

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it is a valid phone number.  It first strips out all non-numeric
				characters, then checks for a length of either 10 or 11 numbers.  If 11, it checks the first number for a 1.

		PARAMETERS:
				phone:				The string to be validated.
				friendlyName:	A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is valid
				error string	if the string is invalid
	 ***************************/
	function validInternationalPhone(phone, friendlyName, errorText) {
		var result = "";
		var str = new String(phone), temp;
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "Please enter a vaild phone number in the " + friendlyName + " field.";

		re = /\D/g;
		temp = str.replace(re, "");
		re = /^\d+$/
		if (!re.test(temp) && (phone.length != 0))
			result = errorText;

		return result;
	}
	
	
	
	/***************************
		FUNCTION: valuesMatch
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 05.31.2007

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks a string to see if it matches a second string.

		PARAMETERS:
				str1:				The string to check.
				friendlyName1:		A string to be used in the error message to refer to the invalid input field.
				errorText:			Error text to override the use of friendlyName
				str2:				The string to be checked against.
				friendlyName2:		A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is a number
				error string		if the string is not a number
	 ***************************/
	function valuesMatch(str1, friendlyName1, errorText, str2, friendlyName2) {
		var result = "";
		if ((friendlyName1 == "") || (friendlyName1 == null) || (friendlyName1 == undefined))
			friendlyName1 = "";
		if ((friendlyName2 == "") || (friendlyName2 == null) || (friendlyName2 == undefined))
			friendlyName2 = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = friendlyName2 + " does not match " + friendlyName1 + ".";

		if (str1 != str2) {
			result = errorText;
		}
		return result;
	}




	/***************************
		FUNCTION: startCount
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function works with endCount() and countItem() to count the number of checkboxes selected
				in a block of checkboxes.  To use this, the block of checkboxes must be wrapped by two hidden input fields.
				The first hidden field starts the count using this function.  Then each checkbox needs to be tagged to continue the count.
				Finally, the last hidden field uses endCount() to check the count.  Its value should be either a 0 (less than) or 1 (greater than).

		PARAMETERS:
				none

		RETURN:
				none
	 ***************************/
	function startCount() {
		itemCount = 0;
	}


	/***************************
		FUNCTION: endCount
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function works with startCount() and countItem() as described above.  It examines the
				current count to see if it is greater than or less than a given number.  To limit a block of checkboxes to
				a range of checked values, use two hidden inputs - one with a greater than flag and one with a less than flag.

		PARAMETERS:
				num:				The number used for the comparison.  This should be stored in the 'value' attribute of the hidden input.
				type:				0 for less than, 1 for greater than.
				friendlyName:	A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the count passes
				error string	if the count does not pass
	 ***************************/
	function endCount(num, type, friendlyName, errorText) {
		var result = "";
		var i = parseInt(num);
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined)) {
			if (type == 0) {
				errorText = "Please select " + i + " or more items in the " + friendlyName + " list.";
			} else {
				errorText = "Please select " + i + " or fewer items in the " + friendlyName + " list.";
			}
		}
		if (type == 0) {
			if (itemCount < i)
				result = errorText;
		} else {
			if (itemCount > i)
				result = errorText;
		}
		return result;
	}





	/***************************
		FUNCTION: endCountExact
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 01.26.2005

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function works with startCount() and countItem() as described above.  It examines the
				current count to see if it is equal to a given number.

		PARAMETERS:
				num:				The number used for the comparison.  This should be stored in the 'value' attribute of the hidden input.
				friendlyName:	A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the count passes
				error string	if the count does not pass
	 ***************************/
	function endCountExact(num, friendlyName, errorText) {
		var result = "";
		var i = parseInt(num);
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined)) {
				errorText = "Please select " + i + " item";
				if (num != 1)
					errorText = errorText + "s";
				errorText = errorText + " from the " + friendlyName + " list."
		}
		if (itemCount != i) {
			result = errorText;
		}
		return result;
	}
	
	
	
	
	
	/***************************
		FUNCTION: countItem
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function works with startCount() and endCount() as described above.  For a flagged
				checkbox, it increments the count only if the checkbox is checked.

		PARAMETERS:
				isSelected:		From the given checkbox, whether or not it is selected.

		RETURN:
				none
	 ***************************/
	function countItem(isSelected) {
		if (isSelected)
			itemCount++;
	}


	/***************************
		FUNCTION: isDropDownSelected
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks to see is a drop-down list has had an item selected.  To use this,
				set the default non-selection's value to -1.

		PARAMETERS:
				value:				The value of the selected option.
				friendlyName:	A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if something has been selected
				error string	if nothing has been selected
	 ***************************/
	function isDropDownSelected(value, friendlyName, errorText) {
		result = "";
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "Please select an item from the " + friendlyName + " list.";

		if (value < 0)
			result = errorText;

		return result;
	}



	/***************************
		FUNCTION: isChecked
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 12.22.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function checks to see is a radio button or checkbox has been checked.

		PARAMETERS:
				value:				The value of the selected option.
				friendlyName:		A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if something has been checked
				error string		if nothing has been checked
	 ***************************/
	function isChecked(value, friendlyName, errorText) {
		result = "";
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = friendlyName + " is not checked.";

		if (!value)
			result = errorText;

		return result;
	}




	/***************************
		FUNCTION: maxChars
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function tests the string to make sure it is n characters or less.  And looks for
				unusual unicode characters (possible malicious code).

		PARAMETERS:
				str:					The string to be validated.
				n:						The maximum number of characters allowed.
				friendlyName:	A string to be used in the error message to refer to the invalid input field.

		RETURN:
				null				if the string is valid
				error string	if the string is invalid
	 ***************************/
	function maxChars(str, n, friendlyName, errorText) {
		result = "";
		if ((friendlyName == "") || (friendlyName == null) || (friendlyName == undefined))
			friendlyName = "";
		if ((errorText == "") || (errorText == null) || (errorText == undefined))
			errorText = "Please input no more than " + n + " characters in the " + friendlyName + " box.";

		re = new RegExp("^[\\w\\W]{0," + n + "}$");
		re2 = new RegExp("[\\u00B1-\\uFFFF]+");
		if (!re.test(str) || re2.test(str))
			result = errorText;

		return result;
	}


	/***************************
		FUNCTION: addEscapeChars
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 10.12.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function takes a string and adds given escape characters when certain reserved characters are found.

		PARAMETERS:
				str:					The string to be escaped.

		RETURN:
				string				the escaped string
	 ***************************/
	function addEscapeChars(str) {
		regExp = /,/g
		result = str.replace(regExp, '%2C');
		return result;
	}


	/***************************
		FUNCTION: maxLength
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function limits the amount of text one can type in a textarea (since it doesn't have
				a 'maxlength' attribute like a text box.  Call it in the onkeypress event of the textarea to constrain.

		PARAMETERS:
				theItem:			The textarea to be constrained.
				n:						The maximum number of characters allowed.

		RETURN:
				none
	 ***************************/
	function maxLength(theItem, n) {
		if (theItem.value.length >= n)
			theItem.value = theItem.value.slice(0, n - 1);
	}





	/***************************
		FUNCTION: IsNumeric
		WRITTEN BY: (from internet)
		WRITTEN ON:

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function figures out whether or not a value is numeric

		PARAMETERS:
				sText:				The value to check.

		RETURN:
				boolean
	 ***************************/

function IsNumeric(sText) {
	var ValidChars = "0123456789.";
	var IsNumber=true;
	var Char;
	var i;
	
	for (i = 0; (i < sText.length) && (IsNumber); i++) 
	{
		Char = sText.charAt(i);
		if (ValidChars.indexOf(Char) == -1) {
			IsNumber = false;
		}
	}
	return IsNumber;
}





	/***************************
		FUNCTION: ignoreIfTag
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 09.01.2005

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function looks for a certain tag.  If all inputs with the tag check out correctly, it should skip
						all other form validation.

		PARAMETERS:
				strTag:				The tag to look for

		RETURN:
				null				if the string is a number
				error string		if the string is not a number
	 ***************************/
	function ignoreIfTag(theForm, strTag) {
		var i, j;
		var result = 'ignore';
		if (strTag != '') {
			var arrElements = getTagElement(theForm, strTag);
			for (i = 0; i < arrElements.length; i++) {
				tagAttr = arrElements[i].attributes.getNamedItem("tag");
				if (tagAttr == null)
					tag = '';
				else
					tag = tagAttr.value;
				if ((tag != "") && (tag != undefined)) {
					var arrTag = tag.split('|');
					for (j = 0; j < arrTag.length; j++) {
						if (masterValidation(arrElements[i], arrTag[j], theForm, true) != '')
							result = '';
					}
				}
			}
		}
		return result;
	}
	
	




	/***************************
		FUNCTION: changeActionPanel
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 9.10.2004

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function dynamically determines which panel to show, based on the selected requested action.

		PARAMETERS:
				none

		RETURN:
				none
	 ***************************/
	function changeActionPanel(divId, reqId, selId) {
		var div = document.getElementById(divId);
		var req = document.getElementById(reqId);
		var sel = document.getElementById(selId);
		var form1 = document.getElementById("form1");

		for (i = 0; i < div.childNodes.length; i++)
			div.childNodes[i].style.display = "none";
		div.childNodes[req.selectedIndex].style.display = "inline";
		sel.value = req.selectedIndex;
		x = div.id.indexOf("__");
		if (x >= 0)
			form1.extra.value = div.id.substr(x + 2);
	}



	function submitFormRaw(theForm) {
		if (validateForm_alt(theForm)) {
		    var theFormId = (theForm.id || '');
			var theButton = document.getElementById(theFormId + 'SubmitButton');
			if ((theButton != undefined) && ((theForm.target != "_blank") && (theForm.target != "_new"))) {
				theButton.value = 'Please wait';
				theButton.disabled = true;
			}
			return true;
		} else {
			return false;
		}
	}
	
    function submitForm(theFormId) {
		var theForm = document.getElementById(theFormId);
		return submitFormRaw(theForm);
    }




	/***************************
		FUNCTION: SelectChooserMoveChild
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 06.24.2005

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function gets used by a Select Chooser to move an option from one select box to another.

		PARAMETERS:
				i:			The index of the child option node to move
				box1:		The origin select box
				box2:		The destination select box

		RETURN:
				none
	 ***************************/
	 
function SelectChooserMoveChild(i, box1, box2) {
	var FromBox = document.getElementById(box1);
	try {
		var arrFrom = eval('arr' + box1);
	} catch (e) {
		var arrFrom = undefined;
	}
	var hidFrom = document.getElementById('hid' + box1);
	var ToBox = document.getElementById(box2);
	try {
		var arrTo = eval('arr' + box2);
	} catch (e) {
		var arrTo = undefined;
	}
	var hidTo = document.getElementById('hid' + box2);
	var opt = document.createElement('OPTION');
	opt.value = FromBox.options[i].value;
	opt.text = FromBox.options[i].text;
	ToBox.add(opt);
	if (arrTo != undefined) {
		if (arrTo[0] == '')
			arrTo[0] = opt.value;
		else
			arrTo[arrTo.length] = opt.value;
		hidTo.value = arrTo.join('|');
	}
	FromBox.remove(i);
	if (arrFrom != undefined) {
		arrFrom.splice(InArray(arrFrom, opt.value), 1);
		hidFrom.value = arrFrom.join('|');
	}
}






	/***************************
		FUNCTION: SelectChooserMove
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 06.24.2005

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function gets used by a Select Chooser to move all selected options from one select box to another.

		PARAMETERS:
				box1:		The origin select box
				box2:		The destination select box

		RETURN:
				none
	 ***************************/
	 
function SelectChooserMove(box1, box2) {
	var FromBox = document.getElementById(box1);
	var i;
	for (i = 0; i < FromBox.options.length; i++) {
		if (FromBox.options[i].selected) {
			SelectChooserMoveChild(i, box1, box2);
			FromBox = document.getElementById(box1);
			i = -1;
		}
	}
}






	/***************************
		FUNCTION: InArray
		WRITTEN BY: Ryan Martin
		WRITTEN ON: 06.24.2005

		UPDATED BY:
		UPDATED ON:

		DESCRIPTION: This function finds a member of an array and returns the index of that number.

		PARAMETERS:
				arr:			The array to search in.
				x:				The thing to find

		RETURN:
				integer:		The index of the found item or -1 if not found
	 ***************************/
function InArray(arr, x) {
	var j;
	for (j = 0; j < arr.length; j++) {
		if (arr[j] == x)
			return j;
	}
	return -1;
}










/***********************
start functions for Credit Card validation
		added by Ryan Martin 9/24/2004
***********************/


/****************
 * Validates a credit card number
 ***************/
function validCC(CCNum1, CCType) {
	var result = '';
	var ret = false;
	
	var CCNum = stripAlpha(CCNum1);
	if (CCType == null) {
 			result = 'The credit card type was invalid.  Please enter a valid credit card type.';
	} else {
		if (!isCreditCard(CCNum)) {
 			result = 'The credit card number was invalid.  Please enter a valid credit card number.';
		} else {
			cardType = CCType.toUpperCase();
			switch (cardType) {
				case "A":
					ret = isCardMatch("AMEX", CCNum);
					break;
				case "M":
					ret = isCardMatch("MASTERCARD", CCNum);
					break;
				case "V":
					ret = isCardMatch("VISA", CCNum);
					break;
				case "D":
					ret = isCardMatch("DISCOVER", CCNum);
					break;
				default:
					ret = false;
					break;
			}
			if (!ret)
 				result = 'The credit card was invalid.  Please enter a valid credit card type and number.';
		}	
	}
	
	return result;
}

/****************
 * Validates a credit card date - in the future
 ***************/
function validCCDate(formFieldMonth, formFieldYear, fieldLabel) {
	
}

/******************
 * This function strips all non-numeric characters from a string
 *****************/
function stripAlpha(s) {
	var i;
	result = "";
	for (i = 0; i < s.length; i++) {
		c = s.slice(i,i+1);
		if (!isNaN(parseInt(c)))
			result += c;
	}
	return result;
}

/*  ================================================================
    Credit card verification functions
    Originally included as Starter Application 1.0.0 in LivePayment.
    20 Feb 1997 modified by egk:
           changed naming convention to initial lowercase
                  (isMasterCard instead of IsMasterCard, etc.)
           changed isCC to isCreditCard
           retained functions named with older conventions from
                  LivePayment as stub functions for backward 
                  compatibility only
           added "AMERICANEXPRESS" as equivalent of "AMEX" 
                  for naming consistency 
    ================================================================ */

/*  ================================================================
    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
  var i;
  if (st.length > 19)
    return (false);

  sum = 0; mul = 1; l = st.length;
  for (i = 0; i < l; i++) {
    digit = st.substring(l-i-1,l-i);
    tproduct = parseInt(digit ,10)*mul;
    if (tproduct >= 10)
      sum += (tproduct % 10) + 1;
    else
      sum += tproduct;
    if (mul == 1)
      mul++;
    else
      mul--;
  }
// Uncomment the following line to help create credit card numbers
// 1. Create a dummy number with a 0 as the last digit
// 2. Examine the sum written out
// 3. Replace the last digit with the difference between the sum and
//    the next multiple of 10.

//  document.writeln("<BR>Sum      = ",sum,"<BR>");
//  alert("Sum      = " + sum);

  if ((sum % 10) == 0)
    return (true);
  else
    return (false);

} // END FUNCTION isCreditCard()



/*  ================================================================
    FUNCTION:  isVisa()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid VISA number.
		    
	      false, otherwise

    Sample number: 4111 1111 1111 1111 (16 digits)
    ================================================================ */

function isVisa(cc)
{
  if (((cc.length == 16) || (cc.length == 13)) &&
      (cc.substring(0,1) == 4))
    return isCreditCard(cc);
  return false;
}  // END FUNCTION isVisa()




/*  ================================================================
    FUNCTION:  isMasterCard()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid MasterCard
		    number.
		    
	      false, otherwise

    Sample number: 5500 0000 0000 0004 (16 digits)
    ================================================================ */

function isMasterCard(cc)
{
  firstdig = cc.substring(0,1);
  seconddig = cc.substring(1,2);
  if ((cc.length == 16) && (firstdig == 5) &&
      ((seconddig >= 1) && (seconddig <= 5)))
    return isCreditCard(cc);
  return false;

} // END FUNCTION isMasterCard()





/*  ================================================================
    FUNCTION:  isAmericanExpress()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid American
		    Express number.
		    
	      false, otherwise

    Sample number: 340000000000009 (15 digits)
    ================================================================ */

function isAmericanExpress(cc)
{
  firstdig = cc.substring(0,1);
  seconddig = cc.substring(1,2);
  if ((cc.length == 15) && (firstdig == 3) &&
      ((seconddig == 4) || (seconddig == 7)))
    return isCreditCard(cc);
  return false;

} // END FUNCTION isAmericanExpress()




/*  ================================================================
    FUNCTION:  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:  isAnyCard()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is any valid credit
		    card number for any of the accepted card types.
		    
	      false, otherwise
    ================================================================ */

function isAnyCard(cc)
{
  if (!isCreditCard(cc))
    return false;
  if (!isMasterCard(cc) && !isVisa(cc) && !isAmericanExpress(cc) && !isDinersClub(cc) &&
      !isDiscover(cc) && !isEnRoute(cc) && !isJCB(cc)) {
    return false;
  }
  return true;

} // END FUNCTION isAnyCard()



/*  ================================================================
    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)
{

	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;
	return doesMatch;

}  // END FUNCTION CardMatch()




/*  ================================================================
    The below stub functions are retained for backward compatibility
    with the original LivePayment code so that it should be possible
    in principle to swap in this new module as a replacement for the  
    older module without breaking existing code.  (There are no
    guarantees, of course, but it should work.)

    When writing new code, do not use these stub functions; use the
    functions defined above.
    ================================================================ */

function IsCC (st) {
    return isCreditCard(st);
}

function IsVisa (cc)  {
  return isVisa(cc);
}

function IsVISA (cc)  {
  return isVisa(cc);
}

function IsMasterCard (cc)  {
  return isMasterCard(cc);
}

function IsMastercard (cc)  {
  return isMasterCard(cc);
}

function IsMC (cc)  {
  return isMasterCard(cc);
}

function IsAmericanExpress (cc)  {
  return isAmericanExpress(cc);
}

function IsAmEx (cc)  {
  return isAmericanExpress(cc);
}

function IsDinersClub (cc)  {
  return isDinersClub(cc);
}

function IsDC (cc)  {
  return isDinersClub(cc);
}

function IsDiners (cc)  {
  return isDinersClub(cc);
}

function IsCarteBlanche (cc)  {
  return isCarteBlanche(cc);
}

function IsCB (cc)  {
  return isCarteBlanche(cc);
}

function IsDiscover (cc)  {
  return isDiscover(cc);
}

function IsEnRoute (cc)  {
  return isEnRoute(cc);
}

function IsenRoute (cc)  {
  return isEnRoute(cc);
}

function IsJCB (cc)  {
  return isJCB(cc);
}

function IsAnyCard(cc)  {
  return isAnyCard(cc);
}

function IsCardMatch (cardType, cardNumber)  {
  return isCardMatch (cardType, cardNumber);
}

/***********************
end functions for Credit Card validation
***********************/

function dmpopup(url,theField)
{
	if (!validRequiredPop(theField,"x"))
		popupwindow = window.open(url,"","toolbar=no,location=no,scrollbars=no,resizable=no,width=500,height=300,left=500,top=200");
} 

function popUp(URL) {
day = new Date();
id = day.getTime();
eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=600,height=400,left = 112,top = 109');");
}

function validRequiredPop(formField,fieldLabel)
{
	var result = true;
	
	if (formField.value == "")
	{
		result = false;
	}
	
	return result;
}

function ChangePackage(strCode, iPackage_id) {
	var arrCode = strCode.split('-');
	arrCode[1] = iPackage_id;
	return arrCode.join('-');
}