	var errorString = ""
	
	function validateElements( elements, originaltheclass, alternatetheclass ) {
		var theclass;
		var validated = true;
		
		if (alternatetheclass){
			theclass = alternatetheclass;
		} else {
			theclass = "";
		}
		if (originaltheclass){
			otheclass = originaltheclass;
		} else {
			otheclass = "";
		}


		for (i = 0; i < validationArray.length; i ++ ) {
			if (Exists( validationArray[i][0] )) {
				element = document.getElementById( validationArray[i][0] );
				
		
				if (element.nodeType == 1 ) { // correct type?
	
					//alert( 1 );
					// is it an input node , and that there is a function that has the same name as the value in the validatefn tag
					if ( ((element.nodeName == "INPUT")||(element.nodeName == "SELECT"))){			
						// runs the fn with the variables stated in validateparam1 attribute to tag
						if ( element.type  == "checkbox" ) {
							valid = eval( validationArray[i][1] )( element.checked );
							if (valid == false) {
								element.className = theclass;
								errorString += "\t" + element.getAttribute( "name" ) + "\n" ;
								validated = false;
							} else {
								element.className = otheclass;
								// otherwise grey
							}
	
						} else { 
							valid = eval( validationArray[i][1] )( element.value , validationArray[i][2] );
							//alert( valid );
							if (valid == false) {
								element.className = theclass;
								errorString += "\t" + element.getAttribute( "name" ) + "\n" ;
								validated = false;
							} else {
								element.className = otheclass;
								// otherwise grey
							}
						}
					}
					else if ( ((element.nodeName == "TEXTAREA")) 
					){
						// runs the fn with the variables stated in validateparam1 attribute to tag
						valid = eval( validationArray[i][1] )( element.value, validationArray[i][2] );
	
						if (valid == false) {
								element.className = theclass;
								errorString += "\t" + element.getAttribute( "name" ) + "\n" ;
								validated = false;
						} else {
							element.className = otheclass;
							// otherwise grey
						}
					}
				}
				
			}
		}
		return validated;
	}


	function Exists( nodeID ) {
		//alert( document.getElementById( nodeID ) );
		ex = document.getElementById( nodeID ) ? true: false;
		return ex;
	}

	function resetForm() {
		var elementsIds  = new Array( "name", "organisation", "nocompte", "emailaddress", "location", "telephone", "address1", "towncity", "telephone", "postcode", "telephone", "prefdate", "address2", "county", "mobiles", "inkjets", "lasers", "envelopes", "boxes", "iwishemailcommunication", "idonotwishfurtherinformation" );
		var elementsVals = new Array( "",     "",             "",             " e.g. Reception", "",          "",         "",         "",          "",         "",          "ASAP",     "",         "",       "",        "",        "",       "2",         "",      false,                         false );
		for (i in elementsIds) {
			if (Exists(elementsIds[i]) ){
				switch (document.getElementById( elementsIds[i] ).type ) {
					case "checkbox":
						//alert( document.getElementById( elementsIds[i] ).checked );
						document.getElementById( elementsIds[i] ).checked = elementsVals[i];
						break;
					default:
						document.getElementById( elementsIds[i] ).value = elementsVals[i];
						break;
				}
			}
		}
	}
	
function validate( fID, submitId, errorId, originaltheclass, alternatetheclass ) {

	var submitButton;
	// by default the form is valid until proven otherwise
	
	if ( ! fID ) {
		formID = "mainform";
	} else {
		formID = fID;
	}
	
	if ( ! submitId ) {
		submitButtonId = "submitbutton";
	} else {
		submitButtonId = submitId;
	}
	
	if ( ! errorId ) {
		errorTextId = "errorText";
	} else {
		errorTextId = errorId;
	}
	
	validated = true;
	errorString = "";
	count = 0;
	// checks there is a form with the id formID
	//alert( 1 );
	if (Exists( formID ) ) {
		//alert( 2 );
		// creates reference to form
		ref = document.getElementById( formID );
		// gets all elements from the form (checks ie or mozilla)
		var inputelements = ref.getElementsByTagName('INPUT');
		var selectelements = ref.getElementsByTagName('SELECT');
		var textareaelements = ref.getElementsByTagName('TEXTAREA');
		var submitElement;
		// for each element between the form tags loop
		//alert( typeof( elements.item(100) ) == "undefined" );
		
		//alert( elements.length );
	}
	
	
	
	validated = validateElements( inputelements, originaltheclass, alternatetheclass )
	validated = validateElements( selectelements, originaltheclass, alternatetheclass ) && validated
	validated = validateElements( textareaelements, originaltheclass, alternatetheclass ) && validated

	//alert( "valid: " + validated  );
	//alert( "validate: end" );
	var moz = (typeof document.implementation != 'undefined') && (typeof document.implementation.createDocument != 'undefined'); 

	//validated ? false: alert( "The following inputs must be filled in correctly: \n\n" + errorString );
	submitButton = document.getElementById( submitButtonId );
	//alert( submitButtonId + ", " + Exists( submitButtonId ) + ", " + document.getElementById( submitButtonId ).disabled );
	if (validated) {
		submitButton.disabled = false;
		if( moz ){
			submitButton.style.MozOpacity=1;
		} else {
			submitButton.style.cursor = "hand";
			if( submitButton.filters.alpha ) {
				submitButton.filters.alpha.opacity = "100";
			} else {
				if (Exists( errorTextId ) ) {
					//document.getElementById( errorTextId ).style.display = "none";
				}
			}
		}
	} else {
		submitButton.disabled = true;
		if( moz ){
			submitButton.style.MozOpacity=0.3;
		} else {
			submitButton.style.cursor = "not-allowed";
			if( submitButton.filters.alpha ) {
				submitButton.filters.alpha.opacity = "30";
			}  else {
				if (Exists( errorTextId ) ) {
					document.getElementById( errorTextId ).style.display = "block";
				}
			}
		}
	}
	//alert( validated );
	return validated;
}

