
	function formValidator()
	{
		// variables
		this.oForm2Validate = null;
		
		this.aRequiredFields = new Array();
		this.aEmailFields = new Array();
		this.aNameFields = new Array();
		this.aIntegerFields = new Array();
		this.aFloatFields = new Array();
		this.aPasswordMatch = new Array();
		
		this.sConfirmButtonValue = '';
		this.sConfirmMessage = '';
		
		this.aErrorMessages = new Array();
		
		// methods
		this.addRequired = addRequired;
		this.addConfirm = addConfirm;
		this.doConfirm = doConfirm;
		this.validateEmail = validateEmail;
		this.isValidEmail = isValidEmail;
		this.validateName = validateName;
		this.isValidName = isValidName;
		this.validateInteger = validateInteger;
		this.isValidInteger = isValidInteger;
		this.validateFloat = validateFloat;
		this.isValidFloat = isValidFloat;
		this.passwordMatch = passwordMatch;
		this.addError = addError;
		this.validate = validate;
		this.submitForm = submitForm;
	}
	
	// Add a required field
	function addRequired(sFieldName, sFieldCaption)
	{
		this.aRequiredFields.push(new Array(sFieldName, sFieldCaption));
	}

/*************************************************************************/

	// Add an email field to validate
	function validateEmail(sEmailFieldName, sEmailFieldCaption)
	{
		this.aEmailFields.push(new Array(sEmailFieldName, sEmailFieldCaption));
	}
	
	// Validate email
	function isValidEmail(sEmailFieldValue, iCurIndex)
	{
		var sEmailRegEx = /^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9-])+(\.[a-zA-Z]+[0-9-]*)+/;
		
		if (!sEmailRegEx.test(sEmailFieldValue)) this.aErrorMessages.push('Your "'+ this.aEmailFields[iCurIndex][1] +'" is not a valid format.');
	}

/*************************************************************************/

	// Add a name field to validate
	function validateName(sNameField, sNameFieldCaption)
	{
		this.aNameFields.push(new Array(sNameField, sNameFieldCaption));
	}
	
	// Validate name
	function isValidName(sNameFieldValue, iCurIndex)
	{
		var sNameRegEx = /^[a-zA-Z]+\s*[a-zA-Z-]*$/;
		
		if (!sNameRegEx.test(sNameFieldValue)) this.aErrorMessages.push('Your "'+ this.aNameFields[iCurIndex][1] +'" is not a valid format.');
	}

/*************************************************************************/	

	// Add an integer field to validate
	function validateInteger(sIntegerField, sIntegerFieldCaption)
	{
		this.aIntegerFields.push(new Array(sIntegerField, sIntegerFieldCaption));
	}
	
	// Validate integer
	function isValidInteger(sIntegerFieldValue, iCurIndex)
	{
		var sIntegerRegEx = /^[0-9]+$/;
		
		if (!sIntegerRegEx.test(sIntegerFieldValue)) this.aErrorMessages.push('Your "'+ this.aIntegerFields[iCurIndex][1] +'" is not a valid format.');
	}

/*************************************************************************/
	
	// Add a float field to validate
	function validateFloat(sFloatField, sFloatFieldCaption)
	{
		this.aFloatFields.push(new Array(sFloatField, sFloatFieldCaption));
	}
	
	// Validate float
	function isValidFloat(sFloatFieldValue, iCurIndex)
	{
		var sFloatRegEx = /^[0-9]+\.{1}[0-9]+$/;
		
		if (!sFloatRegEx.test(sFloatFieldValue)) this.aErrorMessages.push('Your "'+ this.aFloatFields[iCurIndex][1] +'" is not a valid format.');
	}

/*************************************************************************/
	
	// Add a confirm message to the form
	function addConfirm(sButtonValue, sMessage)
	{
		this.submitButtonValue = this.sConfirmButtonValue = sButtonValue;
		this.sConfirmMessage = sMessage;
	}
	
	// Perform a confirm
	function doConfirm(sMessage)
	{
		var sResponse = confirm(sMessage);
		if (sResponse)
		{
			//this.submitButtonValue = '';
			return true;
		}
		else
		{
			return false;
		}
	}
	
/*************************************************************************/
	
	// Add a password match
	function passwordMatch(sPasswordField1, sPasswordField2)
	{
		this.aPasswordMatch[0] = sPasswordField1;
		this.aPasswordMatch[1] = sPasswordField2;
	}
	
