function trim(a) {
  return a.replace(/^\s+/,'').replace(/\s+$/,'')
}

var voff = false;
function validateForm(theForm) 
{	
	// turn off validators on prototype
	if (voff)
		return true ;
		
	var elArr = theForm.elements;			// get all elements of the form into array
	
	var count = 0;
	
	nextloop:
	for(var i = 0; i < elArr.length; i++)
	{	
		var controlObject;
		controlObject = elArr[i];
		var v  = controlObject.getAttribute("val");	// get validator, if any

		if (!v) // no validator property, skip the lot
		{
			continue nextloop;
		}             					    
	
		var tb = true; //assume this is a text box
		var f  = controlObject.getAttribute("val_nofocus");		// Do not focus on an error
		var o  = controlObject.getAttribute("val_optional");		// get optional field, if any (means validate only if a value is supplied)
		var m  = controlObject.getAttribute("val_message");		// get optional message, if any
		var fn = controlObject.getAttribute("val_fieldname");    // get optional field name, if any
		var dt = controlObject.getAttribute("val_donttrim");    	// stop trim
		var controlValue = controlObject.value					// get Controls Value
		var controlName = controlObject.getAttribute("name")     // get Controls Name
		
		// if no fieldname specified, then use html fieldname (which is not too good)
		if (!fn) fn = controlName;
		
		if ( v == 'dropdown')
		{
			controlValue = controlObject.options[controlObject.selectedIndex].value;
			tb = false;
		}
		
		if (!dt && tb) 
		{
			// trim value of all text boxes on fly
			controlObject.value = trim(controlValue);
			controlValue = trim(controlValue);
		}
				
		if(controlValue == "" && tb)
		{
			if (o)				// If a value is not supplied, and its optional, then dont apply the validation rule
			{
				continue;
			}
			else
			{
				alert("Please supply a value for : " + fn);
				// Focus on erroneous edit box unless told otherwise
				if (!f) { controlObject.focus(); }
				return false;
			}
		}

		// Get Pattern Matching for edit box inputs
		var thePat = PatternsDict[v];				// select the validating regular expr
		var gotIt = thePat.exec(controlValue);      // run it on value of form field
		
		if(!gotIt) {
			// If no message then print a standard message
			if(!m)
			{
				var errMsg = patErrors[v];
				// index into patError array and add val_title to end to make a user friendly message
				alert(fn + ": " + errMsg);
			}
			else
			{
				// Print specified error message
				alert(m);
			}
			
			// Focus on erroneous edit box unless told otherwise
			if (!f) { controlObject.focus(); }

			// Form submittal has failed
			return false;
		} // end if (!gotIt)
	} // for elArr
	return true;
}

/*
The following are held in a Pattern object and used to validate date entered in
form fields.

  email			- checks format of email address
  phone			- Numeric with Spaces
  numeric		- checks for valid numeric value
  alphaSpaces	- checks the value only contains characters but can also contain spaces
  alphaSpaces   -
  alphaNoSpaces -  
  alphaNumeric  -
  alphaNumericNoSpaces - 
  integer       - Checks for a valid positive integer value
  amountInteger - Checks for an amount in whole units
  dateddmmyyyy	- checks for valid date in internal format
  password		- checks format of password, 4-40 characters
  textArea		- checks for alpha but allows commas etc
  
  PatternsDict.phone = /^[0-9 ]*$/;
  
 */

var PatternsDict = new Object();

// Current Patterns
// PatternsDict.email = /^[a-z0-9]([a-z0-9_\-\.]*)@([a-z0-9_\-\.]*)(\.[a-z]{2,3}(\.[a-z]{2}){0,2})$/i;  //Accounts for email with country appended does not validate that email contains valid URL type (.com, .gov, etc.) 
// PatternsDict.email = /^[a-z0-9\._]*[a-z0-9_]@[a-z0-9][a-z0-9\-\.]*[a-z0-9]\.[a-z]{2,6}$/i;
PatternsDict.email = /^[a-z0-9]([a-z0-9_\-\.]*)@[a-z0-9][a-z0-9\-\.]*[a-z0-9]\.[a-z]{2,6}$/i;
PatternsDict.phone = /^[\w][\w\s\.\-;:!\(\)\[\]]*$/;	                       // cannot start with spaces
PatternsDict.numeric = /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/;  //matches valid numbers
PatternsDict.dateyyyy = /^\d{4}$/;  //matches portion of date with 4 digit year
PatternsDict.alphaSpaces          = /^([a-zA-z\s\.\-\;:!\(\)\[\]]+)$/;                   //
PatternsDict.alphaNoSpaces        = /^([a-zA-z\.\-\;:@!\(\)\[\]]+)$/;                   //
PatternsDict.alphaNumeric         = /^[\w][\w\s\.\-;:!\(\)\[\]]*$/;	                       // cannot start with spaces
PatternsDict.alphaNumericNoSpaces = /^[\w+\.\-;:!\(\)\[\]][\w+\.\-;:!\(\)\[\]]*$/;  // matches any character and number, must be at least 1 character

