/* *******************************************
   ** FormValidation...
   ** ----------------------------------------
   ** Version: 0.3 Alpha - codename: Mr. Wood
   **
   ** Programmer: Brian Clemmensen
   ** Date:       30/01 - 2001
   ******************************************* */

/* *******************************************
   ** Change log
   ** ----------------------------------------
   ** 25/05-01: Gathered the new version!
   ** 27/03-02: Changed the way functions has
   **			been implemented.
   *******************************************
*/

/* *******************************************
	** Description
	** -----------
	** This system is a generic form validator
	** that can be used to validate any form.
	**
	** The system is object oriented in the way
	** that it is written in objects and thereby
	** making it very easy to use.
	**
	** The main object of this system is
	** FormValidator
	******************************************* */


function FormValidator() {

	// Initializing variables
	this.ErrorMessage_start 			= "The form has errors:\n---------------\n\n";
	this.ErrorMessage_end   			= "\n---------------\n\nPlease correct them and try again.";
	this.ErrorMessage_isRequired 		= "The following elements are required:\n";
	this.ErrorMessage_mustCompare		= "The following elements must compare:\n";
	this.ErrorMessage_isRequired_bullet	= "* ";
	this.ErrorMessage_seperator 		= "---";
	this.ErrorMessage_seperatorCompare	= " - ";
	this.ErrorMessage_function        	= "this.ErrorHandler";
	this.ErrorCode_isRequired 			= "REQUIRED";
	this.ErrorCode_isTooLong 			= "TOO LONG";
	this.ErrorCode_isTooShort 			= "TOO SHORT";
	this.ErrorCode_NameMsgSeperator		= "";
	this.reg_expression_not_empty_obj 	= new RegExp("\\w+");
	this.RulesArray 					= new Array();
	this.GroupsArray 					= new Array();
	this.MulticheckArray				= new Array();
	this.DependencyArray				= new Array();
	this.radio_array 					= new Array();
	this.checkbox_array 				= new Array();
	this.compare_array	 				= new Array();

	this.DependencyArray_currentno			= -1;

	// Now we set the individual functions to be referenced by this object...

	//this.ErrorHandler = formValidation_ErrorHandler;
	/*this.testRegularExpression = formValidation_testRegularExpression
	this.findRuleArrayObject = formValidation_findRuleArrayObject;
	this.checkTextField = formValidation_checkTextField;
	this.checkSelectField = formValidation_checkSelectField;
	this.checkRadioField = formValidation_checkRadioField;
	this.checkCheckboxField = formValidation_checkCheckboxField;
	this.checkGroups = formValidation_checkGroups;
	this.checkDependencies = formValidation_checkDependencies;
	this.checkMultiple = formValidation_checkMultiple;
	this.checkField = formValidation_checkField;*/



	// Now we set the public functions!
	/*this.validate = formValidation_validate;
	this.addRule = formValidation_addRule;
	this.addGroup = formValidation_addGroup;
	this.addMulticheck = formValidation_addMulticheck;
	this.addDependency = formValidation_addDependency;
	this.addDependencyEntry = formValidation_addDependencyEntry;*/
}

/* ***********************************************************
 * Function to set the text of the error message.
 *
 * Returns: -
 * ***********************************************************
 */
FormValidator.prototype.setErrorMessage = function(start, end, required, compare) {
	this.ErrorMessage_start			= start;
	this.ErrorMessage_end   		= end;
	this.ErrorMessage_isRequired 	= required;
	this.ErrorMessage_mustCompare	= compare;

}


/* ***********************************************************
 * Function to init the check arrays
 *
 * Returns: -
 * ***********************************************************
 */
FormValidator.prototype.initArrays = function () {
	this.radio_array 		= new Array();
	this.checkbox_array 	= new Array();
}


/* ***********************************************************
 * Function to alert the user of form errors...
 *
 * Returns: -
 * ***********************************************************
 */
