/*
 * jQuery Simple Tooltip 0.9.1
 * Copyright (c) 2009 Pierre Bertet (pierrebertet.net)
 * Licensed under the MIT (MIT-LICENSE.txt)
 *
*/
(function(j$){
	// simpletooltip
	j$.fn.simpletooltip = function(settings) {
		
		var options = j$.extend({
			hideOnLeave: true,
			margin: 5,
			showEffect: true,
			hideEffect: true,
			click: false,
			hideDelay: 0,
			showDelay: .1,
			showCallback: function(){},
			hideCallback: function(){},
			customTooltip: false,
			customTooltipCache: true
		}, settings);
		
		this.each(function () {
			
			// Get and hide tooltip
			if (! j$.isFunction(options.customTooltip)) {
				j$(this).data("j$tooltip", getTooltip(this).hide());
			}
			
			if (options.click) {
				j$(this).bind("click", {"options": options, "target": this}, openTooltip);
			}
			else {
				var tipTimeOut;
				
				j$(this)
				// On mouseenter, init delay
				.bind("mouseenter", {"options": options, "target": this}, function(e) {
					var mouseEvent = e;
					
					tipTimeOut = window.setTimeout(function() {
						openTooltip(mouseEvent);
					}, (options.showDelay * 1000));
				})
				// On mouseleave, reset delay
				.bind("mouseleave", function() {
					window.clearTimeout(tipTimeOut);
				});
			}
			
		});
		
		return this;
	};
	
	function getTooltip(target) {
		
		// Anchor only
		var currentHrefMatch = j$(target).attr("href").match(/#.+/);
		if (!!currentHrefMatch){
			var j$tooltip = j$(currentHrefMatch[0]);
		}
		
		return j$tooltip;
	};
	
	function initTooltip(j$tooltip) {
		
		j$tooltip
		
		// Append to body
		.appendTo(document.body)
		
		// Store dimensions
		.data("width", j$tooltip.outerWidth())
		.data("height", j$tooltip.outerHeight())
		
		// Set CSS
		.css({"position": "absolute", "zIndex": "9998", "display": "none"})
		
		// Close tooltip btn
		.find("a[rel=close]").click(function (e) {
			e.preventDefault();
			j$tooltip.trigger("hide");
		}).end()
		
		// Init ok.
		.data("init", true);
	};
	
	function openTooltip(e){
		
		if (e.type == "click") {
			e.preventDefault();
		}
		
		var opts = e.data.options;
		
		var j$target = j$(e.data.target);
		
		// Custom tooltip
		if (!opts.customTooltipCache && j$target.data("j$tooltip")) {
			j$target.data("j$tooltip").remove();
			j$target.data("j$tooltip", false);
		}
		
		if (!j$target.data("j$tooltip")) {
			j$target.data("j$tooltip", j$(opts.customTooltip(j$target.get(0))));
		}
		
		var j$tooltip = j$target.data("j$tooltip");
		
		if (!j$tooltip.data("init")) {
			initTooltip(j$tooltip);
		}
		
		var winWidth = j$(window).width();
		var winHeight = j$(window).height();
		var winOffsetY = j$(window).scrollTop();
		var winOffsetX = j$(window).scrollLeft();
		
		// Remove show / hide triggers
		j$tooltip.unbind("show").unbind("hide");
		
		// Show
		if (opts.showEffect && ( opts.showEffect.match(/^fadeIn|slideDown|showj$/) ) ) {
			j$tooltip.bind("show", function(){
				j$tooltip[opts.showEffect](200);
				opts.showCallback(j$target[0], this);
			});
		}
		else {
			j$tooltip.bind("show", function(){
				j$tooltip.show();
				opts.showCallback(j$target[0], this);
			});
		}
		
		// Hide
		if (opts.hideEffect && ( opts.hideEffect.match(/^fadeOut|slideUp|hidej$/) ) ) {
			j$tooltip.bind("hide", function(){
				opts.hideCallback(j$target[0], this);
				j$tooltip[opts.hideEffect](200);
			});
		}
		else {
			j$tooltip.bind("hide", function(){
				opts.hideCallback(j$target[0], this);
				j$tooltip.hide();
			});
		}
		
		// Initial tooltip position
		var tooltipPosX = e.pageX - (j$tooltip.data("width")/2);
		var tooltipPosY = e.pageY - (j$tooltip.data("height")/2);
		
		// Replace tooltip position
		if (tooltipPosX < winOffsetX + opts.margin) { // Left
			tooltipPosX = winOffsetX + opts.margin;
		} else if (tooltipPosX + j$tooltip.data("width") > (winOffsetX + winWidth - opts.margin)) { // Right
			tooltipPosX = winOffsetX + winWidth - j$tooltip.data("width") - opts.margin;
		}
		
		if (tooltipPosY < winOffsetY + opts.margin) { // Top
			tooltipPosY = winOffsetY + opts.margin;
		} else if (tooltipPosY + j$tooltip.data("height") > (winOffsetY + winHeight - opts.margin)) { // Bottom
			tooltipPosY = winOffsetY + winHeight - j$tooltip.data("height") - opts.margin;
		}
		
		// Delay
		if (opts.hideDelay > 0 && opts.hideOnLeave) {
			var timer;
			j$tooltip.hover(
				function(){
					window.clearTimeout(timer);
				},
				function(){
					timer = window.setTimeout(function(){
						j$tooltip.trigger("hide").unbind("mouseenter, mouseleave");
					}, opts.hideDelay * 1000);
				}
			);
		}
		
		// No delay
		else if (opts.hideOnLeave){
			j$tooltip.bind("mouseleave", function(){
				j$tooltip.trigger("hide").unbind("mouseleave");
			});
		}
		
		// Apply CSS and show
		j$tooltip
			.css({"left": tooltipPosX + "px", "top": tooltipPosY + "px"})
			.trigger("show");
		
	};
})(jQuery);
