/*
 * 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_max_width=650;			// Ancho máximo.
	var tooltip_max_height=500;			// 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="";
		caller.url=false;
		caller.domid=false;
		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]";
					}
			}
		// Contenido de un bloque dom
			var ids_encontradas=title.match(/(\[id\=[^\]]*\])/g); // [id=]
			if (ids_encontradas!=null) {
				// Usamos la primera id encontrada como id
				caller.domid=ids_encontradas[0].replace(/\[id\=([^\]]*)\]/g,"$1");
				//console.log(caller.domid);
				caller.t=title.split(ids_encontradas[0]).join($("#"+caller.domid).html()); // Sustituimos en el título la url por [url]
				$("#"+caller.domid).remove();
			}
	}
	// 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-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;
					});
				}
		
		// Si es el contenido de un dom, lo usamos
				if (caller.domid!="") {
					jtooltip.addClass('domid');
					//jtooltip.find(".txt").html($("#"+caller.domid).html()); // usamos el contenido del dom. 
				}
				
		// 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();
	});
