//  form validation 10/9/2009 by James Olson.
//  all required fields need a class of "required".
//  to validate an email add an additional class called validate-email.
//  to validate a group of check/radios wrap the group in a div or span and give the last field a class name of "required" and "validate-one-required".
//  error class is validation-failed and message class is validation-advice.
//  to submit forms via ajax add the class name "do_ajax" to the form tag and put a div with a class name "thanks" above the form
var Validation = Class.create({
	initialize: function(element,options){
		this.options = Object.extend({
			required_text: 'This is a required field.',
			valid_email_text: 'Please enter a valid email address.',
			select_one_text: 'Please select one of the above options.',
			required_classname: 'required',
			validate_email_class: 'validate-email',
			validate_group_class: 'validate-one-required',
			field_error_class: 'validation-failed',
			advice_class: 'validation-advice',
			ajax_message_success: 'thanks',
			ajax_message_fail: 'error',
			onComplete: Prototype.emptyFunction
		}, options || {});
		this.element = $(element);
		if(this.element != undefined){
			this.useAjax = this.element.hasClassName('do_ajax') ? true : false;
			if(this.useAjax) {
				this.thanksBlock = null;
				this.errorBlock = null;
				this.getMessageBlocks();
			}
			this.hideForm = this.element.hasClassName('no_hide') ? false : true;
			this.pass = true;
			this._inputs = new Array();
			this._selects = new Array();
			this._textAreas = new Array();
			this.setup();
		}
	},
	setup: function(){
		this.element.observe('submit',this.handleSubmitEvent.bind(this));
	},
	handleSubmitEvent: function(e){
		this.pass = true;
		this.doValidation();
		if(!this.pass){
			Event.stop(e);
			this._focus();
		}else{
			if(this.useAjax){
				Event.stop(e);
				try{this.thanksBlock.hide();}catch(e){}
				try{this.errorBlock.hide();}catch(e){}
				var ajaxRequest = new Ajax.Request(this.element.action, {
					method: this.element.method,
					parameters: Form.serialize(this.element), 
					asynchronous: true,
					onSuccess: this.showResponse.bind(this),
					onFailure: this.showError.bind(this)
				});
			}
		}
		this.options.onComplete(this.element,e,this.pass);
	},
	getMessageBlocks: function(){
		this.thanksBlock = this.element.up().select('.'+this.options.ajax_message_success)[0];
		this.errorBlock = this.element.up().select('.'+this.options.ajax_message_fail)[0];
		if(this.thanksBlock == undefined)
			this.thanksBlock = this.element.up(1).select('.'+this.options.ajax_message_success)[0];
		if(this.errorBlock == undefined)
			this.errorBlock = this.element.up(1).select('.'+this.options.ajax_message_fail)[0];
	},
	showResponse: function(data){
		try{this.thanksBlock.show();}catch(e){}
		try{this.errorBlock.hide();}catch(e){}
		if(this.hideForm)
			this.element.hide();
	},
	showError: function(data){
		try{this.errorBlock.show();}catch(e){}
	},
	addMessage: function(elm,message){
		try{
			elm.insert({after: '<div class="'+this.options.advice_class+'" id="advice-' + elm.name + '-' + this.getElmID(elm) + '">'+message+'</div>'});
		}catch(e){}
	},
	updateMessage: function(elm,message){
		try{
			$('advice-' + elm.name + '-' + this.getElmID(elm)).update(message);
		}catch(e){}
	},
	removeMessage: function(elm){
		try{
			$('advice-' + elm.name + '-' + this.getElmID(elm)).remove();
		}catch(e){}
	},
	hasAdvice: function(elm){
		return $('advice-' + elm.name + '-' + this.getElmID(elm)) || $('advice-' + this.getElmID(elm));
	},
	getElmID : function(elm) {
		return elm.id ? elm.id : elm.name;
	},
	doValidation: function() {
		//collect elements
		this._inputs = this.element.select('input.'+this.options.required_classname);
		this._selects = this.element.select('select.'+this.options.required_classname);
		this._textAreas = this.element.select('textarea.'+this.options.required_classname);
		this._inputs.each(function(elem){
			var sv = true, a = elem.parentNode, b = elem.up(1);
			if( ( a != undefined && !a.visible() ) || ( b != undefined && !b.visible() ) )
				sv = false;
			if(elem.visible() && sv == true){
				if(elem.value == '' && !elem.hasClassName(this.options.validate_group_class)){
					elem.addClassName(this.options.field_error_class);
					if(this.hasAdvice(elem) == null)
						this.addMessage(elem,this.options.required_text);
					this.pass = false;
				}
				else if(elem.hasClassName(this.options.validate_group_class)){
					var trip = false;
					var cont = elem.parentNode;
					var group = cont.select('input');
					group.each(function(elm){
						if(elm.checked == true){
							trip = true;
						}
					});
					if(!trip){
						elem.addClassName(this.options.field_error_class);
						if( $('advice-' + elem.name + '-' + this.getElmID(elem)) == null ){
							try{
								cont.insert({bottom: '<div class="'+this.options.advice_class+'" id="advice-' + elem.name + '-' + this.getElmID(elem) + '">'+this.options.select_one_text+'</div>'});
							}catch(e){}
						}
						this.pass = false;
					}else{
						this.removeMessage(elem);
						elem.removeClassName(this.options.field_error_class);
					}
				}				
				else if(elem.hasClassName(this.options.validate_email_class)){
					var filter = /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/;
					if(!filter.test(elem.value)){
						if(this.hasAdvice(elem) == null)
							this.addMessage(elem,this.options.valid_email_text);
						else
							this.updateMessage(elem,this.options.valid_email_text);
						this.pass = false;
					}else{
						elem.removeClassName(this.options.field_error_class);
						this.removeMessage(elem);
					}
				}
				else{
					elem.removeClassName(this.options.field_error_class);
					this.removeMessage(elem);
				}
			}
		}.bind(this));
		this._selects.each(function(elem){
			var sv = true, a = elem.parentNode, b = elem.up(1);
			if( ( a != undefined && !a.visible() ) || ( b != undefined && !b.visible() ) )
				sv = false;
			if(elem.visible() && sv == true){
				if(elem.selectedIndex == 0){
					elem.addClassName(this.options.field_error_class);
					if(this.hasAdvice(elem) == null)
						this.addMessage(elem,this.options.required_text);
					this.pass = false;
				}else{
					elem.removeClassName(this.options.field_error_class);
					this.removeMessage(elem);
				}
			}
		}.bind(this));
		this._textAreas.each(function(elem){
			var sv = true, a = elem.parentNode, b = elem.up(1);
			if( ( a != undefined && !a.visible() ) || ( b != undefined && !b.visible() ) )
				sv = false;
			if(elem.visible() && sv == true){
				if(elem.value == ''){
					elem.addClassName(this.options.field_error_class);
					if(this.hasAdvice(elem) == null)
						this.addMessage(elem,this.options.required_text);
					this.pass = false;
				}else{
					elem.removeClassName(this.options.field_error_class);
					this.removeMessage(elem);
				}
			}
		}.bind(this));
	},
	_focus: function() {
		try{
			this.element.select('.'+this.options.field_error_class)[0].focus();
		}catch(e){}
	}	
});
