/**

 * 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 = jQuery(elem);

      

      var tooltip = jQuery(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();

            };

         });

         

         jQuery(window).mousedown(function(event)

         { 

            if(tooltip.css('display') !== 'none')

            {

               var check = (conf.focus) ? jQuery(event.target).parents('.tooltip').andSelf().filter(function(){ return this === tooltip.get(0) }).length : 0;

               if(check === 0) self.hide();

            };

         });

      };

      

      

      jQuery.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 = jQuery(window).width() + jQuery(window).scrollLeft();

            var windowHeight = jQuery(window).height() + jQuery(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(jQuery(conf.position).attr('nodeType') === 1)

               {

                  var offset = jQuery(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;

         }

      });

   };

   

   jQuery.fn.simpletip = function(conf)

   { 

      // Check if a simpletip is already present

      var api = jQuery(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(){}

      };

      jQuery.extend(defaultConf, conf);

      

      this.each(function()

      {

         var el = new Simpletip(jQuery(this), defaultConf);

         jQuery(this).data("simpletip", el);  

      });

      

      return this; 

   };

})();
