// Form Validation Functions  v1.1.8*(see below for custom modifications)
// documentation: http://www.dithered.com/javascript/form_validation/index.html
// license: http://creativecommons.org/licenses/by/1.0/
// code by Chris Nott (chris[at]dithered[dot]com)

/*
Jamie Krug 8/10/2005 modifications
	Renamed isNumeric() function to isNumericDigits(), and created new isNumeric() to allow negatives and decimal.
	Functions added:
	-- numericMin()
	-- numericMax()
	-- isNumeric()/isNumericDigits()--see above
	element.patternTexts added:
	-- 'numeric' (modified)
	-- 'numeric digits' (previously 'numeric')
	-- 'alphabetic no whitespace'
	-- 'alphanumeric no whitespace'
	-- 'numeric digits no whitespace'

Jamie Krug 8/15/2005 modifications
	Functions added:
	-- isDateMDY()
	-- isLeapYear()
	element.patternTexts added:
	-- 'date'

Ilya Fedotov 2/10/2006
	-- isTrue()

Wayne Holler 2/20/2006
	-- isValidSelect()

Ilya Fedotov 2/23/2006
	-- isTrueGroup()
	-- ListFindNoCase()

Tracy Logan 1/16/2007
	-- corrected phone pattern (was using "prefixNumber+prefixNumber" instead of "prefixNumber+suffixNumber")
	-- changed prefixNumber to exchange
	-- changed suffixNumber to lineNumber (per NATP standards)
	-- cleaned up the JS & CFC phone validations (removed entries from *lists* that could be checked for with simpler code)
	-- added *11 exclusion (ie, 411, 911, 311, etc.) for both Areacode and Exchange.
	-- synchronized validations in JS and CFC, so both are checking for the same things, rather than having differing validations as before.
	
Tracy Logan 1/25/2007
	-- worked around a bug in Opera 9.10 (which errors on the word "pattern" as used here!)
		-- changed "pattern" to "patternText" (also in C:\www\cu2005\model\leads\leadValidation\ValidationJS.cfc, which generates the JS that calls this)
*/


/*
function getFormErrors(form) {
   var errors = new Array();
   
   // loop thru all form elements
   for (var elementIndex = 0; elementIndex < form.elements.length; elementIndex++) {
      var element = form.elements[elementIndex];

	  checkFormErrors(element, errors);
	  
	  if (element.type == "text" || element.type == "textarea" || element.type == "password") {
         	element.value = trimWhitespace(element.value)
			if (element.fieldCompareNoCase && fieldCompareNoCase(form.elements, element.value, element.fieldCompareNoCaseTo) == false) {
	            errors[errors.length] = element.fieldCompareNoCaseError;
	         }		
	  }
	  // checkbox
	  else if ( element.type == "checkbox") {
		 // group of checkboxes, different field names, check that at least one is checked
		 if (element.isTrueGroup && isTrueGroup(form.elements, element.isTrueGroupFields) == false) {
            errors[errors.length] = element.isTrueGroupError;
         }		 
	  }
      
	  //save elementIndex of first field in which was error in first slot of errors array
	  if (errors.length == 1)  {
	  	errors[1] = errors[0]; 
		errors[0] = elementIndex;
	  }
	  
   }
   
   return errors;
}
*/

