// JavaScript Document

// from http://www.onlinetools.org/articles/unobtrusivejavascript/chapter5.html
// by Christian Heilmann 
// Modified by Bruce Koch

//We start our form script by testing if DOM is available and that there is a field with the ID required. 
//If neither is the case, we return to the document and the PHP fallback script formsend.php will take care of the rest.



function checkform(of)
{
	var focusField='';
	var alertMsg='';
  if(!document.getElementById || !document.createTextNode){return;}
  if(!document.getElementById('required')){return;}

  //We continue by defining all the variables used in the error display and by splitting the required field IDs into an array.

  var errorID='errormsg';
  var errorClass='requiredfielderror'
  var errorMsg='Please enter or change the fields marked with this image:';
  var errorImg='images/alert.png';
  var errorAlt=' is required';
  var errorTitle='This field has an error!';
  var reqfields=document.getElementById('required').value.split(',');
	
   //As we will add an element with the ID defined in errorID and add images to each field with an error, 
	 //we need to remove all of those should the script be executed a second time. Otherwise, we'd end up 
	 //with several messages and images.

	// Cleanup old mess
  // if there is an old errormessage field, delete it
  if(document.getElementById(errorID))
  {
    var em=document.getElementById(errorID);
    em.parentNode.removeChild(em);
  }
  // remove old images and classes from the required fields
  for(var i=0;i<reqfields.length;i++)
  {
    var f=document.getElementById(reqfields[i]);
    if(!f){continue;}
    if(f.previousSibling && /img/i.test(f.previousSibling.nodeName))
    {
      f.parentNode.removeChild(f.previousSibling);
    }
    f.className='';
  }

//Now we can do what we have undone. We loop over the required fields and test first if the field exists. 
// If not, we skip one round of the loop. This is purely to avoid error messages, the real form markup should have all required fields.

// loop over required fields
  for(var i=0;i<reqfields.length;i++) {
		// check if required field is there
    var f=document.getElementById(reqfields[i]);
    if(!f){continue;}

//We then check each field according to its type. For textareas and text fields we need to check the value, 
//for checkboxes we need to check for the checked attribute and for select boxes if there is a selectedIndex 
//defined and that it is bigger than 0.

//If any of the fields have an error, we send it as an object to the method cf_adderr(). A special case is 
//the email field, as this one also needs to be checked for valid email format. This check is performed by another 
//method called cf_isEmailAddr(), using regular expressions.

// test if the required field has an error, 
// according to its type
    switch(f.type.toLowerCase())
    {
      case 'text':
        if(f.value=='' && f.id!='email') {cf_adderr(f)}              
// email is a special field and needs checking
        if(f.id=='email' && 
        !cf_isEmailAddr(f.value)){cf_adderr(f)}              
        if((document.getElementById(errorID)) && (focusField=='')) {focusField=f.id}
      break;
      case 'textarea':
        if(f.value==''){cf_adderr(f)}              
        if((document.getElementById(errorID)) && (focusField=='')) {focusField=f.id}
      break;
      case 'checkbox':
        if(!f.checked){cf_adderr(f)}              
        if((document.getElementById(errorID)) && (focusField=='')) {focusField=f.id}
      break;
      case 'select':
      	alert(f.selectedIndex);
        if(!f.selectedIndex && f.selectedIndex==0){cf_adderr(f)}              
        if((document.getElementById(errorID)) && (focusField=='')) {focusField=f.id}
      break;
    }
  }

//If any of the tests above trigger an error report, the cf_adderr() generates the error 
//message (a DIV with the errorid as ID). Therefore we return to the sending process of 
//the form only when this element is not existant.

	if(document.getElementById(errorID)) {
		alert(alertMsg);
		document.getElementById(focusField).focus();
  return !document.getElementById(errorID);
}

//That is the main function, now we need to concentrate on the methods used, the first one 
//being the one adding the error images and the error message.

/* Tool methods */
function cf_adderr(o)
{

//We create the image, set its alternative text and title and insert it before the element. 
//We apply the CSS-class stored in errorClass to the element to colour it.

	// create image, add to and colourise the error fields
	var errorIndicator=document.createElement('img');
	var field_error = "";
	
	switch (o.name) {
		case 'EmailN':
				field_error = "Email";
				break;
		case 'FirstNameN':
				field_error = "First name";
				break;
		case 'LastNameN':
				field_error = "Last name";
				break;
		case 'AddressN':
				field_error = "Address";
				break;				
		case 'CityN':
				field_error = "City";
				break;
		case 'ZipN':
				field_error = "Zip";
				break;				
		case 'PhoneN':
				field_error = "Phone";
				break;				
		default:				
				field_error = "";
	}	
	
	if(o.id=='email') {
		errorIndicator.alt=field_error + errorAlt + ' and must be in the correct format.';
		alertMsg+=field_error + errorAlt + ' and must be in the correct format.\n';
	} else {
		errorIndicator.alt=field_error + errorAlt;
		alertMsg+=field_error + errorAlt+'.\n';
	}
	errorIndicator.src=errorImg;
	//errorIndicator.title=errorTitle;
	o.className=errorClass;
	o.parentNode.insertBefore(errorIndicator,o);

//Then we check if there is already an error message and create it if necessary. 
//Once we have created this element, this condition will not be executed again.

  // Check if there is no error message
	if(!document.getElementById(errorID))
	{
	// create errormessage and insert before submit button
		var em=document.createElement('div');
		em.id=errorID;
		var newp=document.createElement('p');
		newp.appendChild(document.createTextNode(errorMsg))
		// clone and insert the error image
		newp.appendChild(errorIndicator.cloneNode(true));
		newp.lastChild.alt='';
		em.appendChild(newp);

//We find the submit button (by checking the type of each input element) and insert the 
//new message before its parent element (the paragraph the submit button resides in).

		// find the submit button 
		for(var i=0;i<of.getElementsByTagName('input').length;i++)
		{
			if(/submit/i.test(of.getElementsByTagName('input')[i].type))
			{
				var sb=of.getElementsByTagName('input')[i];
				break;
			}
		}
		if(sb)
		{
			sb.parentNode.insertBefore(em,sb);
		}  
	} 
}

//Finally, we need the method to test if the submitted email is in a valid format:

	function cf_isEmailAddr(str) {
      return str.match(/^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/);
  }
}