FormValidator.prototype.ErrorHandler = function (errorMessageArray, errorMessageHeaderStart, errorMessageHeaderEnd) {
	// Element structure:
	// [0] = Name of field (Text name) / group error message
	// [1] = Error message / will be null when containing group messages

	var errorReport, requiredReport, errorcode;
	errorReport = "";
	requiredReport = "";


	for (i=0;i<errorMessageArray.length;i++) {

		errorcode = errorMessageArray[i][1];

		if (errorcode.indexOf(this.ErrorCode_isRequired)== -1) {
			errorReport += errorMessageArray[i][0];
			if (errorMessageArray[i][1]) {
				errorReport += this.ErrorCode_NameMsgSeperator+ " " + errorMessageArray[i][1];
			}
			errorReport += "\n";
		}
	}


	for (i=0;i<errorMessageArray.length;i++) {

		errorcode = errorMessageArray[i][1];

		if (errorcode.indexOf(this.ErrorCode_isRequired)== 0) {
			requiredReport += this.ErrorMessage_isRequired_bullet + errorMessageArray[i][0];
			requiredReport += "\n";
		}
	}

	if (requiredReport.length >0) {
		if (errorReport.length >0)
			errorReport = this.ErrorMessage_isRequired + requiredReport + "\n" + this.ErrorMessage_seperator + errorReport;
		else
			errorReport = this.ErrorMessage_isRequired + requiredReport;
	}


	// If there were errors - print them out!
	if (errorReport!="") alert(errorMessageHeaderStart+errorReport+errorMessageHeaderEnd);
}



/* ***********************************************************
 * Function that test a regular expression agaist a value.
 * If no regular expression is passed along the return value
 * always is true.
 *
 * Returns: true | false
 * ***********************************************************
 */
FormValidator.prototype.testRegularExpression = function (objValue, testRegExp, testRegExpflags) {
	var negative = false;
	negative = false;
	if (testRegExp && testRegExp != "") {
		if (!testRegExpflags)
			testRegExpflags="";
		else {
			if (testRegExpflags.substr(0,1)=="!") {
				negative=true;
				testRegExpflags = testRegExpflags.substr(1);
			}
		}
		testRegExpObj = new RegExp(testRegExp,testRegExpflags);
		if (negative)
			return (!(testRegExpObj.test(objValue)));
		else
			return (testRegExpObj.test(objValue));
	} else
		return (true);
}



/* ***********************************************************
 * Function that returns the rule object linked to the specific
 * field - if a rule object exists else an empty object is
 * returned
 *
 * Returns: null | a rule object
 * ***********************************************************
 */
FormValidator.prototype.findRuleArrayObject = function (fieldObjName) {
	var returnObj = null;
	returnObj = null;

	var i = 0;

	// Now search through the rules to find the active rule
	for (i=0; i<this.RulesArray.length; i++) {
		if (this.RulesArray[i][0] == fieldObjName) {
			if (returnObj == null) returnObj = new Array();
			returnObj[returnObj.length] = this.RulesArray[i];
			//returnObj = this.RulesArray[i];
			//break;
		}
	}

	return(returnObj);
}



/* ***********************************************************
 * Function that checks if text fields are filled correctly!
 * If the function returns something else than an empty string
 * the field has erros. The description of these errors are
 * listed in the return value.
 *
 * Returns: empty string | error text/help text
 * ***********************************************************
 */
