(function($) {
	$.fn.tooltip = function(options) {
		options = $.extend({}, $.fn.tooltip.defaults, options);
		
		this.each(function() {
			var tooltip = $(this);
			var tooltipContent = null;
			var content = this.title;
			var visible = false;
			var sequenceNumber = count;
			var id = 'tooltip-'+count++;
			var theTimeout = null;
			
			
			if (this.title) {
				tooltip.attr('title', '');
				content = '<span>'+content+'</span>';
			}
			
			tooltip.addClass('tooltip');
			$(document.body).bind('tooltip:hide', hideInstantly);
			
			tooltip.mouseenter(function() {
				currentSequenceNumber = sequenceNumber;
				if (visible) {
					$('#debug').prepend('tooltip.mouseenter '+ id+' visible <br/>');
					return;
				}
				$('#debug').prepend('tooltip.mouseenter '+ id+'<br/>');
				visible = true;

				$(document.body).trigger('tooltip:hide');
			
				setTimeout(function() {
				
				if (!visible)
					return;
				
				tooltipContent = $('#'+id);
				if (tooltipContent.length==0) {
					$(document.body).append('<div id="'+id+'" class="tooltip-content" style="display:none;"></div>');
					tooltipContent = $('#'+id);
				}
				tooltipContent.html(options.filter(content));
				tooltipContent.css({position:'absolute', visibility: 'hidden', display: 'inline', width: options.width});
				tooltipContent.css(options.style);
				var pos = tooltip.offset();
				tooltipContent.css({
					zIndex: count,
					left: pos.left+options.position.left*tooltip.height()-tooltipContent.width()*options.anchor.left + 'px',
					top: pos.top+options.position.top*tooltip.height()-tooltipContent.height()*options.anchor.top + 'px', 
					opacity:0, visibility: 'visible'
				});
				showTransition = {opacity: 1};
				showTransitionOptions = {duration: 300, complete: function() {
				}};
				tooltipContent.animate(showTransition, showTransitionOptions);
				
				tooltipContent.mouseenter(function() {
					$('#debug').prepend('tooltipcontent.mouseenter '+ id+'<br/>');
					if (theTimeout)
						clearTimeout(theTimeout);
						
					theTimeout =null;
						
					tooltipContent.mouseleave(function() {
						tooltipContent.unbind('mouseleave');
					
						$('#debug').prepend('tooltipcontent.mouseleave '+ id+'<br/>');
						tooltip.trigger('mouseleave');
//						hideInstantly();
					});
				});
				}, options.delay);
			});	
			function hideInstantly() {
				if (visible && tooltipContent && sequenceNumber!=currentSequenceNumber) {
					$('#debug').prepend('tooltip::hideInstantly '+ id+' success'+'<br/>');
					var transition = {opacity: 0};
					var transitionOptions = {duration: 100, complete: function() {
						tooltipContent.hide();
					}};
					tooltipContent.unbind('mouseenter');
					tooltipContent.unbind('mouseleave');
					visible = false;
					tooltipContent.animate(transition, transitionOptions);
				}
			}
			
			tooltip.mouseleave(function() {
				if (theTimeout) {
					$('#debug').prepend('tooltip.mouseleave '+ id+' abort'+'<br/>');
					return;
				}
					
				$('#debug').prepend('tooltip.mouseleave '+ id+' success'+'<br/>');
								
				theTimeout = setTimeout(function() {
				$('#debug').prepend('tooltip.mouseleave '+ id+' complete'+'<br/>');
					theTimeout = null;
					visible = false;
					if (tooltipContent) {
						tooltipContent.unbind('mouseenter');
						tooltipContent.unbind('mouseleave');
						var transition = {opacity: 0};
						var transitionOptions = {duration: 300, complete: function() {
							tooltipContent.hide();
							
						}};
						tooltipContent.animate(transition, transitionOptions);
					}
					
				}, options.timeout);
			});		
			
		});

	};
	var count = 0;
	var currentSequenceNumber = -1;
	
	$.fn.tooltip.defaults = {
		position: {left: 0.5, top: 1.0},
		anchor: {left: 0.5, top: 0},
		width: 'auto',
		style: {},
		sticky: false,
		delay: 0, 
		timeout: 1000,
		
		filter: function(content) { return content; }
	};
})(jQuery);