/*
	Script to validate forms
	© Craig Moir
	
	The following properties can be set for each of the form fields:
	
	1. displayName	- This can be set for all form variables and is used in error messages
	
	2. fieldType	- This can be one of text, number, email, ukpostcode, uktelephone, droplist
	
	3. minimum		- For type text, this represents minimum length
						- For type number, this represents minimum value
						- Other types do not make use of this property
				
	4. maximum		- For type text, this represents maximum length
						- For type number, this represents maximum value
						- Other types do not make use of this property
				
	5. mandatory	- This can be true or false. The default value is false
	
	
	Example of use:

	<form action="/cgi-bin/form" method="post"
		onSubmit="javascript:
			name.displayName='NAME';
			name.mandatory=true;
			name.fieldType='text';
			email.displayName='EMAIL';
			email.mandatory=true;
			email.fieldType='email';
			topic.displayName='TOPIC';
			topic.mandatory=true;
			topic.fieldType='droplist';
			message.displayName='MESSAGE';
			message.mandatory=true;
			message.fieldType='text';
			message.maximum=2000;
			return validateForm(this, false);"
	>
*/


function validateForm(inputForm, usePopup)
{
	var errorMessage = "";

	// Loop through the form elements
	for (var i = 0; i < inputForm.length; i++)
	{
		// Get the current element
		var element = inputForm.elements[i];
		
		// Get the current element type
		if (element.fieldType != null)
		{
			// Set displayName to the field name if not explicitly declared
			if (element.displayName == null)
			{
				elementDisplayName = element.name;
			}
			else
			{
				elementDisplayName = element.displayName;
			}
			
			switch(element.fieldType)
			{
				case "text":

					// Check that the string is not empty
					if (isEmptyString(element.value) && element.mandatory == true)
					{
						errorMessage += "You have not entered anything for " + elementDisplayName + ".\n";					
					}
					
					// Check that the string length is greater than the minimum length (if one has been specified)
					else if (!isEmptyString(element.value) && element.minimum != null && element.value.length < element.minimum)
					{
						errorMessage += "The entry for " + elementDisplayName + " is too short. Minimum length is " + element.minimum + " characters.\n";
					}

					// Check that the string length is less than the maximum length (if one has been specified)
					else if (!isEmptyString(element.value) && element.maximum != null && element.value.length > element.maximum)
					{
						errorMessage += "The entry for " + elementDisplayName + " is too long. Maximum length is " + element.maximum + " characters.\n";
					}
					
					break;
					
				case "number":
				
					var elementValue = parseFloat(element.value)
					
					// Check that the string is not empty
					if (isEmptyString(element.value) && element.mandatory == true)
					{
						errorMessage += "You have not entered anything for " + elementDisplayName + ".\n";					
					}
					
					// Check that a valid number has been entered
					else if (!isEmptyString(element.value) && isNaN(elementValue))
					{
						errorMessage += "The value entered for " + elementDisplayName + " is not a number.\n";
					}

					// Check that the value entered is greater than the minimum value (if one has been specified)
					else if (!isEmptyString(element.value) && element.minimum != null && elementValue < element.minimum)
					{
						errorMessage += "The value for " + elementDisplayName + " is too small. Minimum value is " + element.minimum + ".\n";
					}

					// Check that the value entered is less than the maximum value (if one has been specified)
					else if (!isEmptyString(element.value) && element.maximum != null && elementValue > element.maximum)
					{
						errorMessage += "The value for " + elementDisplayName + " is too large. Maximum value is " + element.maximum + ".\n";
					}

					break;
					
				case "email":
				
					// Check that the string is not empty
					if (isEmptyString(element.value) && element.mandatory == true)
					{
						errorMessage += "You have not entered anything for " + elementDisplayName + ".\n";					
					}

					// Check that a valid email address has been entered
					else if (!isEmptyString(element.value) && !isValidEmail(element.value))
					{
						errorMessage += "The value entered for " + elementDisplayName + " is not valid.\n";
					}
				
					break;
					
				case "ukpostcode":
				
					// Check that the string is not empty
					if (isEmptyString(element.value) && element.mandatory == true)
					{
						errorMessage += "You have not entered anything for " + elementDisplayName + ".\n";					
					}

					// Check that a valid postcode has been entered
					else if (!isEmptyString(element.value) && !isValidUkPostcode(element.value))
					{
						errorMessage += "The value entered for " + elementDisplayName + " is not in a valid UK format (eg. AB12 3CD).\n";
					}
				
					break;
					
				case "uktelephone":
				
					// Check that the string is not empty
					if (isEmptyString(element.value) && element.mandatory == true)
					{
						errorMessage += "You have not entered anything for " + elementDisplayName + ".\n";					
					}

					// Check that a valid telephone number has been entered
					else if (!isEmptyString(element.value) && !isValidUkTelephoneNumber(element.value))
					{
						errorMessage += "The number entered for " + elementDisplayName + " is not in a valid UK format (eg. 0123 4567898).\n";
					}
				
					break;
					
				case "droplist":
				
					// Check that the string is not empty
					if (isEmptyString(element.value) && element.mandatory == true)
					{
						errorMessage += "You have not entered anything for " + elementDisplayName + ".\n";					
					}

					// Check that a valid value has been selected from the droplist
					else if (!isEmptyString(element.value) && !isValidDroplistValue(element))
					{
						errorMessage += "You have not selected anything for " + elementDisplayName + ".\n";
					}
				
					break;
					
				default:
					break;
			}
		}
	}
	
	// Display error messages if required
	if (errorMessage != "")
	{
		if(usePopup)
		{
			alertMessage = "________________________________________________________________________\n\n"
				+ "The information has not been submitted because of the following error(s):\n"
				+ "Please correct these error(s) and resubmit.\n"
				+ "________________________________________________________________________\n\n"
				+ errorMessage;
			
			alert(alertMessage);
		}
		else
		{
			alertMessage = "<p>The information has not been submitted because of the following error(s). "
				+ "Please correct these error(s) and resubmit.</p><p>"
				+ errorMessage.replace(/\n/g, "<br />");
				+ "</p>";
				
			document.getElementById("formerrors").innerHTML = alertMessage;
		}
		
		return false;
	}
	
	document.getElementById("formerrors").innerHTML = "";
	return true;
}


function isEmptyString(inputString)
{
	if (inputString.search(/\S/) == -1)
	{
		return true;
	}

	return false;
}


function isValidEmail(inputString)
{
	if (inputString.search(/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i) == -1)
	{
		return false;
	}

	return true;
}


function isValidUkPostcode(inputString)
{
	inputString = inputString.replace(/ /g, "");
	var inputStringLength = inputString.length;
	
	if (isEmptyString(inputString))
	{
		return false;
	}
	else if (inputStringLength < 5 || inputStringLength > 7)
	{
		return false;
	}
	else if (!isNaN(inputString.charAt(0))
				|| isNaN(inputString.charAt(2))
				|| isNaN(inputString.charAt(inputStringLength - 3))
				|| !isNaN(inputString.charAt(inputStringLength - 2))
				|| !isNaN(inputString.charAt(inputStringLength - 1)))
	{
		return false;
	}
	
	return true;
}


function isValidUkTelephoneNumber(inputString)
{
	inputString = inputString.replace(/ /g, "");
	var inputStringLength = inputString.length;
	
	if (isEmptyString(inputString) || inputString.search(/0[0-9]{10}$/) == -1)
	{
		return false;
	}
	
	return true;
}

function isValidDroplistValue(inputElement)
{
	if (inputElement.options[inputElement.selectedIndex].value == "")
	{
		return false;
	}
	
	return true;
}