FormValidator.prototype.checkTextField = function (textFieldObj, ruleArrayObj) {
   // Returnvalue
   var returnText = "";
   returnText = "";

   // testVars
   var value_filled 	= false;
   var regexp_true 	= false;
   var value_lengthOK   = true;

   value_filled 	= false;
   regexp_true 	= false;
   value_lengthOK = true;

	// Name and value of input object
	var objName 	= textFieldObj.name;
	objName 	= textFieldObj.name;
	var objValue 	= textFieldObj.value;
	objValue 	= textFieldObj.value;

	// Create empty rule objects
	var isRequired 				= false;	// isRequired
	var reg_expression 			= "";		// reg.epression
	var reg_expression_flags 	= "";		// reg.epression flags
	var helptext			 		= "";		// helptext
	var valueLengthMin;
	var valueLengthMax;
	var valueLengthText;
	isRequired 				= false;	// isRequired
	reg_expression 			= "";		// reg.epression
	reg_expression_flags 	= "";		// reg.epression flags
	helptext	= "";		// helptext
	valueLengthMin 				= null;
	valueLengthMax 				= null;
	valueLengthText				= null;

	// If there is passed a ruleArrayObj then extract the values from it
	if (ruleArrayObj) {
		isRequired 				= ruleArrayObj[2];
		reg_expression 		= ruleArrayObj[3];
		reg_expression_flags	= ruleArrayObj[4];
		helptext 				= ruleArrayObj[5];
		valueLengthMin 				= ruleArrayObj[6];
		valueLengthMax 				= ruleArrayObj[7];
		valueLengthText				= ruleArrayObj[8];
	}

	// Retrieve information about the text field. First check to see
	// if it has a value and then if the regular expression is true.
	// These information are stored in temp. variables.
	value_filled 	= this.reg_expression_not_empty_obj.test(objValue);
	regexp_true 	= this.testRegularExpression(objValue, reg_expression, reg_expression_flags);

	// Check to see if the field is required to be filled
	if (isRequired) {
		// If it is and it is not filled - return the appropiate error text
		if (!value_filled) returnText = this.ErrorCode_isRequired;
	}

	// Now we check the length of the value
	if (valueLengthMin!= null && valueLengthMin!="") {
		if (valueLengthMax!=null && valueLengthMax!="") {
			value_lengthOK = (valueLengthMin<=objValue.length && valueLengthMax>=objValue.length);
		} else {
			value_lengthOK = (valueLengthMin.valueOf<=objValue.length);
		}
	}


	if (value_filled && !value_lengthOK) {
		returnText += valueLengthText;
	}

	// Now we check to see if the field is filled and with the correct values.
	// If not return the help text for the field!
	if (value_filled && !regexp_true && value_lengthOK) {
		returnText += helptext;
	}

	// Return the result of the function containing either empty string or the help text!
	return (returnText);
}



/* ***********************************************************
 * Function that checks if text fields are filled correctly!
 * If the function returns something else than an empty string
 * the field has erros. The description of these errors are
 * listed in the return value.
 *
 * Returns: empty string | error text/help text
 * ***********************************************************
 */
FormValidator.prototype.checkSelectField = function (selectFieldObj, ruleArrayObj) {
   // Returnvalue
   var returnText = "";
   returnText = "";

   // testVars
   var value_filled 	= false;
   var regexp_true 	= false;
   var multivalues	= false;
   var error_infield = false;
   var error_inreg	= false;
   var amountchecked = 0;
   var value_lengthOK   = true;

   value_filled 	= false;
   value_lengthOK   = true;
   regexp_true 	= false;
   multivalues	= false;
   error_infield = false;
   error_inreg	= false;
   amountchecked = 0;

	// Create empty rule objects
	var isRequired 				= false;	// isRequired
	var reg_expression 			= "";		// reg.epression
	var reg_expression_flags 	= "";		// reg.epression flags
	var helptext			 		= "";		// helptext
	var valueLengthMin;
	var valueLengthMax;
	var valueLengthText;
	isRequired 				= false;	// isRequired
	reg_expression 			= "";		// reg.epression
	reg_expression_flags 	= "";		// reg.epression flags
	helptext			 		= "";		// helptext
	valueLengthMin 				= null;
	valueLengthMax 				= null;
	valueLengthText				= null;

	// If there is passed a ruleArrayObj then extract the values from it
	if (ruleArrayObj) {
		isRequired 				= ruleArrayObj[2];
		reg_expression 		= ruleArrayObj[3];
		reg_expression_flags	= ruleArrayObj[4];
		helptext 				= ruleArrayObj[5];
		valueLengthMin 				= ruleArrayObj[6];
		valueLengthMax 				= ruleArrayObj[7];
		valueLengthText				= ruleArrayObj[8];
	}

	multivalues = selectFieldObj.multiple;

	// Now we check the length of the value
/*	if (valueLengthMin!= null && valueLengthMin!="") {
		if (valueLengthMax!=null && valueLengthMax!="") {
			value_lengthOK = (valueLengthMin<=selectFieldObj.options.length && valueLengthMax>=selectFieldObj.options.length);
		} else {
			value_lengthOK = (valueLengthMin.valueOf<=selectFieldObj.options.length);
		}
	}
*/
	if (!value_lengthOK) {
		error_infield = true;
	}

	var i = 0;
	for (i=0;i<selectFieldObj.options.length;i++) {

		if (selectFieldObj.options[i].selected) {

			// Keep track of the amount of options selected in the select box
			amountchecked++;

			// Name and value of input object
			//var objName 	= selectFieldObj.options[i].name;
			var objValue;
			objValue 	= selectFieldObj.options[i].value;

			// Retrieve information about the text field. First check to see
			// if it has a value and then if the regular expression is true.
			// These information are stored in temp. variables.
			value_filled 	= this.reg_expression_not_empty_obj.test(objValue);
			regexp_true 	= this.testRegularExpression(objValue, reg_expression, reg_expression_flags);

			// Check to see if the field is required to be filled
			if (isRequired) {
				// If it is and it is not filled - return the appropiate error text
				if (!value_filled) error_infield = true;
				//if (!value_filled && !multivalues) returnText = formValidation_ErrorMessage_isRequired;
				//if (!value_filled && multivalues) returnText = helptext;
			}

			// Now we check to see if the field is filled and with the correct values.
			// If not return the help text for the field!
			if (value_filled && !regexp_true && value_lengthOK) {
				//returnText = helptext;
				error_inreg = true;
			}

		}

	}

	if (error_infield || error_inreg) {
		if (error_infield && !error_inreg)
			if (amountchecked==1 && value_lengthOK) {
				returnText = this.ErrorCode_isRequired;
			} else if (value_lengthOK) {
				returnText = helptext;
			} else {
				returnText = valueLengthText;
			}
		else
			returnText = helptext;
	} else {
		if (amountchecked==0 && isRequired) returnText = this.ErrorCode_isRequired;
	}

	// Return the result of the function containing either empty string or the help text!
	return (returnText);
}