// Key Codes
// 65-90 - a thru z
// 8     - Backspace
// 9     - Tab
// 16    - Shift
// 13    - Enter
// 20    - Caps Lock
// 32    - space
// 35    - end
// 36    - home
// 37    - left arrow
// 38    - up arrow
// 39    - right arrow
// 40    - down arrow
// 45    - insert
// 46    - delete
function checkTextEntry()
{
	var key = window.event.keyCode;
	validChar = 0;
	if ((key >= 65 && key <= 90)) {
		validChar = 1;
	}
	if ((key >= 35 && key <= 46)) {
		validChar = 1;
	}	
	if ((key >= 188 && key <= 190)) {
		validChar = 1;
	}		
	else if (key == 8) {
		validChar = 1;
	}
	else if (key == 9) {
		validChar = 1;
	}
	else if (key == 13) {
		validChar = 1;
	}	
	else if (key == 16) {
		validChar = 1;
	}	
	else if (key == 20) {
		validChar = 1;
	}
	else if (key == 32) {
		validChar = 1;
	}	
	if (validChar == 0) {
		alert("Invalid character!");
		window.event.returnValue = null;
	}
	else {
		return;
	}
}

// Key Codes
// 48-57 - 1 thru 9
// 8     - Backspace
// 9     - Tab
// 16    - Shift
// 13    - Enter
// 20    - Caps Lock
// 32    - space
// 35    - end
// 36    - home
// 37    - left arrow
// 38    - up arrow
// 39    - right arrow
// 40    - down arrow
// 45    - insert
// 46    - delete
// 188   - comma
// 189   - dash
// 190   - period
function checkNumberDashEntry()
{
	var key = window.event.keyCode;
	validChar = 0;
	if ((key >= 48 && key <= 57)) {
		validChar = 1;
	}
	if ((key >= 35 && key <= 46)) {
		validChar = 1;
	}	
	if ((key >= 189)) {
		validChar = 1;
	}		
	else if (key == 8) {
		validChar = 1;
	}
	else if (key == 9) {
		validChar = 1;
	}
	else if (key == 13) {
		validChar = 1;
	}	
	else if (key == 16) {
		validChar = 1;
	}	
	else if (key == 20) {
		validChar = 1;
	}
	else if (key == 32) {
		validChar = 1;
	}		
	if (validChar == 0) {
		alert("Invalid character!");
		window.event.returnValue = null;
	}
	else {
		return;
	}
}

function validateZip(sVal)
{	
// our email regular expression
//Javascript matches US zipcodes not allowing all zeros in first 5 or +4 (http://www.regexlib.com)
// Matches:  	 [12345], [12345-6789], [123456789]
 var regex=/(^(?!0{5})(\d{5})(?!-?0{4})(-?\d{4})?$)/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "none";
	}
	else
	{
      return "Error: Invalid Zip Code";
	}
}

function validatePhone(sVal)
{	
	// our email regular expression
 var regex=/^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,5})|(\(?\d{2,6}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$/;
 
	// do the comparison, if we have a match write thank you or else the phone number is invalid
	if (regex.test(sVal))
	{
      return "none";
	}
	else
	{
      return "Error: Invalid Phone Number";
	}
}


function validateName(sVal)
{ 
//This is the simplest RegEx for validating someone's name. The name can contain only alphabets(in either case) & 
//should be of minimum length 4 & maximum length 32. Only white spaces are allowed apart from alphabets.
//Matches: 	[some body], [hey there], [hello] (http://www.regexlib.com)
 var regex=/^([a-zA-z\s]{4,32})$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "none";
	}
	else
	{
      return "Error: Invalid Name";
	}
}

function textFieldEval(str) {
	strTrim(str);
	strProperCase(str);
}

function strTrim(str) {
	var elem = document.getElementById(str).value;
	document.getElementById(str).value = elem.replace(/^\s+|\s+$/g, '');
}

function strProperCase(str) {
	var elem = document.getElementById(str).value;
	document.getElementById(str).value = elem.toLowerCase().replace(/^(.)|\s(.)/g, 
	function($1) { return $1.toUpperCase(); });
}