function getFormErrors(form,field,step) {
   var errors = new Array();

   // loop thru all form elements
   for (var elementIndex = 0; elementIndex < form.elements.length; elementIndex++) {
      var element = form.elements[elementIndex];
	  if ((field == null || element.name == field) && checkDescendant(element,step))  {
		  checkFormErrors(form, element, errors);
		 
		  if (element.type == "text" || element.type == "textarea" || element.type == "password") {
         	element.value = trimWhitespace(element.value)
			if (element.fieldCompareNoCase && fieldCompareNoCase(form.elements, element.value, element.fieldCompareNoCaseTo) == false) {
	            errors[errors.length] = element.fieldCompareNoCaseError;
	        }

			else if (element.fieldCompareNoCase && fieldCompareNoCase(form.elements, element.value, element.fieldCompareNoCaseTo) == false) {
	            errors[errors.length] = element.fieldCompareNoCaseError;
	        }		
			
		  }
		  // checkbox
		  else if ( element.type == "checkbox") {
			 // group of checkboxes, different field names, check that at least one is checked
			 if (element.isTrueGroup && isTrueGroup(form.elements, element.isTrueGroupFields) == false) {
	            errors[errors.length] = element.isTrueGroupError;
	         }		 
		  }
		  
		  // radio buttons
	      else if (element.type == "radio") {
	         var radiogroup = form.elements[element.name];
			 radiogroup.failed = false;
	         // required element
	         if (radiogroup.length && radiogroup[0] && radiogroup[0].required) {
	            var checkedRadioButton = -1;
				radiogroup.failed = true;
	            for (var radioIndex = 0; radioIndex < radiogroup.length; radioIndex++) {
	               if (radiogroup[radioIndex].checked == true) {
	                  checkedRadioButton = radioIndex;
					  radiogroup.failed = false;
					  break;
	               }
	            }
	            
	            // show error if required and flag group as having been tested
	            if ((checkedRadioButton == -1 || checkedRadioButton == null) && !radiogroup.tested) {
	            	errors[errors.length] = radiogroup[0].requiredError;
	               	radiogroup.tested = true;
	            }
	            
	            // last radio button in group?  reset tested flag
	            if (element == radiogroup[radiogroup.length - 1]) {
				   radiogroup.tested = false;
	            }
	         } 
			 
			 
			 if (!radiogroup.failed && radiogroup.length && radiogroup[0] && radiogroup[0].isValidSelectRadio) {
	            var checkedRadioButton = -1;
	            for (var radioIndex = 0; radioIndex < radiogroup.length; radioIndex++) {
	               if (radiogroup[radioIndex].checked == true && isValidSelect(radiogroup[radioIndex],radiogroup[0].isValidSelectRadioList,radiogroup[0].isValidSelectRadioDelim) ) {
	                  checkedRadioButton = radioIndex;
	                  break;
	               }
	            }
	            
	            // show error if required and flag group as having been tested
	            if (checkedRadioButton == -1 && !radiogroup.isValidSelectRadioTested) {
	               errors[errors.length] = radiogroup[0].isValidSelectRadioError;
	               radiogroup.isValidSelectRadioTested = true;
	            }
	            
	            // last radio button in group?  reset tested flag
	            if (element == radiogroup[radiogroup.length - 1]) {
	               radiogroup.isValidSelectRadioTested = false;
	            }
	         }
	        
	      }
		  
	  }
	  
	  //save elementIndex of first field in which was error in first slot of errors array
	  if (errors.length == 1)  {
	  	errors[1] = errors[0]; 
		errors[0] = elementIndex;
	  }
	  
   }
   return errors;
}