/* ***********************************************************
 * Function that checks if text fields are filled correctly!
 * If the function returns something else than an empty string
 * the field has erros. The description of these errors are
 * listed in the return value.
 *
 * Returns: empty string | error text/help text
 * ***********************************************************
 */
FormValidator.prototype.checkRadioField = function (radioFieldObj, ruleArrayObj) {
   // Returnvalue
   var returnText = "";
   returnText = "";

   var isRequired 	= false;
   var objTextName 	= "";
   isRequired 	= false;
   objTextName 	= "";

   if (ruleArrayObj)	{
   	isRequired 	= ruleArrayObj[2];
   	objTextName	= ruleArrayObj[1];
   }


	// Name and value of input object
	var objName 	= radioFieldObj.name;
	var objValue 	= radioFieldObj.checked;
	objName 	= radioFieldObj.name;
	objValue 	= radioFieldObj.checked;

	// Check to see if the radio button is in the array
	var i = 0;
	var radioExists = false;
	var radioElement = null;
	radioExists = false;
	radioElement = null;

	// Find the radioElement in the array if it exists
	for (i=0;i<this.radio_array.length;i++) {
		if (this.radio_array[i][0] == objName) {
			radioElement = this.radio_array[i];
			radioExists = true;
		}
	}

	// If the element doesn't exist - create one
	if (!radioElement) {
		radioElement = new Array();
		radioElement[1] = false;
	}

	// Fill the element with values...
	radioElement[0] = objName;
	if (!radioElement[1]) radioElement[1] = objValue;
	radioElement[2] = isRequired;
	radioElement[3] = this.ErrorCode_isRequired;
	radioElement[4] = objTextName;

	// Now save the new/modified element in the array
	if (!radioExists) this.radio_array[this.radio_array.length]=radioElement;

	return ("");
}


/* ***********************************************************
 * Function that checks if text fields are filled correctly!
 * If the function returns something else than an empty string
 * the field has erros. The description of these errors are
 * listed in the return value.
 *
 * Returns: empty string | error text/help text
 * ***********************************************************
 */
FormValidator.prototype.checkCheckboxField = function (checkboxFieldObj, ruleArrayObj) {
   // Returnvalue
   var returnText = "";
   returnText = "";

   var isRequired 	= false;
   var objTextName 	= "";
   isRequired 	= false;
   objTextName 	= "";

   if (ruleArrayObj)	{
   	isRequired 	= ruleArrayObj[2];
   }


	// Name and value of input object
	var objName 	= checkboxFieldObj.name;
	var objValue 	= checkboxFieldObj.checked;
	objName 	= checkboxFieldObj.name;
	objValue 	= checkboxFieldObj.checked;

	var checkboxElement = new Array();
	checkboxElement = new Array();
	checkboxElement[0] = objName;
	checkboxElement[1] = objValue;
	this.checkbox_array[this.checkbox_array.length]=checkboxElement;


	// Check to see if the field is required to be filled
	if (isRequired) {
		// If it is and it is not filled - return the appropiate error text
		if (!objValue) returnText = this.ErrorCode_isRequired;
	}

	return (returnText);
}



