String.prototype.trim = function () {
    return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
}; 
function validate(fieldArray, theForm, displayVersion)
{
	/**
	*  fieldArray:
	*	each item in the array is composed of three values that are pipe delimited
	*	the first one is the actual name of the html form field
	*	the second one is the name of the field as it should appear to the user
	*	the third one is a comma delimited list showing what validation to use on the field
	*	the fourth one is optional and specifies a custom error message to use
	*
	*	example:
	*		//This is how the array should be set up in the html template
	*		<script language="javascript">
	*			var fieldArray = new Array();
	*			fieldArray[0] = "last_name|Last Name|blank";
	*			fieldArray[1] = "account_name|Company|blank|This field cannot be blank!!!";
	*			fieldArray[2] = "lead_status_id|Lead Status|DDSelected";
	*			fieldArray[3] = "phone|Phone|phone";
	*			fieldArray[4] = "phone2|International Phone|intphone";
	*			fieldArray[5] = "email|Email|blank,email";
	*			fieldArray[6] = "zip|Zip Code|zip";
	*			fieldArray[7] = "percentage|Percent|numberrange(1-100),number";
	*		</script>
	*
	*	possible values for validation:
	*		blank       - returns an error string if the field is an empty string
	*		blankNoZero - returns an error string if the field is an empty string or it is a 0
	*		DDSelected  - returns an error string if the selected value is an empty string
	*		phone       - tries to parse the field into a standard ###-###-#### format
	*		              if the value cannot be parsed an error string is returned
	*		optPhone    - returns an error if not blank and also not in a standard phone format
	*		email       - returns an error string if the value of the field is not 
	*		              empty and does not match a standard email format
	*		zip         - returns an error string if the value does not match a standard zip format
	*		number      - returns an error string if the value is not a number
	*		numberrange - returns an error string if the value is not a number or if the number is 
	*		              not within a specified range
	*		unsigned_int- returns an error string if the value is not an unsigned whole number
	*		IPv4        - returns an error if the value is not a valid IPv4 address format ###.###.###.###
	*		checkbox    - returns an error if checkbox is not checked
	*/

	var errors = "", data, field, fieldName, validateTypes, custErr, parameter, field_element, theValidateType, x;
	for (var i=0;i<fieldArray.length;i++)
	{
		if (fieldArray[i] == "") continue;
		data = fieldArray[i].split("|");
		field = data[0];
		fieldName = data[1];
		validateTypes = data[2].split(",");
		custErr = data[3];
		for (x=0;x<validateTypes.length;x++)
		{
			if (validateTypes[x].indexOf("(") > 0)
			{
				parameter = getParameter(validateTypes[x]);
				if (parameter.length < 1)
				{
					alert("Invalid parameter value for validation type of " + validateTypes[x] + " on " + field + " field");
				}
				theValidateType = validateTypes[x].toLowerCase().substr(0,validateTypes[x].indexOf("("));
			}else{
				theValidateType = validateTypes[x].toLowerCase();
			}
			field_element = theForm[field];
			//_hidden_ will be set to true when the field is in a hidden panel
			try{
				if(typeof(field_element._hidden_) != "undefined" && field_element._hidden_)
					continue;
			}
			catch(e){}
			switch (theValidateType)
			{
			case "blank":
				errors += isBlank(field_element,fieldName,custErr,false);
				break;
			case "blanknozero":
				errors += isBlank(field_element,fieldName,custErr,true);
				break;
			case "ddselected":
				errors += isDDSelected(field_element,fieldName,custErr);
				break;
			case "multiselecthasoptions":
				errors += checkMultiSelectHasOptions(field_element,fieldName,custErr);
				break;
			case "advmultiselecthasoptions":
				errors += checkAdvMultiSelectHasOptions(theForm[field+"_dst"],fieldName,custErr);
				break;
			case "phone":
				errors += checkPhoneField(field_element,fieldName,custErr);
				break;
			case "optphone":
				errors += checkOptPhoneField(field_element,fieldName,custErr);
				break;
			case "intphone":
				errors += checkIntPhoneField(field_element,fieldName,custErr);
				break;
			case "email":
				errors += isEmail(field_element,fieldName,custErr);
				break;
			case "zip":
				errors += isZip(field_element,fieldName,custErr);
				break;
			case "number":
				errors += isNumber(field_element,fieldName,custErr);
				break;
			case "numberrange":
				errors += isNumberRange(field_element,fieldName,parameter,custErr);
				break;
			case "unsigned_int":
				errors += isUnsignedInteger(field_element,fieldName,custErr);
				break;
			case "ipv4":
				errors += isValidIPv4(theForm, field, fieldName,custErr);
				break;
			case "mx":
				errors += isValidDomain(field_element,fieldName,custErr);
				break;
			case "area_code":
				errors += isValidAreaCode(field_element,fieldName,custErr);
				break;
			case "checkbox":
				errors += isCheckboxChecked(field_element,fieldName,custErr);
				break;
				
			}
		}
	}
	
	return displayErrors(errors, displayVersion, true);
}

