(function(){
	String.prototype.trim = function () {
		return this.replace(/[\s\0\n\t\r\f\v]+/g," ").replace(/(^\s*|\s*$)/g,"");
	};
	var ie7 = /MSIE 7.0/g.test(navigator.userAgent),
	ie6 = /MSIE 6.0/g.test(navigator.userAgent),
	classAttr = (ie7 || ie6) ? "className":"class";

	var s = {
		defaultError: "This is a required field",
		radioError: "You must choose one of these options",
		checkError: "This box must be ticked",
		emailError: "This must be a valid email address",
		phoneError: "This must be a valid phone number",
		postError: "This must be a valid postcode",
		matchError: "This field still requires correct confirmation",
		customTriggers: {}
	},
	regs = {
		required: /required/i,
		classEmail: /email/i,
		classPhone: /phone/i,
		classPcode: /postcode/i,
		classDepends: /depends/i,
		dependsNext: /dependsNext/i,
		dependsPrev: /dependsPrev/i,
		dependsName: /depends-/i,
		dependsChecked: /dependsChecked/i,
		tryChecked: /tryChecked/i,
		email: /([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})/,
		phone: /[0-9\+]/,
		postcode: /(^[A-Z]{1,2}[0-9]{1,2})(\s|)([0-9][A-Z]{2}$)/i,
		inputs: /(hidden|submit|image|button|reset)/i
	},
	createError = function(elm,msg){
	    if(elm.type == "checkbox") {
	        alert("Please agree to our terms and conditions before proceeding");
	    } else {
		    elm.style.border = "2px solid #c00";
		};
	},
	removeError = function(elm) {
		elm.style.border = "";
	},
	radioObj = {},
	check = function(formArray){
		var $return = true,
		len = formArray.length;
		while (len--) {
			var isValid = true,
			errorMsg = "",
			elm = formArray[len],
			className = elm.getAttribute(classAttr),
			tagName = elm.nodeName.toLowerCase(),
			inpType = elm.getAttribute("type"),
			inpValue = elm.value;
			if(inpValue) {inpValue = inpValue.trim() };
			if(className) { className = className.toLowerCase(); };
			if(inpType) { inpType = inpType.toLowerCase(); };
			
			if(!regs.inputs.test(inpType) && tagName != "fieldset" && regs.required.test(className)) {				
				if(inpType == "text" || inpType == "password" || tagName == "textarea") {
					// perform live checking
					elm.onkeyup = function(){
						check([this]);
					};
					
					if(inpValue == '' || inpValue == null) {
						isValid = false;
						errorMsg = s.defaultError;
					} else if(regs.classEmail.test(className)) {
						isValid = regs.email.test(inpValue);
						errorMsg = s.emailError;
					} else if(regs.classPhone.test(className)) {
						isValid = regs.phone.test(inpValue);
						errorMsg = s.phoneError;
					} else if(regs.classPcode.test(className)) {
						isValid = regs.postcode.test(inpValue);
						errorMsg = s.postError;
					};
					if(isValid) {
						if(regs.dependsNext.test(className) || regs.dependsPrev.test(className)) {
							var dependentElem = regs.dependsNext.test(className) ? $(elm).nextAll(".dependsPrev")[0] : $(elm).prevAll(".dependsNext")[0],
							doReturn = true;
						} else if(regs.dependsName.test(className)) {
							var nameAttr = className.split("depends-")[1].split(" ")[0],
							dependentElem = $("[name="+nameAttr+"]")[0],
							doReturn = true;;
						};
						if(doReturn) {
							isValid = (inpValue == dependentElem.value);
							if(isValid) {
								removeError(dependentElem);
							} else {
								createError(dependentElem,s.matchError)
							};
							errorMsg = s.matchError;
						};
					};
				
					
				} else if (inpType == "radio") {
					elm.onclick = function(){
						check([this.form.elements[this.name]][0]);
					};
					var group = elm.getAttribute("name");
					if(group) {
						group = group.toLowerCase();
						if(typeof radioObj[group] === "undefined") {
							radioObj[group] = {
								firstElement: elm,
								valArray: []
							};
						};
						radioObj[group].valArray.push(elm.checked);
					};
				} else if (inpType == "checkbox") {
					elm.onclick = function(){
						check([this]);
					};
					if(!elm.checked) {
						isValid = false;
						errorMsg = s.checkError
					};
				};
				if(regs.dependsChecked.test(className)) {
					var theID = className.split("dependschecked-")[1].split(" ")[0],
					tryElem = $(".tryChecked-" + theID)[0];
					isValid = tryElem.checked ? inpValue != "" : true;
					errorMsg = s.defaultError;
				} else if(regs.tryChecked.test(className)) {
					var theID = className.split("trychecked-")[1].split(" ")[0],
					dependsElem = $(".dependsChecked-" + theID)[0];
					isValid = elm.checked ? dependsElem.value != "" : true;
					errorMsg = s.defaultError;
					check([dependsElem]);
				};
				if(isValid) { removeError(elm); }
				else { createError(elm,errorMsg); $return = false; };
			};
		};
		for(var x in radioObj) {
			var radioValid = false,
			valArray = radioObj[x].valArray;
			for(var y in valArray) {
				if(valArray[y] === true) { radioValid = true; };
			};
			if(radioValid) { removeError(radioObj[x].firstElement); }
			else {
				createError(radioObj[x].firstElement,s.radioError);
				$return = false;
			};
		}; 
		return $return;
	};
	(function($){  
		jQuery.fn.fatValidate = function(o) {  
			s = $.extend(s, o);			
			return this.each(function(i,elm) {
			    var formelms = elm.elements ? elm.elements : $(elm).find("input,textarea"),
			    hasTriggers = (function(){
			        var x = 0;
			        while(s.customTriggers[x] && x < 1) { x++; };
			        return (x == 0 ? false : true);
			    })();
			    if(!hasTriggers) {
			        document.forms[0].onsubmit = function(){
			            var returnVal = check(formelms);
					    return returnVal;
				    };		
                } else {
                    //s.customTriggers["#" + elm.id] = "submit";
                    for (var x in s.customTriggers) {
                        $(elm).find(x).each(function(){
                            var oldHref = $(this).attr("href");
                            $(this).removeAttr("href").bind(s.customTriggers[x],function(){
                                var isValidated = check(formelms);
                                if(isValidated) {
                                    $(this).attr("href", oldHref);
                                };
                                return isValidated;
                            });
                        });
                    };
                };
			});
		};  
	})(window.jQuery);
})();
