//Created By: Chris Campbell
//www.particletree.com

window.onload = attachFormHandlers;

var gRequired; //global holding all required fields
var gAdditional; //global holding all fields with additional validation requirements (i.e. Date, Email, Phone)


function attachFormHandlers()
{
  // Ensure we're on a newer browser
	if (document.getElementsByTagName)
	{
		gRequired = document.getElementById('required').value; //get all required fields
		gAdditional = document.getElementById('additional').value;  // get all additional fields
	
		var objInput = document.getElementsByTagName('input'); // get all input tags
		var form = document.getElementById('form1') // get the form
	
			for (var iCounter=0; iCounter<objInput.length; iCounter++)
			{
				objInput[iCounter].onchange = function(){return attach(this);} // attach the onchange event to each input tag
			}
		
	form.onsubmit = function(){return validate();} // atttach the onsubmit to the form 
	
  }
}


function attach(objInput)
{
	sVal = objInput.value; //sVal is the value of the input field being validated
	sName = objInput.name; //sName is the name of the input field being validated
	var sFeedBack; //feedback message sent back to the user
    var stypeCheck = typeCheck(sName) // any additional validation requirements (i.e. email, phone)
	
	
	if (isRequired(sName)) // checks if the input field is required
	{
		sFeedback = validateRequired(sVal); //validateRequired() checks if it is invalid and sends back feedback
	}
	else sFeedback = "";
			
	if (sVal != "") //if the value is blank we don't need to validate.  If it is required, the word
	//"required"  will already be the feedback message from the validateRequired() function
	{
		// check the different validation cases (ie: email, phone, etc.)
		switch (stypeCheck)
		{
			case "date":
				sFeedback = validateDate(sVal);
				break;
			case "email":
				sFeedback = validateEmail(sVal);
				break;
			case "phone":
				sFeedback = validatePhone(sVal);
				break;
			case "mobile":
				sFeedback = validateMobile(sVal);
				break;
			case "zip":
				sFeedback = validateZip(sVal);
				break;
			case "password":
				sFeedback = validatePassword(sVal);
				break;
			case "name":
				sFeedback = validateName(sVal);
				break;
			case "numeric":
				sFeedback = validateNumeric(sVal);
				break;
		}
		
	}
	// after validation is complete return the feedback 
	document.getElementById(sName + "msg").innerHTML = sFeedback;
}


function isRequired(sName)
	{
		var requiredFields = gRequired.split(',') //store all required fields as an array
		for (i = 0; i<requiredFields.length; i++)
		{
			if(sName == requiredFields[i]) //loop through array and if the name of the input field being 
			//validated is also inside the required fields array then it is required
			{
			return true;
			}
		}
		return false;
	}


function typeCheck(sName)
	{
		additionalFields = gAdditional.split(',') // store additional fields in an array
		var additionalArray;
		
		for (i = 0; i<additionalFields.length; i++) //loop through the additional fields array
		{
			additionalArray = additionalFields[i].split('/');  //this array splits up the array elements
		 // this is done because we pass emailaddress/email.  email address is the field name and email 
		 //is how it will be validated
	       
		    if(sName == additionalArray[0]) // if the name of the input box is in the additional box it has more requirements
		    {
				return additionalArray[1];  //second element is type being checked for
		    }
	    }
	}

function validateRequired(sVal)
{
   		if (sVal != "") //if it is rquired and blank then it is an error and continues to be required
		{
   	 	 return ("Thank You");
		}
		else 
		{
			return("Required");
		}
}


function validateDate(sVal)
{
	// our date regular expression (http://www.regexlib.com)
 var regex=/(((0[13578]|10|12)([-.\/])(0[1-9]|[12][0-9]|3[01])([-.\/])(\d{4}))|((0[469]|11)([-.\/])([0][1-9]|[12][0-9]|30)([-.\/])(\d{4}))|((2)([-.\/])(0[1-9]|1[0-9]|2[0-8])([-.\/])(\d{4}))|((2)(\.|-|\/)(29)([-.\/])([02468][048]00))|((2)([-.\/])(29)([-.\/])([13579][26]00))|((2)([-.\/])(29)([-.\/])([0-9][0-9][0][48]))|((2)([-.\/])(29)([-.\/])([0-9][0-9][2468][048]))|((2)([-.\/])(29)([-.\/])([0-9][0-9][13579][26])))/;
 
	// do the comparison, if we have a match write thank you or else the date is invalid
	if (regex.test(sVal))
	{
      return "Thank You";
	}
	else 
	{
      return "Invalid Date";
	}

}

function validateEmail(sVal)
{
	
// our email regular expression (http://www.regexlib.com)
 var regex=/^[a-zA-Z0-9._-]+@([a-zA-Z0-9.-]+\.)+[a-zA-Z0-9.-]{2,4}$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "Thank You";
	}
	else
	{
      return "Invalid Email Address";
	}
}

function validatePhone(sVal)
{
	
// our phone regular expression
// This expression is a very simplex expression that allows null values or 3 digits, dash, 
//3 digits, dash, 4 digits. It validates a basic US phone number. Written by Jason N. Gaylord.(http://www.regexlib.com)
// Matches:  	 [555-555-1212], [123-456-7890]
var regex=/(\s*\(?0\d{4}\)?\s*\d{6}\s*)|(\s*\(?0\d{3}\)?\s*\d{3}\s*\d{4}\s*)$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "Thank You";
	}
	else
	{
      return "Invalid Phone";
	}
}

function validateMobile(sVal)
{
	
// our phone regular expression
// This expression is a very simplex expression that allows null values or 3 digits, dash, 
//3 digits, dash, 4 digits. It validates a basic US phone number. Written by Jason N. Gaylord.(http://www.regexlib.com)
// Matches:  	 [555-555-1212], [123-456-7890]
var regex=/^(\+44\s?7\d{3}|\(?07\d{3}\)?)\s?\d{3}\s?\d{3}$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "Thank You";
	}
	else
	{
      return "Invalid Phone";
	}
}


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 "Thank You";
	}
	else
	{
      return "Invalid ZipCode";
	}
}

function validatePassword(sVal)
{ 
//Description: The password's first character must be a letter, it must contain at least 4 characters
//and no more than 15 characters and no characters other than letters, numbers and the underscore may be used
//Matches: 	[abcd], [aBc45DSD_sdf], [password] (http://www.regexlib.com)
 var regex=/^[a-zA-Z]\w{3,14}$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "Thank You";
	}
	else
	{
      return "Invalid Password";
	}
}

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 "Thank You";
	}
	else
	{
      return "Invalid Name";
	}
}


function validateNumeric(sVal)
{ 
//Input for Numeric values. Handles negatives, and comma formatted values. Also handles a single decimal point
//Matches: 	[5,000], [-5,000], [100.044] (http://www.regexlib.com)
 var regex=/^(\d|-)?(\d|,)*\.?\d*$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "Thank You";
	}
	else
	{
      return "Invalid Number";
	}
}