/*
 * a standard way to display errors
 */
function displayErrors(
	errors, displayVersion, for_validation
) {
	var retVal = true;
	var msg = '';

	if (errors.length > 0)
	{
		if (for_validation) {
			if (displayVersion == 'pdsf') {
				alert(errors, "Attention!");
			} else if (displayVersion == 2) {
				msg = "More Information Required\n\
Please complete all required fields:\n\n" +
errors;
				alert(msg);
			} else {
				msg = "More Information Required:\n\
==============================\n\
Please complete all required fields:\n\n" +
errors;
				alert(msg);
			}
		} else {
			alert(errors);
		}

		retVal = false;
	}

	return retVal;
}


//////////////////////////////////////////////////////////////////////////////
//
//  isBlank()
//
//////////////////////////////////////////////////////////////////////////////
function isBlank(theField, fieldName,custErr,zeroIsBlank)
{
	var errors = "";
	if(typeof(theField) == "object"){
		var theValue = theField.value;
		theValue = theValue.trim();
		if (theValue.length < 1 || (zeroIsBlank && theValue==0)){
			if (custErr){
				errors += custErr+"\n"
			} else {
				errors += fieldName + " is a required field.\n"
			}
		}
	}
	
	return errors;
}


//////////////////////////////////////////////////////////////////////////////
//
//  isDDSelected()
//
//////////////////////////////////////////////////////////////////////////////
function isDDSelected(theField, fieldName,custErr)
{
	var errors = "";
	var theValue = "";

	if (theField.options.length > 0 && theField.selectedIndex >= 0){
		theValue = theField.options[theField.selectedIndex].value;
	} else {
		if (custErr){
			errors += custErr+"\n"
		} else {
			errors += "You must select an option from " + fieldName + ".\n"
		}
		return errors;
	}

	// CHECK IF THE VALUE IS SOMETHING OTHER THAN BLANK
	if (theValue.length < 1){
		if (custErr){
			errors += custErr+"\n"
		} else {
			errors += "You must select an option from " + fieldName + ".\n"
		}
	}
	return errors;
}

//////////////////////////////////////////////////////////////////////////////
//
//  isCheckboxChecked()
//
//////////////////////////////////////////////////////////////////////////////
function isCheckboxChecked(theField, fieldName,custErr)
{
	var errors = "";
	if(typeof(theField) == "object"){
		if (!theField.checked){
			if (custErr){
				errors += custErr+"\n"
			} else {
				errors += fieldName + " is a required field.\n"
			}
		}
	}
	
	return errors;
}

//////////////////////////////////////////////////////////////////////////////
//
//  checkMultiSelectHasOptions()
//
//////////////////////////////////////////////////////////////////////////////
function checkMultiSelectHasOptions(theField, fieldName,custErr)
{
	var errors = "";
	var theValue = "";
	// CHECK THAT THE SELECT FIELD HAS OPTIONS
	if (theField.options.length < 1)
	{
		if (custErr){
			errors += custErr+"\n"
		} else {
			errors += fieldName + " cannot be blank.\n"
		}
	}
	return errors;
}
function checkAdvMultiSelectHasOptions(theField, fieldName,custErr)
{
	var errors = "";
	var theValue = "";
	// CHECK THAT THE SELECT FIELD HAS OPTIONS
	if (theField.options.length < 1)
	{
		if (custErr){
			errors += custErr+"\n"
		} else {
			errors += fieldName + " must have a value.\n"
		}
	}
	return errors;
}
//////////////////////////////////////////////////////////////////////////////
//
//  isEmail()
//
//////////////////////////////////////////////////////////////////////////////
function isEmail(theField, fieldName,custErr)
{
	var errors = "";
	var theValue = theField.value;
	theValue     = theValue.trim();
	
	// CHECK IF THE EMAIL IS VALID
	var re = new RegExp();
	re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/;
	if (!re.test(theValue) && theValue.length != 0) 
	{
		if (custErr){
			errors += custErr+"\n"
		} else {
			errors += fieldName + " is not a valid email address.\n";
		}
	}
	return errors;
}

