(function ($) {
	$.fn.tipsy = function(opts) {
	
		opts = $.extend({gravity: 'nw'}, opts || {});
		var tip = null, cancelHide = false;
	
		this.hover(function() {
			
			$.data(this, 'cancel.tipsy', true);
	
			var tip = $.data(this, 'active.tipsy');
			if (!tip) {
				tip = $('<div class="tipsy"><div class="tipsy-inner">' + $(this).attr('data-title') + '</div></div>');
				tip.css({position: 'absolute', zIndex: 100000});
				$.data(this, 'active.tipsy', tip);
			}
			
			var pos = $(this).offset();
			var h = $(this).height();
			var w = $(this).width();
			tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);
			var ah = tip[0].offsetHeight;
			var aw = tip[0].offsetWidth
	
			var decalage = 0;
			if ($(this).attr('data-pixel')) decalage = parseInt($(this).attr('data-pixel'));
	
			switch (opts.gravity) {
				case 'n':
					tip.css({top: pos.top + h + decalage, left: pos.left + w / 2 - aw / 2}).addClass('tipsy-north');
					break;
				case 's':
					tip.css({top: pos.top - ah - decalage, left: pos.left + w / 2 - aw / 2}).addClass('tipsy-south');
					break;
				case 'e':
					tip.css({top: pos.top + h / 2 - ah / 2, left: pos.left - aw}).addClass('tipsy-east');
					break;
				case 'w':
					tip.css({top: pos.top + h / 2 - ah / 2, left: pos.left + w}).addClass('tipsy-west');
					break;
				case 'nw':
					tip.css({top: pos.top + h + decalage, left: pos.left - 6}).addClass('tipsy-nw');
					break;
				case 'ne':
					tip.css({top: pos.top + h + decalage, left: pos.left + w + 5 - aw}).addClass('tipsy-ne');
					break;
				case 'sw':
					tip.css({top: pos.top - ah - 2 - 5, left: pos.left - 6}).addClass('tipsy-sw');
					break;
				case 'se':
					tip.css({top: pos.top - ah - 2, left: pos.left + w + 5 - aw}).addClass('tipsy-se');
					break;
			}
	
			tip.css({visibility: 'visible'});
	
		}, function() {
			$.data(this, 'cancel.tipsy', false);
			var self = this;
			if ($.data(this, 'cancel.tipsy')) return;
			var tip = $.data(self, 'active.tipsy');
			tip.remove();
		});
	
	};
})(jQuery);

