RedSquare.FormValidator = Class.create();

RedSquare.FormValidator.prototype = 
{
	initialize: function(form, onDisplayErrors)
	{
		this.form = form;
		this.onDisplayErrors = onDisplayErrors;
		
		this.setup();
	},
	
	addField: function(field)
	{
		if (field.tagName.match(/input|select|textarea/i))
			this.fields.push(field);	
	},
	
	setup: function()
	{
		Event.observe(this.form, 'submit', this.formOnSubmit.bindAsEventListener(this));
		// fix for Safari
		
		this.form.onsubmit = function() { return this.willSubmit(); }.bindAsEventListener(this);
		
		// build up the fields array
		this.fields = new Array();
		this.culprits = new Array();
		this.errors = new Array();
		
		$A(this.form.elements).each(this.addField.bind(this));		
	},

	clearCulprits: function()
	{
		this.culprits = new Array();	
		this.errors = new Array();	
	},

	formOnSubmit: function(event)
	{
		// build the error list, or let the form through
		
		this.clearCulprits();
		
		// validate all fields
		this.fields.each(this.validateField.bind(this));
		
		if (this.errors.length > 0)
		{
			// display the errors, using either the custom callback, or the default handler
			
			if (this.onDisplayErrors)
				this.onDisplayErrors(this.culprits, this.errors);
			else
				this.displayErrors();
			
			this.culprits[0].focus();
			
			if (this.culprits[0].tagName.match(/input|textarea/i))
			{
				this.culprits[0].select();
			}
			
			Event.stop(event);

			return false;
		}

		return true;
	},

	willSubmit: function()
	{
		// validate all fields
		this.fields.each(this.validateField.bind(this));
		
		return this.errors.length == 0;
	},
	
	displayErrors: function()
	{
		// standard error display function. displays errors joined with new-line in a JavaScript alert box
		alert(this.errors.join("\n"));
	},
	
	addCulprit: function(element)
	{
		if (this.culprits.indexOf(element) == -1)
		{
			this.culprits.push(element);
			this.errors.push(element.title);
		}
	},

	validateField: function(element)
	{
		element.setAttribute('autocomplete', 'off'); // avoids pesky Mozilla permission denied errors
		
		// get class names of this element
		var classNames = element.className.split(" ");

		for (var i=0; i<classNames.length; i++)
			this.validate(element, classNames[i]);
	},
	
	validate: function(element, className)
	{
		// validation check for each CSS class type
		var valid = true;
		
		switch (className)
		{
			case 'required':
			{
				valid = valid && element.value.trim() != '';
				break;
			}
			case 'email':
			{
				valid = valid && element.value.trim() == '' || element.value.isEmailAddress();
				break;
			}
			case 'integer':
			{
				valid = valid && element.value.trim() == '' || element.value.isInteger();
				break;
			}
			case 'float':
			{
				valid = valid && element.value.trim() == '' || element.value.isFloat();
				break;
			}
			default :
			{
				// custom validation routines
				
			}
		}

		if (!valid)
			this.addCulprit(element);
	}
}
