/*
 * xTooltip 1.0 - Plugin for jQuery
 * 
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * Depends:
 *   jquery.js
 * Optional:
 *	xpngFix
 *  bgiframe
 *  fx animations
 *
 *
 *  Copyright (c) 2008 Oleg Slobodskoi (ajaxsoft.de)
 */


;(function($){


	$.fn.extend({
		xTooltip: function( options ) {
		
			var	args = Array.prototype.slice.call(arguments, 1);
			return this.each(function() {
				var method = (typeof options == 'string') ? options : 'init',
					xTooltip = $.data(this, 'xTooltip') || $.data( this, 'xTooltip', new $.xTooltip(this, options));
				xTooltip[method].apply(xTooltip, args);
			});
	

		}
	});
	

	$.xTooltip = function(elem, options)
	{

		//Defaults
		var d = {
			animation: {opacity: "toggle"},
			speed: 300,
			content: null,
			contentAttr: 'title',
			addClass: '',
			delay: 500, 
			side: 'auto', //right left top bottom auto - relative to cursor
			position: 'mouse', // mouse | element
			preventDefaultTooltip: true,
			margin: 10,
			template: '<div class="arrow"/><div class="background"><div class="content">%content%</div></div>',
			fixpng: true,
			ajax: false,
			bgiframe: true,
			showEvent: 'mouseover', //mouseover | click 
			closeEvent: 'mouseout',
			autohide: 5000,
			form: false // error | tip
			
		};
		
		var formDefaults = {
			contentAttr: 'rel',
			position: 'element',
			showEvent: options && options.form == 'tip' ? 'focus click' : null,
			closeEvent: 'blur',
			addClass: d.form
		};
		
		options && options.form && $.extend(d,formDefaults);
		
		$.extend(d, options);


		var 
			self = this,
			content,
			size = {},
			position = {},
			sideClass,
			destPos = {},
			wnd = {},
			timeout,
			$elem = $(elem),
			$xTooltip,
			$wnd = $(window)
	
		;
		
		this.ready = false;
		this.complete = false;

		this.defaults = function (opt, callback)
		{
			opt ? $.extend(d, opt) : callback && callback(d);
		};
		
		this.init = function()
		{
		
			content = $elem.attr(d.contentAttr) || d.content;
			if (!content) return;		

			d.preventDefaultTooltip && $elem.removeAttr('title').removeAttr('alt');
		
			d.showEvent && $elem.bind(d.showEvent,	self.show);
			d.closeEvent && $elem.bind(d.closeEvent, self.close);
			$elem.mousemove(function(e){
				initDestPos(e);
				self.ready && !self.complete && setPosition(d.side);
			});
			
			$(document).click(self.close);
		};

		
		this.show = function (e)
		{
			initDestPos(e);
			timeout = setTimeout(create, d.delay);			
			d.autohide && setTimeout(self.close, d.autohide);
		};
		
		this.close = function ()
		{
			//if (!self.complete) return;
			
			clearTimeout(timeout);
			if (!$xTooltip) return;

			d.animation ? $xTooltip.animate(d.animation, d.speed, remove) : remove();
			 
			 function remove ()
			 {
				$xTooltip.remove();
				self.ready = false;
				self.complete = false;
			 };
			
		};

		/**************************************************************************/

		
		function create ()
		{
			
			if (self.ready) return;
			$xTooltip = $('<div class="x-tooltip" />').addClass(d.addClass).appendTo('body').hide();


			if (d.ajax)
			{
				$xTooltip.css({top: destPos.top+d.margin, left: destPos.left+d.margin}).addClass('loading').show();
				$.get(content, function(data){ $xTooltip.hide().html(template(data)).removeClass('loading'); ready(); } ); 
			} else
				$xTooltip.html(template(content)) && ready();
		};
		
		function template (content)
		{
			return  /%content%/.test(d.template) ? d.template.replace(/%content%/, content) : d.template+content;
		};
		
		function ready ()
		{
			initSizes();

			setPosition(d.side);
		
			d.animation ? $xTooltip.animate(d.animation, d.speed, complete) : $xTooltip.show() && complete();
			
			self.ready = true;
		};
		
		function complete ()
		{
			d.fixpng && xpngFix && xpngFix({onload: false, root: $xTooltip.get(0)});		
			d.bgiframe && $.fn.bgiframe && $xTooltip.bgiframe();
			self.complete = true;
		};
		
		function initSizes ()
		{
			$.extend(size, {
				width: $xTooltip.innerWidth(),
				height: $xTooltip.innerHeight()
			});
			
			$.extend(wnd, {
				width: $wnd.width(),
				height: $wnd.height(),
				scrollTop: $wnd.scrollTop(),
				scrollLeft: $wnd.scrollLeft()
			});
			
		};
		
		function initDestPos (e)
		{
			if (d.position == 'mouse')
				$.extend(destPos, {
					top: e.pageY,
					left: e.pageX
				});
			else if (d.position == 'element')
				$.extend(destPos, {
					top: $elem.offset().top + $elem.outerHeight()/2,
					left: $elem.offset().left + $elem.innerWidth()/2
				});
				

		};
		
		function setPosition (side)
		{
			//autodetect side
			position.left = (destPos.left+size.width+d.margin <= wnd.width+wnd.scrollLeft) ? destPos.left+d.margin : destPos.left-size.width-d.margin;
			position.top = (destPos.top+size.height+d.margin <= wnd.height+wnd.scrollTop) ? destPos.top+d.margin : destPos.top-size.height-d.margin;

	
			if (side != 'auto')
			{	
				if (/right/.test(side))
					position.left = destPos.left+d.margin;
				else if (/left/.test(side))
					position.left = destPos.left-size.width-d.margin;

				if (/top/.test(side))
					position.top = destPos.top-size.height-d.margin;
				else if (/bottom/.test(side))
					position.top = destPos.top+d.margin;
			};


			sideClass = (position.left<destPos.left) ? 'left ' : 'right ';
			sideClass += (position.top<destPos.top) ? 'top' : 'bottom';
			
			$xTooltip.css(position).addClass(sideClass);
			return position;
		};




		
	};



})(jQuery);		