/*
 * 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, IDs of names van elementen
 
 //dateFormat -> ymd | dmy | mdy
 
 /*types
 .reqd -> required, can not be empty
 .email -> email adres
 .number -> a number
 .phone -> phone number International (+3232810145) OR Local (032810155)
 .thesame -> fields that contain the same value alt='otherfieldNAME'
 .file -> a file (valid extensions = rel='jpg,gif,png') case insensitive
 .vcard -> identiteitskaartnr
 .normalString -> alphabetic string
 .date -> date
 .bankAcc ->
 */
(function($){
		  
	
	$.fn.liveValidation2 = function (userSettings) {
		var settings = $.extend({
				 invalidClass:"invalid",
				 validClass:"valid",
				 ignoreClass: "ignore",
				 onSendError:function() {},
				 onSendSucces:function() {},
				 performAction:true,
				 errorDiv:"div#error",
				 dateFormat:"DMY",
				 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.",
						number: "De waarde die u opgaf in het [FIELDTITLE] veld is geen nummer.",
						file: "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",
						vcard: "U gaf een ongeldig identiteitskaartnummer op.",
						normalString: "U gaf een ongeldige waarde in het [FIELDTITLE] veld, de volgende tekens zijn verboden: +, ;, ', [, ], (, ), &, %, <, >, \", &, =, /",
						date:"U gaf een ongeldige datum in het [FIELDTITLE] veld, datums dienen op de volgende manier geschreven worden: dd/mm/yyyy",
						rijksreg:"U gaf een ongeldig rijksregisternummer, correcte schrijfwijze: 00.00.00-000.00",
						bankAcc:"U gaf een ongeldig banknummer op, correcte schrijfwijze: 000-0000000-00"
				}
		}, userSettings ? userSettings: {});
		
		var form = this;
		var types = ".reqd, .email, .number, .phone, .thesame, .file, .vcard, .normalString, .date, .bankAcc, .rijksreg, .SIS";
		
		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 target = $(f);
			//var type = target.attr("class");
			var valid = false;
			var value = target.val();
			var title = target.attr("title");
			var isIgnored =  target.hasClass(settings.ignoreClass) ? true: false;
			var type;
			
			if (title == "") {
				title = target.attr("name");
				if (title == "")
					title = target.attr("id");
			}
			
			if (!isIgnored) {
				
				var valAr = validateThe(target);
				
				valid = valAr[0];
				type = valAr[1];
				
				if (!valid) {
					target.addClass(settings.invalidClass).removeClass(settings.validClass);
				}
				else if (valid) {
					target.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 validateThe(elem) {
			var elem = $(elem);
			var type = "";
			var valid = true;
						
			if (elem.hasClass("reqd")) {
				type = "reqd";
				
				if (elem[0].tagName == "INPUT" && $.trim(elem.val()) == "")
					return [false, type];
				else if (elem[0].tagName == "SELECT" && $.trim(elem.find("option:selected").val()) == "")
					return [false, type];
			}
			//.bankAcc, .rijksreg, .SIS
			
			if (elem.hasClass("email")) 	{ valid = validateMail(elem.val()); type="email"; }
			if (elem.hasClass("thesame")) 	{ valid = validateTheSame(elem);	type="thesame";}
			if (elem.hasClass("number")) 	{ valid = validateNumber(elem.val());type="number";}
			if (elem.hasClass("file")) 		{ valid = validateFile(elem); 		type="file";  }
			if (elem.hasClass("phone")) 	{ valid = validatePhone(elem.val()); type="phone";}
			if (elem.hasClass("vcard")) 	{ valid = validateVCard(elem.val()); type="vcard";}
			if (elem.hasClass("date")) 		{ valid = validateDate(elem.val()); type="date";}
			if (elem.hasClass("normalString")) { valid = validateNormalString(elem.val()); type="normalString";}
			if (elem.hasClass("bankAcc"))	{valid = validateBankAcc(elem.val()); type="bankAcc";}
			if (elem.hasClass("SIS"))		{valid = validateSIS(elem.val()); type="SIS";}
			if (elem.hasClass("rijksreg"))	{valid = validateRijksreg(elem.val()); type="rijksReg";}
			
			
			return [valid, type];
		}
		
		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(types);

			settings.errorReporting ? clearErrors(): "" ;

			fields.each(function() {
				validate(this, settings.errorReporting ? true: false);	 
			});
			if (fields.filter("."+settings.invalidClass + ":not(."+ settings.ignoreClass +")").size()>0 || !validRadios()) {
				event.preventDefault();
				settings.onSendError();
			}
			
			else {
				if (!settings.performAction) {
					event.preventDefault();	
				}
				return settings.onSendSucces();
			}
		}
		function validateSIS(val) {
			if (val.length == 10) {
				var pattern = /\d{10}/;
				if (val.match(pattern)) {
					return true;	
				}
			}
			else if (val.length == 0) {
				return true;	
			}
			return false;
		}
		function validateRijksreg(val) {
			if (val.length == 15) {
				var pattern = /(\d{2}\.){2}(\d){2}\-(\d{3}\.\d{2})/;
				if  (val.match(pattern)) {
					return true;	
				}
			}
			else if (val.length == 0) {
				return true;	
			}
			return false
		}
		function validateBankAcc(val) {
			if (val.length == 14) {
				var pattern = /\d{3}\-\d{7}\-\d{2}/;
				if  (val.match(pattern)) {
					return true;	
				}
			}
			else if (val.length == 0) {
				return true;	
			}
			return false	
		}
		function validateDate(val) {
			var pattern;
			var form = settings.dateFormat;
			var patternMDY = /(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d/;
			var patternYMD = /(19|20)\d\d[- \/.](0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])/;
			var patternDMY = /(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.](19|20)\d\d/;
			pattern = form == "DMY" ? patternDMY : form == "MDY" ? patternMDY : form == "YMD" ? patternYMD: patternMDY;
						
			if (val.length == 10) {
				if (val.match(pattern)) {
					return true;
				}	
			}
			else if (val.length == 0) {
				return true;	
			}
			return false;
		}
		function validateNormalString(val) {
			var pattern = /^[^\+\;\'\[\]\(\)\&\%\<\>\"\&\=\/]+$/;
			if (val.match(pattern)) {
				return true;	
			}
			else if ($.trim(val) == "") {
				//validatie op reqd gebeurt hiervoor dus het veld mag leeg zijn
				return true;	
			}
			return false;
		}
		function validateVCard(val) {
			if (val.length == 14) {
				var pattern = /[0-9]{3}-[0-9]{7}-[0-9]{2}/;
				if (val.match(pattern)) {
					return true;	
				}
			}
			else if (val.length == 0) {
				return true;	
			}
			return false;
		}
		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 true;	
			}
			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 true;	
			}
			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.match(pattern)) {
				return true;	
			}
			else if ($.trim(val) == "") {
				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).removeClass(settings.invalidClass);
				return true;
			}
			if (value != "" && otherValue === "") {
				//first password entered waiting for second
				otherElem.addClass(settings.invalidClass).removeClass(settings.validClass);
				return true;
			}
			otherElem.addClass(settings.invalidClass).removeClass(settings.validClass);
			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 validateFile(elem) {
			var validExts = $(elem).attr("rel").split(",");
			var value = $(elem).val();
 			var dot = value.lastIndexOf(".");
 			var ext = value.substr(dot+1,value.length).toLowerCase();			
			$.each(validExts, function(i) {
				validExts[i] = $.trim(validExts[i]);
				validExts[i] = validExts[i].toLowerCase();
			});
			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)