//////////////////////////////////////////////////////////////////////////////
//
//  isValidDomain()
//
//////////////////////////////////////////////////////////////////////////////
function isValidDomain(theField, fieldName,custErr)
{
	var errors = "";
	theField.value = theField.value.trim();
	var theValue = theField.value;

	try
	{
		url = "validate_email.php?email="+theValue;
		response = AJAX_get(url, false);
		if (response == "valid")
		{
			errors.length == 0;
			return errors;
		}
	}
	catch(e){}

	if (custErr){
		errors += custErr+"\n"
	} else {
		errors += theValue + " is not a valid email address.\n";
	}
	return errors;
}

//////////////////////////////////////////////////////////////////////////////
//
//  isValidAreaCode()
//
//////////////////////////////////////////////////////////////////////////////
function isValidAreaCode(theField, fieldName, custErr)
{
	var errors = "";
	theField.value = theField.value.trim();
	var theValue = theField.value;

	try
	{
		url = "validate_areacode.php?phone_number="+theValue;
		response = AJAX_get(url, false);
		if (response == "1")
		{
			errors.length == 0;
			return errors;
		}
	}
	catch(e){}

	if (custErr){
		errors += custErr+"\n"
	} else {
		errors += theValue + " has an invalid area code.\n";
	}
	return errors;
}

//////////////////////////////////////////////////////////////////////////////
//
//  isZip()
//
//////////////////////////////////////////////////////////////////////////////
function isZip(theField, fieldName,custErr)
{
	return "";
	var errors = "";
	var theValue = theField.value;

	// CHECK IF THE ZIPCODE IS VALID
	var re = new RegExp();
	re = /^[0-9]{5}$/;
	if (theValue.length > 5)
	{
		theValue = theValue.substr(0,5);
	}
	if (!re.test(theValue) && theValue.length != 0) 
	{
		errors += fieldName + " is not a valid zip code.\n";
	}
	theField.value = theValue;
	return errors;
}

function checkOptPhoneField(phoneField, fieldName,custErr)
{
    if(!isBlank(phoneField, fieldName,custErr))
    {
	return checkPhoneField(phoneField, fieldName,custErr)
    } else {
	return "";
    }
}


//////////////////////////////////////////////////////////////////////////////
//
//  checkPhoneField()
//
//////////////////////////////////////////////////////////////////////////////
function checkPhoneField(phoneField, fieldName,custErr)
{
	//INITIALIZE VARS
	var firstThree = "";
	var middleThree = "";
	var lastNumbers = "";
	var errors = "";
	var phone=phoneField.value;
	// CLEAR ALL NON NUMBER CHARACTERS
	phone = phone.replace(/[\(\)\- ,\.]/g,"");
	if (phone.length == 0)
	{
	    return "Required Phone Field cannot be blank";
	}
	// CLEAR LEADING 1
	if (phone.length > 10){
		phone = (phone.charAt(0)=="1"?phone.substr(1,phone.length):phone);
		if(validateIntl(phone)) //Do not rewrite phone number if it is a valid international number
		{
		    return "";
		}
	}

	// CHECK LENGTH OF PHONE NUMBER
	if (phone.length < 10 && phone.length > 0){
		errors += fieldName + " is an invalid phone format:  Not enough numbers.\n"
	}

	// CHECK LENGTH OF PHONE NUMBER
	if (phone.length > 10){
		errors += fieldName + " is an invalid phone format:  Too many numbers.\n"
	}

	// CHECK IF INPUT IS A NUMBER
	if (isNaN(phone)){
		errors += fieldName + " is an invalid phone format:  Invalid characters.\n"
	}
	areaCode = phone.substr(0,3);
	if(!checkAreaCode(areaCode)) {
	    errors += fieldName + " is an invalid phone format:  Invalid area code.\n"
	}

	// SHOW ERRORS
	if (errors.length > 0){
		//errors += "\nMust use following format:  ###-###-####";
		return errors;
	}
	
	// GET FIRST THREE
	if (phone.length > 2){
		firstThree = "(" + areaCode + ") ";
		// GET SECOND THREE
		if (phone.length > 5){
			middleThree = phone.substr(3,3) + "-";
			// GET REST OF NUMBER
			if (phone.length > 5){
				lastNumbers = phone.substr(6,phone.length);
			}
		}else{
			lastNumbers = phone.substr(3,phone.length);
		}
	}else{
		lastNumbers = phone;
	}
	
	// PUT NUMBERS TOGETHER
	newPhone = firstThree + middleThree +lastNumbers;
	// RETURN VALUE
	phoneField.value = newPhone;
	return errors;
}

