/* ______________________________________________________________________________
 *
 * jQuery ToolTip Plugin
 * 
 * 	@version		- 0.1.1 - 07.02.2011
 * 	@author 		- VOID (www.void.pt)
 *	@dependencies 	- jQuery
 *
 * ------------------------------------------------------------------------------
 *	OPTIONS
 * ------------------------------------------------------------------------------
 *		- layer (string) 		- the layer id name.
 *		- css (string) 			- the main css class for the tooltip.
 *		- container (string) 	- the css class for the tooltip's content wrapper.
 *		- follow (boolean)		- if the tooltip should move with the mouse.
 *		- offsetx (int)			- the horizontal margin.
 *		- offsety (int)			- the vertical margin.
 *		- attrib (string)		- the attribute that contains the info.
 * ------------------------------------------------------------------------------
 *	USAGE
 * ------------------------------------------------------------------------------
 *		$('#mytooltip').tooltip({ layer: 'jqToolTip', css: 'ttLayer', container: 'ttContent', follow: true, offsetx: 15, offsety: 15, attrib: 'title' });
 *		$('#mytooltip').data('tooltip').method();
 * ------------------------------------------------------------------------------
 *	INFO
 * ------------------------------------------------------------------------------
 *		'file,width,height,flashvars(&var:val)'
 *		parsed to: 0 file, 1 width, 2 height, 3 flashvars, 4 extension, 5 title
 * ___________________________________________________________________________ */

