/**
 * @author ezdermam
 * @author ghosnf
 * @author strumb
 */
(function($) {
	$.fn.tooltip = function( options ) {
		var defaults = {
			id: "default-tooltip",	// ID of tool-tip popup
			contentSelector: "",	// where to clone content from
			contentTitle: false,	// use the selected element title tag as the pop-ups content (ie <[element] title="title of element"></[element]>)
			lockTo: "",				// lock element the pop-up to the "side" or "top"
			lockToElement: "",		// what element to lock the pop-up to
			followMouse: true,		// pop-up will follow the mouse while hovering the target element
			allowAccess: true, 		// allow access inside the Tooltip
			offsetX: 0,				// x-offset from the selected element (ie. the element this plug-in is applied to)
			offsetY: 5,				// x-offset from the selected element (ie. the element this plug-in is applied to) 
			allowFlip: true,		// allow the "flipped" class to be applied to the pop-up if the element is too close to the top or bottom
			delay: 500,				// delay in milisecconds before pop-up show up
			fixedPostion: "", 		// top-left, top-right, left-top, left-bottom, bottom-left, bottom-right, left-bottom, left-top
			openMethod: "hover", 	// what mouse event triggers the pop-up "hover" or "click"
			rolloverElementClass: ""// class name you want the slected elemet to have appended to it
		};
		
		var options = $.extend(defaults, options);
		
		var popUp = '<div id="' + options.id + '" style="z-index: 9999999;"><div class="arrow png"></div><div id="tooltip-content" class="content png"></div></div>';
		
		if ( $("#" + options.id).size() == 0 ){	$("body").append(popUp); }
		
		var container  = $("#" + options.id);
		var title      = "";
		var timer      = null;
		var delay      = null;
		var isOpening = false;
		var mouseEvent = options.openMethod == "hover" ? "mouseenter" : "click";
		
		this.each(function() {
			$(this).bind(mouseEvent,
				function(e) {
					
					e.stopPropagation(); // stop click from propagating through the DOM
					
					if ( !$("body").hasClass("tootipOpen") ){ // Clicking body hides the tooltip
						_open(container, $(this));
					} else {
						_close(container, $(this));
					}

					// Tooltip prevention
					$(this).find("img,a").removeAttr("title").removeAttr("alt");
					$(this).removeAttr("title");
 
					clearTimeout(delay);
					clearTimeout(timer);
					isOpening = false;
					
					if ( options.contentTitle == false ) {
						container.find(".content").empty();
						$(this).find(options.contentSelector).clone(true).appendTo( container.find(".content") ).show().parent().click( function(e){
							e.stopPropagation();
						});
					} else {
						title = $(this).attr("title");
						container.find(".content").html(title);
					}
					

					if ( options.allowAccess == true && mouseEvent == "mouseenter" ) {
						container.hover(function(e) {
							clearInterval(timer);
						},
						function(e) {
							_close(container);
							$(this).attr("title", title);
						});
					};
					
					_moveElement($(this), e, options);
				});
			
			
			if ( mouseEvent == "mouseenter" ) {
				$(this).mouseleave(
					function (e) {
						clearTimeout(delay);
						isOpening = false;
						if ( options.allowAccess == false ) {
							_close(container);
							$(this).attr("title", title);
						} else {
							timer = setTimeout(function() {
								_close(container);
								$(this).attr("title", title);
							}, options.delay);
						}
					}
				);
			}

			if ( options.followMouse == true ) {
				
				$(this).unbind("mousemove").mousemove(function (e) {
					_moveElement($(this), e, options);
				});
			}
		});
		
		function _open(container, mEle) {
			$(document).bind("click", function() { _close(container, mEle); });
			container.show();
			if ( options.rolloverElementClass != "" ){
				$("." + options.rolloverElementClass).removeClass(options.rolloverElementClass);
				mEle.addClass(options.rolloverElementClass);
			}
		}
		
		function _close(container, mEle) {
			$(document).unbind("click", function() { _close(container); });
			container.hide();
			if ( options.rolloverElementClass != "" ){
				mEle.removeClass(options.rolloverElementClass);
			}
		}

		function _moveElement(el, e, options) {
			var container = $("#" + options.id);
			var arrow     = container.find(".arrow");
			var top       = options.offsetY + e.pageY;
			var left      = options.offsetX + e.pageX;
			
			
			if( options.fixedPostion != '' && typeof( options.fixedPostion) === 'string'){
				switch (options.fixedPostion){ //top-left, top-right, left-top, left-bottom, bottom-left, bottom-right, left-bottom, left-top
					case 'top-left':
						arrow.addClass("left").removeClass("right");
						container.addClass("top").removeClass("bottom");
						break;
					case 'top-right':
						arrow.addClass("right").removeClass("left");
						container.addClass("top").removeClass("bottom");
						break
					case 'left-top':
						arrow.addClass("top").removeClass("bottom");
						container.addClass("left").removeClass("right");
						break
					case 'left-bottom':
						arrow.addClass("bottom").removeClass("top");
						container.addClass("left").removeClass("right");
						break
					case 'bottom-right':
						arrow.addClass("right").removeClass("left");
						container.addClass("bottom").removeClass("top");
						arrow.css("top", container.height()-2);
						break
					case 'bottom-left':
						arrow.addClass("left").removeClass("right");
						container.addClass("bottom").removeClass("top");
						arrow.css("top", container.height()-2);
						break
					case 'right-bottom':
						arrow.addClass("bottom").removeClass("top");
						container.addClass("right").removeClass("left");
						break
					case 'right-top':
						arrow.addClass("top").removeClass("bottom");
						container.addClass("right").removeClass("left");
						break
				}
			}
			
			if ( options.lockTo == "side" ) {
				if ( options.lockToElement.length == 0 ) {
					left = el.offset().left + el.width() + options.offsetX;
				} else {
					var subEl = el.find(options.lockToElement).eq(0);
					left = subEl.offset().left + subEl.width() + options.offsetX;
				}

				if ( top < el.offset().top ) {
					top = el.offset().top;
				}
			} else if ( options.lockTo == "top" ) {
				top = el.offset().top + options.offsetY;
				//left -= container.width() / 2;
				//arrow.css("left", (container.width() / 2) - (arrow.width() / 2));
			}

			if ( options.allowAccess == true && options.followMouse == true && options.lockTo != "side" && container.offset().top != 0 & top > container.offset().top ) {
				top = container.offset().top;
			}

			if ( options.allowFlip == true ) {
				if ( ((top + container.height()) + options.offsetY) > ($(window).scrollTop() + $(window).height()) ) {
					top = container.height() + arrow.height() + options.offsetY;
					container.addClass("flipped");
					arrow.css("top", container.height());
				} else {
					container.removeClass("flipped");
					arrow.css("top", 0);
				}

				if ( left >= ($(window).width() - container.width()) ) {
					left = $(window).width() - container.width();
					arrow.addClass("right").css("left", (e.pageX - left));
				} else {
					arrow.removeClass("right").css("left", 0);
				}
			}
			

			container.css({
				top: top,
				left: left
	        });
			
		}
	}
})(jQuery);