/*
liveToolTip - Plugin JQuery
par Eric BATARSON - eric.batarson@gmail.com - http://www.eric-batarson.fr
Description :
plugin permettant de générer une bulle d'information sur un élément d'une page web. N'ayant pas trouvé de plugin fonctionnant sur du contenu généré en ajax, j'ai décidé de le développer moi-même!
Attention, ce plugin requière JQuery 1.4.x minimum. J'utilise en effet la fonction live() permettant de répercuter les événements aux données chargées après le DOM.
N'hésitez pas à me contacter pour toute question, ou suggestion d'amélioration.

Je ne soumets ce plugin à aucune licence, vous pouvez en faire l'utilisation que vous en voulez! Utilisez-le si vous le trouvez utile et faites-moi un retour, ça fait tjrs plaisir ;)

Utilisation :
// exemple :
$(function() {
	
	// Tous les éléments existants ou créés via ajax ayant la classe tip seront impactés
	$(".tip").liveToolTip({options});
	
});

options :
- offsetY 	:	permet de définir à quelle distance se place la div de tooltip, sur l'axe vertical
- cssDiv	: 	permet de définir la classe css de la div tooltip	

Style :
A intégrer dans un css ou dans une balise <style> : 
.tooltip {
	display:none;
	background:transparent url(toolTip.png);
	background-position:0 120px;
	font-size:12px;
	height:70px;
	width:160px;
	padding:25px;
	color:#fff;
}

Image : tooltip.png

Version : 1.0

Version 1.1 :
Correctif sur le positionnement à gauche et à droite de manière à ce que la bulle soit toujours visible quelque soit l'endroit ou est placé le curseur


*/