FormValidator.prototype.checkGroups = function () {
	var returnArray;
	returnArray = new Array();


	// We start by running through the group list
	var i = 0;
	for (i=0; i<this.GroupsArray.length; i++) {
		//
		var regularExpressionGroup 		= this.GroupsArray[i][0];
		var regularExpressionGroupFlags 	= this.GroupsArray[i][1];
		var minElements 						= this.GroupsArray[i][2];
		var maxElements 						= this.GroupsArray[i][3];
		var strHelpText 						= this.GroupsArray[i][4];
		regularExpressionGroup 				= this.GroupsArray[i][0];
		regularExpressionGroupFlags 		= this.GroupsArray[i][1];
		minElements 							= this.GroupsArray[i][2];
		maxElements 							= this.GroupsArray[i][3];
		strHelpText 							= this.GroupsArray[i][4];

		var foundElements = 0;
		foundElements = 0;

		var y=0;
		for (y=0; y<this.checkbox_array.length; y++) {
			var objChecked 	= this.checkbox_array[y][1];
			var objName 		= this.checkbox_array[y][0];
			objChecked 			= this.checkbox_array[y][1];
			objName 				= this.checkbox_array[y][0];

			if (objChecked) {
				if (this.testRegularExpression(objName, regularExpressionGroup, regularExpressionGroupFlags))
					foundElements++;
			}
		}

		if (!((minElements==0 && maxElements==0) || (minElements>0 && maxElements==0 && foundElements>=minElements) || (minElements>0 && maxElements>0 && foundElements>=minElements && foundElements<=maxElements))) {
			returnArray[returnArray.length]=strHelpText;

		}
	}

	return (returnArray);
}



FormValidator.prototype.checkDependencies = function (formtovalidate) {
	var returnArray, objArray;
	returnArray = new Array();

	var element_strField,
		 element_strRegExp,
		 element_strRegExpFlags,
		 element_strHelpText,
		 element_entryArray;

	var entry_strField,
		 entry_isRequired,
		 entry_strRegExp,
		 entry_strRegExpFlags;


	var objValue, hasToCheckDependencies, y;

	var i=0, x=0, z=0;
	var numberOfElements = formtovalidate.elements.length;
	numberOfElements = formtovalidate.elements.length;

	for (i=0;i<this.DependencyArray.length;i++) {

		hasToCheckDependencies = false;

		objArray = this.DependencyArray[i];

		element_strField = objArray[0];
		element_strRegExp = objArray[1];
		element_strRegExpFlags = objArray[2];
		element_strHelpText = objArray[3];
		element_entryArray = objArray[4];

		// Now we find the element in the form
		for (x=0;x<numberOfElements;x++) {
			if (formtovalidate.elements[x].name == element_strField) {

			    switch (formtovalidate.elements[x].type) {
			        case "select-multiple":
            			        for (y=0;y<formtovalidate.elements[x].options.length;y++) {
            						if (formtovalidate.elements[x].options[y].selected) {
            							objValue = formtovalidate.elements[x].options[y].value;

            							// Field found - now check to see if the field regexp tests positive
            							if (this.testRegularExpression(objValue, element_strRegExp, element_strRegExpFlags)) {
            								// The test was positive. Now we have to test all the dependencies
            								hasToCheckDependencies = true;
            								break;
            							}
            						}
            					}
            					break;

            	    case "checkbox":
            	                if (formtovalidate.elements[x].checked) hasToCheckDependencies = true;
            	                break;

            	    default:
            	                objValue = formtovalidate.elements[x].value;
            	                // Field found - now check to see if the field regexp tests positive
            					if (this.testRegularExpression(objValue, element_strRegExp, element_strRegExpFlags)) {
            						// The test was positive. Now we have to test all the dependencies
            						hasToCheckDependencies = true;
            					}
            					break;

			    }

			    if (hasToCheckDependencies) break;

			}

		}

		if (hasToCheckDependencies) {
			var errorInDependency;
			errorInDependency = false;
			for (z=0;z<element_entryArray.length;z++) {

				var checkentryRuleArray, errorElement;
				chechentryRuleArray = new Array();

				entry_strField 			= element_entryArray[z][0];
		 		entry_isRequired 			= element_entryArray[z][1];
		 		entry_strRegExp 			= element_entryArray[z][2];
		 		entry_strRegExpFlags 	= element_entryArray[z][3];


		 		chechentryRuleArray[0] = entry_strField;
				chechentryRuleArray[1] = "DEPENDENCY";
				chechentryRuleArray[2] = entry_isRequired;
				chechentryRuleArray[3] = entry_strRegExp;
				chechentryRuleArray[4] = entry_strRegExpFlags;
				chechentryRuleArray[5] = "_NONE_";

				for (y=0;y<numberOfElements;y++) {
					if (formtovalidate.elements[y].name == entry_strField) {

						errorElement = this.checkField(formtovalidate.elements[y], chechentryRuleArray);
						if (errorElement) errorInDependency = true;
					}
				}

			}

			if (errorInDependency) returnArray[returnArray.length] = element_strHelpText;
		}

	}

	return (returnArray);
}



