var FormValidator = new Class({
	Implements : [Events, Options],
	Extends: Fx,
	options : {
		useAjax			: false,
		rules			: [],
		scrollToError	: true,
		onInitialize	: function(){},
		onReset			: function(){},
		onSubmit		: function (){},
		onSuccess		: function (){},
		update			: null
		},
	initialize : function(element, options) {
		this.setOptions(options);
		this.addValidationRules = options.rules;
		this.element = element;
		this.request = new Request.HTML({
			url : element.get("action"),
			method : "POST",
			update : $(options.update),
			evalScripts : true,
			onSuccess: function(responseTree, responseElements, responseHTML, responseJavaScript){
							
							options.onSuccess.attempt(arguments)
							}.bind(this),
			onRequest : function(){options.onSubmit.attempt()}.bind(this)
			})
		
		
		element.addEvent('submit', function(e) {
			//console.log("submitting")
			// Prevent the submit event
			if (options.useAjax) {
				if (e) e.stop();
				}
			// Clean up previous error messages
			$$("div.error-message").dispose();
			// Validate the form
			var errors = this.validate();
			
			if (errors.length) {
				if (e) e.stop();
				for (var i=0; i < errors.length; ++i) {
					//alert(result[i].field)
					if ($(errors[i].field)) {
						new Fx.Morph(
									new Element("div", {
														"class":"error-message"
														}).set(
																"text", 
																errors[i].message
																).inject(($(errors[i].field) || this.element[errors[i].field]).getParent()).setOpacity(0), {
									duration: 1000, 
									wait:false
									}).start({"opacity":[.5,1]});
						}
					else {
						alert(error[i].field + " not found")
						}
					}
				if (options.scrollToError) new Fx.Scroll(window).toElement($$("div.error-message")[0].getParent());
				} // end form validation
			else {
				//alert("form validator : " + this)
				//alert("do useAjax? " + options.useAjax);
				if (options.useAjax) {
				//	console.log("sending....");
					this.request.post(this.element);
					//console.log(this)
					}
				} // end result if
			}.bind(this)); // end form event
		},
	reset : function () {
		if (this.element.getElement("input[type=reset]")) {
			this.element.getElement("input[type=reset]").addEvent("click", function() {
				$$("div.error-message").each(
					function (e) {
						e.dispose();
						}
					); // end div error removal
				var myFx = new Fx.Scroll(window).toElement(this.getParent("form"));
				this.options.onReset.attempt();
				});
			}	
		},
	addValidationRule : function () {
		this.addValidationRules.append(arguments[0]);
		},
	
	validate : function() {
		var errors = [];
		errors.length = 0;
		for(var i =0; i < this.addValidationRules.length; ++i) {
			if (!this.validateField(this.addValidationRules[i])) {
				errors.push(this.addValidationRules[i]);
				}
			}
		
		return errors;
		
		},
		
	validateField : function (rule) {
		var field 		= ($(rule.field) || this.element[rule.field]);
		var required 	= rule.required;
		var datatype 	= rule.datatype;
		var emailReg 	= /^[^@]+@[^@.]+\.[^@]*\w\w$/
		var fieldType 	= field.length && !field.options ? field[0].type : field.type;
		
		switch (fieldType.toLowerCase()) {
			
			case "text" : {
				
				if (datatype != null && field.value.replace(/[ ]/g, "").length != 0) {
					
					switch(datatype) {
						case "email" : {
							if (!emailReg.test(field.value)) {
								return false;
							}
							return true;
							break;
							}
						case "numeric" : {
							return !isNaN(field.value);
							break;
							}
						default : {
							
							if(required) {
								return field.value.replace(/[ ]/g, "").length;
								}
							else {
								return true;
								}
							break
							}
						}
					}
					
				
				if(required) {
					return field.value.replace(/[ ]/g, "").length;
					}
				else {
					return true;
					}
				return field.value.replace(/[ ]/g, "").length
				break;
				}
				
			case "checkbox" : {
				if (field.length) {
					for (var i = 0; i < field.length; ++i) {
						if (field[i].checked) {
							return true;
							}
						}
					}
				else {
					return field.checked;
					}
					
				return false;
				break;
				}
			
			case "radio" : {
				
				for (var i = 0; i < field.length; ++i) {
					if (field[i].checked) {
						return true;
						}
					}
					
				return false;
				break;
				}
			
			case "textarea" : {
				
				var validate 	= field.getAttribute("onkeydown");
				field.value = field.value.replace(/( ){1,}/g, '$1');
				if (validate) {
					if (typeof validate == "string") {
						return eval(validate);
						}
					else {
						return validate();
						}
					}
				
				if(required) {
					return field.value.replace(/[ ]/g, "").length;
					}
				else {
					return true;
					}	

				break;
				}
			
			default : {
				return field.value.replace(/[ ]/g, "").length
				break;
				}
			}
		}
	});	