function checkFormErrors(form, element, errors)  {
	// text and textarea types
      if (element.type == "text" || element.type == "textarea" || element.type == "password") {
         element.value = trimWhitespace(element.value)
         
         // required element
         if (element.required  && element.value == '') {
            errors[errors.length] = element.requiredError;
         }
         
		 // chars interval
         else if (element.charsintervalmin && isValidLength(element.value, element.charsintervalmin, element.charsintervalmax) == false) {
            errors[errors.length] = element.charsintervalError;
         }
		 
         // maximum length
         else if (element.maxlength && isValidLength(element.value, 0, element.maxlength) == false) {
            errors[errors.length] = element.maxlengthError;
         }
		
         // minimum length
         else if (element.minlength && isValidLength(element.value, element.minlength, Number.MAX_VALUE) == false) {
            errors[errors.length] = element.minlengthError;
         }
		 
		 // numeric range
         else if (element.numericrangemin && isValidNumericRange(element.value, element.numericrangemin, element.numericrangemax) == false) {
            errors[errors.length] = element.numericrangeError;
         }
         
         // maximum number
         else if (element.numericmax && numericMax(element.value, element.numericmax) == false) {
            errors[errors.length] = element.numericmaxError;
         }
         
         // minimum number
         else if (element.numericmin && numericMin(element.value, element.numericmin) == false) {
            errors[errors.length] = element.numericminError;
         }
		 
		 // true or false
         else if (element.isTrue && isTrue(element.value) == false) {
            errors[errors.length] = element.isTrueError;			 
         }
         
         // patternText (credit card number, email address, zip or postal code, alphanumeric, numeric)
         else if (element.patternText) {
            if ( ( (element.patternText.toLowerCase() == 'visa' || element.patternText.toLowerCase() == 'mastercard' || element.patternText.toLowerCase() == 'american express' || element.patternText.toLowerCase() == 'diners club' || element.patternText.toLowerCase() == 'discover' || element.patternText.toLowerCase() == 'enroute' || element.patternText.toLowerCase() == 'jcb' || element.patternText.toLowerCase() == 'credit card') && isValidCreditCard(element.value, element.patternText) == false) ||
                  (element.patternText.toLowerCase() == 'email' && isValidEmailStrict(element.value) == false) ||
                  (element.patternText.toLowerCase() == 'zip or postal code' && isValidZipcode(element.value) == false && isValidPostalcode(element.value) == false) ||
                  (element.patternText.toLowerCase() == 'zipcode' && isValidZipcode(element.value) == false) ||
                  (element.patternText.toLowerCase() == 'postal code' && isValidPostalcode(element.value) == false) ||
                  (element.patternText.toLowerCase() == 'us phone number' && 
                     ( (element.phonePrefix && element.phoneSuffix && isValidUSPhoneNumber(element.value, form[element.phonePrefix].value, form[element.phoneSuffix].value) == false) || 
					   (element.phonePrefix && !element.phoneSuffix && isValidUSPhoneNumber(element.value, form[element.phonePrefix].value) == false) || 
                       (!element.phonePrefix && !element.phoneSuffix && isValidUSPhoneNumber(element.value) == false) ) ) ||					   
				  (element.patternText.toLowerCase() == 'us phone number optional' && 
                     ( (element.phonePrefix && element.phoneSuffix && isValidUSPhoneNumberOptional(element.value, form[element.phonePrefix].value, form[element.phoneSuffix].value) == false) || 
					   (element.phonePrefix && !element.phoneSuffix && isValidUSPhoneNumberOptional(element.value, form[element.phonePrefix].value) == false) || 
                       (!element.phonePrefix && !element.phoneSuffix && isValidUSPhoneNumberOptional(element.value) == false) ) ) ||
                  (element.patternText.toLowerCase() == 'alphabetic' && isAlphabetic(element.value, true) == false) ||
                  (element.patternText.toLowerCase() == 'alphabetic no whitespace' && isAlphabetic(element.value, false) == false) ||
                  (element.patternText.toLowerCase() == 'alphanumeric' && isAlphanumeric(element.value, true) == false) ||
                  (element.patternText.toLowerCase() == 'alphanumeric no whitespace' && isAlphanumeric(element.value, false) == false) ||
                  (element.patternText.toLowerCase() == 'numeric digits' && isNumericDigits(element.value, true) == false) ||
                  (element.patternText.toLowerCase() == 'numeric digits no whitespace' && isNumericDigits(element.value, false) == false) ||
                  (element.patternText.toLowerCase() == 'numeric' && isNumeric(element.value) == false) ||
                  (element.patternText.toLowerCase() == 'date' && isDateMDY(element.value) == false) ) {
               errors[errors.length] = element.patternError;
            }
         }
      }
      
      // file upload
      if (element.type == "file") {
         
         // required element
         if (element.required  && element.value == '') {
            errors[errors.length] = element.requiredError;
         }
      }
      
      // select
      else if (element.type == "select-one" || element.type == "select-multiple" || element.type == "select") {

         // required element
         if (element.required && element.selectedIndex == -1) {
            errors[errors.length] = element.requiredError;
         }
         
         // disallow empty value selection
         else if (element.disallowEmptyValue && element.options[element.selectedIndex].value == '') {
            errors[errors.length] = element.disallowEmptyValueError;
         }
	
	 	// Bad List value selection
         else if (element.isValidSelection && isValidSelect(element.options[element.selectedIndex],element.isValidSelectList,element.isValidSelectDelim)== false ){
            errors[errors.length] = element.isValidSelectError;
         }
		 
	 	// Good List value selection
         else if (element.isInvalidSelection && isInvalidSelect(element.options[element.selectedIndex],element.isInvalidSelectList,element.isInvalidSelectDelim)== true ){
            errors[errors.length] = element.isInvalidSelectError;
         }
		 
		 else if (element.isValidConditionList && isValidConditionList(element.options[element.selectedIndex].value, element.validList, element.conditionValue, element.conditionList) == false) {
	            errors[errors.length] = element.isValidConditionListError;	
		 }
		 
		 else if (element.isNotValidConditionList && isNotValidConditionList(element.options[element.selectedIndex].value, element.validList, element.conditionValue, element.conditionList) == false) {
	            errors[errors.length] = element.isNotValidConditionListError;	
		 }
      }
      
	  // checkbox
	  else if ( element.type == "checkbox") {
	  	 // true or false
         if (element.isTrue && isTrue(element.checked) == false) {
            errors[errors.length] = element.isTrueError;
         }
		 
	  }
}


