/*
 * Construtor stores the passed in form widget internally and defines available
 * methods.  This object will validate each widget.  It checks for entries in
 * mandatory fields, meets range requirements and a radio button is selected
 * based off of radio button group.  This object provides a way to mark
 * certain textfield/text area and file for mandatory and range checks
 * (textfield/text area only).  Then goes though the widget list and marks
 * all textfield, text area and file to optional.
 */
function ValidateForm(formObject)
{
	// Class attributes
	this.objForm = formObject;

	// Method declarations
	this.setFileMandatory = ValidateForm_setFileMandatory;
	this.setTextMax = ValidateForm_setTextMax;
	this.setTextMin = ValidateForm_setTextMin;
	this.setTextMandatory = ValidateForm_setTextMandatory;
	this.setTextRange = ValidateForm_setTextRange;
	this.validateForm = ValidateForm_validateForm;

	// Initialization code

	/*
	 * Mark all textfield, text area and files to optional.
	 */
	 for (var i = 0; i < this.objForm.length; i++)
	 {
		var elemField = this.objForm.elements[i];

		/*
		 * Check if the current field is some type of text and it is not optional.
		 */
		if ((elemField.type == "text") || (elemField.type == "textarea") ||
			(elemField.type == "file"))
			elemField.optional = true;
	 }
}

/*
 * This method will look for the widget instance that matches the passed in
 * widget name and then checks to see that it is a file.  It then set the 
 * optional attribute to false, which makes the widget mandatory.
*/
function ValidateForm_setFileMandatory(strFileName)
{
	//	Find the first widget instance name under this form
	var txtFieldElem = this.objForm.elements[strFileName];

	// Do this only for file updload widget
	if (txtFieldElem.type == "file")
		this.objForm.elements[strFileName].optional = false;
}

/*
 * Marks the textfield to only allow up to a certain max value.  Takes the widget
 * instance name and looks for the widget instance with in the defined form.
 * Once found, a type check is done on the widget and then the max attribute is
 * set to the passed in integer value.
*/
function ValidateForm_setTextMax(strTextName, intMaxValue)
{
	//	Find the first widget instance name under this form
	var txtFieldElem = this.objForm.elements[strTextName];

	txtFieldElem.numeric = true;

	// Do this only for text field or text area widgets
	if (txtFieldElem.type == "text")
		this.objForm.elements[strTextName].maxVal = intMaxValue;
}

/*
 * Marks the textfield to only allow upto a certain max value.  Takes the widget
 * instance name and looks for the widget instance with in the defined form.
 * Once found, a type check is done on the widget and then the min attribute is
 * set to the passed in integer value.
 */
function ValidateForm_setTextMin(strTextName, intMinValue)
{
	//	Find the first widget instance name under this form
	var txtFieldElem = this.objForm.elements[strTextName];

	txtFieldElem.numeric = true;

	// Do this only for text field or text area widgets
	if (txtFieldElem.type == "text")
		this.objForm.elements[strTextName].minVal = intMinValue;
}

/*
 * This method will look for the widget instance that matches the passed in
 * widget name and then checks to see that it is either a textfield or a text
 * area.  It then set the optional attribute to false, which makes the widget
 * mandatory.
 */
function ValidateForm_setTextMandatory(strTextName)
{
	//	Find the first widget instance name under this form
	var txtFieldElem = this.objForm.elements[strTextName];

	// Do this only for text field or text area widgets
	if ((txtFieldElem.type == "text") || (txtFieldElem.type == "textarea"))
		this.objForm.elements[strTextName].optional = false;
}

/*
 * Sets the min and max values for specific widget based on name.  It compares
 * the passed in min/max values and will swap them if they are put in the
 * wrong order.
 */
function ValidateForm_setTextRange(strTextName, intMinValue, intMaxValue)
{
	/*
	 * Check to make sure the range are not backwards then set the min and
	 * max with already establish methods.
	 */
	if (intMinValue <= intMaxValue)
	{
		// Range is correct so process normal
		this.setTextMin(strTextName, intMinValue);
		this.setTextMax(strTextName, intMaxValue);
	}
	else
	{
		// Range is backwords so swap values
		this.setTextMin(strTextName, intMaxValue);
		this.setTextMax(strTextName, intMinValue);
	}
}

