/**
 * @class AjaxValidator Class
 * AjaxValidator is the JavaScript portion of the Ajax Validation Software Package.
 * @constructor
 * @param {String} formId The DOM id of the form element in which to perform validation upon
 * @param {String} validationRequestURL The URL of the PHP validation page
 * @param {Boolean} addBlurEvents If true, this will add onBlur events to all the form elements.
 *                  All elements will be validated at the time they loose focus as well as when the
 *                  form has been submitted.
 */
function AjaxValidator(formId, validationRequestURL, addBlurEvents)
{
	this.formId = formId;
	this.validationRequestURL = validationRequestURL;
	this.errorDiv = "";
	this.errorCallback = "";
	this.formElement = document.getElementById(this.formId);

	faction = this.formElement.action;
	fi = faction.indexOf('?');
	if (fi < 1)
	{
		naction = faction + "?vm=sp";
	}
	else
	{
		naction = faction + "&vm=sp";
	}
	this.formElement.action = naction;
	if (addBlurEvents == true)
	{
		this.enableBlurEvents();
	}
	ajaxEngine.registerRequest('validationRequest',this.validationRequestURL);
	ajaxEngine.registerAjaxObject('AjaxValidator',this);
}

/**
 * Sets the id of the HTML Form element.
 * @param {String} formId The DOM id of the HTML form element.
 */
AjaxValidator.prototype.setFormId = function(formId)
{
	this.formId = formId;
}

/**
 * Get the DOM id of the HTML form element.
 * @returns The DOM id of the the form element.
 */
AjaxValidator.prototype.getFormId = function()
{
	return this.formId;
}
	
/**
 * Gets the actual form element
 * @returns The DOM form elements.
 */
AjaxValidator.prototype.getFormElement = function()
{
	return document.getElementById(this.formId);
}	

/**
 * Registers a local callback that is issued before or instead of the validation request being sent to the server
 * @param {String} methodId The name of the local method that will be called.
 * @param {String} validationType
 * @param {String} sendToServer Send the request to the server after the local validation has finished
 */
AjaxValidator.prototype.registerLocalCallback = function(methodId, validationType, sendToServer)
{
}

/**
 * Sets a global location to display validation error messages
 * @param {String} id The DOM id of the element in which to display the error messages.
 */
AjaxValidator.prototype.setErrorDiv = function(id)
{
	this.errorDiv = document.getElementById(id);
	//this.errorDiv = id;
}


AjaxValidator.prototype.setErrorCallback = function(cb)
{
	this.errorCallback = cb;
}


/**
 * Adds an onBlur event to each of the form elements.
 */
AjaxValidator.prototype.enableBlurEvents = function()
{
	var elementList = Form.getElements(this.formId);
	for (var i=0; i<elementList.length; i++)
	{
		var current = elementList[i];
		this.addBlurEvent(current);
	}	
}

/**
 * Disables the onBlur event for each of the form elements
 */
AjaxValidator.prototype.disableBlurEvents = function()
{
	var elementList = Form.getElements(this.formId);
	for (var i=0; i<this.elementList.length; i++)
	{
		var current = this.formId.elementList[i];
		this.removeBlurEvent(current);
	}	
}

/**
 * Adds an onBlur event to an individual form element.
 * @param {String} element The DOM element of the form onto which to add the event
 */
AjaxValidator.prototype.addBlurEvent = function(element)
{
	var name = "blur";
	Event.observe(element, name, function(e) {AjaxValidator.prototype.validateElement(element);}, false)	
}

/**
 * Removes an onBlur event from an individual form element.
 * @param {String} element The DOM element of the form of which to remove the event
 */
AjaxValidator.prototype.removeBlurEvent = function(element)
{
	var name = "blur";
	Event.stopObserving(element, name, function(e) {AjaxValidator.prototype.validateElement(element);});
}

/**
 * Adds an onSubmit handler to the form
 */
AjaxValidator.prototype.enableSubmitHandler = function()
{
	this.formId.onsubmit = function() {return this.validate();}
}

/**
 * Removes the onSubmit hadler from the form.
 */
