function rotationFlash(listeImage, width, height, alt) {
    var i = 0;
    var p = listeImage.length;
    var whichImage = Math.round(Math.random()*(p-1));
    document.write('<object type="application/x-shockwave-flash" data="'+listeImage[whichImage]+'" width="'+ width +'" height="'+height+'" alt="'+alt+'" title="'+alt+'"><param name="movie" value="'+listeImage[whichImage]+'" /><param name="loop" value="true" /><param name="play" value="true" /></object>');
}

function rotationImage(listeImage, width, height, alt) {
    var i = 0;
    var p = listeImage.length;
    var whichImage = Math.round(Math.random()*(p-1));
    document.write('<img src="'+listeImage[whichImage]+'" width="' +width +'" height="'+height +'" alt="'+alt+'" title ="'+ alt + '"/>');
}


/**
 * Internationalisation class
 * @constructor
 * @class I18N
*/
function I18N() {}
I18N.prototype = {
	/**
	 * Return a localiztion key
	 * @member I18N
	 * @param key
	 * @return a localised text corresponding to the provided key
	 * @type String
	 */
    get: function (key) {
        return this.keys[key];
    },
	// The list of stores keys
	keys : {}
};

/**
 * Pads a number with leading zeros.
 * @param number the number to pad
 * @param length the maximum number of digits
 */
jQuery.zeroPad = function (number, length) {
    var str = '' + number;
    while (str.length < length)
        str = '0' + str;
    return str;
};


/**
 * namespace bna
 */

if(typeof(bna) == 'undefined') {
    var bna = {};
}

