	//This script is derived from scripts derived from various sources. I have attempted to keep the original sources and
	// copyright notices intact. All portions not marked as copyrighted by others are copyright 1997-1999 by Brett Knights (brett@knightsofthenet.com).
	// This script may be used and modified for commercial or non-commercial purposes, but the copyright notice must remain intact.
	// No warranty is offered nor implied. Use of this software is done at your own risk.

	// All or some portion of functions marked "copyright 1997, Tom Negrino and Dori Smith" go with the following notice
	// This script copyright 1997, Tom Negrino and Dori Smith.
	// This script is from "JavaScript for the WWW, Visual QuickStart Guide, 2nd Ed."
	// For more information, see <http://www.chalcedony.com/javascript/>.
	// This script may be used and modified, but the copyright notice must remain intact.
	
	// 03/23/00   BAK   Stripped leading space from date parts in validDate check

	function validEmail(emailObj) { //copyright 1997, Tom Negrino and Dori Smith
		var email = emailObj.value;
		var invalidChars = " /:,;";
		if (email == "") {
			return false;
		}
		for (i=0; i<invalidChars.length; i++) {
			badChar = invalidChars.charAt(i);
			if (email.indexOf(badChar,0) != -1) {
				return false;
			}
		}
		atPos = email.indexOf("@",1);
		if (atPos == -1) {
			return false;
		}
		if (email.indexOf("@",atPos+1) != -1) {
			return false;
		}
		periodPos = email.indexOf(".",atPos)
		if (periodPos == -1) {
			return false;
		}
		if (periodPos+3 > email.length)	{
			return false;
		}
		return true;
	}
	
	

	function validText(textObj) {
		if (textObj.value == null || textObj.value == "" || isblank(textObj.value))
			return false;
		return true;
	}
	

	function isNum(passedVal) {					// Is this a number?
		//copyright 1997, Tom Negrino and Dori Smith
		if (passedVal == null || passedVal == "") {
			return false
		}
		for (i=0; i<passedVal.length; i++) {
			if (passedVal.charAt(i) < ".") {
				return false
			}
			if (passedVal.charAt(i) > "9") {
				return false
			}
			if (passedVal.charAt(i) == "/") {
				return false
			}
		}
		return true
	}
	
	function validZip(inZip) {					// Is this a valid US Zip code?
		//copyright 1997, Tom Negrino and Dori Smith
		var zipVal = inZip.value;
		if (zipVal == "") {
			return false;
		}
		if (zipVal.length >= 5){				// form can limit to 5 chars if required;
			if (isNum(inZip)) {			// Check if Zip is numeric
				return true;
			}
		}
		return false;
	}

	function validNum(numObj){
		return isNum(numObj.value);
	}
	
	function validNARegion(inState){
		//check is in state list
		var stateList = new Array('AL', 'AK', 'AS', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FM', 'FL', 'GA', 'GU', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MH', 'MD', 'MA', 'MI', 'AE', 'AA', 'AP', 'AE', 'AE', 'AA', 'AE', 'AE', 'AP', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'MP', 'OH', 'OK', 'OR', 'PW', 'PA', 'PR', 'RI', 'SC', 'SD', 'TN', 'TX', 'TT', 'UT', 'VT', 'VI', 'VA', 'WA', 'WV', 'WI', 'WY');
		var provList = new Array('AB', 'BC', 'MB', 'NB', 'NF', 'NT', 'NS', 'ON', 'PE', 'QC', 'SK', 'YT');
		// provList needs code for nunavit (new Territory as of 1999
		
		var regn = inState.value.toUpperCase();
		for(var i = 0; stateList[i];i++){
			if (regn == stateList[i])
				return true;
		}
		for(var i = 0; provList[i];i++){
			if (regn == provList[i])
				return true;
		}
		return false;
	}
	
	function validPhone(inPhone){
		//phone number can be (nnn)nnn-nnnn x nnnnn
		//or nnn.nnn.nnnnxnnnn etc
		
		if (!validText(inPhone)) return false;
		
		var rawPhone = inPhone.value;

			// must have at least 10 digits

		var digitCount = 0;
		var digTest = /\d/;
		for(var i = 0; i < rawPhone.length; i++){
			if (digTest.test(rawPhone.charAt(i))) digitCount++;
		}

		if (digitCount >= 10) return true;
		
		return false;

	}
	
	function validCC(inCC){
		// check this looks like a valid CC number
		// as with most of these functions this is an aid to 
		// helping the authentic user catch typos or oversights
		// it doesn't care what type of card the user has
		
		// Encoding only works on cards with less than 19 digits
		// core taken from sample script provided (apparently) by Netscape  
		
		if (!validText(inCC))
			return false;
			
		var st = inCC.value;
		if (st == "1111222233334444")
			return true; //testing value
			
		  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--;
		  }

		  if ((sum % 10) == 0)
			return (true);
		  else
			return (false);

	} // END FUNCTION validCC()
		
	function validDate(inDate){
		if(validText(inDate)){
			var parts = inDate.value.split("/");
			if (parts[0] && parts[1] && parts[2]){
				while (parts[0].substring(0,1) == '0' && parts[0].length > 1) //BAK 03/23/00 Added the while loop for all parts
					parts[0] = parts[0].substring(1);
				var mm = parseInt(parts[0]);
				if (mm > 12 || mm <= 0)
					return false;
				while (parts[1].substring(0,1) == '0' && parts[1].length > 1)
					parts[1] = parts[1].substring(1);
				var dd = parseInt(parts[1]);
				if (dd > 31 || mm <= 0)
					return false;
				while (parts[2].substring(0,1) == '0' && parts[2].length > 1)
					parts[2] = parts[2].substring(1);
				var yy = parseInt(parts[2]);
				if (yy > 100 || yy < 0)
					return false;
				return true;
			}
		}
		return false;
	}
		
	
	function validCCDate(inDate){
		//looks for dates of the form mm/yyyy or m/yy 
		if (validText(inDate)){
			var rawDate = inDate.value;
			var fSpace = false;
			var repList = "-/\\";
			var ch = "";
			var normDate = "";
			for(var i = 0; i < rawDate.length; i++){
				ch = rawDate.charAt(i);
				if (repList.indexOf(ch) != -1) {
					if (!fSpace) {
						normDate = normDate + " ";
						fSpace = true;
					}
				}
				else {
					fSpace = false;
					normDate = normDate + ch;
				}
			}
			var sepPosn = normDate.indexOf(" ");
			if (sepPosn != 1 && sepPosn != 2)
				return false;
			var monthPart = normDate.substring(0, sepPosn);
			if (!isNum(monthPart))
				return false;
				
			while (monthPart.substring(0,1) == '0'&& monthPart.length > 1)
				monthPart = monthPart.substring(1);
				
			if (parseInt(monthPart)>12)
				return false;
			var yearPart = normDate.substring(sepPosn + 1);
			if (!isNum(yearPart))
				return false;
			// take any valid number
			// yearPart = parseInt(yearPart); 
			// if (yearPart <= 50)
				return true;

			return false; //never get's here for now

		}
		return false;
		
	}