// check that element in the correct step and should be validated
function checkDescendant(element,step) {
	var isDescendant = true;
	if(step != null) {
		//find out if this element in an ancestor of our step
		var arrAncestors = $(element).parents(); //TODO: Is this function only used for UoP?  See school380Hybrid_LeadForm.cfm.  This seems to be the only line to make this library dependent on prototype/jQuery.
	  	var isDescendant = false;
	  	for (var arrIter = 0; arrIter < arrAncestors.length; arrIter++) {
	  		if (arrAncestors[arrIter].id == step) {
	  			isDescendant = true;
		  	}
	  	}
	}
	return isDescendant;
}

// Check that the number of characters in a string is between a max and a min
function isValidLength(string, min, max) {
   if (string.length < min || string.length > max) return false;
   else return true;
}

// Check that a credit card number is valid based using the LUHN formula (mod10 is 0)
function isValidCreditCard(number) {
   number = '' + number;
   
   if (number.length > 16 || number.length < 13 ) return false;
   else if (getMod10(number) != 0) return false;
   else if (arguments[1]) {
      var type = arguments[1];
      var first2digits = number.substring(0, 2);
      var first4digits = number.substring(0, 4);
      
      if (type.toLowerCase() == 'visa' && number.substring(0, 1) == 4 &&
         (number.length == 16 || number.length == 13 )) return true;
      else if (type.toLowerCase() == 'mastercard' && number.length == 16 &&
         (first2digits == '51' || first2digits == '52' || first2digits == '53' || first2digits == '54' || first2digits == '55')) return true;
      else if (type.toLowerCase() == 'american express' && number.length == 15 && 
         (first2digits == '34' || first2digits == '37')) return true;
      else if (type.toLowerCase() == 'diners club' && number.length == 14 && 
         (first2digits == '30' || first2digits == '36' || first2digits == '38')) return true;
      else if (type.toLowerCase() == 'discover' && number.length == 16 && first4digits == '6011') return true;
      else if (type.toLowerCase() == 'enroute' && number.length == 15 && 
         (first4digits == '2014' || first4digits == '2149')) return true;
      else if (type.toLowerCase() == 'jcb' && number.length == 16 &&
         (first4digits == '3088' || first4digits == '3096' || first4digits == '3112' || first4digits == '3158' || first4digits == '3337' || first4digits == '3528')) return true;
      
    // if the above card types are all the ones that the site accepts, change the line below to 'else return false'
    else return true;
   }
   else return true;
}