(function($) {
	var bna = this;
	// detects if the browser is IE6
	window.ie6hell = false;
	// Enable the use of the console in the prodution environments
	$.mockConsole();
	// Configuration options which are merged with the options
	// supplied by the main init method
	bna.options = {
	};
	/**
	 * On each page, override this method with one containing all your form validators
	 */
	bna.initForm = function() {};
	/**
	 * Initialisation of the general scripts
	 * @param options
	 */
	bna.init = function(options) {
		$.extend(this.options, options);
		$.extend(this.i18n.keys, options.i18n);

		// Trigger enhancement on document ready
		$(function(){
			bna.enhance();
		});
	};

	/**
	 * Helper functions for the I18N class
	 */
	bna.i18n = new I18N();
	function _(key) {
	    return bna.i18n.get(key);
	}

	/**
	 * Apply all progressive enhancements
	*/
	bna.enhance = function () {
		$.safe("binding fancy selects", this, function(){
			if (!ie6hell) $(".fancySelect").fancySelect();
		});
		$.safe("Enhance help popups", this, function(){
			bna.enhanceHelpPopups();
		});
		$.safe("Enhance date fields", this, function(){
			bna.enhanceDateFields(bna.options.i18n.lang);
		});
        $.safe("Enhance empty select boxes", this, function(){
            bna.enhanceEmptySelects();
		});
        $.safe("Enhance multi-field dates", this, function(){
            bna.enhanceMultifieldDates();
		});
		$.safe("Enhance shadowbox", this, function() {
			bna.enhanceShadowbox();
		});
		$.safe("Enhance input hints", this, function(){
			bna.enhanceInputHints();
		});
		this.initForm();

		/* Hook for IE :focus on input */
		if($.browser.msie) {
			$('body.form .section.form form input[type=text],body.form .section.form form select, body.form .section.form form textarea').focus(function() {
				$(this).css({border: '3px groove #B2B2B2'});
			}).blur(function() {
				$(this).css({border: '3px groove #eee'});
			});
		}
	};

	/*
	bna.enhanceDateFields
	Add the dhtml calendar plugin to all date fields
	Usage:
		Add the "datePicker" class to the text field that needs a date picker.
	*/
	bna.enhanceDateFields = function (lang) {
		var datePickerOptions = $.extend({
			buttonImage: 'images/icn-calendar.png',
			buttonText: 'Choisir la date',
			buttonImageOnly: true,
			changeYear: true,
			yearRange: '-100:+0',
			showOn: 'button',
            regional: $.datepicker.regional[lang],
            // blurring the date picket's text field allows for the hint plug-in to work correctly
            onSelect: function(dateText, inst) {
                // event triggering is for the multifield date component
                $(this).trigger("dateSelected", {date: $(this).datepicker("getDate")}).blur();
            },
            beforeShow: function(input, inst) {
//                $(inst.dpDiv).position($(inst.trigger).position());
                //console.log($(inst.dpDiv).position());
            }
		}, bna.options.i18n.datePicker);
		$(".datepicker").datepicker(datePickerOptions);
	};
    
    /**
	 * Enhances every <select> in order to add a 'novalue' class when no value is selected.
	 */
    bna.enhanceEmptySelects = function () {
        function checkEmpty(srcSelect) {
            var fancyParent = srcSelect.parent(".fancySelect");
            var selValue = srcSelect.val();

            if (selValue == "") {
                fancyParent.addClass("empty");
            } else {
                fancyParent.removeClass("empty");
            }    
        }

        $("select").bind("change", function(event) {
            checkEmpty($(event.target));
        }).each(function (idx, element) {
            checkEmpty($(element));
        });
    };

    /**
	 * Enhances every <select> in order to add a 'novalue' class when no value is selected.
	 */
    bna.enhanceMultifieldDates = function () {
        $(".datepicker").multifieldDate();
    };

	/*
	bna.enhanceHelpPopups
	Add the dhtml popup plugin to all form help markers
	Usage:
		The markup is in two parts:
		1. The clickable icon: <span class="helpPopup" ...
		2. The hidden help content: <div class="helpContent" ...

		Both part ar bound together by specifying the id of the content in the
		"rel" attribute of the clickable marker.

		Here is an example of this markup:

			<div class="field">
				<div class="label">
					<label for="standardTextField">This is a standard text field with help instructions</label>
					<span class="helpPopup" rel="helpContentSample">
						<a href="#" class="openLink">Help:</a>
					</span>
				</div>
				<input id="standardTextField" name="standardTextField" size="9" type="text" title="Enter some text here..." />
				<div class="helpContent" id="helpContentSample">
					<h3>This is a help popup</h3>
					<p>This is the help content for this popup!</p>
				</div>
			</div>

	*/
	bna.enhanceHelpPopups = function () {
		$(".helpPopup").each(function(){
			var helpContentId,
				self = this,
				$self = $(this);
			// Ensure the markup is enhanced only once
			if ($self.hasClass("helpPopupEnhanced")) {
				return;
			}
			$(this).addClass("helpPopupEnhanced");
			// Cancel the click on the open button
			$(this).find(".openLink").click(function(){
				return false;
			});
			// Get the ID of the referenced content
			helpContentId = $(this).attr("rel");
			// Create the HTML content of the popup
			if (!$(this).hasClass("isCompact")) {
				var helpcontent = $("<div></div>")
				.append("<div class='helpPopup-popup'></div>")
				.children()
				.append("<div class='header'><a href='#' class='closeLink'>Close</a></div>")
				.append("<div class='content'>" + $("#" + helpContentId).html() + "</div>")
				.append("<div class='footer'><button class='c ds closeButton' type='button'><span class='base tl'><span class='br'><span class='text icn'>" + _("close") + "</span></span></span></button></div>")
				.parent()
				.html();
				// Activate the beautyTip plugin
				$(this).find(".openLink").bt(helpcontent, {
					container: this,
					padding: 0,
					trigger: ['click'],
					fill: '#FFF',
					cornerRadius: 5,
					strokeStyle: '#90acba',
					strokeWidth: 1,
					positions: ['right', 'top'],
					spikeGirth: 20, // width of spike
					spikeLength: 50, // length of spike
					width: "300px",
					overlap: 0,
					shadow: true,
					shadowOffsetX: 8,
					shadowOffsetY: 8,
					shadowBlur: 14,
					shadowColor: 'rgba(0,0,0,.4)',
					shadowOverlap: false,
					postShow: function(box) {
						var $tip = $(this);
						// Cancel the click on the open button
						$(".closeButton, .closeLink", box).click(function (e) {
							$tip.btOff();
							return false;
						});
					},
					showTip: function(box){
						$(box).fadeIn(500);
					},
					/* when using hideTip, do NOT forget 'callback' at end of animation */
					hideTip: function(box, callback){
						$(box).fadeOut(300);
						callback();
					}
				});
			} else {
				var helpcontent = $("<div></div>")
				.append("<div class='helpPopup-popup'></div>")
				.children()
				.append("<div class='header'><a href='#' class='closeLink'>Close</a></div>")
				.append("<div class='content'>" + $("#" + helpContentId).html() + "</div>")
//				.append("<div class='footer'><button class='c ds closeButton' type='button'><span class='base tl'><span class='br'><span class='text icn'>" + _("close") + "</span></span></span></button></div>")
				.parent()
				.html();
				$(this).find(".openLink").bt(helpcontent, {
					container: this,
					padding: 0,
					trigger: ['click'],
					fill: '#FFF',
					cornerRadius: 5,
					strokeStyle: '#90acba',
					strokeWidth: 1,
					positions: ['right', 'top'],
					spikeGirth: 5, // width of spike
					spikeLength: 5, // length of spike
					width: "340px",
					overlap: 0,
					shadow: true,
					shadowOffsetX: 4,
					shadowOffsetY: 4,
					shadowBlur: 14,
					shadowColor: 'rgba(0,0,0,.4)',
					shadowOverlap: false,
					postShow: function(box) {
						var $tip = $(this);
						// Cancel the click on the open button
						$(".closeButton, .closeLink", box).click(function (e) {
							$tip.btOff();
							return false;
						});
					},
					showTip: function(box){
						$(box).fadeIn(500);
					},
					/* when using hideTip, do NOT forget 'callback' at end of animation */
					hideTip: function(box, callback){
						$(box).fadeOut(300);
						callback();
					}
				});
			}
		});
	};


	/**
	 * Tests if the field groups still contains errors.
	 * This is necessary to clear errors only when it it the last one
	 * Used when opening and collapsing conditionnal panels
	 * @param t
	 * @param elem
	 */
	bna.testKeepHighlight = function(t, elem) {
		//var ierr = t.find('[iserror=true,name!='+elem.name+']');
		var ierr = t.find('.fn-error[name!='+elem.name+']');
		if(ierr.length == 0) {
			t.removeClass('error').removeClass('multi-input');
		}
	};

	/**
	 * Activate the field hint plugin (the greyed out text inside a field when nothing is typed)
	 */
	bna.enhanceInputHints = function () {
	    /* Configure global field hints. Field hints will be enabled for any field input that specifies a 'title' attribute. */
	    $(".field input[title]:not(.datepicker)").hint({method:'valueSwap'});
	};

	/*
	 * Ajouter toutes les fonctionnalité générique au shadowbox (overlay) dans cette méthode
	*/
	bna.enhanceShadowbox = function() {
	
		/*Shadowbox.init({
			handleOversize:     "resize",
			displayNav:         false,
			handleUnsupported:  "remove",
			autoplayMovies:     false,
			modal:				true,
			overlayColor:		"#fff",
			overlayOpacity:		0.7
		});*/
		Shadowbox.init();
		
		// Ajoute la fonctionnalité générique d'affichage de la boite de sauvegarde de la soumission sur le lien #save-link
		if($('#save-link,#save-link-top').length) {
			$('#save-link,#save-link-top').click(function(event) {
				event.preventDefault();
				bna.openMessage({
					player:     "html",
					title:      "<span id=\"fn-bna-sb-title\">Sauvegarder votre soumission <a onclick=\"Shadowbox.close()\" title=\""+bna.options.i18n.close+"\" id=\"bna-nav-close\"></a>",
					content:    '<iframe scrolling="no" src="'+this.href+'" class="ifrm-save"></iframe>',
					height:     225,
					width:      460
				});
			});
		}
	};

	/**
	 * Ouvre un popup DHTML avec des paramêtres optionels
	 * @param options
	 */
	bna.openMessage = function(options) {
		// Default properties
		var props = {
			handleOversize:     "resize",
			displayNav:         false,
			handleUnsupported:  "remove",
			autoplayMovies:     false,
			modal:				true,
			overlayColor:		"#fff",
			overlayOpacity:		0.7
		};
		if(options.options) {
			// Récupère les options d'initialisation
			for (var key in options.options) {
				if (options.options.hasOwnProperty(key)) {
					props[key] = options.options[key];
				}
			} 
		}
		//console.log(props);
		options['options'] = props;
		Shadowbox.open(options);
	};
	
	/**
	 * Toggle the display of the login panel found
	 * on the homepage
	 */
	bna.toggleLogin = function() {
		var loginPanel = $(".login-form-content");
		if (loginPanel.is(":hidden")) {
			loginPanel.parent('div').children('a.toggle-login').first().addClass('active');
			loginPanel.slideDown(300);
		} else {
			loginPanel.parent('div').children('a.toggle-login').first().removeClass('active');
			loginPanel.slideUp(300);
		}
	};

	/**
	 * theme switching for car vs home insurance found on the homepage
	 */
	bna.insuranceTheme = {
		options: {
			banners: {
				car: "", // the url of the car insurance banner image
				home: "" // the url of the auto insurance banner image
			}
		},
		init: function(options) {
			var self = this;

			$.extend(this.options, options);
			/*
			$("#bannerImageCar").css({
				"background-image": "url(" + this.options.banners.car + ")",
				"background-repeat": "no-repeat",
				"z-index": "100"
			});
			$("#bannerImageHome").css({
				"background-image": "url(" + this.options.banners.home + ")",
				"background-repeat": "no-repeat",
				"z-index": "100"
			});
			*/

			$(".tab-car").click(function (e) {
				self.swap("car");
				return false;
			});

			$(".tab-home").click(function (e) {
				self.swap("home");
				return false;
			});

		},
		swap: function (type) {
			var wasHome = $("body").hasClass("isInsuranceTypeHome"),
				isHome = (type === "home"),
				panelToShow = (isHome) ? $("#tab-home") : $("#tab-car"),
				panelToHide = (!isHome) ? $("#tab-home") : $("#tab-car"),
				tabToShow = (isHome) ? $(".tab-home") : $(".tab-car"),
				tabToHide = (!isHome) ? $(".tab-home") : $(".tab-car"),
				bannerToShow = (isHome) ? $("#bannerImageHome") : $("#bannerImageCar"),
				bannerToHide = (!isHome) ? $("#bannerImageHome") : $("#bannerImageCar"),
				classToShow = (isHome) ? "isInsuranceTypeHome" : "isInsuranceTypeCar",
				classToHide = (!isHome) ? "isInsuranceTypeHome" : "isInsuranceTypeCar";

			if (wasHome !== isHome) {
				//Remove classes used for class switching show & hide
				$("#tab-home, #tab-car, #bannerImageHome, #bannerImageCar").removeClass("forInsuranceTypeCar forInsuranceTypeHome");

				panelToHide.show();
				panelToShow.hide();
				bannerToHide.show();
				bannerToShow.hide();

				// Apply the class switching to the body of the page
				$("body").removeClass(classToHide).addClass(classToShow);
				// Run transition animations on tabs and background image of the header.

				panelToShow.css({
					"display": "none",
					"z-index": 100
				});
				panelToHide.css({
					"z-index": 1
				});
				panelToShow.fadeIn(300);

				bannerToShow.css({
					"display": "none",
					"z-index": 100
				});
				bannerToHide.css({
					"z-index": 1
				});
				bannerToShow.fadeIn(500);
			}
		}
	}

	/**
	 * Utility class to show or hide panels according to a set of rules applied to form elements
	 */
	bna.conditionnalPanels = {
		panels: {},
		/**
		 * Add a set of rules to be processed during the page execution
		 * @param form
		 * @param rules
		 */
		isShiftPressed: false,
		add: function(form, rules) {
			// Trigger the processing of rules when the form or its content
			// changes or when the page is ready to load
			var isShiftPressed = false,
				self = this,
				switchPanels = function (e) {
					self.switchPanels(form, rules, e);
				},
				keyUpOrDown = function (e) {
					self.isShiftPressed = e.shiftKey;
				};
			// Bind on form events
			$(form).delegate(":input", "change blur click", switchPanels);
			$(form).delegate(":input", "keydown keyup", keyUpOrDown);
			// Bind on page ready
			$(switchPanels);
		},
		/**
		 * switch the visibility of an element depending on the values
		 * of elements contained in a form.
		 * @param form
		 * @param rules
		 */
		switchPanels: function (form, rules, e) {
			var self = this;
			// Process each rules
			$.each(rules, function () {
				var rule = this;

				//$('#console-ie').append('<div style="border-bottom: 1px solid red;">CP RULE : '+rule.targets+'</div>');
				// Store the conditions result before switching affected panels
				var conditionResult = this.condition() || false;
				// Process each panel that needs to be witcheds
				$.each($(rule.targets), function () {
					// Show or hide the target depending on the conditions result
					if (conditionResult) {
						$(this).fadeIn(500);
						if (rule.focusIfFrom) {
//							console.log(e.currentTarget, $(rule.focusIfFrom).get(0), e.type);
							if (
									(e.currentTarget === $(rule.focusIfFrom).get(0))
									&& (e.type === "blur" || e.type === "focusout")
									&& !self.isShiftPressed
								) {
								$(rule.focusTo).focus();
								//console.log("Focus moved to :", $(rule.focusTo));
							}
						}

					} else {
						//$('#console-ie').append('<div style="border-bottom: 1px solid red;">CP :: Hide error!</div>');
						// If the panel needs to be hidden, if first
						// removes all validation markers from the DOM.
						if (!$(this).is(':hidden')) {
							var parents = $(this).find(".field.error, .rc.error");
							if(parents.length == 0) parents = $(this).parents(".field.error");
							//console.log("parents: ", parents);
							// console.log(parents);
							parents.removeClass("error")
								.find(".error")
								.remove();
							parents.find(".fn-error").removeClass("fn-error");
							$(this).hide();
						}
					}
				});
			});

		}
	};


	/**
	 * Enable validation on a specific form with a set of rules
	 */
	bna.validation = {
		enabled: function(value) {
			if (typeof value === "undefined") {
				return ($.cookie('bnaValidationDisabled') !== "true");
			}
			if (value) {
				$.cookie('bnaValidationDisabled', 'false');
			} else {
				$.cookie('bnaValidationDisabled', 'true');
			}
		},
		//enhanceFormValidation
		add: function (formId, oRules, oMessages) {
			var targetForm = $("#" + formId),
				oGroups = (arguments.length > 3) ? arguments[3] : {};
			// Enhance the form with validation only if it isnt disabled

			if (this.enabled()) {
				targetForm.each(function(){
					// Ad the form to the list of validated forms
					// This is necessary if multiple forms are on the page
					$(this).bind('invalid-form.validate', function() {
						$.safe("Enhance input hints", this, function(){
							bna.enhanceInputHints();
						});
						$('#error-summary').html('<span>' + _("formContainsErrors") + '</span>').css('display','block');
						window.scrollTo(0, 0);
					});
					$(this).validate({
						// This command will force the validator to ignore
						// all hidden and disabled inputs
						// NOTE: All inputs which have been hidden for progressive enhancement
						// need to have a ".forceValidation" class to ensure that the original field
						// can undergo validation.
						ignore: ":not(.forceValidation):hidden, :hidden:parent .forceValidation",
						groups: oGroups,
						// Todo: put this in the configuration file
						debug: true,
						ignoreTitle: true,
						submitHandler: function(form) {
							// s'il n'y a pas d'overlay, envoyer le formulaire
							form.submit(); // OR .ajaxSubmit();
						},
						invalidHandler: function(form, validator) {
							// Reactivate the field hints if the form was
							// unable to submit because of validation errors.
							bna.enhanceInputHints();
						},
						onfocusout: function(element) {
							$(element).valid();
						},
						success: function(label){
						},
						focusInvalid: false,
						errorElement: 'span',
						errorContainer: $('#error-summaray'),
						errorPlacement: function(error, element) {
							var containers = element.parents('.field,.rc');
							var subContainers = containers.filter('.sub-field');
							containers = (subContainers.length) ? subContainers : containers.last();
							var target = $(containers).children('.error-wrapper');
							if(target.length == 0) {
								var d = document.createElement('div');
								$(containers).append('<div class="error-wrapper"></div>');
								target = $(containers).children('.error-wrapper');
							}
							// console.log(target);
							error.appendTo($(target));
						},
						highlight: function (element, errorClass) {
							$(element).attr('iserror', true).addClass('fn-error').removeClass('fn-isvalide');
							var p = $(element).parents('.field,.rc');
							//console.log(p);
							//var tclass = (p.length > 1) ? 'multi-input' : '';
							var target = p.last();
							target.addClass(errorClass); //.addClass(tclass);
						},
						unhighlight: function(element, errorClass) {
							$(element).attr('iserror', 'no').removeClass('fn-error').addClass('fn-isvalide');
							var target = $(element).parents('.field,.rc').last();
							bna.testKeepHighlight(target, element);
						},
						rules: oRules,
						messages: oMessages
					});

				});
			}
		}
	};

}).call(bna, jQuery);


/**
 * 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);

