//Implementation routine of the FormValidator class
//The FormValidator class requires that label elements be defined
//in order to validate a form
function validateForm(form) {
	
	var formObj			= $(form.id);
	var isValid			= Validator.isValid(formObj);
	
	// Return error message when false
	if (isValid) {
		return true;
	} else {
		Validator.displayErrors();
		return false;
	}

}

//FormValidator Class
var Validator = {};

//Checks for validity of form
Validator.isValid = function(formObj) {

	//Create a new form object
	var myForm				= formObj;
	var formElements		= myForm.getElements();
	var invalidFieldLabels	= new Array();
	var labels				= getLabels();
	var numInvalidFields	= 0;

	// Loop through all the fields in the form
	for (var i = 0; i < formElements.length; i++) {
		var myFormFieldId 	= formElements[i].id;
		
		//If the element doesn't have a valid id, it cannot be validated
		if (myFormFieldId) {
			var formField		= $(myFormFieldId);
			var formFieldName	= $(myFormFieldId).name;
			var formFieldClass	= formField.className;
						
			if (!formFieldName) {
				alert('System error [validation.js]: form field name undefined after ' + formElements[i - 1].id);
				return false;
			}
			
			//Omit field that aren't required
			if (Validator.omitField(myFormFieldId)) {
				continue;
			
			//Check for a valid value
			} else {
		
				//Check phone numbers
				var phoneFieldRegEx		= /phone|fax/i;
				var phoneTypeRegEx		= /type/i;
						
				if (formFieldName.match(phoneFieldRegEx) && !formFieldName.match(phoneTypeRegEx)) {
					var validPhone = Validator.isValidPhone(formField);
					if (!validPhone) {
						break;
						return false;
					}
				}			
		
				//Check for general validity
				if(Validator.isInvalidField(myFormFieldId)) {
					//Push values on to an array for reporting later
					invalidFieldLabels.push(labels[myFormFieldId]);
					numInvalidFields++;
				}
			}
		}
	}
		
	//When the number of invalid fields is 0, it's considered an invalid form
	if (numInvalidFields > 0 ) {
		Validator.setInvalidFieldLabels(invalidFieldLabels);
		return false;
	} else {
		return true;
	}	
	
}


// Check to see whether validation for the field is required 
Validator.omitField = function(myFormFieldId) {
	var myFormField	= $(myFormFieldId);
	
	//Only check values for field that have an id attribute defined
	if (myFormField) {
		
		var optionalRegEx		= /optional/i;
		var myFormClassName		= myFormField.className;
		
		// We don't need to validate hidden fields or buttons 	
		if (myFormField.type == 'hidden' || myFormField.type == 'button' || myFormField.type == 'image') {
			return true;
		
		// Allow the user to proceed when this distinct class is found
		} else if (myFormClassName.match(optionalRegEx)) {
			return true;
			
		// Require validation for everything else
		} else {
			return false;
		}
	
	} else {
		return true;
	}
	
}

// Get labels as a hash with 
// the input id as the hash key and the label text as the value
Validator.getLabels = function () {

	var fieldLabels		= $T('label');
	var labels			= new Hash({ });
	
	for (var i = 0; i < fieldLabels.length; i++) {
		var fieldLabelID	= fieldLabels[i].htmlFor;
		var fieldLabelName	= fieldLabels[i].firstChild.nodeValue;
		labels[fieldLabelID] = fieldLabelName;
	}
	
	return labels;
}

// Validate the field based on its value and type
Validator.isInvalidField = function(myFormFieldId) {
	var myFormField	= $(myFormFieldId);	
	
	//Only check values for field that have an id attribute defined
	if (myFormField) {
		if (myFormField.value == '' || myFormField.value == null || myFormField.selectedIndex == 0) {
			return true;
		}
	} else {
		return false;
	}
	
}

//Private array storing invalid Fields Labels
Validator.setInvalidFieldLabels = function (fieldLabels) {
    Validator._invalidFieldLabels = fieldLabels;
}

Validator._invalidFieldLabels;

Validator.getInvalidFieldLabels = function() {
    return Validator._invalidFieldLabels;
}

// Take an array and build a summary error message
Validator.displayErrors = function() {

	var invalidFields		= Validator.getInvalidFieldLabels();		
	var headerText			= 'Oops! Looks Like You Forgot Something';
	var bodyText 			= 'You have ' + invalidFields.length + ' invalid or blank fields:<br/><br/> -' +  invalidFields.join('<br/> -') + '<br/><br/>';
	bodyText				+= " Fix that up and you'll be good to go.";
	
	ErrorMessage.setHeader(headerText);
	ErrorMessage.setMessage(bodyText);
	ErrorMessage.displayMessage();
				
}