// Check that an email address is valid based on RFC 821 (?)
function isValidEmail(address) {
   if (address != '' && address.search) {
      if  (address.search(/^\w+((-\w+)|(\.\w+))|(\+)*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) != -1) return true;
      else return false;
   }
   
   // allow empty strings to return true - screen these with either a 'required' test or a 'length' test
   else return true;
}

// Check that an email address has the form something@something.something
// This is a stricter standard than RFC 821 (?) which allows addresses like postmaster@localhost
function isValidEmailStrict(address) {
   if (isValidEmail(address) == false) return false;
   var domain = address.substring(address.indexOf('@') + 1);
   if (domain.indexOf('.') == -1) return false;
   if (domain.indexOf('.') == 0 || domain.indexOf('.') == domain.length - 1) return false;
   return true;
}

// Check that a US zip code is valid
function isValidZipcode(zipcode) {
   zipcode = removeSpaces(zipcode);
   if (!(zipcode.length == 5 || zipcode.length == 9 || zipcode.length == 10)) return false;
   if ((zipcode.length == 5 || zipcode.length == 9) && !isNumericDigits(zipcode)) return false;
   if (zipcode.length == 10 && zipcode.search && zipcode.search(/^\d{5}-\d{4}$/) == -1) return false;
   return true;
}

// Check that a Canadian postal code is valid
function isValidPostalcode(postalcode) {
   if (postalcode.search) {
      postalcode = removeSpaces(postalcode);
      if (postalcode.length == 6 && postalcode.search(/^[a-zA-Z]\d[a-zA-Z]\d[a-zA-Z]\d$/) != -1) return true;
      else if (postalcode.length == 7 && postalcode.search(/^[a-zA-Z]\d[a-zA-Z]-\d[a-zA-Z]\d$/) != -1) return true;
      else return false;
   }
   return true;
}


// Check that a US or Canadian phone number is valid
function isValidUSPhoneNumberOptional(areacode, exchange, lineNumber) {
	var phoneNumber = '';
	if (arguments.length == 1) {
		phoneNumber = '' + arguments[0];
		if (phoneNumber != '') {
			return isValidUSPhoneNumber(arguments[0]);
		} else {
			return true;
		}
	} else if (arguments.length == 2) {
		phoneNumber = '' + arguments[0] + arguments[1];
		if (phoneNumber != '') {
			return isValidUSPhoneNumber(arguments[0], arguments[1]);
		} else {
			return true;
		}
	} else if (arguments.length == 3) {
		phoneNumber = '' + arguments[0] + arguments[1] + arguments[2];
		if (phoneNumber != '') {
			return isValidUSPhoneNumber(arguments[0], arguments[1], arguments[2]);
		} else {
			return true;
		}
	}
	return false;
}