//////////////////////////////////////////////////////////////////////////////
//
//  checkIntPhoneField()
//
//////////////////////////////////////////////////////////////////////////////
function checkIntPhoneField(phoneField, fieldName,custErr)
{
	var firstThree = "";
	var middleThree = "";
	var lastNumbers = "";
	var errors = "";
	var phone=phoneField.value;
	
	// CLEAR LEADING 1
	if (phone.length == 11){
		phone = (phone.charAt(0)=="1"?phone.substr(1,phone.length):phone);
	}

	// IF LENGTH OF PHONE IS EQUAL TO 10 CLEAR ALL NON NUMBER CHARACTERS
	if (phone.replace(/[\(\)\- ,\.]/g,"").length == 10){
		phone = phone.replace(/[\(\)\- ,\.]/g,"");
	}else{
		return errors;
	}

	// GET FIRST THREE
	firstThree = "(" + phone.substr(0,3) + ") ";

	// GET SECOND THREE
	middleThree = phone.substr(3,3) + "-";
	
	// GET REST OF NUMBER
	lastNumbers = phone.substr(6,phone.length);
	
	// PUT NUMBERS TOGETHER
	newPhone = firstThree + middleThree + lastNumbers;
	
	// RETURN VALUE
	phoneField.value = newPhone;
	return errors;
}

//////////////////////////////////////////////////////////////////////////////
//
//  isNumber()
//
//////////////////////////////////////////////////////////////////////////////
function isNumber(theField, fieldName,custErr)
{
	var errors = "";
	var theFieldValue = theField.value;
	
	// CHECK IF THE VALUE IS A NUMBER OR NOT
	if (isNaN(theFieldValue)){
		if (custErr){
			errors += custErr+"\n"
		} else {
			errors += fieldName + " is not a valid number.\n"
		}
	}
	return errors;
}

//////////////////////////////////////////////////////////////////////////////
//
//  isNumberRange(range)
//
//////////////////////////////////////////////////////////////////////////////
function isNumberRange(theField, fieldName, range,custErr)
{
	var errors = "";
	var theFieldValue = theField.value;
	
	// CHECK IF THE VALUE IS A NUMBER OR NOT
	errors += isNumber(theField, fieldName, custErr);
	
	// CHECK IF THE VALUE WITHIN THE SPECIFIED RANGE
	rangeVals = range.split("-");
	if (parseInt(theFieldValue) < parseInt(rangeVals[0]) || parseInt(theFieldValue) > parseInt(rangeVals[1])){
		if (custErr){
			errors += custErr+"\n"
		} else {
			errors += fieldName + " is not within the specified range of " + rangeVals[0] + " - " + rangeVals[1] + ".\n"
		}
	}
	return errors;
}

function isUnsignedInteger(theField, fieldName, custErr){

	var errors = "";
	var theFieldValue = theField.value;

	// CHECK IF THE VALUE IS AN UNSIGNED INTEGER OR NOT
	if ((theFieldValue.toString().search(/^[0-9]+$/) != 0)){
		if (custErr){
			errors += custErr+"\n"
		} else {
			errors += fieldName + " is not a positive whole number.\n"
		}
	}
	return errors;
}

//////////////////////////////////////////////////////////////////////////////
//
//  isValidIPv4()
//
//////////////////////////////////////////////////////////////////////////////
function isValidIPv4(theForm, theField, fieldName, custErr)
{
	var errors = "";
	// CHECK TO SEE IF ITS AN ARRAY OF VALUES
	if (theField.indexOf("[]") > 0){
	  ipFields = theForm.elements[theField];
	  for (var i=0;i<ipFields.length;i++ )
	  {
		ipFields[i].value = ipFields[i].value.trim();
		// ALLOW EMPTY FIELDS
		if (ipFields[i].value != "")
		  errors += validateIP(ipFields[i].value, custErr);
		
	  }
	} else {
      ipField = eval("theForm." + theField);
	  ipField.value = ipField.value.trim();
	  // ALLOW EMPTY FIELD
	  if (ipField.value != "")
	    errors += validateIP(ipField.value, custErr);
	  
	}
	
	return errors;
}

