/*
 * jQuery liveValidation plugin
 * 
 * YOU ARE FREE TO USE, MODIFY OR EXTEND THIS PLUGIN, AS LONG AS THIS COPYRIGHT NOTICE STAYS PRESENT.
 *
 * Copyright (c) 2009 Glenn Ceurvels - www.gackson.be
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 */
 //NOTES
 //the same wordt gevalideerd op basis van het alt attribuut, dit attribuut verwijst naar de name van het andere element dat hetzelfde moet zijn
 //errorreporting gebeurt op basis van de UNIEKE titels van elementen
(function($){
	$.fn.liveValidation = function (userSettings) {
		var settings = $.extend({
				 invalidClass:"invalid",
				 validClass:"valid",
				 ignoreClass: "ignore",
				 onSendError:function() {},
				 onSendSucces:function() {},
				 performAction:true,
				 errorDiv:"div#error",
				 errorReporting:true,
				 errorReports: {
						email: "U gaf een ongeldig e-mail adres in het \"[FIELDTITLE]\" veld.",
						reqd:"U vergat het \"[FIELDTITLE]\" veld in te vullen.",
						radios: "U vergat een \"[FIELDTITLE]\" op te geven.",
						reqdNumber: "De waarde die u opgaf in het \"[FIELDTITLE]\" veld is geen nummer.",
						reqdFile: "Het bestand dat u selecteerde in het \"[FIELDTITLE]\" veld is ongeldig.",
						thesame: "U gaf verschillende waarden in de \"[FIELDTITLE]\" velden",
						phone: "U gaf een ongeldig telefoonnummer. Telefoonnummers moeten op de volgende manier geschreven worden: +3230000000 of 030000000",
						reqdSelect: "U selecteerde geen waarde in de \"[FIELDTITLE]\" lijst."
					}
		}, userSettings ? userSettings: {});
		var form = this;
		var types = ".reqd, .email, .reqdNumber, .phone, .thesame, .reqdFile, .reqdSelect";
		var fields = this.find("input[type!=submit], textarea, select").filter(types);
		var radios = this.find("input[type=radio].reqdRadio");
		var reported = "";
		init()
		
		return form;
		
		function init() {
			form.bind("submit", submitHandler);
			fields.bind("blur", function(){validate(this, false)});
		}
		function validate(f, report) {
			var type = $(f).attr("class");
			var valid = false;
			var value = $(f).val();
			var title;
			var isIgnored =  type.search(settings.ignoreClass) > -1 ? true: false;
			
			if ($(f).attr("title") !== "")  {
				title = $(f).attr("title");
			}
			else if ($(f).attr("name") !== "") {
				title = $(f).attr("name");
			}
			else if ($(f).attr("id") !== "") {
				title = $(f).attr("id");
			}
			
			if (!isIgnored) {
				if (type.search("email")> -1) 		 	{valid = validateMail(value);	type="email";}
				else if (type.search("thesame")> -1) 	{valid = validateTheSame(f); 	type="thesame";}
				else if (type.search("reqdSelect")> -1) {valid = validateReqdSelect(f); type="reqdSelect";}
				else if (type.search("reqdNumber")> -1) {valid = validateNumber(value); type="reqdNumber";}
				else if (type.search("reqdFile")> -1) 	{valid = validateFile(f); 		type="reqdFile";}
				else if (type.search("reqd")> -1) 		{valid = validateReqd(value); 	type="reqd";}
				else if (type.search("phone")> -1) 		{valid = validatePhone(value); 	type="phone";}
				
				if (!valid) {
					$(f).addClass(settings.invalidClass).removeClass(settings.validClass);
				}
				else if (valid) {
					$(f).addClass(settings.validClass).removeClass(settings.invalidClass);
				}
				if (report && settings.errorReporting && !valid) {
					if (reported.search(title)<0) {
						$(settings.errorDiv).append("<p>"+ settings.errorReports[type].replace("[FIELDTITLE]",title) +"</p>");
						reported += title + " ";
					}
				}
			}
		}
		function submitHandler(event) {
			//alle fields checken, met autocomplete van velden zijn de goede class'en mogelijk nog niet aanwezig
			//velden kunnen ook gewijzigd zijn.
			
			fields = form.find("input[type!=submit], textarea, select").filter(types);

			settings.errorReporting ? clearErrors(): "" ;
			
			fields.each(function() {
				validate(this, settings.errorReporting ? true: false);		 
			});
			if (fields.filter("."+settings.invalidClass).size()>0 || !validRadios()) {
				event.preventDefault();
				settings.onSendError();
			}
			
			else {
				if (!settings.performAction) {
					event.preventDefault();	
				}
				settings.onSendSucces();
			}
		
		}
		function validateMail(val) {
			var value = $.trim(val);
			var pattern = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
			if (value.length == 0) {
				return false;	
			}
			if (value.match(pattern)) {
				return true;	
			}
			return false;
		}
		function validateReqd (val) {
			if ($.trim(val).length == 0) {
				return false;	
			}
			else {
				return true;	
			}
			return false;		
		}
		function validateNumber (val) {
			if ($.trim(String(val)).length == 0) {
				return false;	
			}
			if (isNaN(Number(val))) {
				return false;	
			}
			else {
				return true;	
			}
			
			return false;		
		}
		function validatePhone (val) {
			var value = $.trim(val);
			var pattern = /^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,5})|(\(?\d{2,6}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$/;
			if (value.length == 0) {
				return false;	
			}
			if (value.match(pattern)) {
				return true;	
			}
			return false;
		}
		function validateTheSame(elem) {
			var elem = $(elem);
			var value = $(elem).val();
			var otherValueName = $(elem).attr("alt");
			var otherElem = $("*[name="+ otherValueName +"]");
			var otherValue = otherElem.val();
			
			if (value === otherValue && value != "") {
				otherElem.addClass(settings.validClass);
				return true;
			}
			if (value != "" && otherValue === "") {
				//first password entered waiting for second
				otherElem.addClass(settings.invalidClass);
				return true;
			}
			otherElem.addClass(settings.invalidClass);
			return false;
			
		}
		function validRadios() {
			if (radios.size() > 0) {
				//valideren
				var checkedNames = new Array();
				var groepName;
				for (var i=0; i< radios.size(); i++) {
					groepName = radios.eq(i).attr("name");
					if ($.inArray(groepName, checkedNames)<0) {
						if (radios.filter("[name="+ groepName +"]:checked").size() > 0) {
							checkedNames.push(groepName);
							radios.filter("[name=" + groepName +"]").parent().addClass(settings.validClass);
						}
						else {
							radios.filter("[name=" + groepName +"]").parent().addClass(settings.invalidClass);
							return false;
						}
					}
					else if (($.inArray(groepName, checkedNames)>-1) && i == radios.size()-1) {
						return true;
					}
				}
			}
			else {
				return true;
			}
		}
		function validateReqdSelect (elem) {
			var sel = $(elem).children(":selected").eq(0).val();
			return sel === "" ? false: true; 
		}
		function validateFile(elem) {
			var validExts = $(elem).attr("rel").split(",");
			var value = $(elem).val();
 			var dot = value.lastIndexOf(".");
 			var ext = value.substr(dot+1,value.length);			
			$.each(validExts, function(i) {
				validExts[i] = $.trim(validExts[i]);					   
			});
			if( dot == -1 && value === "") {
				//het veld mag leeg zijn!
				return true;
			}
			else if (dot == -1) {
				//geen extentie
				return false;
			}
			else if (dot != -1 && $.inArray(ext, validExts)!=-1) {
				return true;
			}
			else if (dot == -1 && $(elem).hasClass("empty")){
				return true;
			}
			return false;
		}
		function clearErrors() {
			reported = "";
			$(settings.errorDiv).html(" ").show();	
		}
		
	}		  
})(jQuery)