// Check that a US or Canadian phone number is valid
function isValidUSPhoneNumber(areacode, exchange, lineNumber) {
	
   if (arguments.length == 1) {
      var phoneNumber = arguments[0];
      phoneNumber = phoneNumber.replace(/\D+/g, '');
      var length = phoneNumber.length;
      if (phoneNumber.length >= 7) {
         var areacode = phoneNumber.substring(0, length-7);
         var exchange = phoneNumber.substring(length-7, length-4);
         var lineNumber = phoneNumber.substring(length-4);
      } else return false;
   }
   
   else if (arguments.length == 2) {
      var phoneNumber = arguments[0]+arguments[1];
      phoneNumber = phoneNumber.replace(/\D+/g, '');
      var length = phoneNumber.length;
      if (phoneNumber.length >= 7) {
         var areacode = phoneNumber.substring(0, length-7);
         var exchange = phoneNumber.substring(length-7, length-4);
         var lineNumber = phoneNumber.substring(length-4);
      }
      else return false;
   }
   
   else if (arguments.length == 3) {
      var areacode = arguments[0];
      var exchange = arguments[1];
      var lineNumber = arguments[2];
   }
   else return true;

   var invalidAreacodeList = "222,333,444,555,666,777,999,123";
   var invalidPhoneNumberList = "2222222,3333333,4444444,5555555,6666666,7777777,8888888,9999999,2345678,3456789,4567890,5551234";
   
   if (areacode.length != 3 || !isNumeric(areacode) || exchange.length != 3 || !isNumeric(exchange) || lineNumber.length != 4 || !isNumeric(lineNumber)) return false; // all sections must be the right length, and numeric
   else if (areacode.substring(0, 1) == 0 || areacode.substring(0, 1) == 1) return false; // area code can't start with 0 or 1
   else if (areacode.substring(1, 3) == 11) return false; // area code can't be *11
   else if (invalidAreacodeList.indexOf(areacode) >= 0) return false; // area code can't be in invalid area code list
   else if (exchange.substring(0, 1) == 0 || exchange.substring(0, 1) == 1) return false; // exchange can't start with 0 or 1
   else if (exchange.substring(1, 3) == 11) return false; // exchange can't be *11
   else if (invalidPhoneNumberList.indexOf(exchange + lineNumber) >= 0) return false; // local phone number (xxx-xxxx) can't be in the invalid phone number list
   return true;
}

// Check that a string contains only letters and numbers
function isAlphanumeric(string, ignoreWhiteSpace) {
   if (string.search) {
      if ((ignoreWhiteSpace && string.search(/[^\w\s]/) != -1) || (!ignoreWhiteSpace && string.search(/\W/) != -1)) return false;
   }
   return true;
}

// Check that a string contains only letters
function isAlphabetic(string, ignoreWhiteSpace) {
   if (string.search) {
      if ((ignoreWhiteSpace && string.search(/[^a-zA-Z\s]/) != -1) || (!ignoreWhiteSpace && string.search(/[^a-zA-Z]/) != -1)) return false;
   }
   return true;
}

// Check that a string contains only numeric digits, and optionally white space
function isNumericDigits(string, ignoreWhiteSpace) {
   if (string.search) {
      if ((ignoreWhiteSpace && string.search(/[^\d\s]/) != -1) || (!ignoreWhiteSpace && string.search(/\D/) != -1)) return false;
   }
   return true;
}

// Check that a string is numeric (negative sign first, one decimal point okay)
function isNumeric(str) {
	var strValidChars = "0123456789.-";
	var strChar;
	var decimalCount = 0;
	var blnResult = true;
	
	if (str.length == 0) return false;
	
	// test str consists of valid characters listed above
	// count any decimals (should be only one)
	// only one hyphen allowed, and must be first character
	for (i = 0; i < str.length && blnResult == true; i++) {
		strChar = str.charAt(i);
		if (strValidChars.indexOf(strChar) == -1) {
			blnResult = false;
		}
		else if (i > 0 && strChar == '-') {
			blnResult = false;
		}
		else if (strChar == '.') {
			decimalCount++;
			if (decimalCount > 1) blnResult = false;
		}
	}
	return blnResult;
}