FormValidator.prototype.checkMultiple = function (formtovalidate) {
	var returnArray, objArray, strText, strRegExp, strRegExpFlags, strEval, bFunctionResult_true, objValue;
	var dummyvar = "________DUMMY________";
	returnArray = new Array();

	var i, y, strText;
	for (i=0;i<this.MulticheckArray.length;i++) {
		strText = this.MulticheckArray[i][0];
		strRegExp = this.MulticheckArray[i][3];
		strRegExpFlags = this.MulticheckArray[i][4];

		for (y=0;y<formtovalidate.elements.length;y++) {
			objValue = formtovalidate.elements[y].value;
			if (!objValue || objValue=="") objValue=dummyvar;

			strText = strText.replace("#" + formtovalidate.elements[y].name + "#", objValue);
		}

		if (!(this.testRegularExpression(strText, dummyvar))) {

			strEval = "bFunctionResult_true="+this.MulticheckArray[i][1]+"(strText,strRegExp,strRegExpFlags)";
			bFunctionResult_true = false;

			eval(strEval);

			if (bFunctionResult_true) returnArray[returnArray.length] = this.MulticheckArray[i][2];
		}

	}
	return (returnArray);
}



FormValidator.prototype.checkField = function (objElement, ruleArrayObj) {
	var returnObj
	returnObj = null;

	switch (objElement.type) {
		case "select-multiple":   	// select box - multiple
		case "select-one":   		// select box - single
											strHelpText = this.checkSelectField(objElement, ruleArrayObj);

											if (strHelpText!="") {
												errorElement = new Array();
												errorElement[0] = ruleArrayObj[1];
												errorElement[1] = strHelpText;
												//errorReportArray[errorReportArray.length]=errorElement;
												returnObj = errorElement;
											}

											break;
		case "hidden":   				// hidden input boxes
		case "password":   			// input password boxes
		case "file":   				// input file boxes
		case "text":   				// input text boxes
		case "textarea":   				// input text boxes
											strHelpText = this.checkTextField(objElement, ruleArrayObj);

											if (strHelpText!="") {
												errorElement = new Array();
												errorElement[0] = ruleArrayObj[1];
												errorElement[1] = strHelpText;
												//errorReportArray[errorReportArray.length]=errorElement;
												returnObj = errorElement;
											}

											break;

		case "checkbox": 				// input text boxes
											strHelpText = this.checkCheckboxField(objElement, ruleArrayObj);

											if (strHelpText!="") {
												errorElement = new Array();
												errorElement[0] = ruleArrayObj[1];
												errorElement[1] = strHelpText;
												//errorReportArray[errorReportArray.length]=errorElement;
												returnObj = errorElement;
											}

											break;

		case "radio":					// radio button
											this.checkRadioField(objElement, ruleArrayObj);

											break;
	}

	return (returnObj);
}



/* ***********************************************************
 * Main function - run this to check the form!
 *
 * Returns: true | false
 * ***********************************************************
 */