AjaxValidator.prototype.disableSubmitHandler = function()
{
	this.formId.onsubmit = function() {return true;}
}

/**
 * Adds a custom onSubmit hadler to the form
 * @param {String} methodName The method name to be called when the onSubmit event fires.
 */
AjaxValidator.prototype.addCustomSubmitHandler = function(methodName)
{
	this.formId.onsubmit = function() {return this.methodName;}
}

/**
 * Removes the custom onSubmit event handler from the form.
 */
AjaxValidator.prototype.removeCustomSubmitHandler = function()
{
	this.disableSubmitHandler();
}

/**
 * Performs the validation routines.
 */
AjaxValidator.prototype.validate = function()
{
}

/**
 * Performs the validation routines on a single form element
 * @param {String} element The DOM element of the form in which to perform the validation.
 */
AjaxValidator.prototype.validateElement = function(element)
{
	var current = element;
	var type = current.type;
	var value;
	var id = current.id;
	switch(type)
	{
		case "text":
		case "textarea":
		case "hidden":
			value = current.value;
			this._sendValidateRequest(escape(id), escape(value), "NA");
			break;
		case "select-one":
			value = current.options[current.selectedIndex].value;
			this._sendValidateRequest(escape(id), escape(value), "NA");
			break;
		case "checkbox":
		case "radio":
			value = current.value;
			if (current.checked)
			{
				cv = "true";
			}
			else
			{
				cv = "false";
			}
			this._sendValidateRequest(escape(id), escape(value), cv);
	}
	
}

/**
 * Sends the AJAX Validation request to the server
 * @param {String} value The value of the HTML form element.
 * @param {String} rules The validation rules contained in the validate attribute in the HTML code.
 */
AjaxValidator.prototype._sendValidateRequest = function(id, value, checked)
{
	ajaxEngine.sendRequest('validationRequest', "id=" + id, "value=" + value, "checked=" + checked);
}

/**
 * Display the validation error message in the first available location in the HTML code.
 * @param {String} id The DOM id of the form element we are displaying information for
 * @param {String} msg The message to be displayed in the error message location
 */
AjaxValidator.prototype.displayErrorMsg = function(id, msg, description)
{
	if (this.errorCallback != "")
	{
		var cb = this.errorCallback;
		cb.errorCallback(id,msg, description);
	}
	else
	{
		var element = this.getErrorDiv(id);
		element.innerHTML = description;
	}
}

/**
 * Gets the correct location to display the error messages.
 * @ params {String} id The DOM id of the HTML element to display a validation error for.
 */

AjaxValidator.prototype.getErrorDiv = function(id)
{
	if (this.errorDiv != "")
	{
		return this.errorDiv;
	}
	else
	{
		return this._getLocalErrorDiv(id);
	}
}

/** 
 * Private method to get the DOM element to get the location in which to display the error message.
 * @param {String} id The DOM id of the HTML elememt to display a validation error for.
 */

AjaxValidator.prototype._getLocalErrorDiv = function(id)
{
	var name = id + "_error";
	var tid = document.getElementById(name);
	if (tid != null)
	{
		return tid;
	}
	else
	{
		return "";
	}
}

/**
 * A private method used to parse the server response to a validation request.
 * This method gets all the error messages and displays them in the proper places.
 * @param {Array} responseNodes The XML response nodes from the Ajax Validation Request.
 */
AjaxValidator.prototype._parseResponseNodes = function(responseNodes)
{
		var length = responseNodes.childNodes.length;
		var j = 0;
		for (var i=0; i < length; i++)
		{
			var responseNode = responseNodes.childNodes[i];
			var id = responseNode.getAttribute('id');
			//var isError = responseNode.getAttribute('error');
			var msg = responseNode.getAttribute('msg');
			var description = responseNode.getAttribute('description');
			
			this.displayErrorMsg(id,msg, description);
		}
}

/**
 * This is an abstract method that must be implemented in order to handle the AJAX callbacks from the server.
 * @param ajaxResponse Array The AJAX XML DOM that comes from an AJAX response from the server.
 */
AjaxValidator.prototype.ajaxUpdate = function(ajaxResponse)
{
	this._parseResponseNodes(ajaxResponse);
}