// Remove characters that might cause security problems from a string 
function removeBadCharacters(string) {
   if (string.replace) {
      string.replace(/[<>\"\'%;\)\(&\+]/, '');
   }
   return string;
}

// Remove all spaces from a string
function removeSpaces(string) {
   var newString = '';
   for (var i = 0; i < string.length; i++) {
      if (string.charAt(i) != ' ') newString += string.charAt(i);
   }
   return newString;
}

// Remove leading and trailing whitespace from a string
function trimWhitespace(string) {
   var newString  = '';
   var substring  = '';
   beginningFound = false;
   
   // copy characters over to a new string
   // retain whitespace characters if they are between other characters
   for (var i = 0; i < string.length; i++) {
      
      // copy non-whitespace characters
      if (string.charAt(i) != ' ' && string.charCodeAt(i) != 9) {
         
         // if the temporary string contains some whitespace characters, copy them first
         if (substring != '') {
            newString += substring;
            substring = '';
         }
         newString += string.charAt(i);
         if (beginningFound == false) beginningFound = true;
      }
      
      // hold whitespace characters in a temporary string if they follow a non-whitespace character
      else if (beginningFound == true) substring += string.charAt(i);
   }
   return newString;
}

// Returns a checksum digit for a number using mod 10
function getMod10(number) {
   
   // convert number to a string and check that it contains only digits
   // return -1 for illegal input
   number = '' + number;
   number = removeSpaces(number);
   if (!isNumericDigits(number)) return -1;
   
   // calculate checksum using mod10
   var checksum = 0;
   for (var i = number.length - 1; i >= 0; i--) {
      var isOdd = ((number.length - i) % 2 != 0) ? true : false;
      digit = number.charAt(i);
      
      if (isOdd) checksum += parseInt(digit);
      else {
         var evenDigit = parseInt(digit) * 2;
         if (evenDigit >= 10) checksum += 1 + (evenDigit - 10);
         else checksum += evenDigit;
      }
   }
   return (checksum % 10);
}

// Check that a string is numeric and withing given numeric range
function isValidNumericRange(string, min, max) {
	if (!isNumeric(string) || (!numericMin(string, min)) || (!numericMax(string, max))) return false;
	return true;
}

// Check that a string is numeric and greater than or equal to a minimum value
function numericMin(string, min) {
	if (!isNumeric(string) || (string < min)) return false;
	return true;
}

// Check that a string is numeric and greater than or equal to a minimum value
function numericMax(string, max) {
	if (!isNumeric(string) || (string > max)) return false;
	return true;
}


// Check that a string is (not numeric and < than or = 0) - false
function isTrue(string) {
	if (!isNumeric(string) || (string <= 0)) return false;
	return true;
}


// Group of checkboxes, check if at least one is checked
function isTrueGroup(elements, fields) {
	// loop thru all form elements
	for (var elementIndex = 0; elementIndex < elements.length; elementIndex++) {
		var element = elements[elementIndex];
		// checkbox
		if ( element.type == "checkbox" && ListFindNoCase(fields, element.name, ",") && element.checked == true ) {
	  		return true;
		}
	}
	return false;
}


// Compare value of one field to another
function fieldCompareNoCase(elements, value, field) {
	// loop thru all form elements
	for (var elementIndex = 0; elementIndex < elements.length; elementIndex++) {
		var element = elements[elementIndex];
		if ( element.value != null && element.name == field && element.value.toLowerCase() == value.toLowerCase() ) {
	  		return true;
		}
	}
	return false;
}

// Check if conditionValue in conditionList 
// then check if value is in validList
function isValidConditionList(value, validList, conditionValue, conditionList) {	
	if ( ListFindNoCase(conditionList, conditionValue, ",") == true && ListFindNoCase(validList, value, ",") == false ) return false;
	return true;
}

// check if value of field is in validList 
// then Check if conditionValue in conditionList 
function isNotValidConditionList(value, validList, conditionValue, conditionList) {	
	if ( ListFindNoCase(validList, value, ",") == true && ListFindNoCase(conditionList, conditionValue, ",") == false  ) return false;
	return true;
}



// Check that string passed is a valid date format
function isDateMDY(dt) {
	var strDate = dt;
	var strDateArray = new Array("", "", "");
	var strValidSeparators = '-/.';
	var strThisSeparator = '';
	var strDigits = '0123456789';
	var strChar;
	var intMonth;
	var intDay;
	var intYear;
	var intSeparatorCount = 0;
	var i;
	// make sure date string is a valid length
	if (strDate.length < 6 || strDate.length > 10) return false;
	// find first valid separator and check for invalid characters
	for (i=0; i < strDate.length; i++) {
		strChar = strDate.charAt(i);
		if (strDigits.indexOf(strChar) == -1) {
			// check if separator not set and current character is a valid separator
			if (strThisSeparator.length == 0 && strValidSeparators.indexOf(strChar) != -1) {
				strThisSeparator = strChar;
				intSeparatorCount++;
			}
			// check if current character is a separator
			else if (strChar == strThisSeparator) {
				// only two separators allowed
				if (intSeparatorCount == 2) return false;
				else intSeparatorCount++;
			}
			// otherwise, current character is not a digit and not a separator
			else {
				return false;
			}
		}
		else {
			// current character is a 0-9 digit, so append to current data array position
			strDateArray[intSeparatorCount] = strDateArray[intSeparatorCount] + strChar;
		}
	}
	// make sure a valid separator was found
	if (strThisSeparator.length == 0) return false;
	// extract month integer
	if (strDateArray[0].length == 2 && strDateArray[0].charAt(0) == '0') 
		intMonth = parseInt(strDateArray[0].charAt(1));
	else intMonth = parseInt(strDateArray[0]);
	// extract day integer
	if (strDateArray[1].length == 2 && strDateArray[1].charAt(0) == '0') 
		intDay = parseInt(strDateArray[1].charAt(1));
	else intDay = parseInt(strDateArray[1]);
	// extract year integer
	if (strDateArray[2].length == 2) strDateArray[2] = '20' + strDateArray[2];
	intYear = parseInt(strDateArray[2]);
	// make sure all date parts are numeric
	if (isNaN(intMonth) || isNaN(intDay) || isNaN(intYear)) 
		return false;
	// validate month
	if (intMonth < 1 || intMonth > 12) return false;
	// validate year
	if (intYear < 1000 || intYear > 9999) return false;
	// validate day
	if (intDay < 1 || intDay > 31) {
		return false;
	}
	else if ((intMonth == 1 || intMonth == 3 || intMonth == 5 || intMonth == 7 || intMonth == 8 || intMonth == 10 || intMonth == 12) && (intDay > 31 || intDay < 1)) {
		return false;
	}
	else if ((intMonth == 4 || intMonth == 6 || intMonth == 9 || intMonth == 11) && (intDay > 30 || intDay < 1)) {
		return false;
	}
	else if (intMonth == 2) {
		if (intDay > 29) return false;
		else if (isLeapYear(intYear) == false && intDay > 28) return false;
	}
}

// Check whether year passed is a leap year or not
function isLeapYear(yr) {
	var intYear = parseInt(yr, 10);
	if (isNaN(intYear) || intYear == 0) {
		return false;
	}
	else if (intYear % 100 == 0) {
		if (intYear % 400 == 0) { return true; }
	}
	else {
		if ((intYear % 4) == 0) { return true; }
	}
	return false;
}

// Check whether a selection is in the invalid list
function isValidSelect(selection,vList,vDelim)
{
	var vList_array=vList.split(vDelim);
	var i=0;
	while (i  <  vList_array.length)
	 {
		 if ( vList_array[i]==selection.value ){ return false; }
			 i+=1;
	  }
	   return true;
}

// Check whether a selection is in the valid list
function isInvalidSelect(selection,vList,vDelim)
{
	 if ( ListFindNoCase(vList,selection.value,vDelim)){ return false; }
	  return true;
}

// Check whether a value is in the list
function ListFindNoCase(List,Value,Delim)
{
	var ListArr = List.split(Delim);
	var i=0;
	if (!Value.toLowerCase) {
		// when numeric passed, then toLowerCase does not exist; convert to string
		Value = '' + Value;
	}
	while (i  <  ListArr.length)
	{
		if ( ListArr[i].toLowerCase() == Value.toLowerCase() ) { return true; }
		i+=1;
	}
	return false;
}


