/*
 * fonction minfobulle
 * Gestionnaire d'infobulle
 *
 * Basé sur jQuery
 *
 * Copyright 2011, Jérôme Engeln
 *
 * Depend de :
 *		me_ajax.js
 * 
 * Date: 17/06/2011
 */

(function( $, undefined ) {

	var mouseX = 0, mouseY = 0;
	var ua = navigator.userAgent;
	var isSmartPhone = /iPad/i.test(ua) || /iPhone OS 3_1_2/i.test(ua) || /iPhone OS 3_2_2/i.test(ua);
	var meinfobulle_listeSelectors = new Array();
	var meinfobulle_selectorOuvert = null;
	var meinfobulle_autoriseFermetureClick = true;
	var meinfobulle_eventClickDocumentAttribue = false;
	var timerFermeture = null;

	$(document).bind({
		// Lorsqu'on bouge la souris
		mousemove: function(evt) {
			// On retient la position de la souris dès que le mouvement est enclenché
			if (document.all) {
				mouseX = event.clientX+((document.body.scrollLeft != null)?document.body.scrollLeft:0);
				mouseY = event.clientY+((document.body.scrollTop != null)?document.body.scrollTop:0);
			} else if (document.layers) {
				mouseX = evt.x;
				mouseY = evt.y;
			} else if (document.getElementById) {
				mouseX = evt.pageX;
				mouseY = evt.pageY;
			}
		}
	});

	$.fn.meinfobulle = function(selector, message, options, callback) {

		// Si le premier parametre est une chaine, on décale les paramètres
		if(typeof selector == "string" && (message == null || jQuery.isPlainObject(message)) ) {
			callback = options;
			options = message;
			message = selector;
			selector = this.selector;
		}
		// Si on passe le callback dans le 3ème paramètre de la fonction
		if(jQuery.isFunction(options) && !callback && !jQuery.isPlainObject(options)) {
			callback = options;
		}
		// Aucune option locale n'est passée en paramètres, on initialise les options avec les options définies au niveau global
		if(!options) {
			// objet vide ou configuré
			options =  $me.options.infobulle; 
		} 
		// Si des options locales sont communiquées et que les options globales sont configurées, on ajoute les options globales manquantes aux options locales
		// Les options locales surchargent ainsi les options globales
		else if(jQuery.isPlainObject($me.options.infobulle)) {
			for ( name in $me.options.infobulle ) {
				if(!options[name]) {
					options[name] = $me.options.infobulle[name];
				}
			}
		}
		// Déclaration des variables
		var self = this,
			options = {
				infobulleClass:		options.infobulleClass != undefined ?options.infobulleClass:	"me-infobulle",
				textClass:			options.textClass != undefined ?options.textClass:				"me-infobulle-text",
				openerEvent:		options.openerEvent != undefined ?options.openerEvent:			"mouseover",
				closerEvent:		options.closerEvent != undefined ?options.closerEvent:			"mouseout",
				zIndex:				options.zIndex != undefined ?options.zIndex:					10000,
				width:				options.width != undefined ?options.width:						'auto',
				height:				options.height != undefined ?options.height:					'auto',
				marge:				options.marge != undefined ?options.marge:						0,
				margeX:				options.margeX != undefined ?options.margeX:					options.marge,
				margeY:				options.margeY != undefined ?options.margeY:					options.marge,
				cssInfobulle:		options.cssInfobulle != undefined ?options.cssInfobulle:		'',
				cssTexteInfobulle:	options.cssTexteInfobulle != undefined ?options.cssTexteInfobulle:	'',
				position:			options.position != undefined ?options.position:				'auto', // auto, top, left, right ou bottom
				ciblePosition:		options.ciblePosition != undefined ?options.ciblePosition:		'mouse', // mouse ou document
				minwidth:			options.minwidth != undefined ?options.minwidth:				null,
				minheight:			options.minheight != undefined ?options.minheight:				null,
				maxwidth:			options.maxwidth != undefined ?options.maxwidth:				null,
				maxheight:			options.maxheight != undefined ?options.maxheight:				null,
				defaultContent:		options.defaultContent != undefined ?options.defaultContent:	"Texte par défaut",
				fadein:				options.fadein != undefined ?options.fadein:					200,
				fadeout:			options.fadeout != undefined ?options.fadeout:					100,
				appendIn:			options.appendIn != undefined ?options.appendIn:				"#body",
				group:				options.group != undefined ?options.group:						"",
				timeFermeture:		options.timeFermeture != undefined ?options.timeFermeture:		450,
				typeFermeture:		options.typeFermeture != undefined ?options.typeFermeture:		"remove", // remove ou hide : hide laisse le layer ds le DOM
				effetSlide:			options.effetSlide != undefined ?options.effetSlide:			0, // 
				directionSlide:		options.directionSlide != undefined ?options.directionSlide:	"top", // 
				libelleFermer:		options.libelleFermer != undefined ?options.libelleFermer:		"",
				openingCall:		options.openingCall != undefined ?options.openingCall:			function() {}
			};

		if(options.margeX == undefined) options.margeX = 0;
		if(options.margeY == undefined) options.margeY = 0;

		self.selectorInterne = selector;

		// Récupération de la hauteur et largeur de la fenetre
		var win = $(window),
			doc = $(document);
		var hauteurDocument = win.height(),
			largeurDocument = win.width(),
			initialise = self.initialise = true;

		var meInfobulle, 
			meInfobulleText, 
			id = self.id = 0,
			open = function() {

				if(options.typeFermeture == "remove" || meInfobulle == undefined) {
				
					if(options.group != "") {
						if(options.typeFermeture == "remove") {
							$("."+options.group).remove();
						}
					} else {
						$("."+options.infobulleClass).each( function() {
							var nomClass = $(this).attr("class");
							var nbSClass = nomClass.split(" ");
							if(nbSClass.length == 1) {
								if(options.typeFermeture == "remove") {
									$(this).remove();	
								} 
							}
						});
					}
					
					if(timerFermeture) {
						clearTimeout(timerFermeture);
						timerFermeture = null;
					}

					// Création du layer conteneur
					meInfobulle = self.meInfobulle = ($('<div></div>')
					.appendTo(options.appendIn)
					.hide()
					.addClass(options.infobulleClass+((options.group)?" "+options.group:""))
					.attr("id","infobulle"+(Math.random()*100))
					.css({
						zIndex: options.zIndex,
						position: "relative",
						// Pour IE6 => Sinon la largeur se met à 100% de la fenetre
						float: "left",
						display: "none",
						top : 0,
						left : 0
					}));

					if(options.cssInfobulle != '') {
						meInfobulle.css(options.cssInfobulle);
					}
					
					// Création du layer texte
					meInfobulleText = self.meInfobulleText = ($('<div></div>')
					.appendTo(meInfobulle)
					.addClass(options.textClass)
					.css({	
						position: "relative",
						// Pour IE6 => Sinon la largeur se met à 100% de la fenetre
						float: "left"
					})
					.html( ((message != "")?message:options.defaultContent) ));

					if(options.openerEvent == "click" && options.libelleFermer != "") {
						meInfobulleLienFermer = self.meInfobulleLienFermer = ($('<a></a>')
						.appendTo(meInfobulleText)
						.addClass("btfermer")
						.css({	
							position: "absolute",
							top:"0px",
							right:"0px"
						})
						.attr("href", "javascript:void(0)")
						.click( function() {  } )
						.html( options.libelleFermer ));
					}

					if(options.cssTexteInfobulle != '') {
						meInfobulleText.css(options.cssTexteInfobulle);
					}

				} 

				if(options.typeFermeture != "remove") {

					if(options.group != "") {
						if(options.typeFermeture == "remove") {
							$("."+options.group).hide();
						}
					} else {
						$("."+options.infobulleClass).each( function() {
							var nomClass = $(this).attr("class");
							var nbSClass = nomClass.split(" ");
							if(nbSClass.length == 1) {
								$(this).hide();	
							}
						});
					}

					for(var a in meinfobulle_listeSelectors) {
						if ($(selector).attr('id') != $(meinfobulle_listeSelectors[a].selector).attr('id') && options.group == meinfobulle_listeSelectors[a].group) {
							meinfobulle_listeSelectors[a].fermeture.call();
						}
					}

				}

				// On appelle la fonction de retour
				if(jQuery.isFunction(options.openingCall)) {
					options.openingCall.call(self);
				}

				// On récupère la largeur et la hauteur du layer alerte
				meInfobulle.show();
				var h = self.meInfobulle.css({
					width: options.width,
					height: options.height
				}).innerHeight();
				h = (h - parseInt(meInfobulle.css('paddingTop')));
				h = (h - parseInt(meInfobulle.css('paddingBottom')));
				meInfobulle.css({height: h+"px" });
				if(h < options.minheight && options.minheight != null) {

					h = options.minheight; 
					self.meInfobulle.css({height: options.minheight });

				} else if (h > options.maxheight && options.maxheight != null) {

					h = options.maxheight; 
					self.meInfobulle.css({height: options.maxheight });

				}
				me.globals.infobulle.h = h;
				meInfobulle.hide();

				meInfobulle.show();
				var l = self.meInfobulle.css({
					width: options.width,
					height: options.height
				}).innerWidth();
				l = (l - parseInt(meInfobulle.css('paddingLeft')));
				l = (l - parseInt(meInfobulle.css('paddingRight')));
				meInfobulle.css({width: l+"px" });
				if(l < options.minwidth && options.minwidth != null) {

					l = options.minwidth; 
					meInfobulle.css({width: options.minwidth+"px" });

				} else if(l > options.maxwidth && options.maxwidth != null) {

					l = options.maxwidth; 
					meInfobulle.css({width: options.maxwidth+"px" });

				}
				me.globals.infobulle.l = l;
				meInfobulle.hide();
				
				position(l, h, false);
				if(options.ciblePosition == 'mouse') {
					$(selector).unbind("mousemove");
					$(selector).bind({
						// Lorsqu'on bouge la souris
						mousemove: function(evt) {
							position(l, h, true);
						}
					});
				}

				$me.globals.infobulle.open = 1;

			},
			// Fonction de fermeture
			close = function(infoBulle) {

				if($me.globals.infobulle.open == 1 && infoBulle != undefined) {

					if(options.typeFermeture == "remove") {

						if(options.ciblePosition == "layer") {
							if(timerFermeture) {
								clearTimeout(timerFermeture);
								timerFermeture = null;
							}
						}

						infoBulle.fadeOut(options.fadeout, function() {

							// Desctruction des layers
							self.meInfobulle.remove();

							// L'infobulle est fermée
							$me.globals.infobulle.open = 0;

						});

					} else {

						infoBulle.fadeOut(options.fadeout);

					}
				}
			},
			// Fonction de positionnement de la fenêtre
			position = function(l, h, noeffect) {

				self.meInfobulle.css({position: "absolute"});

				var margeX = options.margeX;
				var margeY = options.margeY;
				var conteneurW = $( ((options.appendIn == "#body")?window:options.appendIn) ).width();
				var conteneurH = $( ((options.appendIn == "#body")?window:options.appendIn) ).height();
				
				var win = $(window),
					doc = $(document);
				
				// Ajout du scroll pour tester le contour
				if(doc.scrollTop() && options.appendIn == "#body") {
					conteneurH += doc.scrollTop();
				}

				var paddingBulleL = parseInt(self.meInfobulle.css("paddingLeft"));
				var paddingBulleR = parseInt(self.meInfobulle.css("paddingRight"));
				var paddingBulleT = parseInt(self.meInfobulle.css("paddingTop"));
				var paddingBulleB = parseInt(self.meInfobulle.css("paddingBottom"));

				if(options.ciblePosition == 'layer') {

					// L'infobulle est placée dans un layer, on va récupérer ce dernier pour connaitre la largeur et la hauteur
					var layerParentMax;
					var layerParentTrouve = false;
					if(options.appendIn != "#body") {
						var position = $(selector).position();
						var posX = position.left;
						var posY = position.top;
						$(selector).parents().each(function() {
							if(!layerParentTrouve) {
								if( $(this).attr("id") == $(options.appendIn).attr("id") ) {
									layerParentTrouve = true;
									layerParentMax = this;
									return this;
								}
								var position = $(this).position();
								posY += position.top;
								posY += parseInt($(this).css("marginTop"));
								posX += position.left;
								posX += parseInt($(this).css("marginLeft"));
							}
						});
					} else {
						var position = $(selector).offset();
						var posX = position.left;
						var posY = position.top;
					}
					var selectorW = $(selector).outerWidth(true);
					var selectorH = $(selector).outerHeight(true);

					switch(options.position) {
						// Aligné sous le layer au centre
						case 'bottom': 
							self.meInfobulle.css({top: (posY+margeY+selectorH)+"px" });
							self.meInfobulle.css({left: ((posX+margeX+(selectorW/2)) - (l/2) - paddingBulleL )+"px" });
						break;
						case 'top': 
							self.meInfobulle.css({top: (posY - margeY - h - paddingBulleB - paddingBulleT)+"px" });
							self.meInfobulle.css({left: ((posX+margeX+(selectorW/2)) - (l/2) - paddingBulleL )+"px" });
						break;
						case 'left': 
							self.meInfobulle.css({top: (posY - (h/2) - paddingBulleT + (selectorH/2) )+"px" });
							self.meInfobulle.css({left: (posX-margeX-l-paddingBulleL-paddingBulleR )+"px" });
						break;
						case 'right': 
							self.meInfobulle.css({top: (posY - (h/2) - paddingBulleT + (selectorH/2) )+"px" });
							self.meInfobulle.css({left: (posX+selectorW+margeX )+"px" });
						break;
						case 'righttop': 
							// A droite aligné par rapport au haut
							self.meInfobulle.css({top: (posY+margeY)+"px" });
							self.meInfobulle.css({left: (posX+selectorW+margeX )+"px" });
						break;
						case 'lefttop': 
							// A gauche aligné par rapport au haut
							self.meInfobulle.css({top: (posY+margeY)+"px" });
							self.meInfobulle.css({left: (posX-margeX-l-paddingBulleL-paddingBulleR)+"px" });
						break;
						case 'rightbottom': 
							// A droite aligné par rapport au bas
							self.meInfobulle.css({top: (posY+margeY+selectorH-h-paddingBulleT- paddingBulleB)+"px" });
							self.meInfobulle.css({left: (posX+selectorW+margeX )+"px" });
						break;
						case 'leftbottom': 
							// A gauche aligné par rapport au bas
							self.meInfobulle.css({top: (posY+margeY+selectorH-h-paddingBulleT- paddingBulleB)+"px" });
							self.meInfobulle.css({left: (posX-margeX-l-paddingBulleL-paddingBulleR )+"px" });
						break;
						case 'bottomleft': 
							// En dessous, aligné à gauche
							self.meInfobulle.css({top: (posY+selectorH+margeY)+"px" });
							self.meInfobulle.css({left: (posX+margeX)+"px" });
						break;
						case 'bottomright': 
							// En dessous, aligné à droite
							self.meInfobulle.css({top: (posY+selectorH+margeY)+"px" });
							self.meInfobulle.css({left: (posX+selectorW+margeX - l - paddingBulleL - paddingBulleR)+"px" });
						break;
						case 'topleft': 
							// Au dessus, aligné à gauche
							self.meInfobulle.css({top: (posY-margeY-h-paddingBulleT- paddingBulleB)+"px" });
							self.meInfobulle.css({left: (posX+margeX)+"px" });
						break;
						case 'topright': 
							// Au dessus, aligné à droite
							self.meInfobulle.css({top: (posY-margeY-h-paddingBulleT- paddingBulleB)+"px" });
							self.meInfobulle.css({left: (posX+selectorW+margeX - l - paddingBulleL - paddingBulleR)+"px" });
						break;
					}
					
					// Si mode horizontale du conteneur : On test si on dépasse en left
					if(options.position == "bottom" || options.position == "top") {
						// Si le top ou le left est négatif on le force == à la marge
						if(parseInt(self.meInfobulle.css("left")) < 0) {
							self.meInfobulle.css({left: margeX+"px" });
						}
						if(parseInt(self.meInfobulle.css("top")) < 0) {
							self.meInfobulle.css({top: margeY+"px" });
						}
						// Si le l + left > à la largeur du conteneur on décalle
						if( (parseInt(self.meInfobulle.css("left")) + l) > conteneurW ) {
							self.meInfobulle.css({left: (conteneurW - margeX - l - paddingBulleL - paddingBulleR)+"px" });
						}
					} 
				
					else { 

						// Si le h + top > à la hauteur du conteneur on décalle
						if( (parseInt(self.meInfobulle.css("top")) + paddingBulleT + paddingBulleB + h + margeY ) > conteneurH ) {
							self.meInfobulle.css({top: (conteneurH - (h + paddingBulleT + paddingBulleB + margeY))+"px" });
						}

						// Si top négatif, top = 0
						if(parseInt(self.meInfobulle.css("top")) < 0) {
							self.meInfobulle.css({top: margeY+"px" });
						}

						// Si le appendIn est le body, on test si le layer sort du cadre ou non
						if(options.appendIn == "#body") {
							
							// Dépassement à droite
							if((parseInt(self.meInfobulle.css("left")) + paddingBulleL + l + paddingBulleR + margeX) > conteneurW) {
								self.meInfobulle.css({left: (conteneurW - margeX - l - paddingBulleL - paddingBulleR)+"px" });
							}
							
							// Dépassement à gauche
							if(parseInt(self.meInfobulle.css("left")) < 0) {
								self.meInfobulle.css({left: margeX+"px" });
							}
							// Dépassement en bas

						}
					}

				} else {

					var largeurRestanteADroite = ((largeurDocument - mouseX) - margeX);
					var largeurRestanteAGauche = (mouseX - margeX);
					var hauteurRestanteEnHaut = (mouseY - margeY);
					var hauteurRestanteEnBas = ((hauteurDocument - mouseY) - margeY);
					
					if(options.ciblePosition != 'mouse') {
						var win = $(window);
						var doc = $(document);
						var left = ( (win.width()/2) + $(document).scrollLeft() ) - (l/2);
						if(win.height() < doc.height()) {
							left = left - 12;
						}
						var top = ( (win.height()/2) + $(document).scrollTop() ) - (h/2);
						if(win.width() < doc.width()) {
							top = top - 14;
						}
					}

					if(options.position == 'auto') {

						if(options.ciblePosition != 'mouse') {

							self.meInfobulle.css({top: top+"px" });
							self.meInfobulle.css({left: left+"px" });

						} else {

							// Est-ce qu'on placer l'infobulle en bas à droite
							if(largeurRestanteADroite > l && hauteurRestanteEnBas > h) {
								self.meInfobulle.css({top: (mouseY+margeY)+"px" });
								self.meInfobulle.css({left: (mouseX+margeX)+"px" });
							}
							// en haut à droite ?
							else if (largeurRestanteADroite > l && hauteurRestanteEnHaut > h) {
								self.meInfobulle.css({top: (mouseY-margeY-h)+"px" });
								self.meInfobulle.css({left: (mouseX+margeX)+"px" });
							}
							// à droite au milieu
							else if (largeurRestanteADroite > l) {
								self.meInfobulle.css({top: (mouseY-(h/2))+"px" });
								self.meInfobulle.css({left: (mouseX+margeX)+"px" });
							} 
							// en haut à gauche ?
							else if (largeurRestanteAGauche > l && hauteurRestanteEnHaut > h) {
								self.meInfobulle.css({top: (mouseY-margeY-h)+"px" });
								self.meInfobulle.css({left: (mouseX-margeX-l)+"px" });
							}
							// en haut au milieu ?
							else if (hauteurRestanteEnHaut > h) {
								self.meInfobulle.css({top: (mouseY-margeY-h)+"px" });
								self.meInfobulle.css({left: (mouseX-(l/2))+"px" });
							}
							// en bas à gauche ?
							else if (largeurRestanteAGauche > l && hauteurRestanteEnBas > h) {
								self.meInfobulle.css({top: (mouseY+margeY)+"px" });
								self.meInfobulle.css({left: (mouseX-margeX-l)+"px" });
							}
							// à gauche au milieu ?
							else if (largeurRestanteAGauche > l) {
								self.meInfobulle.css({top: (mouseY-(h/2))+"px" });
								self.meInfobulle.css({left: (mouseX-margeX-l)+"px" });
							}
							// en bas au milieu ?
							else if (hauteurRestanteEnBas > h) {
								self.meInfobulle.css({top: (mouseY+margeY)+"px" });
								self.meInfobulle.css({left: (mouseX-(l/2))+"px" });
							}
							// Sinon pas d'affichage	
							else {
								close(self.meInfobulle);
								return false;
							}

						}

					} else if (options.position == 'top') {

						if(options.ciblePosition != 'mouse') {

							self.meInfobulle.css({top: 0+"px" });
							self.meInfobulle.css({left: left+"px" });

						} else {

							self.meInfobulle.css({top: (mouseY-margeY-h)+"px" });
							self.meInfobulle.css({left: (mouseX-(l/2))+"px" });

						}

					} else if (options.position == 'bottom') {

						if(options.ciblePosition != 'mouse') {

							self.meInfobulle.css({top: (win.height()-h-margeY)+"px" });
							self.meInfobulle.css({left: left+"px" });

						} else {
			
							self.meInfobulle.css({top: (mouseY+margeY)+"px" });
							self.meInfobulle.css({left: (mouseX-(l/2)-margeX)+"px" });
						
						}

					} else if (options.position == 'right') {

						if(options.ciblePosition != 'mouse') {

							self.meInfobulle.css({top: top+"px" });
							self.meInfobulle.css({left: (win.width()-l-margeX)+"px" });

						} else {
			
							self.meInfobulle.css({top: (mouseY-(h/2))+"px" });
							self.meInfobulle.css({left: (mouseX+margeX)+"px" });

						}

					} else if (options.position == 'left') {

						if(options.ciblePosition != 'mouse') {

							self.meInfobulle.css({top: top+"px" });
							self.meInfobulle.css({left: 0+"px" });

						} else {
			
							self.meInfobulle.css({top: (mouseY-(h/2))+"px" });
							self.meInfobulle.css({left: (mouseX-margeX-l)+"px" });

						}

					}

				}
	
				if(!noeffect) {

					var top = parseInt(self.meInfobulle.css("top"));
					if(options.effetSlide > 0 && top) {
						
						var left = parseInt(self.meInfobulle.css("left"));
						var left = parseInt(self.meInfobulle.css("left"));

						switch(options.directionSlide) {

							case 'top': 

								self.meInfobulle.css({top: (top+options.effetSlide)+"px"});
								self.meInfobulle.animate({ top: '-='+options.effetSlide, opacity: 'toggle' }, options.fadein);
								
							break;

						}

					} else {

						self.meInfobulle.fadeIn(options.fadein, function() {
							if(self.initialise) {
								// On appelle la fonction de retour
								if(jQuery.isFunction(callback)) {
									callback.call(self);
								}	
							}
							self.initialise = false;
						});

					}
					
				}

			};

		
		if (options.openerEvent == "null") {
			
			open();

			// On sauvegarde les params de la fenêtre ouverte
			self.id = me.paramsInfobulleOpen($(selector), message, options, callback, meInfobulle);

		} else if(options.openerEvent != 'click') {

			// Création de l'évènement d'ouverture
			$(selector).unbind(options.openerEvent);
			$(selector).bind(options.openerEvent, function(){
				
				open();

				// Si on est en mode menu et qu'on entre dans la zone de l'inobulle on détruit le timer de fermeture
				if(options.ciblePosition == "layer") {
					$(meInfobulle).unbind("mouseenter");
					$(meInfobulle).bind("mouseenter", function(){
						if(timerFermeture) {
							clearTimeout(timerFermeture);
							timerFermeture = null;
						}
					});
					$(meInfobulle).unbind("mouseleave");
					$(meInfobulle).bind("mouseleave", function(event) {
						timerFermeture = setTimeout( function() { 
							close(self.meInfobulle);
							clearTimeout(timerFermeture);
							timerFermeture = null;
						}, options.timeFermeture);
					});
				}
	
				// On sauvegarde les params de la fenêtre ouverte
				self.id = me.paramsInfobulleOpen($(selector), message, options, callback, meInfobulle);

			});

			// Création de l'évènement de fermeture
			if(options.closerEvent != null) {
				$(selector).unbind(options.closerEvent);
				$(selector).bind(options.closerEvent, function(event) {
					if(options.ciblePosition == "layer") {
						if(timerFermeture) {
							clearTimeout(timerFermeture);
							timerFermeture = null;
						}
						timerFermeture = setTimeout( function() { 
							close(self.meInfobulle);
							clearTimeout(timerFermeture);
							timerFermeture = null;
						}, options.timeFermeture);
					} else {
						close(self.meInfobulle);
					}
				});
			}

		} else if(options.openerEvent == "click") {

			if(isSmartPhone) {
				var specialOpenerEvent = " touchestart";
			} else {
				var specialOpenerEvent = "";
			}

			var eventFermeture = function() {
				if(meinfobulle_autoriseFermetureClick) {
					close(self.meInfobulle);
					meinfobulle_selectorOuvert = null;
				}
			};

			var eventOuverture = function() {
				open();
				meinfobulle_selectorOuvert = selector;
				$(self.meInfobulle).unbind("mouseenter");
				$(self.meInfobulle).bind("mouseenter", function(){
					meinfobulle_autoriseFermetureClick = false;
				});
				
				$(self.meInfobulle).unbind("mouseleave");
				$(self.meInfobulle).bind("mouseleave", function(){
					meinfobulle_autoriseFermetureClick = true;
				});

				if(self.meInfobulleLienFermer) {
					$(self.meInfobulleLienFermer).unbind("mouseover");
					$(self.meInfobulleLienFermer).bind("mouseover", function(){
						meinfobulle_autoriseFermetureClick = true;
					});
				}

				// On sauvegarde les params de la fenêtre ouverte
				self.id = me.paramsInfobulleOpen($(selector), message, options, callback, meInfobulle);
			};

			if(!meinfobulle_eventClickDocumentAttribue) {
				meinfobulle_eventClickDocumentAttribue = true;
				$(document).bind(options.openerEvent+specialOpenerEvent, function(event) {
					
					for(var a in meinfobulle_listeSelectors) {
						var parentFound = false;
						if ($(event.target).attr('id') == $(meinfobulle_listeSelectors[a].selector).attr('id')) {
							parentFound = true;
						}
						if(!parentFound) {
							$(event.target).parents().each(function() {
								if($(this).attr('id') == $(meinfobulle_listeSelectors[a].selector).attr('id')) {
									parentFound = true;
								}
							});
						}
						if (!parentFound) {
							// Si l'infobulle ouverte est celle-ci on la ferme
							if(meinfobulle_selectorOuvert == meinfobulle_listeSelectors[a].selector || meinfobulle_selectorOuvert == "null") {
								if(meinfobulle_autoriseFermetureClick) {
									meinfobulle_listeSelectors[a].fermeture.call();
								}
							}
						}
					}
				});
			}

			$(selector).bind(options.openerEvent+specialOpenerEvent, function(event){
				if(meinfobulle_selectorOuvert == selector) {
					eventFermeture();
				} else {
					eventOuverture();	
				}
			});

			for(var a in meinfobulle_listeSelectors) {
				if(meinfobulle_listeSelectors[a].selector == selector) {
					meinfobulle_listeSelectors[a] = "";
				}
			}
			meinfobulle_listeSelectors.push( { selector : selector, fermeture : eventFermeture, ouverture : eventOuverture, group : options.group } );

		}

	};


	$.fn.meinfobulleclose = function(selector, message, options, callback, meInfobulle) {
		
		if($me.globals.infobulle.open == 1) {
			
			//meInfobulle.remove();
			//$me.globals.infobulle.open = 0;
			meInfobulle.fadeOut(options.fadeout, function() {
				// Desctruction des layers
				meInfobulle.remove();

				// L'infobulle est fermée
				$me.globals.infobulle.open = 0;
			});

		}

	};

}(jQuery));