/*










	
// pass in form element reference
function FormObject(element, options) {

	this.addValidationRules = new Array();
	this.formElement = arguments[0];
	this.formElement.externalSubmit = (options.externalSubmit || false)
	if (this.formElement.getElement("input[type=reset]")) {
		this.formElement.getElement("input[type=reset]").addEvent("click", function() {
			$$("div.error-message").each(
				function (e) {
					e.dispose();
					}
				); // end div error removal
			var myFx = new Fx.Scroll(window).toElement(this.getParent("form"));
			});
		}
	
	//this.formObject.validateForm = this.validateForm(this.formObject);
	//alert("//" + this.formObject.fid)
	this.addValidationRule = function () {
		this.addValidationRules.push(arguments[0]);
		}
	
			
			
	this.validateField = function (fieldname, required, datatype) {
		
		var field = this.formElement[fieldname];
		
		var emailReg = /^[^@]+@[^@.]+\.[^@]*\w\w$/
		var fieldType = field.length && !field.options ? field[0].type : field.type;

		switch (fieldType.toLowerCase()) {
			
			case "text" : {
				
				if (datatype != null && field.value.replace(/[ ]/g, "").length != 0) {
					
					switch(datatype) {
						case "email" : {
							if (!emailReg.test(field.value)) {
								return false;
							}
							return true;
							break;
							}
						case "numeric" : {
							return !isNaN(field.value);
							break;
							}
						default : {
							
							if(required) {
								return field.value.replace(/[ ]/g, "").length;
								}
							else {
								return true;
								}
							break
							}
						}
					}
					
				
				if(required) {
					return field.value.replace(/[ ]/g, "").length;
					}
				else {
					return true;
					}
				return field.value.replace(/[ ]/g, "").length
				break;
				}
				
			case "checkbox" : {
				if (field.length) {
					for (var i = 0; i < field.length; ++i) {
						if (field[i].checked) {
							return true;
							}
						}
					}
				else {
					return field.checked;
					}
					
				return false;
				break;
				}
			
			case "radio" : {
				
				for (var i = 0; i < field.length; ++i) {
					if (field[i].checked) {
						return true;
						}
					}
					
				return false;
				break;
				}
			
			case "textarea" : {
				
				var validate 	= field.getAttribute("onkeydown");
				field.value = field.value.replace(/( ){1,}/g, '$1');
				if (validate) {
					if (typeof validate == "string") {
						return eval(validate);
						}
					else {
						return validate();
						}
					}
				
				if(required) {
					return field.value.replace(/[ ]/g, "").length;
					}
				else {
					return true;
					}	

				break;
				}
			
			default : {
				return field.value.replace(/[ ]/g, "").length
				break;
				}
			}
		}
			
			
	
	
	this.validateForm = function() {
		var errors = new Array();
		errors.length = 0;
		for(var i =0; i < this.addValidationRules.length; ++i) {
			if (!this.validateField(this.addValidationRules[i].field, this.addValidationRules[i].required, this.addValidationRules[i].datatype)) {
				errors.push(this.addValidationRules[i]);
				}
			}
		
		return errors;
		
		}
	
	}
	


function addFormSubmit() {	
	var formObject = arguments[0];
	var result = "";
	formObject.formElement.validator = arguments[0];
	
	if (typeOf(formObject.formElement.externalSubmit)) {
		formObject.formElement.externalSubmit = false
		}
	console.log(formObject.formElement.externalSubmit)
	formObject.formElement.addEvent('submit', function(e) {
		// Prevent the submit event
		//alert(this)
		
		result = formObject.validateForm();
		$$("div.error-message").each(
			function (e) {
				e.dispose();
				}
			); // end div error removal
		
		if (result.length) {
			new Event(e).stop();
			for (i=0; i < result.length; ++i) {
				//alert(result[i].field)
				if ($(result[i].field)) {
					element = new Element("div", {"class":"error-message"}).set("text", result[i].message).inject(this.getElementById(result[i].field).getParent()).setOpacity(0);
					var myEffects = new Fx.Morph(element, {duration: 1000, wait:false});
					myEffects.start({"opacity":[.5,1]})
					}
				else {
					alert(result[i].field + " not found")
					}
				}
			var myFx = new Fx.Scroll(window).toElement($$("div.error-message")[0].getParent());
			
			} // end form validation
		else {
				
			var targetContainer = this.getParent();
			//alert("form validator : " + this)
			alert("do send? " + this.externalSubmit);
			if (!formObject.formElement.externalSubmit) {
				
				this.send();
				}
			} // end result if
		}); // end form event
		
	}
*/
	