if (jQuery) (function ($) {
	
	var ToolTip = function (element, settings) {
		
		/* SCOPE VARS -------------------------------------------------------- */
		
		var elem = $(element);
		var self = this;
		
		/* OPTIONS ----------------------------------------------------------- */
		
		var options = $.extend({
			layer: 'jqToolTip', 
			css: 'ttLayer', 
			container: 'ttContent', 
			follow: true, 
			offsetx: 15, 
			offsety: 15, 
			attrib: 'rel'
		}, settings || {});
		
		/* VARIABLES --------------------------------------------------------- */
		
		var _layer;
		
		/* -------------------------------------------------------------------
		 * build
		 * 	Builds the tooltip and hides it.
		 * ------------------------------------------------------------------- */
		
		var build = function () {
			if ($('#' + options.layer).length == 0) {
				$('body').prepend('<div id="' + options.layer + '" class="' + options.css + '" style="visibility:hidden;display:none;"></div>');
			}
			_layer = $('#' + options.layer);
		};
		
		/* -------------------------------------------------------------------
		 * init
		 * 	Extracts element's infos and binds events to them.
		 * ------------------------------------------------------------------- */
		 
		var init = function () {
			elem.each( function() {
				var el = $(this);
				var str = $(this).attr(options.attrib);
				var title = $(this).attr('title');
				var info = getInfo(str, title);
				
				// Events
				$(el).mouseover( function() {
					show(info, el);
				}).mouseout( function() {
					hide();
				});
			});
		}
		
		/* -------------------------------------------------------------------
		 * getInfo
		 * 	Gets the info from the string.
		 * ------------------------------------------------------------------- */
		
		var getInfo = function (str, tit) {
			var info = str.split(',');
			
			var file = info[0].split('.');
			info[4] = file[1];
			info[5] = (tit != 'undefined') ? tit : '';
			
			return info;
		}
		
		/* -------------------------------------------------------------------
		 * show
		 * 	Shows the tooltip layer.
		 * ------------------------------------------------------------------- */
		 
		var show = function (info, elem) {
			_layer.html(createPreview(info));
			
			var p = $(elem).offset();
			var pw = parseInt($(elem).attr('width'));
			
			if (info[1] != null && info[2] != null) {
				$(options.container).css({
					'width': parseInt(info[1]) + 'px', 
					'height': (parseInt(info[2]) + 16) + 'px'
				});
			}
			
			_layer.css({
				'visibility': 'visible', 
				'display': 'block'
			});
			
			setPosition(info, p, pw);
			
			if (options.follow) {
				$(document).mousemove(function (e) {
					setPosition(info, e);
				});
			}
		}
		
		/* -------------------------------------------------------------------
		 * hide
		 * 	Hides the tooltip layer.
		 * ------------------------------------------------------------------- */
		 
		var hide = function () {
			if (options.follow) $(document).mousemove = null;
			_layer.empty().css({
				'left': -1000, 
				'top': -1000,
				'visibility': 'hidden', 
				'display': 'none'
			});
		}
		
		/* -------------------------------------------------------------------
		 * createPreview
		 * 	Creates the container with the preview inside to be injected.
		 * ------------------------------------------------------------------- */
		
		var createPreview = function (info) {
			var html = '<div class="' + options.container + '" style="overflow:hidden; background-position: center '+((parseInt(info[2])/2)-12)+'px;">';
			
			// Flash
			if (info[4] == 'swf') {
				var mov = info[0];
				var fv = info[3].replace(/\|/g,'=');
				
				if ($.browser.msie) {
					// <object> for IE
					html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="' + info[1] + '" height="' + info[2] + '" id="swf_preview" align="middle">';
					html += '<param name="movie" value="' + mov + '" />';
				} else {
					// <object> for the other browsers
					html += '<object type="application/x-shockwave-flash" data="' + mov + '" width="' + info[1] + '" height="' + info[2] + '">';
				}
				
				html += '<param name="wmode" value="opaque">';
				html += '<param name="quality" value="high">';
				html += '<param name="flashvars" value="' + fv + '">';
				html += '</object>';
				
			// Images
			} else {
				html += '<img src="' + info[0] + '"';
				if (info[1] != null) html += ' width="' + info[1] + '"';
				if (info[2] != null) html += ' height="' + info[2] + '"';
				html += ' alt="' + info[5] + '" />';
			}
			
			html += '<br /><span>' + info[5] + '</span></div>';
			return html;
		}
		
		/* -------------------------------------------------------------------
		 * setPosition
		 * 	Positions the tooltip.
		 * ------------------------------------------------------------------ */
		
		var setPosition = function (info, p, pw) {
			// Vars
			var docw = $(window).width();
			var doch = $(window).height();
			
			var divw = (info[1] != null) ? parseInt(info[1]) + 14 : _layer.outerWidth();
			var divh = (info[2] != null) ? parseInt(info[2]) + 30 : _layer.outerHeight();
			
			var xpos = 0;
			var ypos = 0;
			
			if (options.follow) {
				if (typeof p != "undefined") {
					xpos += p.pageX + options.offsetx;
					ypos += p.pageY + options.offsety;
				// Old IE
				} else if (typeof window.event != "undefined") {
					xpos += $(window).scrollLeft() + event.clientX + options.offsetx;
					ypos += $(window).scrollTop() + event.clientY + options.offsety;
				}
			} else {
				xpos = pw + p.left;
				ypos = p.top;
			}
			
			// Fix X
			if (xpos + divw + 5 > docw) {
				if (options.follow) xpos = p.pageX - divw - options.offsetx;
				else xpos = p.left - divw - options.offsetx;
			}
			
			// Fix Y
			if (ypos - $(window).scrollTop() + divh > doch) {
				if (ypos - divh < 5 + $(window).scrollTop()) {
					ypos = $(window).scrollTop() + 5;
				} else {
					ypos = ypos - divh;
				}
			}
		
			// Move layer
			_layer.css({
				'left': xpos, 
				'top': ypos
			});
		}
		
		/* INITIALIZATION ---------------------------------------------------- */
		
		build();
		init();
	};
	
	$.fn.tooltip = function (settings) {
		return this.each(function () {
			var element = $(this);
			
			if (element.data('tooltip')) return;
			
			var tooltip = new ToolTip(this, settings);
			
			element.data('tooltip', tooltip);
		});
	};

}) (jQuery);
