/**
http://webcloud.se/article/Form_validation_with_jQuery_from_scratch/

Modified by rickard@spiro.se to provide more functionality in a better manner
*/
(function($) {
	
	/*
	Validation Singleton
	*/
	var Validation = function() {
		var rules = {
			email : {
				check: function(value) {
					if(!value.empty()) {
						test = value.split('@');
						test = test[test.length-1];
						if(value.indexOf('@') <= -1 || test.indexOf('.') <= -1)
						{
							return false;
						}
						//return testPattern(value,".+@.+\..+");
						return testPattern(value,"^[a-zA-Z0-9\.\-\~]+@[a-zA-Z0-9\.\-]+\.[a-zA-Z]{2,4}$");
					}
					return true;
				},
				msg : "E-postadressen &auml;r inte giltig."
			},
			integer : {
				check: function(value) {
					if(value) {
						value = value.trim();
						test = value.replace(/[0-9]/g,'');
						if(test != '')
						{
							return false;
						}
					}
					return true;
				},
				msg : "Fyll i ett giltigt nummer (endast siffror &auml;r till&aring;tna)."
			},
			numeric : {
				check: function(value) {
					if(value) {
						value = value.trim();
						test = value.replace(/[0-9\.,]/g,'');
						if(test != '')
						{
							return false;
						}
					}
					return true;
				},
				msg : "Fyll i ett giltigt nummer."
			},
			url : {
				check : function(value) {
					if(value) {
						return testPattern(value,"https?://(.+\.)+.{2,4}(/.*)?");
					}
					return true;
				},
				msg : "Fyll i en giltig URL."
			},
			password : {
				check : function(value) {
					if(!value.empty() && value.length < 6) {
						return false;
					}
					return true;
				},
				msg : "L&ouml;senordet &auml;r f&ouml;r kort."
			},
			required : {
				check: function(value) {
					return ! value.empty();
				},
				msg : "Du m&aring;ste fylla i detta f&auml;lt."
			}
		}
		var testPattern = function(value, pattern) {
			var regExp = new RegExp("^"+pattern+"$","");
			return regExp.test(value);
		}
		return {
			addRule : function(name, rule) {
				rules[name] = rule;
			},
			getRule : function(name) {
				return rules[name];
			}
		}
	}

	/* 
	Form factory 
	*/
	var Form = function(form) {
		var fields = [];
		form.find("input.validate, textarea.validate, select.validate").each(function() {
			fields.push(new Field(this));
		});
		this.fields = fields;
	}
	Form.prototype = {
		validate : function() {
			for(field in this.fields) {
				this.fields[field].validate();
			}
		},
		isValid : function() {
			for(field in this.fields) {
				if(!this.fields[field].valid) {
					this.fields[field].field.focus();
					return false;
				}
			}
			return true;
		}
	}

	/* 
	Field factory 
	*/
	var Field = function(field) {
		this.field = $(field);
		this.valid = false;
		this.attach("change");
	}
	Field.prototype = {
		attach : function(event) {
			var obj = this;
			if(event == "change") {
				obj.field.bind("change",function() {
					return obj.validate();
				});
			}
			if(event == "keyup") {
				obj.field.bind("keyup",function(e) {
					return obj.validate();
				});
			}
		},
		validate : function() {
			var obj = this,
				field = obj.field,
				errorClass = "errorlist",
				errorlist = $(document.createElement("ul")).addClass(errorClass),
				types = field.attr("class").split(" "),
				container = field.parent(),
				errors = []; 
			field.next(".errorlist").remove();
			for (var type in types) {
				var rule = $.Validation.getRule(types[type]);
				if(rule)
				{
					if(!rule.check(field.val())) {
						container.addClass("error");
						errors.push(rule.msg);
					}
				}
			}
			if(errors.length) {
				obj.field.unbind("keyup")
				obj.attach("keyup");
				field.after(errorlist.empty());
				for(error in errors) {
					errorlist.append("<li>"+ errors[error] +"</li>"); 
					break; // 1 error is enough      
				}
				obj.valid = false;
			} 
			else {
				errorlist.remove();
				container.removeClass("valid");
				if(container.hasClass("error"))
				{
					container.removeClass("error");
					container.addClass("valid");
				};
				obj.valid = true;
			}
		}
	}

	/* 
	Validation extends jQuery prototype
	*/
	$.extend($.fn, {
		validation : function() {
			var validator = new Form($(this));
			$.data($(this)[0], 'validator', validator);
			$(this).bind("submit", function(e) {
				validator.validate();
				if(!validator.isValid()) {
					e.preventDefault();
				}
			});
		},
		validate : function() {
			var validator = $.data($(this)[0], 'validator');
			validator.validate();
			return validator.isValid();
		}
	});
	$.Validation = new Validation();
})(jQuery);