/*
 * Tooltip script 
 * written by xplorastudios
 * http://www.xplorastudios.com
 * 
 * v.1.0.4
 * 
 */
 

/* CONFIG */
	var tooltip_position="top";			// Posición por defecto 
	var tooltip_alignment="center";		// Alineación por defecto 
	var tooltip_time=200; 				// timeout para mostrar el tooltip
	var tooltip_time_delayed=500; 		// timeout para mostrar el tooltip
	var tooltip_time_sdelayed=1000; 	// timeout para mostrar el tooltip
	var tooltip_time_fast=50; 			// timeout para mostrar el tooltip
	var tooltip_max_width=500;			// Ancho máximo.
	var tooltip_max_height=450;			// Alto máximo.
	var tooltip_body_margin=20;  		// Márgen mínimo en el body
	var tooltip_timeoutInstance=false;	// instancia del timeout
	var tooltip_timeoutInstanceClear=false;	// instancia del timeout
	var tooltip_active=false;
	var tooltip_active_ajax=false;
	var tooltip_active_iframe=false;
	var tooltip_debug=false;			// Debug de tooltip, si se establece true, no se eliminan los tooltips (se quedan abiertos)
	
// Eventos principales
this.tooltip = function(){	
	// Eventos
		$(".tooltip").live("mouseover",function(e){
			processTooltip(this);	// Procesamos caller para obtener el título y eliminarlo si aun no lo tiene procesado
			
			// Si el mouseover es desde un tooltip hoverable no mostramos nada, sino que limpiamos el timeout de limpieza
			if ($(this).hasClass('tooltip-active')) {
				if (tooltip_timeoutInstanceClear) {
					clearTimeout(tooltip_timeoutInstanceClear);
					tooltip_timeoutInstanceClear=false;
				}
				return;
			}
			
			// Mostramos sólo si el tooltip no se debe lanzar en el onclick 
			if (!$(this).hasClass("tooltip-onclick") && !tooltip_timeoutInstance) {
				showTooltip(this,e);
			}
		});
		$(".tooltip").live("click",function(e){
			processTooltip(this);	// Procesamos caller para obtener el título y eliminarlo si aun no lo tiene procesado
			
			if ($(this).hasClass("tooltip-active")) {
				clearTooltips();
			} else {
				if ($(this).hasClass("tooltip-onclick")) {
					$(this).addClass('tooltip-instant'); // Para que se abra inmediatamente
					showTooltip(this,e);
					// Cortamos el bubbling.
					return false;
				}
			}
			
			if ($(this).attr('href')=="") return false; // Si no hay vínculo cortamos el bubbling.
				
		});
	    $(".tooltip:not(.tooltip-static)").live("mouseout",function(e){
	    		// Si hay pendiente mostrar un tooltip, cancelamos la instancia
	    		if (tooltip_timeoutInstance) {
	    			clearTimeout(tooltip_timeoutInstance); // Si hay algo pendiente de mostrar, ya no lo mostramos
	    			tooltip_timeoutInstance=false;
	    		} else {
	    			// Si no hay pendiente, es eliminamos la instancia de borrado si hay alguna y creamos una nueva para borrar
	    			if (tooltip_timeoutInstanceClear) {
	    				clearTimeout(tooltip_timeoutInstanceClear);
	    				tooltip_timeoutInstance=false;
	    			}
			    	tooltip_timeoutInstanceClear=setTimeout(
						function() {
							clearTooltips();
						},
						200
					);
	    		}
	    });	
	    $("#tooltip.tooltip-hoverable").live("mouseover",function(e){
	    	if (tooltip_timeoutInstanceClear) clearTimeout(tooltip_timeoutInstanceClear);
	    	tooltip_timeoutInstanceClear=false;
		});
	    $("#tooltip.tooltip-hoverable:not(.tooltip-static)").live("mouseout",function(e){
	    	if (!tooltip_timeoutInstanceClear) {
		    	tooltip_timeoutInstanceClear=setTimeout(
					function() {
						clearTooltips();
					},
					200
				);
	    	}
	    });
};
// Procesa el título de un tooltip
this.processTooltip = function(caller) {
	if (typeof caller.title=="undefined" || caller.title=="" || caller.title==false) return;
	title=caller.title.split("|").join("<br/>");// Convertimos barras en saltos de línea.
	title=title.split("<s>").join("<small>").split("</s>").join("</small>");
	title=title.split("<c>").join("<p class='center'>").split("</c>").join("</p>");
	title=title.split("<l>").join("<p class='left'>").split("</l>").join("</p>");
	title=title.split("<r>").join("<p class='right'>").split("</r>").join("</p>");
	caller.t=title;
	caller.title="";
	jcaller=$(caller);
	// Iframe o Ajax // Asignamos una propiedad con la url
		if (jcaller.hasClass("tooltip-iframe") || jcaller.hasClass("tooltip-ajax")) {
			// Buscamos si tiene [url=http://url] en el título, si no, usamos todo el título como url
				var urls_encontradas=title.match(/(\[url\=[^\]]*\])/g); // [url=]
				if (urls_encontradas!=null) {
					// Usamos la primera url encontrada como url
					caller.url=urls_encontradas[0].replace(/\[url\=([^\]]*)\]/g,"$1");
					caller.t=title.split(urls_encontradas[0]).join("[url]"); // Sustituimos en el título la url por [url]
				} else {
					// Usamos titulo como url
					caller.url=title;
					caller.t="[url]";
				}
		}
}
// Borra tooltips si hay activos
this.clearTooltips = function() {
	if (tooltip_active) {
		$(".tooltip.tooltip-active").removeClass("tooltip-active");
		if (!tooltip_debug) $("#tooltip").remove();
		tooltip_active=false;
	}
	// Si queda alguna instancia abierta del proceso de limpiado, la eliminamos
	if (tooltip_timeoutInstanceClear) {
		clearTimeout(tooltip_timeoutInstanceClear);
		tooltip_timeoutInstanceClear=false;
	}
	if (tooltip_active_ajax) {
		tooltip_active_ajax.abort();
	}
}
// Lanza el timeout para mostrar el tooltip o lo muestra directamente
this.showTooltip = function (caller,e) {
	var self=caller;
	// Si es instantáneo lo mostramos ya, si no, creamos un timeout que lo cree
		if ($(self).hasClass('tooltip-instant')) {
			if (tooltip_timeoutInstance) clearTimeout(tooltip_timeoutInstance); // Eliminamos el timeout si hay
			displayTooltip(self,e);
		} else {
			if ($(self).hasClass('tooltip-fast')) {
				if (!tooltip_timeoutInstance) {
					tooltip_timeoutInstance=setTimeout(
						function() {
							displayTooltip(self,e);
						},
						tooltip_time_fast
					);
				}
				return
			} 
			if ($(self).hasClass('tooltip-delayed')) {
				if (!tooltip_timeoutInstance) {
					tooltip_timeoutInstance=setTimeout(
						function() {
							displayTooltip(self,e);
						},
						tooltip_time_delayed
					);
				}
				return
			} 
			if ($(self).hasClass('tooltip-sdelayed')) {
				if (!tooltip_timeoutInstance) {
					tooltip_timeoutInstance=setTimeout(
						function() {
							displayTooltip(self,e);
						},
						tooltip_time_sdelayed
					);
				}
				return
			}
			if (tooltip_time==0) {
				if (tooltip_timeoutInstance) clearTimeout(tooltip_timeoutInstance); // Eliminamos el timeout si hay
				displayTooltip(self,e);
			} else {
				if (!tooltip_timeoutInstance) {
					tooltip_timeoutInstance=setTimeout(
						function() {
							displayTooltip(self,e);
						},
						tooltip_time
					);
				}
				return
			}
		}
}
// Muestra el tooltip
this.displayTooltip = function(caller,e){
	// Eliminamos el timeout de mostrar el tooltip
		if (tooltip_timeoutInstance) {
			clearTimeout(tooltip_timeoutInstance);
			tooltip_timeoutInstance=false;
		}
	
	// Ocultamos otros tooltips si hay alguno abierto
		clearTooltips();
		
	// Título lo copiamos a un alternativo y lo eliminamos para evitar el hover por defecto
		title=caller.t;
		if (title=="") return;

	// Variables
		var self=caller;
		var position=tooltip_position;
		var alignment=tooltip_alignment;
		var found=false;
		jcaller=$(caller);

	// Determinamos posición y alineamiento
			if ($(caller).hasClass("tooltip-top")) {
				position="top";
			}
			if ($(caller).hasClass("tooltip-bottom")) {
				position="bottom";
			}
			if ($(caller).hasClass("tooltip-center")) {
				alignment="center";
			}
			if ($(caller).hasClass("tooltip-left")) {
				alignment="left";
			}
			if ($(caller).hasClass("tooltip-right")) {
				alignment="right";
			}
	
	// Clases adicionales
	// Si tiene clases "tooltip-class-[CLASE]", se las añadiremos al diálogo del tooltip
			var clases_encontradas=jcaller.attr("class").match(/tooltip-class-([^\s])*/g); // Clases que contengan tooltip-class-XXXXXXX
			var clase="";
			if (clases_encontradas!=null) {
				for(i=0;i<clases_encontradas.length;i++ ) {
					clase+=clases_encontradas[i].split("tooltip-class-").join("")+" ";
				}
			}
					
	// Hoverable
			if ($(caller).hasClass("tooltip-hoverable")) clase+="tooltip-hoverable";
	// Static
			var tooltip_static=false;
			if ($(caller).hasClass("tooltip-static")) {
				tooltip_static=true;
				clase+="tooltip-static";
			}
				
	// Creamos el tooltip
			jcaller.addClass("tooltip-active"); // Añadimos una clase activa
			if (tooltip_static) {
				$("body").append("<div id='tooltip' class='"+clase+"'><div class='pointer'></div><a class='close' href='' onclick='clearTooltips();return false;'></a><div class='outer'><div class='inner'><div class='txt'>"+ title +"</div></div></div></div>");
			} else {
				$("body").append("<div id='tooltip' class='"+clase+"'><div class='pointer'></div><div class='outer'><div class='inner'><div class='txt'>"+ title +"</div></div></div></div>");
			}
			var jtooltip=$("#tooltip");
			tooltip_active=true;
			
	// Si es ajax, lo cargamos (usando el atributo url que asignamos anteriormente)
			if (jcaller.hasClass("tooltip-ajax") && caller.url!="") {
				jtooltip.addClass('ajax');
				jtooltip.find(".txt").addClass('loading').html("");
				tooltip_active_ajax=$.ajax({
					type: "GET",
					url: caller.url,
				   	success: function(respuesta){
						jtooltip.find(".txt").removeClass('loading').html(title.split("[url]").join(respuesta));
						positionTooltip(e,jcaller,jtooltip,position,alignment,0); // Reposicionamos
						tooltip_active_ajax=false;
					},
				   	error: function(){
						jtooltip.find(".txt").removeClass('loading').html(title.split("[url]").join("No se ha podido cargar la información de la <b><a href='"+caller.url+"'>url</a></b>"));
						jtooltip.addClass('hoverable'); // si no la tenia ya Para poder hacer click en la url
						positionTooltip(e,jcaller,jtooltip,position,alignment,0); // Reposicionamos
						tooltip_active_ajax=false;
					}
				});
			}
			
	// Si es iframe, lo cargamos (usando el atributo url que asignamos anteriormente)
			if (jcaller.hasClass("tooltip-iframe") && caller.url!="") {
				jtooltip.addClass('iframe');
				jtooltip.find(".txt").addClass('loading').html("<span class='tmp'>"+title.split("[url]").join("<iframe src='"+caller.url+"' id='tooltip-iframe' ></iframe>")+"</span>");
				var myiframe = $("#tooltip-iframe");
				myiframe.css({visibility:"hidden"});
				jtooltip.find(".txt .tmp").css({visibility:"hidden"}); // Ocultamos el código adicional anterior y posterior si hay
				tooltip_active_iframe=true;
				myiframe.load(function() {
					if (myiframe.get(0).contentDocument) {
						myiframecontent=$(myiframe.get(0).contentDocument.body);
					} else {
						myiframecontent=$(myiframe.get(0).contentWindow.document.body);
					}
					myiframecontent.css({margin:"0",padding:"0"}); // Eliminamos el padding y el margin del iframe si tiene
					myiframe.height(myiframecontent.outerHeight() > myiframecontent.get(0).scrollHeight ? myiframecontent.outerHeight():myiframecontent.get(0).scrollHeight );
					myiframe.width(myiframecontent.outerWidth() > myiframecontent.get(0).scrollWidth ? myiframecontent.outerWidth():myiframecontent.get(0).scrollWidth );
					myiframe.css({visibility:"visible"});
					jtooltip.find(".txt .tmp").css({visibility:"visible"}); // Mostramos el código adicional que ocultamos
					jtooltip.find(".txt").removeClass('loading');
					positionTooltip(e,jcaller,jtooltip,position,alignment,0); // Reposicionamos
					tooltip_active_iframe=false;
				});
			}
			
	// Posicionamos el tooltip con un pequeño timeout para que de tiempo a que el navegador renderice el dialogo
			positionTooltip(e,jcaller,jtooltip,position,alignment,0);

};
// Reposiciona el tooltip para que encuadre en el documento
this.positionTooltip = function(e,jcaller,jtooltip,position,alignment,call_number){
	// Reset de posicionamiento de dialogo y pointer
		jtooltip.removeAttr("style");
		jpointer=jtooltip.find(".pointer"); // Acceso al pointer
		jpointer.removeAttr("style");
		//jtooltip.css({visibility:"hidden"});
	
	// Clases para el dialogo
		jtooltip.removeClass("mouse top bottom left right center").addClass(position).addClass(alignment);
		
	// Clases para el contenedor del tooltip
		// Ya no hacemos esto para evitar que se recuerde la posición, de ésta forma se intentará usar siempre la que se haya especificado o descubrirla automáticamente.
		//jcaller.removeClass("tooltip-top tooltip-bottom").addClass("tooltip-"+position);
		//jcaller.removeClass("tooltip-left tooltip-center tooltip-right").addClass("tooltip-"+alignment);
	
	// Si el texto sobrepasa el ancho máximo le damos un ancho nuevo.
		if ( jtooltip.find(".txt").outerWidth()>tooltip_max_width ) {
			jtooltip.find(".txt").css({width: tooltip_max_width+"px"});
		}	
	// Si el texto sobrepasa el alto máximo le damos un alto nuevo.	
		if ( jtooltip.find(".txt").outerHeight()>tooltip_max_height ) {
			jtooltip.find(".txt").css({height: tooltip_max_height+"px"});
		}	
		
	// Dimensiones y posiciones (Despues de asignar las clases)	
		callerPos=jcaller.offset();													// top, left
		callerDim={width: jcaller.outerWidth(),height: jcaller.outerHeight()}; 		// width, height
		tooltipDim={width: jtooltip.outerWidth(),height: jtooltip.outerHeight()};	// width, height
		
	// Ancho del pointer (Coincide con el ancho del caller del tooltip, pero si el caller es más grande que el tooltip, lo igualamos a la dimensión del tooltip para que no se salga del mismo)
		if (callerDim.width>tooltipDim.width) {
			jpointer.css({
				width: tooltipDim.width+"px"
			});
		} else {
			jpointer.css({
				width: callerDim.width+"px"
			});
		}
		pointerDim={width: jpointer.outerWidth(),height: jpointer.outerHeight()}; 
			
	// Posicionamiento  vertical
		if (position=="top") {
			jtooltip.css({
				top: (callerPos.top - tooltipDim.height) +"px"
			});	
			jpointer.css({
				bottom: "0px"
			});
		}
		if (position=="bottom") {
			jtooltip.css({
				top: (callerPos.top + callerDim.height) +"px"
			});		
			jpointer.css({
				top: "0px"
			});
		}
		
	// Posicionamiento  horizontal
		if (alignment=="left") {
			jtooltip.css({
				left: (callerPos.left) +"px"
			});	
			jpointer.css({
				left: "0px"
			});
		}
		if (alignment=="right") {
			jtooltip.css({
				left: (callerPos.left + callerDim.width - tooltipDim.width) +"px"
			});		
			jpointer.css({
				right: "0px"
			});
		}
		if (alignment=="center") {
			jtooltip.css({
				left: ( callerPos.left + (callerDim.width/2) - (tooltipDim.width/2 ) )+"px" // centramos
			});		
			jpointer.css({
				left: ((tooltipDim.width/2) - (pointerDim.width/2)) +"px"
			});
		}
		
	// Comprobamos bounds y si se excede alguno de ellos, decidimos la nueva posición y reposicionamos llamando a la misma función recursivamente.
			if (call_number==0) {
					//console.log("call "+call_number)
					// Dimensiones
						tooltipDim={width: jtooltip.outerWidth(),height: jtooltip.outerHeight()};
						tooltipPos=jtooltip.offset();	// top, left
						docDim={width:  $("body").outerWidth(),height: $("body").outerHeight()};
						windowDim={width: $(window).width(),height: $(window).height()};
						scrollPos={left: $(window).scrollLeft(),top: $(window).scrollTop()};
					// Límites	
						t=scrollPos.top + tooltip_body_margin;
						b=scrollPos.top + windowDim.height - tooltip_body_margin;
						r=scrollPos.left + windowDim.width - tooltip_body_margin;
						l=scrollPos.left + tooltip_body_margin;
						//console.log("cuadro t: "+t+" / " + "r: "+r+" / " + "b: "+b+" / " + "l: "+l);  
						//console.log("toolti t: "+tooltipPos.top+" / " + "r: "+(tooltipPos.left+tooltipDim.width)+" / " + "b: "+(tooltipPos.top+tooltipDim.height)+" / " + "l: "+tooltipPos.left);  
						reposicionar=false;
					// Superior
						if (tooltipPos.top<t) {
							if (position=="top") {
								position="bottom";
								reposicionar=true;
							}
						}
					// Inferior
						if ((tooltipPos.top+tooltipDim.height)>b) {
							if (position=="bottom") {
								position="top";
								reposicionar=true;
							}
						}
					// Izquierdo
						if (tooltipPos.left<l) {
							if (alignment!="left") {
								alignment="left";
								reposicionar=true;
							}
						}
					// Derecho
						if ((tooltipPos.left+tooltipDim.width)>r) {
							if (alignment!="right") {
								alignment="right";
								reposicionar=true;
							}
						}
						
					if (reposicionar) {
						positionTooltip(e,jcaller,jtooltip,position,alignment,(call_number+1));
						return;
					}
			}
			//jtooltip.css({visibility:"visible"});	
}

// starting the script on page load
$(document).ready(function(){
	tooltip();
});
