
/**
 * namespace bna
 */

if(typeof(bna) == 'undefined') {
    var bna = {};
}

(function($) {

	/**
	 * Add all custom validator
	 */

	$.validator.addMethod("hintRequired", function(value, element, param) {
		// check if dependency is met
		if ( !this.depend(param, element) )
			return "dependency-mismatch";

		switch( element.nodeName.toLowerCase() ) {
		case 'select':
			// could be an array for select-multiple or a string, both are fine this way
			var val = $(element).val();
			return val && val.length > 0;
		case 'input':
			if (this.checkable(element))
				return this.getLength(value, element) > 0;
		default:
			if(value === element.title) return false;
			else return $.trim(value).length > 0;
		}
	});
	$.validator.addMethod("zipFormat", function(value, element) {
		var t = /[A-Z][0-9][A-Z](-|\s)?[0-9][A-Z][0-9]/i;
		return this.optional(element) || t.test(value);
	});
	$.validator.addMethod("normalString", function(value, element) {
		// Si false dans arguments[2], le test ne doit pas Ítre exécuté.
		if(arguments.length >= 3 && !arguments[2]) return true;
		//console.debug('normalString call..');
		var t = /^[a-zA-ZÀÁÂÃÄÅÆàáâãäåæÇçÈÉÊËèéêëÌÍÎÏìíîïÑñÒÓÔÕÖØòóôõöøÙÚÛÜùúûüÝŸýÿ' \-]*$/i;
		return this.optional(element) || t.test(value);
	});
	$.validator.addMethod("alphaNumString", function(value, element) {
		// Si false dans arguments[2], le test ne doit pas Ítre exécuté.
		if(arguments.length >= 3 && !arguments[2]) return true;
		//console.debug('alphaNumString call..');
		var t = /^[a-zA-ZÀÁÂÃÄÅÆàáâãäåæÇçÈÉÊËèéêëÌÍÎÏìíîïÑñÒÓÔÕÖØòóôõöøÙÚÛÜùúûüÝŸýÿ' \-0-9]*$/i;
		return this.optional(element) || t.test(value);
	});
	$.validator.addMethod("alphaNumStrict", function(value, element) {
		// Si false dans arguments[2], le test ne doit pas Ítre exécuté.
		if(arguments.length >= 3 && !arguments[2]) return true;
		//console.debug('alphaNumStrict call..');
		var t = /^[a-zA-Z0-9]*$/i;
		return this.optional(element) || t.test(value);
	});
	$.validator.addMethod("phoneNumber", function(value, element) {
		//console.debug('phoneNumber call.. : '+ value);
		// (XXX)   : débute avec ( optionnel suivi d'un code régional valide suivi de ) ou - optionnel suivi de 'space' optionnel
		// xXX     : suivie d'un chiffre entre 2 et 9 suivi de 2 chiffres entre 0 et 9 suivi de - ou 'space' optionnel
		// XXXX    : suivi de 4 chiffre entre 0 et 9
		/*** L'extention téléphonique a été déplacé dans un champs indépendant ***/
		// #Xxxxxx : optionnellement suivi d'un extension composé optionnellement d'un espace suivi d'un x ou # et suivie de 1 à 6 chiffres entre 0 et 9
		//var t = /^\(?(514|438|819|418|450|581)\)?-?\s?\.?[2-9][0-9]{2}[-. ]?[0-9]{4}(\s?[x#]?[0-9]{1,6})?$/i;
		var t = /^\(?(514|438|819|418|450|581)\)?-?\s?\.?[2-9][0-9]{2}[-.\s]?[0-9]{4}$/i;
		return this.optional(element) || t.test(value);
	});
	$.validator.addMethod("shortNum", function(value, element) {
		//console.debug('shortNum call.. : '+ value);
		var t = /^[1-9]([0-9]{1,5})?$/i;
		return this.optional(element) || t.test(value);
	});
	$.validator.addMethod("noSerie", function(value, element) {
		//console.debug('noSerie call.. : '+ value);
		var t = /^[a-z0-9]{17}$/i;
		return this.optional(element) || t.test(value);
	});
	$.validator.addMethod("minIndex", function(value, element, minIdx) {
		//console.debug('minIndex call.. : '+ element.selectedIndex);
		return this.optional(element) || (element.selectedIndex >= minIdx);
	});
	$.validator.addMethod("fullYear", function(value, element) {
		if(arguments.length >= 3 && typeof arguments[2] == 'string') {
			var test = $(arguments[2]);
			if(test.length == 0) return true;
		}
		// console.log('fullYear call for value ' + value);
		// Assure une valeur numérique
		var intValue = ''+parseInt(value,10);
		if(intValue != value) return false; // La valeur saisie n'est pas numérique
		// RécupËre le range valide s'il y en a un, sinon utilise le range par défaut qui est entre 1900 et 2099
		// console.log('arguments.length='+arguments.length);
		var range = (arguments.length >= 3 && typeof arguments[2] != 'string') ? arguments[2] : {min:1900, max:2099, extra: false};
		// Assure que la valeur la plus grande soit en position 1 du range
		if(range.max < range.min) {
			var tmp = range.min;
			range.min = range.max;
			range.max = tmp;
		}
		// si un test supplémentaire doit Ítre exécuté, il est exécuté
		// console.dir($(range.extra));
		var extra = (range.extra && $.isFunction(range.extra)) ? range.extra(value,element) : false;
		// console.debug('('+intValue+' >= '+range.min+' && '+intValue+' <= '+range.max+') && '+!extra);
		return ((intValue >= range.min && intValue <= range.max) && !extra);
	});
	$.validator.addMethod("month", function(value, element) {
		var val = parseInt(value,10);
		// La valeur n'est pas nurmérique ou n'est pas un mois valide
		if(val != value || val < 1 || val > 12) return false;
		// zero pad element value
		element.value = $.zeroPad(val,2);
		return true;
	});
	$.validator.addMethod("day", function(value, element) {
		// console.dir(arguments);
		var m=1,y=2010; // mois et année par défaut (31 jours sans année bissextile)
		if(arguments.length == 3) {
			m = parseInt($(arguments[2].mois).val(),10);
			if(isNaN(m) || m < 1 || m > 12) m=1;
			y = parseInt($(arguments[2].annee).val(),10);
			if(isNaN(y) || y < 1000 || y > 9999) y=2010;
		}
		var val = parseInt(value,10);

		// La valeur n'est pas nurmérique ou n'est pas un jour valide
		if(val != value || val < 1 || val > 31) return false;

		// Lors de la création de la date si le jour est inférieur ou supérieur au nombre de jours pouvant Ítre
		// inclus dans le mois spécifier, javascript change le mois et diminue le nombre de jours pour s'ajuster.
		// Ex.: 34/01/2010 = 03/02/2010. Donc on sait que le jours n'est pas valide si le mois a changé.
		var dt = new Date(y,m-1,val);

		if(dt.getMonth()+1 != m) return false;

		// zero pad element value
		element.value = $.zeroPad(val,2);
		// console.log('day return true');
		return true;
	});
	$.validator.addMethod("multiFieldDate", function(value, element) {
		console.log('multiFieldDate',arguments);
		var name = $(element).attr('name'),dId,mId,yId;
		if(arguments.length == 3 && arguments[2] !== true) {
			dId = arguments[2].jour;
			mId = arguments[2].mois;
			yId = arguments[2].annee;
		} else {
			/*dId = element.dateFields[0]; //'#'+name+'-day';
			mId = element.dateFields[1]; //'#'+name+'-month';
			yId = element.dateFields[2]; //'#'+name+'-year';*/
			console.log('date field "#'+element.id+'" is optional ?',this.optional(element));
			if($(element).attr('isDateValid').toString() == "true") {
				return true;
			}
			if(this.optional(element)) {
				return ($(element).val() == "");
			}
			return false;
		}
		console.log('day Id = '+dId);
		var d = $(dId);
		var m = $(mId);
		var y = $(yId);
		console.log('d.val() = "'+d.val()+'"');
		//if(d.val() != "") d.val($.zeroPad(d.val(),2));
		//if(m.val() != "") m.val($.zeroPad(m.val(),2));

		// console.log(d); console.log(m); console.log(y);
		// Valide le jour, le mois et et l'année
		/*if(!$.validator.methods.day(d.val(), d.get(), {annee: yId, mois: mId}) ||
			!$.validator.methods.month(m.val(), m.get()) ||
			!$.validator.methods.fullYear(y.val(), y.get())) return false;
		*/
		//console.log('les contrÙles individuel semble valide');


			var dt = $(element).val().split('/');
			// console.debug(parseInt(dt[0],10)+'!='+d.val()+'||'+parseInt(dt[1],10)+'!='+m.val()+'||'+parseInt(dt[2],10)+'!='+y.val());
			if(parseInt(dt[0],10) != d.val() || parseInt(dt[1],10) != m.val() || parseInt(dt[2],10) != y.val()) return false;

		// console.log('multifieldDate return true');
		if(d.val() && m.val() && y.val()) {
			return this.optional(element) || $(element).attr('isDateValid') == "true";
		} else {
			return true;
		}
	});
	$.validator.addMethod("multiFieldDateRequired", function(value, el, required) {
		//console.clear();
		console.log('required = ', required);
		if($(el).attr('isDateValid') == "false") {
			if(required) {
				return false;
				console.log('required && not valid!');
				for(var f in el.dateFields) {
					if($(el.dateFields[f]).val() != "") {
						return true;
					}
				}
				return false;
			} else {
				for(var f in el.dateFields) {
					//if($(el.dateFields[f]).attr('hasChange') == "true" && $(el.dateFields[f]).val() != "") {
					if($(el.dateFields[f]).val() != "") {
						return true;
					}
				}
			}
		} else {
			return true;
		}
		console.log(el.id, ': required = ', required, ' : all fields are empty! ');
		return false;
	});
	$.validator.addMethod("multiFieldDateMin", function(value, element, minDate) {
		//if(!$.validator.methods.multiFieldDate(value, element)) return false;
		var tmp = value.split('/');
		var dt = new Date(parseInt(tmp[2],10),parseInt(tmp[1],10)-1,parseInt(tmp[0],10),23,59,59,999);
		// console.log(dt);
		// console.log(minDate);
		return this.optional(element) || dt >= minDate;

	});
	$.validator.addMethod("multiFieldDateMax", function(value, element, maxDate) {
		//if (!$.validator.methods.multiFieldDate(value, element)) return false;
		var tmp = value.split('/');
		var dt = new Date(parseInt(tmp[2], 10), parseInt(tmp[1], 10) - 1, parseInt(tmp[0], 10), 0, 0, 0, 0);
		console.log('max date',dt,'<=',maxDate);
		return this.optional(element) || dt <= maxDate;

	});
	$.validator.addMethod("permisConduire", function(value, element) {
		var permisRegexp = /^[a-z][0-9]{4}-[0-9]{6}-[0-9]{2}$/i ;
		return this.optional(element) || permisRegexp.test(value) ;

	});
	/**
	 * Validates for visa or mastercard
	 * Visa: ^4[0-9]{12}(?:[0-9]{3})?$ All Visa card numbers start with a 4. New cards have 16 digits. Old cards have 13.
	 * MasterCard: ^5[1-5][0-9]{14}$ All MasterCard numbers start with the numbers 51 through 55. All have 16 digits.
	 */
	$.validator.addMethod("isVisaOrMastercard", function(value, element) {
		var visaRegexp = /^4[0-9]{12}(?:[0-9]{3})?$/i,
			mastercardRegexp = /^5[1-5][0-9]{14}$/i;
		return visaRegexp.test(value) || mastercardRegexp.test(value);
	});
	$.validator.addMethod("func", function(value, element, result) {
		return result;
	});
	$.validator.addMethod("func2", function(value, element, result) {
		return result;
	});
	$.validator.addMethod("func3", function(value, element, result) {
		return result;
	});



}).call(bna, jQuery);

