/**
 * jquery.simpletip 1.3.1. A simple tooltip plugin
 * 
 * Copyright (c) 2009 Craig Thompson http://craigsworks.com
 * 
 * Licensed under GPLv3 http://www.opensource.org/licenses/gpl-3.0.html
 * 
 * Launch : February 2009 Version : 1.3.1 Released: February 5, 2009 - 11:04am
 */
(function($) {

	function Simpletip(elem, conf) {
		var self = this;
		elem = $(elem);

		var tooltip = $(document.createElement('div')).addClass(
				conf.baseClass).addClass((conf.fixed) ? conf.fixedClass : '')
				.addClass((conf.persistent) ? conf.persistentClass : '').html(
						conf.content).appendTo(elem);

		if (!conf.hidden)
			tooltip.show();
		else
			tooltip.hide();

		if (!conf.persistent) {
			elem.hover(function(event) {
				self.show(event)
			}, function() {
				self.hide()
			});

			if (!conf.fixed) {
				elem.mousemove(function(event) {
					if (tooltip.css('display') !== 'none')
						self.updatePos(event);
				});
			}
			;
		} else {
			elem.click(function(event) {
				if (event.target === elem.get(0)) {
					if (tooltip.css('display') !== 'none')
						self.hide();
					else
						self.show();
				}
				;
			});

			$(window).mousedown(
					function(event) {
						if (tooltip.css('display') !== 'none') {
							var check = (conf.focus) ? $(event.target)
									.parents('.tooltip').andSelf().filter(
											function() {
												return this === tooltip.get(0)
											}).length : 0;
							if (check === 0)
								self.hide();
						}
						;
					});
		}
		;

		$.extend(self, {
			getVersion : function() {
				return [ 1, 2, 0 ];
			},

			getParent : function() {
				return elem;
			},

			getTooltip : function() {
				return tooltip;
			},

			getPos : function() {
				return tooltip.offset();
			},

			setPos : function(posX, posY) {
				var elemPos = elem.offset();

				if (typeof posX == 'string')
					posX = parseInt(posX) + elemPos.left;
				if (typeof posY == 'string')
					posY = parseInt(posY) + elemPos.top;

				tooltip.css( {
					left : posX,
					top : posY
				});

				return self;
			},

			show : function(event) {
				conf.onBeforeShow.call(self);

				self.updatePos((conf.fixed) ? null : event);

				switch (conf.showEffect) {
				case 'fade':
					tooltip.fadeIn(conf.showTime);
					break;
				case 'slide':
					tooltip.slideDown(conf.showTime, self.updatePos);
					break;
				case 'custom':
					conf.showCustom.call(tooltip, conf.showTime);
					break;
				default:
				case 'none':
					tooltip.show();
					break;
				}
				;

				tooltip.addClass(conf.activeClass);

				conf.onShow.call(self);

				return self;
			},

			hide : function() {
				conf.onBeforeHide.call(self);

				switch (conf.hideEffect) {
				case 'fade':
					tooltip.fadeOut(conf.hideTime);
					break;
				case 'slide':
					tooltip.slideUp(conf.hideTime);
					break;
				case 'custom':
					conf.hideCustom.call(tooltip, conf.hideTime);
					break;
				default:
				case 'none':
					tooltip.hide();
					break;
				}
				;

				tooltip.removeClass(conf.activeClass);

				conf.onHide.call(self);

				return self;
			},

			update : function(content) {
				tooltip.html(content);
				conf.content = content;

				return self;
			},

			load : function(uri, data) {
				conf.beforeContentLoad.call(self);

				tooltip.load(uri, data, function() {
					conf.onContentLoad.call(self);
				});

				return self;
			},

			boundryCheck : function(posX, posY) {
				var newX = posX + tooltip.outerWidth();
				var newY = posY + tooltip.outerHeight();

				var windowWidth = $(window).width()
						+ $(window).scrollLeft();
				var windowHeight = $(window).height()
						+ $(window).scrollTop();

				return [ (newX >= windowWidth), (newY >= windowHeight) ];
			},

			updatePos : function(event) {
				var tooltipWidth = tooltip.outerWidth();
				var tooltipHeight = tooltip.outerHeight();

				if (!event && conf.fixed) {
					if (conf.position.constructor == Array) {
						posX = parseInt(conf.position[0]);
						posY = parseInt(conf.position[1]);
					} else if ($(conf.position).attr('nodeType') === 1) {
						var offset = $(conf.position).offset();
						posX = offset.left;
						posY = offset.top;
					} else {
						var elemPos = elem.offset();
						var elemWidth = elem.outerWidth();
						var elemHeight = elem.outerHeight();

						switch (conf.position) {
						case 'top':
							var posX = elemPos.left - (tooltipWidth / 2)
									+ (elemWidth / 2);
							var posY = elemPos.top - tooltipHeight;
							break;

						case 'bottom':
							var posX = elemPos.left - (tooltipWidth / 2)
									+ (elemWidth / 2);
							var posY = elemPos.top + elemHeight;
							break;

						case 'left':
							var posX = elemPos.left - tooltipWidth;
							var posY = elemPos.top - (tooltipHeight / 2)
									+ (elemHeight / 2);
							break;

						case 'right':
							var posX = elemPos.left + elemWidth;
							var posY = elemPos.top - (tooltipHeight / 2)
									+ (elemHeight / 2);
							break;

						default:
						case 'default':
							var posX = (elemWidth / 2) + elemPos.left + 20;
							var posY = elemPos.top;
							break;
						}
						;
					}
					;
				} else {
					var posX = event.pageX;
					var posY = event.pageY;
				}
				;

				if (typeof conf.position != 'object') {
					posX = posX + conf.offset[0];
					posY = posY + conf.offset[1];

					if (conf.boundryCheck) {
						var overflow = self.boundryCheck(posX, posY);

						if (overflow[0])
							posX = posX - (tooltipWidth / 2)
									- (2 * conf.offset[0]);
						if (overflow[1])
							posY = posY - (tooltipHeight / 2)
									- (2 * conf.offset[1]);
					}
				} else {
					if (typeof conf.position[0] == "string")
						posX = String(posX);
					if (typeof conf.position[1] == "string")
						posY = String(posY);
				}
				;

				self.setPos(posX, posY);

				return self;
			}
		});
	}
	;

	$.fn.simpletip = function(conf) {
		// Check if a simpletip is already present
		var api = $(this).eq(typeof conf == 'number' ? conf : 0).data(
				"simpletip");
		if (api)
			return api;

		// Default configuration
		var defaultConf = {
			// Basics
			content : 'A simple tooltip',
			persistent : false,
			focus : false,
			hidden : true,

			// Positioning
			position : 'default',
			offset : [ 0, 0 ],
			boundryCheck : true,
			fixed : true,

			// Effects
			showEffect : 'fade',
			showTime : 150,
			showCustom : null,
			hideEffect : 'fade',
			hideTime : 150,
			hideCustom : null,

			// Selectors and classes
			baseClass : 'tooltip',
			activeClass : 'active',
			fixedClass : 'fixed',
			persistentClass : 'persistent',
			focusClass : 'focus',

			// Callbacks
			onBeforeShow : function() {
			},
			onShow : function() {
			},
			onBeforeHide : function() {
			},
			onHide : function() {
			},
			beforeContentLoad : function() {
			},
			onContentLoad : function() {
			}
		};
		$.extend(defaultConf, conf);

		this.each(function() {
			var el = new Simpletip($(this), defaultConf);
			$(this).data("simpletip", el);
		});

		return this;
	};
})($jYtc);
