﻿//
// create closure
//
(function($) {
    
	var tooltipWrapper;
	var tooltip;
	var tooltipComponents = {};
	
	function createTooltipDiv(id){
		tooltipComponents[id] = $("<div/>").attr("id", "tooltip-" + id).appendTo(tooltip);
	}
	
    function initTooltip(){
        tooltipWrapper = $("<div/>").attr("id", "tooltip-wrapper").appendTo(document.body);
	    tooltip = $("<div/>").attr("id", "tooltip").hide().appendTo(tooltipWrapper);
	    createTooltipDiv("n");
	    createTooltipDiv("ne");
	    createTooltipDiv("e");
	    createTooltipDiv("se");
	    createTooltipDiv("s");
	    createTooltipDiv("sw");
	    createTooltipDiv("w");
	    createTooltipDiv("nw");
	    createTooltipDiv("content");
    }
    
	// plugin definition
	$.fn.tooltip = function(options) {
		// build main options before element iteration
		var opts = $.extend({}, $.fn.tooltip.defaults, options);
		
		if(!$("#tooltip").length){
		    initTooltip();
		}
		
		var linkHover = false;
		var tooltipHover = false;
		
		var deferredHideOnMouseOutTimeout = null;
		
		function deferredHideOnMouseOut(){
			if(linkHover || tooltipHover){
				return;
			}
			
			tooltip.hide();
		}
		
		function deferHideOnMouseOut(){
			if(deferredHideOnMouseOutTimeout){
				clearTimeout(deferredHideOnMouseOutTimeout);
				deferredHideOnMouseOutTimeout = null;
			}
			
			deferredHideOnMouseOutTimeout = setTimeout(deferredHideOnMouseOut, 200);
		}
		
		tooltip.hover(function(){
			tooltipHover = true;
		}, function(){
			tooltipHover = false;
			
			deferHideOnMouseOut();
		});
		
		return this.each(function() {
			var link = $(this);
			
			// build element specific options
			//var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
			
			link.addClass("tooltip-link-" + opts.theme);
			
			var markup = link.attr(opts.attributeForDescription);
			
			// cache markup for later use (in table popups)
			if(markup != ""){
				link.attr(opts.attributeForDescription, "");
    			
			    if(markup == ""){
				    return;
			    }
    			
			    // call our format function
			    markup = $.fn.tooltip.format(markup);
    			
			    link[0].description = markup;
			}
			
			link.hover(function(){
				linkHover = true;
				
				var offset = link.offset();
				
				tooltip.css("left", -9999 + "px");
				tooltip.css("top",  -9999  + "px");
				
				tooltip.removeClass();
			    tooltip.addClass("tooltip-" + opts.theme);
				
				tooltip.show();
				
				tooltipComponents["content"].html(link[0].description);
				
				if(opts.beforeRender){
				    opts.beforeRender.apply(link);
				}
				
				tooltipComponents["n"].css("width", tooltipComponents["content"].width() + "px");
				tooltipComponents["s"].css("width", tooltipComponents["content"].width() + "px");
				tooltipComponents["w"].css("height", tooltipComponents["content"].height() + "px");
				tooltipComponents["e"].css("height", tooltipComponents["content"].height() + "px");
				
				if(opts.position){
				    opts.position.apply(link);
				}
			},function(){
				linkHover = false;
			    
				deferHideOnMouseOut();
			});
		});
	};
	
	// define and expose our format function
	$.fn.tooltip.format = function(txt) {
		return '' + txt + '';
	};
	
	// plugin defaults
	$.fn.tooltip.defaults = {
		theme: 'basic',
		attributeForDescription:"title",
		position:function(){
		    var link = $(this);
			var offset = link.offset();
			var tooltip = $("#tooltip");
			tooltip.css("left", (offset.left + ((link.width() - tooltip.outerWidth())/2)) + "px");
			tooltip.css("top", (offset.top + link.height()) + "px");
		},
		beforeRender: null
	};
	
	// end of closure
})(jQuery);
