/*******
*	
*	FormHandler base class for checking required fields etc
*
* 	By: joacim.magnusson@orbitsville.com
*
* 	Requires mootools, http://www.mootools.net/ 
*
*/

/********
*
* 	Version history
* 	0.1: initial version
* 	0.2: added support for specifying fields that must match
* 	0.3: added support for selects and email validation + fancy header
*/

var FormHandler = new Class({
/* v0.3.1 */

	Implements: Options,

	initialize: function(options)
	{
		this.setOptions(options);
		this._output = $(this.options.output);
		this._form = $(this.options.form);
		this._form.onsubmit = this.testSubmit.bind(this);
		this._clsRequired = this.options.required;
		this._identical = this.options.identical;
		this._arrErrors = new Array;
		this._arrMsgs = new Array;
		this._emailPat = /^[!-'*+=?{-~\/-9A-Z^-z-]+(\.[!-'*+={-~\/-9A-Z^-z-]+)*@[!#$%&'*+"\/=?^_`{|}~0-9A-Za-z-]+\.[!-'*+={-~\/-9A-Z^-z-]{2,}/;
		
		// Register ovverride buttons that will force-submit the form without
		// checking the fields
		$$("input[type=submit]").each(function(btn,index)
		{
			if(btn.hasClass("nocheck")){
				btn.addEvent('click',this.forceSubmit.bind(this));
			}
		}.bind(this));
		
		// Default messages
		if(this.options.errorMsg) {
			this._errorMsg = this.options.errorMsg;
		} else {
			this._errorMsg = "Please fill out all required fields";
		}
	},
	
	testSubmit: function()
	{	
		// Clean up previous run
		if(this.dirty == true) {
			this._arrErrors.each(function(objErr, index){
				objErr.elmInput.removeClass('error');
			});
			this._arrMsgs.each(function(elm, index){
				elm.remove();
			});
			
			if(this._output) {this._output.setText("");}
			this._arrErrors = new Array;
			this._arrMsgs = new Array;
		}
		
		if(this.hasErrors()) {
			if(this._output) {
				this._output.setText(this._errorMsg);
			}
			
			this._arrErrors.each(function(objErr, index){
				if(objErr.strMsg != null) {
					var errorText = new Element('span',{'class':'error'}).injectAfter(objErr.elmInput);
					errorText.setText(objErr.strMsg);
					this._arrMsgs.include(errorText);
				}
			}.bind(this));
			
			this.dirty = true;
			return false;
		} else {
			return true;
		}
	},
	
	hasErrors: function()
	{
		this._arrErrors = new Array;
		var inputs = $$("input,textarea,select");
		inputs.each(function(elm,index){
			
			/* Only check field if it has the reuired class */
			if(elm.hasClass(this._clsRequired) && elm.style.display != "none") {
				switch(elm.getProperty("type")){
				case "text":
				case "password":
					
					/* Check that the field is not empty */
					if(elm.value == "" && !elm.hasClass('email')) {
						elm.addClass('error');
						this._arrErrors.include({elmInput:elm,strMsg:null});
						
					} else if(elm.hasClass('email')) {
						
						/* This field has the email class, so check for valid email */
						if(!this._emailPat.test(elm.value)) {
							elm.addClass('error');
							this._arrErrors.include({elmInput:elm,strMsg:"This email is not valid"});
						}
					}
					
					break;
				
				case "radio":
					
					// Handle radio buttons
					
					break;
				
				case "checkbox":
					
					// Handle checkboxes
					
					break;
				
				/* Handles stuff like selects and textareas */
				default:
				if(elm.getTag() == "select") {
					//alert("Name: "+elm.name+" Value: '"+elm.value+"'")
					if(elm.value == "" || elm.value == "0") {
						elm.addClass('error');
						this._arrErrors.include({elmInput:elm,strMsg:null});
					}
				}
				if(elm.getTag() == "textarea") {
					if(elm.value == "") {
						elm.addClass('error');
						this._arrErrors.include({elmInput:elm,strMsg:null});
					}
				}
				break;
				}
			}
			
			/* Also check valid email on fields that are not required, and doesn't already have an error */
			if(elm.hasClass('email') && !elm.hasClass('error') && elm.style.display != "none") {
				if(!this._emailPat.test(elm.value)) {
					elm.addClass('error');
					this._arrErrors.include({elmInput:elm,strMsg:"This email is not valid"});
				}
			}
			
		}.bind(this));
		
		if(this._identical) {
			this.tmpVal = $(this._identical[0]).value;
			this.tmpDiffer = false;
			
			this._identical.each(function(elm,index,val1) {
				if($(elm).value != this.tmpVal){
					this.tmpDiffer = true;
					$(elm).addClass('error');
					this._arrErrors.include({elmInput:$(elm),strMsg:"These fields must match"});
				}
			}.bind(this));
			
			if(this.tmpDiffer == true){
				
				$(this._identical[0]).addClass('error');
				this._arrErrors.include({elmInput:$(this._identical[0]),strMsg:"These fields must match"});
			
			}
			
			/* Clean up the mess */
			this.tmpVal = null;
			this.tmpDiffer = null;
		}
		
		if(this._arrErrors.length < 1) {
			return false;
		} else {
			return true;
		}
	},
	
	/* Removes the onsubmit event, so that the checking will not occur */
	forceSubmit: function()
	{
		this._form.onsubmit = null;
	}
	
});