PatternsDict.alphaSpacesLoose          = /^([a-zA-z\s,\.\-\'\;:!\(\)\[\]]+)$/;                   //
PatternsDict.alphaNoSpacesLoose        = /^([a-zA-z,\.\-\'\;:!\(\)\[\]]+)$/;                   //
PatternsDict.alphaNumericLoose         = /^[\w][\w\s,\.\-\';:!\(\)\[\]]*$/;	                       // cannot start with spaces
PatternsDict.alphaNumericNoSpacesLoose = /^[\w+\.\-\';:!\(\)\[\],][\w+\.\-;:!\(\)\[\],]*$/;  // matches any character and number, must be at least 1 character
PatternsDict.textArea                  = /^[\w\s\.\-\+\&\\@%;,£:!\(\)\[\]\/'\?\*]*$/;
PatternsDict.alphaNumericWildcard         = /^[\w\s,\.\*!\(\)\[\]]*$/;	                       // cannot start with spaces

PatternsDict.dateddmmyyyy = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/;  //matches valid dates with 2 digit day, 2 digit month, 4 digit year. Date separator can be ., -, or /. Ex. mm/dd/yyyy or mm-dd-yyyy or mm.dd.yyyy

PatternsDict.password = /^([0-9a-zA-z\s]{4,15})$/;          //matches any character or integer between 4-40 characters
PatternsDict.amount   = /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/;
// Actual amount after trimming should match ^[0-9]+[0-9]{2}$

PatternsDict.integer       = /^[0-9]+$/;       // Instead of numeric which checks for 999.999, have integer check for whole number
PatternsDict.amountInteger = /^[0-9]+$/;       // Whole Numbered Amount, gives a specific money error message

PatternsDict.dropdown = /^[^\s]+$/;       // 
PatternsDict.filePath         = /^([\wa-zA-z\s\.\-\;:!\(\)\[\]]+)$/;	                       // cannot start with spaces

//Pattern error arrays.  Used to send errors back to forms if not specified on Input string
var patErrors = new Array;

patErrors['phone'] = "Invalid phone number, please enter only numbers and optional spaces.";
patErrors['email'] = "Please check your email address";
patErrors['numeric'] = "Please use numbers only";
patErrors['date'] = "Invalid date, values allowed: dd/mm/yyyy, dd-mm-yyyy, dd.mm.yyyy";
patErrors['alphaSpaces'] = "Please use letters only";
patErrors['alphaNoSpaces'] = "Please use letters with no spaces only";
patErrors['alphaNumeric'] = "Please use letters and/or numbers only. Please avoid special characters.";
patErrors['alphaNumericNoSpaces'] = "Please use letters and/or numbers only. Please avoid special characters and spaces.";
patErrors['alphaSpacesLoose'] = "Please use letters only";
patErrors['alphaNoSpacesLoose'] = "Please use letters with no spaces only";
patErrors['alphaNumericLoose'] = "Please use letters and/or numbers only. Please avoid special characters.";
patErrors['alphaNumericNoSpacesLoose'] = "Please use letters and/or numbers only. Please avoid special characters and spaces.";
patErrors['textArea'] = "You are ONLY allowed the following special characters (.-+&@%;,£:!()[]\\/ ' ?*)";
patErrors['password'] = "Your password must be at least 4 characters long";
patErrors['amountInteger'] = "is not a valid amount, please enter the amount in whole pounds only";
patErrors['integer']  = "Please use whole numbers only";
patErrors['dropdown'] = "Please select a value for this dropdown";
patErrors['filePath'] = "Please use a valid file path.";
patErrors['alphaNumericWildcard'] = "Please use letters and/or numbers only, with an optional wildcard (*). Please avoid other special characters.";