/* Procedural utility function for validating lists
use with portals requiring checked items to take action
For example, deleting a paritcular row */
Validator.isFieldChecked = function (listForm) {

	var listCount = 0;	
			
	for(var i = 0; i < listForm.length; i++) {
        var field = listForm.elements[i];
		
		if (listCount > 0 ) {
			break;
		}
						
		if (field.type == 'checkbox' && field.checked == true) {
			listCount++;	
		}
	}
	
	if (listCount == 0) {
		alert('You have not selected any items from the list. Please select an item.');
		return false;
	} else {
		return true;
	}
	
}


/*
Corrects the phone number when matched and
returns false when it cannot be corrected 
Requires the field object as an argument
The object can be called with the keyword this
*/
Validator.validatePhoneWithAutoCorrect = function (phoneField) {
	
	// Set standard phone reg exs
	var targetPhoneRegEx 	= /\d{3}-\d{3}-\d{3}/;
	var parensPhoneRegEx 	= /[(]\d{3}[)]\s+\d{3}-\d{3}/;
	var dotPhoneRegEx 		= /\d{3}[.]\d{3}[.]\d{3}/;

	// Set values from field
	var phoneNumber 	= phoneField.value;
	var phoneFieldName	= phoneField.name;
	
	if (targetPhoneRegEx.test(phoneNumber)) {	
		return true;
		
	} else if (parensPhoneRegEx.test(phoneNumber)) {
		var phoneArray 		= new Array();
		phoneArray 			= phoneNumber.split(/\s/);
		var areaCode		= phoneArray[0].replace(/[(]/, '');
		areaCode			= areaCode.replace(/[)]/, '');

		// Set the auto-correct field value
		phoneField.value 	= areaCode + '-' + phoneArray[1];
		
		return true;

	} else if (dotPhoneRegEx.test(phoneNumber)) {
		var phoneArray 		= new Array();
		phoneArray 			= phoneNumber.split('.');
	
		// Set the auto-correct field value
		phoneField.value 	= phoneArray.join('-');

		return true;

	} else {
		
		//A false value indicates that the auto correct failed
		return false;
	}

}

Validator.validateWebsite = function (website) {
	var webRegEx = /http:\/\/\w/;

	return webRegEx.test(website);
}

Validator.validateIPV4Address = function (ipAddress) {
	var ipV4Address = /\d+\.\d+\.\d+/;

	return ipV4Address.test(ipAddress);
}

Validator.isFloat = function (number) {
	var floatRegEx		= /^\d+(.\d+)?$/;
	var decimalRegEx	= /^.\d+$/;
	number = number.strip();

	if (number.match(floatRegEx) || number.match(decimalRegEx)) {
		return true;
	} else {
		return false;
	}
}

// Requires the field object as an argument
//The object can be called with the keyword this
Validator.isValidPhone = function (phoneField) {

	//Set phone values
	var phoneNumber 	= phoneField.value;
	var phoneFieldName	= phoneField.name;
	var phoneFieldId	= phoneField.id;
	
	//Set parent object to get class data
	// For example, a palette element has paletteSection as its parent node
	var currentNode		= $(phoneFieldId);
	var myParentNode	= currentNode.up();
	var parentNodeClass	= myParentNode.className;
	
	//Stash the class name in our global DBM hash
	if (parentNodeClass != 'alertElement') {
		DBM[phoneFieldId] = parentNodeClass;
	}
		
	if (validatePhoneWithAutoCorrect(phoneField)) {
		// Set the class back to the default in case it was changed by the error
		myParentNode.className = DBM[phoneFieldId];
		var ErrorMessage		= new ErrorMessage();
		ErrorMessage.hideMessage();
		return true;
				
	} else {

		myParentNode.className = 'alertElement';
		
		var labels				= getLabels();
				
		var headerText		= 'Error: Invalid Phone Number';
		var bodyText 		= 'Please enter the value for ' + labels[phoneFieldId] + ' in this format: xxx-xxx-xxxx';

		//Currently assume that is a palette that's being validated
		var xPosition		= getDefaultPaletteXPosition(); 
		var yPosition		= 200; 
		var balloonWidth	= 240;
		var handleOrientation	= 'east';
		var balloonType		= 'urgent';
		
		ErrorMessage.setHeader(headerText);
		ErrorMessage.setMessage(bodyText);
		ErrorMessage.displayMessage();
		
		return false;
	}
	
}

//Depreciated
function clearError(currentField) {
	
	if (currentField.value != '' || currentField.value != 'null')  {
		var elementID = currentField.name;
		$(elementID).style.color = "#000000";
	}
	
}