FormValidator.prototype.validate = function (formtovalidate) {
	// Init the arrays
	this.initArrays();

	// Create an errorreport
	var errorReport = new String();
	var errorReportArray = new Array();
	var formvalidation_grouparray;
	var formvalidation_dependencyarray;
	var formvalidation_multiplearray;
	errorReport = new String();
	errorReportArray = new Array();
	formvalidation_grouparray = null;
	formvalidation_dependencyarray = null;
	formvalidation_multiplearray = null;
	formvalidation_comparearray = null;


	// How many elements are there in the form
	var numberOfElements = formtovalidate.elements.length;
	numberOfElements = formtovalidate.elements.length;

	var i = 0, y = 0;
	var focus = 0;

	// Now we run through the form elements
	for (i=0;i<numberOfElements;i++) {
		var ruleArrayObj;
		var errorElement;
		ruleArrayObj = this.findRuleArrayObject(formtovalidate.elements[i].name);

		if (ruleArrayObj != null) {
			// If there are rules to the field - run them all
			for (y=0; y<ruleArrayObj.length;y++) {
				errorElement = this.checkField(formtovalidate.elements[i], ruleArrayObj[y]);

				if (errorElement) {
					errorReportArray[errorReportArray.length]=errorElement;
					//focus on the field witht the error, if another filed has got the error focus then don't take it from that field
					if(focus == 0){
						focus = 1;
						formtovalidate.elements[i].focus();
					}
				}
			}
		} else {
			// If there are no rules to the field
			errorElement = this.checkField(formtovalidate.elements[i], null);

			if (errorElement) {
				errorReportArray[errorReportArray.length]=errorElement;
				//focus on the field with the error, if another filed has got the error focus then don't take it from that field
				if(focus == 0){
					focus = 1;
					formtovalidate.elements[i].focus();
				}
			}
		}

		//alert(formtovalidate.elements[i].name + " -- " + formtovalidate.elements[i].type);
	}

	// Now we do post-checks
	// =====================

	// First we check the radio buttons
	for (i=0;i<this.radio_array.length;i++) {
		if (this.radio_array[i][2]) {
			if (!this.radio_array[i][1]) {
				var errorElement;
				errorElement = new Array();
				errorElement[0] = this.radio_array[i][4];
				errorElement[1] = this.radio_array[i][3];
				errorReportArray[errorReportArray.length]=errorElement;
			}
		}
	}

	formvalidation_grouparray = this.checkGroups();
	formvalidation_dependencyarray = this.checkDependencies(formtovalidate);
	formvalidation_multiplearray = this.checkMultiple(formtovalidate);
	formvalidation_comparearray 		= this.checkCompare(formtovalidate);

	for (i=0;i<formvalidation_grouparray.length;i++) {
		var errorElement;
		errorElement = new Array();
		errorElement[0] = formvalidation_grouparray[i];
		errorElement[1] = "";
		errorReportArray[errorReportArray.length]=errorElement;
	}

	for (i=0;i<formvalidation_dependencyarray.length;i++) {
		var errorElement;
		errorElement = new Array();
		errorElement[0] = formvalidation_dependencyarray[i];
		errorElement[1] = "";
		errorReportArray[errorReportArray.length]=errorElement;
	}

	for (i=0;i<formvalidation_multiplearray.length;i++) {
		var errorElement;
		errorElement = new Array();
		errorElement[0] = formvalidation_multiplearray[i];
		errorElement[1] = "";
		errorReportArray[errorReportArray.length]=errorElement;
	}
	
	for (i=0;i<formvalidation_comparearray.length;i++) {
		var errorElement;
		errorElement = new Array();
		errorElement[0] = formvalidation_comparearray[i];
		errorElement[1] = "";
		errorReportArray[errorReportArray.length]=errorElement;
	}

	// Send the output to the ErrorHandler
	if (this.ErrorMessage_function!=null && this.ErrorMessage_function!="") {
		var errorhandler;
		errorhandler = this.ErrorMessage_function + "(errorReportArray, this.ErrorMessage_start, this.ErrorMessage_end);";

		eval(errorhandler);

	}

	// If there were errors return false so the form isn't submitted...
	return (errorReportArray.length==0);
}


/* ***********************************************************
 * Function to add a rule to the environment
 *
 * Returns: -
 * ***********************************************************
 */
