/*
	formValidation.js
	A class to validate a form.
	fields who's label has an * at the begining are tested for being empty
	)ther Static function are used to add extra validation functions
*/

/* 
	constructor
	formId is the id of the form and funcArray is an array of extra validation routines
*/
function FormValidation(formId, funcArray)
{
	this.inputNodes = new Array();
	this.handlers = funcArray;
	
	if ( typeof(formId) == 'string' )
		this.formNode = document.getElementById(formId);
	else
		this.formNode = formId;
		
	this.collectInputFields();
	this.registerSubmit();
}

/*
	collect all the input elements to be checked
*/
FormValidation.prototype.collectInputFields = function()
{
	FormValidation.cleanWhiteSpacesOut(this.formNode);
	var labelNodes = this.formNode.getElementsByTagName('label');
	
	for ( var i = 0; i != labelNodes.length; i++ )
	{
		if ( /^\*[^*]/.test(labelNodes[i].childNodes[0].nodeValue) )
		{
			this.inputNodes.push(labelNodes[i].nextSibling);
			labelNodes[i].className = 'req';
		}
	}
}

/*
	method that registers the pn submit event for the form
*/
FormValidation.prototype.registerSubmit = function()
{
	var thisObj = this;
	addEvent(this.formNode, 'submit', function(e) { thisObj.submitHandler.call(thisObj, e); });
}

/* 
	this handles the event calling the basic validdation routine and then any added ones
*/
FormValidation.prototype.submitHandler = function(e)
{
	this.emptyFieldHandler(e);
	for ( var i = 0; i != this.handlers.length; i++ )
		this.handlers[i](e);
}
	
/*
	method that handles checking for empty fields
*/
FormValidation.prototype.emptyFieldHandler = function(e)
{
	var empty_tags = this.checkValues();

	if ( empty_tags.length != 0 )
	{
		FormValidation.alertUser(empty_tags);
		e.cancelable ? e.preventDefault() : e.returnValue = false;
	}
}

// checks all registered fields to see if the value has any data in it.
FormValidation.prototype.checkValues = function()
{
	var empty = new Array();
	
	for (var i = 0, ii = 0; i != this.inputNodes.length; i++ )
	{
		if ( this.inputNodes[i].value.length == 0 )
			empty[ii++] = this.inputNodes[i].id;
	}
	
	return empty;
}

FormValidation.prototype.toString = function()
{
	if ( inputNodes.length < 0 )
		return "There are " + inputlNodes.length + "input nodes to check in form " + this.formNode.id;
	else
		return "There are no nodes to check in form " + this.formNode.id;
}

/*
*	display an alert box telling user which fields he has not filled in
*/
FormValidation.alertUser = function(tag_names)
{
	var alert_string = "Error - empty fields in: " + tag_names.join("; ");
	
	alert(alert_string);
}

/*
	utility function to remove white spaces from forms
	this is so we can travers the from to get to the input tags
*/
FormValidation.cleanWhiteSpacesOut = function(el)
{
	var children = el.childNodes;
	
	for ( var i = 0; i < children.length; i++ )
	{
		var node = children[i];
		if ( node.nodeType == 3 && !/\S/.test(node.nodeValue) )
			node.parentNode.removeChild(node);
	}
}

// forms is to hold an array of forms to be validated: Use registerForm to populate this.
FormValidation.forms = new Array();

/*
	chreates a Formvalifation Object there by registering event habdler for the onsubmit event of the form
*/
FormValidation.registerForm = function(formId, theHandlers)
{
	FormValidation.forms.push(new FormValidation(formId, theHandlers));
}

/*
	utility functions for the creation of an array of extra validation routines
*/
FormValidation.createHandlerCollection = function(newHandler)
{
	var collection = new Array();
	
	collection.push(newHandler);
	return collection;
}

FormValidation.addHandler = function(handlerCollection, newHandler)
{
	handlerCollection.push(newHandler);
}