// match a regular expression
function matchReg( value, param ){
	alert( "matchReg Start: " + param + ", value: " + value + ", value length: " + value.length );
	var rg = new RegExp( param, "i" );
	alert( "matchReg 1: " + param + ", value: " + value + ", value length: " + value.length );
	truth = rg.test( value );
	alert( "matchReg End: " + param + ", value: " + value + ", value length: " + value.length );
	return truth;
}

function lengthBetween( value, param ){
	low = Number( param.split( "," )[0] );
	high = Number( param.split( "," )[1] );
	return (value.length >= low) && (value.length <= high)
}

// if one form element's value is the same as another
function sameas( value, param ){
	return (document.getElementById( param ).value == value );	
}


// if the two passwords match

function pwmatch( value, param ){
	return ((document.getElementById( param ).value == value ));
}

// if they match and they are more than one character in length
function pwmatchneeded( value, param ){
	return ((document.getElementById( param ).value == value ) && (value.length > 1) );
}

function isEmailOld( value, param ) {
	alert( "isEmail Start" );
	var rg = /^.+@[^\.].*\.[a-z]{2,}$/i;
	alert( "isEmail Mid" );
	truth = rg.test( value );
	alert( "isEmail End" );
	return truth
}

function isEmail( value, param ){
	emailParts = value.split( "@" );
	if (emailParts.length == 2) {
		if (emailParts[0].length >= 1) {
			if (emailParts[1].split(".").length >= 2) {
				if ((emailParts[1].split(".")[emailParts[1].split(".").length - 1].length >= 2) && (emailParts[1].split(".")[0].length >= 2)){
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
	} else {
		return false;
	}
}

function isEmailOrBlankSameAs( value, param ) {
	if ((value.length == 0) || isEmail( value, param )){
		truth = true;
	} else {
		truth = false;
	}
	return (document.getElementById( param ).value == value ) && truth
}

function isEmailOrBlank( value, param ) {
	if ((value.length == 0) || isEmail( value, param )){
		truth = true;
	} else {
		truth = false;
	}
	return truth;
}

function isEmailSameAs( value, param ) {
	if (isEmail( value, param )){
		truth = true;
	} else {
		truth = false;
	}
	return (document.getElementById( param ).value == value ) && truth
}

function isIntegerInRange( value, param ) {
	var low, high;
	if ( (value != "") && (Number(value) != Number.NaN) && (Number(value) % 1 == 0)) {
		low = Number( param.split( "," )[0] );
		high = Number( param.split( "," )[1] );
		return ((Number( value ) <= high) && (Number( value ) >= low));
	} else {
		return false;
	}
}

function isMoneyInRange( value, param ) {
	var low, high;
	if ( (value != "") && (Number(value) != Number.NaN) && ((value.indexOf( "." ) < 0) || (value.split( "." )[1].length <= 2) ) ) {
		low = Number( param.split( "," )[0] );
		high = Number( param.split( "," )[1] );
		return ((Number( value ) <= high) && (Number( value ) >= low));
	} else {
		return false;
	}
}

//  Examples:
//
//  Length of input between 2 and 10
//  <input type="text" id="customername" name="customername" value="as" onKeyUp="validate( this );" validatefn="matchReg" validateparam1="\S{2,10}" />			
//
//
//  Valid E-mail address
//  <input type="text" id="primaryemail" name="primaryemail" value="" onKeyUp="validate( this );" validatefn="isEmail" validateparam1="" />
//
//
//  Password and confirm password fields:
//	<input type="password" id="password" name="password" value="" onKeyUp="validate( this );" validatefn="pwmatch" validateparam1="confirmpassword" />
//  <input type="password" id="confirmpassword" name="confirmpassword" value="" onKeyUp="validate( this );" validatefn="pwmatch" validateparam1="password" />