FormValidator.prototype.addRule = function (elementName, elementTextName, isRequired, elementHelp, regExpression, regExpressionFlags, valueLengthMin, valueLengthMax, valueLengthText) {

	var newElement;
	newElement = new Array(5);

	newElement[0] = elementName;
	newElement[1] = elementTextName;
	newElement[2] = isRequired;
	newElement[3] = regExpression;
	newElement[4] = regExpressionFlags;
	newElement[5] = elementHelp;
	newElement[6] = valueLengthMin;
	newElement[7] = valueLengthMax;
	newElement[8] = valueLengthText;

	this.RulesArray[this.RulesArray.length]=newElement;
}



/* ***********************************************************
 * Function to add a group to the environment
 *
 * Returns: -
 * ***********************************************************
 */
FormValidator.prototype.addGroup = function (regularExpressionGroup, minElements, maxElements, strHelpText) {

	var newElement;
	newElement = new Array(5);

	newElement[0] = regularExpressionGroup;
	newElement[1] = "i";
	newElement[2] = minElements;
	newElement[3] = maxElements;
	newElement[4] = strHelpText;

	this.GroupsArray[this.GroupsArray.length]=newElement;
}



/* ***********************************************************
 * Function to add a multicheck to the environment
 *
 * Returns: -
 * ***********************************************************
 */
FormValidator.prototype.addMulticheck = function (strFields, strCheckFunction, strHelpText, strRegExp, strRegExpFlags) {

	var newElement;
	newElement = new Array(5);

	newElement[0] = strFields;
	newElement[1] = strCheckFunction;
	newElement[2] = strHelpText;
	newElement[3] = strRegExp;
	newElement[4] = strRegExpFlags;

	this.MulticheckArray[this.MulticheckArray.length]=newElement;
}




/* ***********************************************************
 * Function to add a dependency to the environment
 *
 * Returns: -
 * ***********************************************************
 */
FormValidator.prototype.addDependency = function (strField, strRegExp, strHelpText, strRegExpFlags) {

	var newElement;
	newElement = new Array(5);

	newElement[0] = strField;
	newElement[1] = strRegExp;
	newElement[2] = strRegExpFlags;
	newElement[3] = strHelpText;
	newElement[4] = new Array();

	this.DependencyArray_currentno = this.DependencyArray.length;

	this.DependencyArray[this.DependencyArray_currentno]=newElement;
}



/* ***********************************************************
 * Function to add a dependency entry to the environment
 *
 * Returns: -
 * ***********************************************************
 */
FormValidator.prototype.addDependencyEntry = function (strField, isRequired, strRegExp, strRegExpFlags) {

	if (this.DependencyArray_currentno==-1) {
		alert("ERROR - Remember to add a dependency first!");
		return;
	}

	var newElement;
	newElement = new Array(5);

	newElement[0] = strField;
	newElement[1] = isRequired;
	newElement[2] = strRegExp;
	newElement[3] = strRegExpFlags;

	objArray = this.DependencyArray[this.DependencyArray_currentno][4];

	objArray[objArray.length]=newElement;
}

/* ***********************************************************
 * Function to add a check for if two fields is alike
 *
 * Returns: -
 * ***********************************************************
 */
FormValidator.prototype.addCompareFields = function (elementName1, elementTextName1, elementName2, elementTextName2) {
	
	var newElement;
	newElement = new Array(4);

	newElement[0] = elementName1;
	newElement[1] = elementName2;
	newElement[2] = elementTextName1;
	newElement[3] = elementTextName2;
	
	this.compare_array[this.compare_array.length]=newElement;
}


/* ***********************************************************
 * Function check if two fields contain the same value
 *
 * Returns: -
 * ***********************************************************
 */
FormValidator.prototype.checkCompare = function (formtovalidate){
	var returnArray, objArray, compare1, compare2, oneCompareError;

	returnArray = new Array();
	oneCompareError = 0;

	var i, strText;

	for (i = 0; i < this.compare_array.length; i++) {
		objArray = this.compare_array[i];
		
		compare1 = eval("document."+formtovalidate.name+"."+objArray[0]);
		compare2 = eval("document."+formtovalidate.name+"."+objArray[1]);

		if(compare1.value != compare2.value){
			if(oneCompareError == 0){
				returnArray[returnArray.length] = this.ErrorMessage_mustCompare;
			}
			returnArray[returnArray.length] =  objArray[2] +  ""+this.ErrorMessage_seperatorCompare+"" + objArray[3];
			oneCompareError = 1;
		}

	}
	
	return (returnArray);
}