// JGB - 10/21/2009
// checks that reCAPTCHA entry is correct
// relies on reCAPTCHA generated fields and ajax.recaptcha.php ready

function validCaptcha()
{
    if (typeof jQuery != "undefined") {
      challengeField = $("input#recaptcha_challenge_field").val();
      responseField = $("input#recaptcha_response_field").val();
      //alert(challengeField);
      //alert(responseField);
      //return false;
      var html = $.ajax({
      type: "POST",
      url: "ajax.recaptcha.php",
      data: "recaptcha_response_field=" + responseField + "&" + "recaptcha_challenge_field=" + challengeField,
      async: false
      }).responseText;
  
      if(html != "success")
      {
          //alert("Your reCAPTCHA entry was invalid.  Please try again.");
          //Recaptcha.reload();
          return false;
      }
      return true;
    }
    else {           // what else can we do? we can't check
      alert("jQuery required to validate reCAPTCHA.");
      return false;
    }
}

	
	// This code is based  code from _JavaScript: The Definitive Guide_.     --
	// Written by David Flanagan.  Copyright (c) 1996 O'Reilly & Associates. --
	// This example is provided WITHOUT WARRANTY either expressed or implied.--
	// You may study, use, modify, and distribute it for any purpose.        --
	// A utility function that returns true if a string contains only 
	// whitespace characters.
	function isblank(s)
	{
	    for(var i = 0; i < s.length; i++) {
	        var c = s.charAt(i);
	        if ((c != ' ') && (c != '\n') && (c != '\t')) return false;
	    }
	    return true;
	}
	
 	// This is the function that checks the form element. 
 	
 	function elementValid(elem){
 		if (elem.nullOk && elem.nullOk == true){
 			if (elem.value == null || elem.value == "")
 				return true;
 		}
 		if (elem.handler)
 			return elem.handler(elem);
 		return true;
 	}


	function addValidation(f, testFcn, msgFcn){
		if (f.customValidations == null) f.customValidations = new Array();
		f.customValidations[f.customValidations.length] = testFcn;
		f.customValidations[f.customValidations.length] = msgFcn;
	}
	
	// This is the function that performs form verification.  It will be invoked
	// from the onSubmit() event handler.  The handler should return whatever
	// value this function returns.
	
	function formvalid(f)
	{
	    var msg;
	    var empty_fields = "";
	    var errors = "";
	    
	    // Loop through the elements of the form, looking for all 
	    // text and textarea elements that don't have an "optional" property
	    // defined.  Then, check for fields that are empty and make a list of them.
	    // Also, if any of these elements have a "min" or a "max" property defined,
	    // then verify that they are numbers and that they are in the right range.
	    // Put together error messages for fields that are wrong.
		 // var tester = "";
	    for(var i = 0; i < f.length; i++) {
	        var e = f.elements[i];
				if(!elementValid(e)){ //handler should return true if valid
					if (e.prompt != null) 
						empty_fields += "\n          " + e.prompt;
					else 
	               empty_fields += "\n          " + e.name;
	        }
            }
//	    if (f.customValidations != null) // custom validations that don't fit in the text field model but want to communicate all validation errors at once.
//	    	for(var i = 0; i< f.customValidations.length; i += 2){
//				if (!f.customValidations[i](f)) empty_fields += "\n          " + f.customValidations[i+1](f);				
//			}
	    //alert(empty_fields);
	    // Now, if there were any errors, then display the messages, and
	    // return true to prevent the form from being submitted.  Otherwise
	    // return false
	    if (empty_fields == "") return true;
	
	    msg  = "______________________________________________________\n\n"
	    msg += "The form was not submitted because the following\n";
		msg += "required field(s) have errors or are empty.\n";
	    msg += "______________________________________________________\n\n"
	
	    msg += empty_fields + "\n\n";
		msg += "Please correct these error(s) and re-submit.\n";
	    alert(msg);
            if (typeof(Recaptcha) != "undefined") {
                Recaptcha.reload();
            }
	    return false;
	
}