(function($){
        // définition du plugin jQuery 
       jQuery.fn.extend({
   				findPos : function() {
     			  obj = jQuery(this).get(0);
     			  var curleft = obj.offsetLeft || 0;
       				var curtop = obj.offsetTop || 0;
       				while (obj = obj.offsetParent) {
                curleft += obj.offsetLeft;
                curtop += obj.offsetTop;
      			 }
       return {x:curleft,y:curtop};
   }
});
        $.fn.liveToolTip = function(opt) {
                // Options du plugin
                var options = $.extend({
					offsetY		: 0,
					offsetX		: 0,
					cssDiv 		: "tooltip",
					effets		: true,
					top			:0,
					left		:0,
					search		:null,
					titleArray	:null,
					actionIn	:"mouseover",
					actionOut	:"mouseout",
					position	:null,
					track		:false
				}, opt);
				
                if(options.search ){
					
					options.titleArray=seachTitle(options.search);
				
				}
                // On recherche les évènements mouseenter et mouseleave uniquement
				
				
				return this.live("mouseover mouseout focus click blur", function(e){
						// Déclaration des variables 
						// Type d'événement mouse capturé : mouseover, mouseleave, mouseout...
						
						var typeEvt 		= e.type;					
                        var tip 			= $(this);
						var liveTooltip		=null;
						// On entre sur l'élément? On va afficher la tooltip!
						var regin=new RegExp(options.actionIn);
						if (regin.test(typeEvt)) {
							// On supprime la bubule par défaut du navigateur
						if((typeof(e.pageY)=='undefined') || (typeof(options.track)=='false'))   {
							p=tip.findPos();
							e.pageY=p.y;
							e.pageX=p.x;
						}
							if(options.titleArray){
									p=tip.findPos();
									e.pageY=p.y;
									e.pageX=p.x;
									this.TooltipContenu= options.titleArray[tip.attr('id')];
							}
							if (tip.attr('title').length) {
								// On prend soin d'en enregistrer le titre pour pouvoir le ré-afficher + tard
								this.TooltipContenu = tip.attr('title');
								tip.attr('title', "");
							}
							if(typeof(this.TooltipContenu)=='undefined'){return;}
							//divTip.remove();
							var divTip = $("#liveTooltip");
							// On va créer une div pour y afficher la tooltip si elle n'existe pas!
							if (divTip.length < 1) {
								var content = '<div id="liveTooltip"><div id="contenuToolTip"></div></div>';
								// On va ajouter la div au BODY de la page
								liveTooltip = $("body").append(content);
								// On enregistre l'objet créé
								divTip = $("#liveTooltip");
							}
							// On va supprimer les classes précédentes:
							var classesExistantes = divTip.attr('className');
							divTip.removeClass(classesExistantes);
							
							// On ajoute la classe css passée en paramètre
							divTip.addClass(options.cssDiv);
							
							// Suppression des effets en cours sur d'autres éléments
							divTip.stop(true, true);
							
							// On masque la div
							divTip.hide();
							
							// Hauteur et largeur de la div qui va être créée pour contenir la tooltip
							// Position css du background
							var cssBackgroundPos 	= "0px 0px";
							// Padding top dans le cas ou on a la bulle en dessous du texte
							var cssPaddingTop		= "0px";
							
							// Sous-div permettant de bien centrer le texte verticalement en cas de bulle en dessous du texte 
							var divTipContenu = $("#contenuToolTip");
							divTipContenu
								.empty()
								.html(this.TooltipContenu);
							var hDiv = divTip.outerHeight();
						    var lDiv = divTip.outerWidth();	
							// Calcul de la position de départ de la div 
							
							var posX = 	(e.pageX - (lDiv / 2) );
							var posY = 	(e.pageY - options.offsetY - (hDiv));
							//gestion de l'option position  
							if(options.position){
								var reg=new RegExp(" ");
								tblpos=options.position.split(reg);
									for(i=0;i<tblpos.length;i++){
										if(i<2){
										switch(tblpos[i].toLowerCase()){
											case 'top':
											posY = 	(e.pageY - options.offsetY - (hDiv));
											break;
											case 'bottom':
											posY = 	(e.pageY +tip.outerHeight()+ options.offsetY);
											break;
											case 'center':
											if(i==0){posY =(e.pageY +(tip.outerHeight()/2)+ options.offsetY-(hDiv/2));}
											if(i==1){posX =(e.pageX +(tip.outerWidth()/2)+ options.offsetX -(lDiv/2) );}
											break;
											case 'left':
											posX = (e.pageX - options.offsetX-lDiv);
											break;
											case 'right':
											posX = (e.pageX +tip.outerWidth()+ options.offsetX);
											break;
										}
									}
									}
							}
						//gestion postion fixe 
						if(options.left!=0){
							var posX=options.left;	
							}	
						if(options.top!=0){
							var posY=options.top;	
							}
						//gestion des depassements d'ecran
						if (posX < 0) {
						// On dépasse sur le côté gauche? on va recaler tout ça
							posX = 0;
						}
						var Wsize=getWindowSize();
						if (posX + lDiv> $(window).width()) {
						// On dépasse sur le côté droit ? on va recaler tout ça
							posX = $(window).width() - lDiv;
						}					
						// Gestion du bornage en hauteur
						if (posY < $(window).scrollTop()) {
									// On est un peu trop haut? On va afficher la tooltip sous le texte sélectionné
							posY = ( $(window).scrollTop() );
									// Et on change d'image :)
								cssBackgroundPos 	= "0px " + hDiv.toString() + "px";
								cssPaddingTop		= "20px";
						}
						if (posY+hDiv >( $(window).scrollTop()+Wsize.Height)) {
								posY=$(window).scrollTop()+Wsize.Height-hDiv;
						}
						divTipContenu.css("padding-top", cssPaddingTop);
						// On affecte les paramètres CSS indispensables
						divTip
							.css("background-position", cssBackgroundPos)
							.css("position", "absolute")
							.css("top", posY + "px")
					        .css("left", posX + "px");
								
							if (options.effets) {
								divTip.slideDown(200);
							}
							else {
								divTip.show();
							}
							divTip.live("click",function(){
								$(this).remove();
								})
						}
						// On sort de la zone? On supprime la tooltip
						var regout=new RegExp(options.actionOut);
						if (regout.test(typeEvt)) {
							// Enregitrement de l'objet dans une variable
							var divTip = $("#liveTooltip");							
							// Récupération du title de l'élément
							tip.attr('title', this.TooltipContenu);
							// On efface la div avec un effet fadeOut ou pas (svt option)
								if (options.effets) {
									divTip.slideUp(200);
								}
								else {
									divTip.hide();
								}																	
						}
                });
        // Permettre le chaînage par jQuery
       		
       		function seachTitle(findelem){
					switch (findelem){
						case 'label':
							ret=Array();
							tmp=null;
							$(findelem).each(function(){
								if($(this).attr('title')){
								tmp=true;
								ret[$(this).attr('for')]=$(this).attr('title');
								}
							});
							if(tmp){
							return ret;
							}else {
							return null;
							}
						break;
						default:
						return null;
					}
				}
       	function getWindowSize() {
			  var myWidth = 0, myHeight = 0;
			  if( typeof( window.innerWidth ) == 'number' ) {
			    //Non-IE
			    myWidth = window.innerWidth;
			    myHeight = window.innerHeight;
			  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
			    //IE 6+ in 'standards compliant mode'
			    myWidth = document.documentElement.clientWidth;
			    myHeight = document.documentElement.clientHeight;
			  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
			    //IE 4 compatible
			    myWidth = document.body.clientWidth;
			    myHeight = document.body.clientHeight;
			  }
			 return {Width:myWidth,Height:myHeight};
		}
        return this;
        };
})(jQuery)