//////////////////////////////////////////////////////////////////////////////
//
//  validateIP()
//
//////////////////////////////////////////////////////////////////////////////
function validateIP(address, custErr)
{
	var sections = address.split(".");
	if (sections.length != 4)
	{
		if (custErr)
			return custErr+"\n";
		else
			return "IP Address: "+address+" is invalid.\n";
	}

	for (var i=0;i<sections.length;i++)
	{
		num = Number(sections[i]);
		if (num > 255 || num < 0 || isNaN(num))
		{
			if (custErr)
				return custErr+"\n";
			else
				return "IP Address: "+address+" is invalid.\n";
		}
	}
	return "";
}


//////////////////////////////////////////////////////////////////////////////
//
//  getParameter()
//
//////////////////////////////////////////////////////////////////////////////
function getParameter(theValue)
{
	startIndex = theValue.indexOf("(");
	endIndex   = theValue.indexOf(")");
	return theValue.substr(startIndex+1,endIndex-startIndex-1);
}

residentialAreaCodes = new Array(
    201, 202, 203, 205, 206, 207, 208, 209, 210, 212, 213, 214, 215, 216, 217, 218,
    219, 224, 225, 228, 229, 231, 234, 236, 239, 240, 248, 251, 253, 254, 256, 260,
    262, 267, 269, 270, 276, 278, 281, 283, 301, 302, 303, 304, 305, 307, 308, 309,
    310, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 323, 325, 330, 331, 334,
    336, 337, 339, 341, 347, 351, 352, 360, 361, 369, 380, 385, 386, 401, 402, 404,
    405, 406, 407, 408, 409, 410, 412, 413, 414, 415, 417, 419, 423, 424, 425, 430,
    432, 434, 435, 440, 442, 443, 464, 469, 470, 475, 478, 479, 480, 484, 501, 502,
    503, 504, 505, 507, 508, 509, 510, 512, 513, 515, 516, 517, 518, 520, 530, 540,
    541, 551, 557, 559, 561, 562, 563, 564, 567, 570, 571, 573, 574, 575, 580, 585,
    586, 601, 602, 603, 605, 606, 607, 608, 609, 610, 612, 614, 615, 616, 617, 618,
    619, 620, 623, 626, 627, 628, 630, 631, 636, 641, 646, 650, 651, 660, 661, 662,
    669, 678, 679, 682, 689, 701, 702, 703, 704, 706, 707, 708, 712, 713, 714, 715,
    716, 717, 718, 719, 720, 724, 727, 731, 732, 734, 737, 740, 747, 754, 757, 760,
    762, 736, 764, 765, 769, 770, 772, 773, 774, 775, 779, 781, 785, 786, 801, 802,
    803, 804, 805, 806, 808, 810, 812, 813, 841, 815, 816, 817, 818, 828, 830, 831,
    832, 835, 845, 847, 848, 850, 856, 857, 858, 859, 860, 862, 863, 864, 865, 870,
    872, 878, 901, 903, 904, 906, 907, 908, 909, 910, 912, 913, 914, 915, 916, 917,
    918, 919, 920, 925, 927, 928, 931, 935, 936, 937, 940, 941, 947, 949, 951, 954,
    956, 957, 959, 970, 971, 972, 973, 975, 978, 979, 980, 984, 985, 989);

tollFreeAreaCodes = new Array('800', '888', '877', '866');

function checkAreaCode(intValue)
{
    for(codeIndex in (residentialAreaCodes))
    {
	if(intValue == residentialAreaCodes[codeIndex])
	    return true;
    }
    for(codeIndex in (tollFreeAreaCodes))
    {
	if(intValue == tollFreeAreaCodes[codeIndex])
	    return true;
    }
    return false;
}

function validateIntl (phone) {
    var regex = /^\+(?:[0-9] ?){6,14}[0-9]$/;

    if (regex.test(phone)) {
        return true;
    } else {
        return false;
    }
}