/*
 * Goes through all of the widgets for this form and determines the widget type.
 * Once the type is determined, it is process accroding to type.  As each widget
 * is being processed, an error message is being build for any that fail
 * validation.  Once validation is complete, a final string message is build.
 * It states all of the validation errors for this form and presents a dialog
 * with that message to the user.  The method will either return true, no
 * validation errors or false, validation errors occured.
 */
function ValidateForm_validateForm()
{
	var blnValSuccess = true;  // Assume form is correct.
	var intRangeErrType = 0;   // For textfields with range qualifiers
	var strMsg;
	var strEmptyFields = "";
	var strRangeErrors = "";
	var strRadioErrors = "";
	var objRadLst = new RadioElements();
	var objTxtFld = new ValidateTextField();
	var objFileUpload = new ValidateFileUpload();

	/*
	 * Loop through all the elements on the passed in form object,
	 * looking for all text/textarea that are not optional.  Check
	 * the field for null and make a list of them that are.  If any
	 * of the elements have min/max defined then verify that they
	 * are in the right range.
	 */
	for (var i = 0; i < this.objForm.length; i++)
	{
		var elemField = this.objForm.elements[i];

		/*
		 * Set the textfield to white, in case that it was red
		 */
		 if ((elemField.type == "text") || (elemField.type == "textarea")
			 || (elemField.type == "file"))
			elemField.style.backgroundColor = "white";

		/*
		 * Check if the current field is some type of text and it
		 * is not optional.
		 */
		if ((elemField.type == "text") || (elemField.type == "textarea"))
		{
			// Make sure this field is not null or empty if mandatory
			if (!elemField.optional)
			{
				if (objTxtFld.isEmpty(elemField))
				{
					strEmptyFields += "\n          " + elemField.name;
				
					// Change the textfield color
					elemField.style.backgroundColor = "red";
				}
			}

			// Now check for fields that are supposed to be numeric
			if (objTxtFld.isNumeric(elemField))
			{
				if (!objTxtFld.inRange(elemField))
				{
					strRangeErrors += "-  The field '" + elemField.name + "' must be a number";

					// Change the textfield color
					elemField.style.backgroundColor = "red";

					// Determine the range qualifiers and complete the error range message
					switch (objTxtFld.rangeErrType(elemField))
					{
						case 1:
							strRangeErrors += " that is greater than " + elemField.minVal;
							break;
						case 2:
							strRangeErrors += " that is less than " + elemField.maxVal;
							break;
						case 3:
							strRangeErrors += " that is greater than " + elemField.minVal;
							strRangeErrors += " and less that " + elemField.maxVal;
							break;
					}
					strRangeErrors += ".\n";
				}
			}
		}
		else if (elemField.type == "radio")
		{
			// Add radio button to list
			objRadLst.addRadioButton(elemField.name);

			// If the radio button is checked, mark it "set" and store the value
			if (elemField.checked == true)
				objRadLst.markSet(elemField.name);
		}
		else if ((elemField.type == "file") && (!elemField.optional))
		{
			if (objFileUpload.isEmpty(elemField))
			{
				strEmptyFields += "\n          " + elemField.name;

				// Change the textfield color to red
				elemField.style.backgroundColor = "red";
			}
		}
	}

	/*
	 * If there were no error message return true.  If there were, 
	 * display error message of all fields that have a problem
	 * entry.
	 */
	if (!strEmptyFields && !strRangeErrors)
		blnValSuccess = true;
	else
	{
		blnValSuccess = false;

		// Build up the message based off of validation done.
		strMsg  = "____________________________________________________________\n\n";
		strMsg += "The form was not submitted because of the following errors(s).\n";
		strMsg += "Please correct these error(s) and re-submit.\n";
		strMsg += "____________________________________________________________\n\n";

		// Go through and identify each field that is incorrect.
		if (strEmptyFields)
		{
			strMsg += "-  The following required field(s) are empty: ";
			strMsg += strEmptyFields + "\n";
		}

		// Report any range errors
		if (strRangeErrors)
			strMsg += "\n" + strRangeErrors + "\n";

		// Now process the radio buttons, to see if there are any errors.
		if (objRadLst.getLength() > 0)
		{
			strRadioErrors += objRadLst.checkSet();
			if (strRadioErrors != "")
			{
				strMsg += "\n-  The following option needs to have a selection:";
				strMsg += objRadLst.checkSet();
			}
		}
		alert(strMsg);
	}
	return (blnValSuccess);
}