/*************************************************************************/
	
	// Add an error message
	function addError(sErrorText)
	{
		this.aErrorMessages.push(sErrorText);
	}
	
	// Validate the form
	function validate(oForm)
	{
		this.oForm2Validate = oForm;
		
		// if two password fields have been added to match.
		if (this.aPasswordMatch.length != 0) 
		{
			if (eval('this.oForm2Validate.'+ this.aPasswordMatch[0] +'.value') != '')
			{
				var sPassword1 = eval('this.oForm2Validate.'+ this.aPasswordMatch[0] +'.value');
				var sPassword2 = eval('this.oForm2Validate.'+ this.aPasswordMatch[1] +'.value');
				
				if (sPassword1 != sPassword2)
				{
					this.aErrorMessages.push('The passwords you have supplied do not match.');
				}
			}
		}
		
		// If a confirm action has been added to the form
		if (this.submitButtonValue == this.sConfirmButtonValue) 
		{
			if (!this.doConfirm(this.sConfirmMessage)) return false;
		}
		
		// Loop through the required fields as added via addRequired()
		var iRequiredFieldCount = this.aRequiredFields.length;
		
		for (var iCounter = 0; iCounter < iRequiredFieldCount; iCounter++)
		{
			var sFieldType = eval('this.oForm2Validate.'+ this.aRequiredFields[iCounter][0] +'.type');
			var sFieldValue = eval('this.oForm2Validate.'+ this.aRequiredFields[iCounter][0] +'.value');
			
			switch (sFieldType)
			{
				case 'text':
					if (sFieldValue == '')
					{
						this.aErrorMessages.push('"'+ this.aRequiredFields[iCounter][1] +'" cannot be empty.');
					}
					break;
					
				case 'textarea':
					if (sFieldValue == '')
					{
						this.aErrorMessages.push('"'+ this.aRequiredFields[iCounter][1] +'" cannot be empty.');
					}
					break;
					
				case 'select-one':
					if (eval('this.oForm2Validate.'+ this.aRequiredFields[iCounter][0] +'.selectedIndex') == 0)
					{
						this.aErrorMessages.push('"'+ this.aRequiredFields[iCounter][1] +'" cannot be empty.');
					}
					break;
					
				case 'checkbox':
					if (eval('this.oForm2Validate.'+ this.aRequiredFields[iCounter][0] +'.checked') == false)
					{
						this.aErrorMessages.push('"'+ this.aRequiredFields[iCounter][1] +'" cannot be empty.');
					}
					break;
			}
		}
			
		// Loop through the email addresses to validate
		var iEmailFieldCount = this.aEmailFields.length;
		
		for (var iCounter = 0; iCounter < iEmailFieldCount; iCounter++)
		{
			var sEmailFieldValue = eval('this.oForm2Validate.'+ this.aEmailFields[iCounter][0] +'.value');
			if (sEmailFieldValue != '')	this.isValidEmail(sEmailFieldValue, iCounter);
		}
		
		// Loop through the names to validate
		var iNameFieldCount = this.aNameFields.length;
		
		for (var iCounter = 0; iCounter < iNameFieldCount; iCounter++)
		{
			var sNameFieldValue = eval('this.oForm2Validate.'+ this.aNameFields[iCounter][0] +'.value');
			if (sNameFieldValue != '')	this.isValidName(sNameFieldValue, iCounter);
		}
			
		// Loop through the Integers to validate
		var iIntegerCount = this.aIntegerFields.length;
		
		for (var iCounter = 0; iCounter < iIntegerCount; iCounter++)
		{
			var sIntegerFieldValue = eval('this.oForm2Validate.'+ this.aIntegerFields[iCounter][0] +'.value');
			if (sIntegerFieldValue != '')	this.isValidInteger(sIntegerFieldValue, iCounter);
		}
		
		// Loop through the Floats to validate
		var iFloatCount = this.aFloatFields.length;
		
		for (var iCounter = 0; iCounter < iFloatCount; iCounter++)
		{
			var sFloatFieldValue = eval('this.oForm2Validate.'+ this.aFloatFields[iCounter][0] +'.value');
			if (sFloatFieldValue != '')	this.isValidFloat(sFloatFieldValue, iCounter);
		}
			
		// Do error reporting
		if (this.aErrorMessages.length != 0)
		{
			var sErrorMessage = 'We could not process your request because:\n\n';
			var iErrorCount = this.aErrorMessages.length;
		
			for (var iCounter = 0; iCounter < iErrorCount; iCounter++)
			{
				sErrorMessage += '\t'+ this.aErrorMessages[iCounter] +'\n';
			}
			
			sErrorMessage += '\nPlease review these errors ';
			sErrorMessage += 'and try to submit this form again.';
			
			alert(sErrorMessage);
			this.aErrorMessages.length = 0;
			
			return false;
		}
		else return true;
	}
	
	function submitForm(oForm)
	{
		if (this.validate(oForm)) oForm.submit();
	}