/*
	
How to use it:

IDs for field <field>: 
  for each label:
      l_<field> is the label (required)
      l_<field>Star is the star that appears for a required field (optional)
      l_<field>Hint is a hint for the user, displayed if there's an error (optional)

Classes:
  for the labels:
  	  hint: indicates that this is a hint field
  for the field itself:
	  required: the field is required
	  charsType: plain alphanumeric characters 
	  addressType: alphanumerics + a few special characters
	  emailType: its an email
	  telType: its a telephone type (currently set to check US numbers)
*/

var OK_COLOR = "#fff";
var NOT_OK_COLOR = "#fff2db";
var NOT_REQ_COLOR = "#dddddd";
var ILLEGAL_CHARS = /[^a-zA-Z0-9()@\-\._,\'\s]/;
var ILLEGAL_CONTACT_CHARS = /[^0-9()@\-\._,\'\s]/;
var ILLEGAL_ADDRESS_CHARS = /[^a-zA-Z0-9&#()@\-\._,\'\s]/;

var currField;
var currLabel;
var allFieldClasses; 
var err;
var selects;
var inputs;
var required;
var referrerPage;

function formCheck () {
  // Initialize everything. /
  var radioChecked = false; // true means a button in the current radio button group has been checked. 
  
  // Get all the fields.  Radio buttons come in as regular input fields, but are handled separately.  
  // Text areas come in separately, but are handled the same as plain input fields, so append them to the 
  // inputs array. 
  if (selects == null) {
	  selects = collectionToArray (document.getElementsByTagName ("select")); 
  }
  if (inputs == null) {
	  inputs = collectionToArray(document.getElementsByTagName("input")); 
      inputs = inputs.concat(collectionToArray (document.getElementsByTagName ("textarea"))); 
  }
  
  // Hide all of the hints (such as "10 digits" for US phone numbers) each time.
  hideHints ();
  
  // Initialize the error messages each time. 
  err = 0; 
  document.getElementById("errorMessage").style.visibility = "hidden";

  // ----------------------------
  // Check dropdown fields ('selects').  The field's value must be set to "" in the form for it to be 
  // considered unselected. 
  //----------------------------
  for (var j in selects) {
  	currField=selects [j];
	currLabel="l_"+currField.name;
    //alert ("currField: "+currField.name);
	setColor (currField, OK_COLOR);
	if ((currField.value) == "") { // nothing selected yet
		if  (currField.className.indexOf('required') >= 0) {
		setErr (currField, currLabel+"Hint");
		}
	}
  } // end checking select fields
  
  //----------------------------
  // Check input fields, including radio buttons and textareas.
  //----------------------------
  
  for (var i=0; i<inputs.length; i++) { 
  	currField=inputs[i];
	//alert ("currField: "+currField.name);
	currLabel="l_"+inputs[i].name;
	currHint=currLabel+"Hint";
	
    // Get the next field's name (this is needed for radio button processing). 
  	if (i == inputs.length-1) {
	  nextField="";
	}
	else {
	  nextField=inputs[i+1].name;
	}
	
	// allFieldClasses contains all the classes for this field.  
	allFieldClasses = currField.className; 
	
	if (allFieldClasses.indexOf('required') >= 0) { // if required field
	  setColor (currField, OK_COLOR);
	  if (currField.type == "radio") { // radio button
	    //alert ("radio button");
	    setColor (currField, OK_COLOR);
		  if (allFieldClasses.indexOf('required') >= 0) {
			// If any of them has been checked, we're set. 
		    if (!radioChecked) {
			    if (currField.checked) {
					radioChecked = true;
				}
			}
			if (inputs[i].name != nextField) {
		        // We check for required radio buttons after having seen all of the buttons with the same name. 
			    // If we get to the last button in this group, and none have been checked, its an error. 
			    if (!radioChecked) {
					err=1;
	  				setColor (currField,  NOT_OK_COLOR);
				}
				radioChecked = false;  // Reinitialize for the next radio button. 
			}		
		  }
	  } // end radio button
	  else { // normal input field - check for empty
	      if (currField.value == "") { // if its an empty required field, that's an error. 
			setErr (currField, currHint);
	      } // end check for blank field 
		  
		else { 
		  //-----------------------------------------------------------
	 	  if (allFieldClasses.indexOf('charsType') >= 0) {
		    if (ILLEGAL_CHARS.test(currField.value)) {				
			  setErr (currField, currHint);
		    }
          } // end checking regular illegal chars
		  //-----------------------------------------------------------
	      if (allFieldClasses.indexOf('addressType') >= 0) {
		    if (ILLEGAL_ADDRESS_CHARS.test(currField.value)) {
			  setErr (currField, currHint);
		    }
	      } // end checking illegal address chars
		  //-----------------------------------------------------------
	      if (allFieldClasses.indexOf('emailType') >= 0) {
	        if ((ILLEGAL_CHARS.test(currField.value)) || (!validateEmail (currField))) {
			  setErr (currField, currHint);
	        }
	      } // end checking email 
		  //-----------------------------------------------------------
          if (allFieldClasses.indexOf ('telType') >= 0) {
            if ((ILLEGAL_CHARS.test(currField.value)) || 
               (!checkUSANumber (currField, currHint))) {
				setErr (currField, currHint);
		    }
	      } // end checking phone
		  //-----------------------------------------------------------
		  
		} // end regular input
	  } // end blank required field
	} // end required field	
  } // end check inputs
  
  doSpecialChecks();
  if (err == 0) {
  	  //alert ("the form was OK");
	  //showHidePlain('aForm','forwardLink', 'Forwarded this page to '+document.getElementById("rEmail").value);
      document.getElementById("forwardForm").submit();
    } else {
  	  //alert ("the form was not OK");
	  document.getElementById("errorMessage").style.visibility = "visible";
    }
}

// -----------------------------------------------------------------------------------
// General functions

function collectionToArray(col) {
	// This is needed so that we can access the selects and inputs arrays as arrays
	a = new Array();
	for (i = 0; i < col.length; i++)
		a[a.length] = col[i];
	return a;
}
function setErr (errField, errHint) {
	//alert ("in setErr");
	err=1;
	setColor (errField, NOT_OK_COLOR);
    showHint (errHint);
}
function setColor (which, color) {
  //document.getElementById(whichLabel).style.color = color;  
  which.style.borderColor = color;
  which.style.backgroundColor = color;
}
function showHint (whichHint) {
	if (document.getElementById (whichHint) != null) {
	  // alert ("whichHint "+whichHint);
      //document.getElementById (whichHint).style.color="#ff00ff";
      document.getElementById(whichHint).style.visibility = "visible";
	  }
}
function hideHints() {
    var els = document.getElementsByTagName("span");
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)hint(\\s|$)");
    var j = 0;
    for (i = 0; i < elsLen; i++) {
        if (pattern.test(els[i].className) ) {
			//els[i].style.color="#ffff00";
			els[i].style.visibility = "hidden";
			//alert ("found: "+els[i].id+", color: "+els[i].style.color);
            }
        }
}


// -----------------------------------------------------------------------------------
// Special cases

function validateEmail(field) {
  //alert ("email value: "+field.value);
  var apos=field.value.indexOf("@");
  var dotpos=field.value.lastIndexOf(".");
  if (apos<1||dotpos-apos<2) {
	return false;
  }
  else {
	return true;
  }
}
function checkUSANumber(phone,prompt) {
  //alert ("in checkUSANumber, phone: "+phone.value);
  var stripped = phone.value.replace(/[\(\)\.\-\ ]/g, '');
  //strip out unacceptable non-numeric characters
  if ((isNaN(parseInt(stripped))) || (stripped.length != 10)) {
    return false;
  }
  else {
	return true;
  }
}