(function($) {

$.extend({
  joeltip: {
    cached: {},
    last_options: null,
    hide_count: 1,
    timeout_ids: [],
    timeout_ids_index: 0,
    timeout_delay: 250,
    tip: null,
    title: null,
    on: false,
    defaults: {
      close_button: 'http://www.acne.org/images/close-button.png',
      autowidth: false,
      height: 'auto',
      minwidth: 250,
      maxwidth: 500,
      offsetx: 40,
      offsety: 15,
      fadeSpeed: 300,
      background: '#faf7e6',
      padding: '4px',
      border: 'solid 1px #aaa',
      interval: 200, // hover intent mouse polling interval
      sensitivity: 7,
      opacity: 1,
      mode: 'hover'
    },
    hide: function(options) {
      if(!$.joeltip.on || $.joeltip.hide_count < 1)
        return;

      $.joeltip.hide_count = 1;
      $('body').stopTime().unbind('click.jt');

      if(!$.browser.msie)
        $.joeltip.tip.fadeOut(options.fadeSpeed, function() { $.joeltip.on = false; });
      else
        $.joeltip.tip.css({display: 'none'});
    },
    setHideTimer: function(options) {
      $.joeltip.tip.oneTime($.joeltip.timeout_delay, 'hide', function() { $.joeltip.hide(options); });
    },
    addCloseButton: function(options) {
      $.joeltip.tip.append(
        $('<img src="'+options.close_button+'">')
          .css( $.extend({}, {position: 'absolute', top: 0, right: 0, cursor: 'pointer'}, options.close_button_css) )
          .click( function() { $.joeltip.hide(options); } )
      );
    },
    clearHideTimeout: function() {
      $.joeltip.hide_count--;
      $.joeltip.tip.stopTime('hide');
    },
    setClickOutsideTimer: function() {
      $('body').oneTime(500, function() {
        $(this).bind('click.jt', function(e) {
          if( $(e.target).parents( '#joeltip' ).length || $(e.target).is( '#joeltip' ) || $(e.target).attr('joeltip') )
            return;
          $.joeltip.hide( $.joeltip.last_options );
        });
      });
    }
  }
});

$.fn.extend({
  joeltip: function( options ) {

    var options = $.extend({}, $.joeltip.defaults, options);

    return this.each(function() {

      var obj = $(this);
      var title = (options.label_as_title ? obj.text() : null ) || options.title;
      var content = '';
      obj.attr('savetext', title);
      obj.attr('joeltip', true);
      

      $.joeltip.showTip = function() {
        if(options.mode == 'hover')
          $.joeltip.clearHideTimeout();

        var offset, x = 0, y = 0;
        if( options.relativeTo )
        {
          offset = obj.find(options.relativeTo).offset();
          x = offset.left;
          y = offset.top;
        }
        else
        {
          offset = obj.offset();
          x = offset.left;
          y = offset.top;
        }

        if (options.load_and_cache) {
          if ($.joeltip.cached[options.load_and_cache])
            content = $.joeltip.cached[options.load_and_cache];
          else
            $.joeltip.tip.load(options.load_and_cache, null, function() {
              content = $.joeltip.cached[options.load_and_cache] = $.joeltip.tip.html();
              if(typeof(options.callback) == 'function')
                options.callback();
              $.joeltip.addCloseButton(options);
            });
        }
        else
          content = obj.next('.jt_desc').html();
        
        if( title )
          content = "<strong class='title'>"+title+"</strong><br>" + content;
        
        $.joeltip.tip
          .css({
            height: options.height, border: options.border, background: options.background,
            padding: options.padding, width: options.minwidth+'px', top: options.offsety+y+'px',
            opacity: options.opacity, left: options.offsetx+x+'px'})
          .html( content );
        if($.joeltip.cached[options.load_and_cache] && typeof(options.callback) == 'function')
          options.callback();

        if (options.mode == 'click')
          $.joeltip.addCloseButton(options);
        
        if (options.width)
          $.joeltip.tip.css({width: options.width});

        if (!$.joeltip.on && !$.browser.msie)
          $.joeltip.tip.fadeIn(options.fadeSpeed);
        else
        {
          $.joeltip.tip.stop();
          $.joeltip.tip.css({display: 'block', opacity: 1});
        }

        if (options.autowidth)
        {
          var w, h = $.joeltip.tip.height();
          w = h > options.maxwidth ? options.maxwidth : h;
          if(w < options.minwidth)
            w = options.minwidth;
          $.joeltip.tip.css({width: w+'px'});
        }

        $.joeltip.on = true;
        $.joeltip.last_options = options;
        $.joeltip.setClickOutsideTimer();
      }

      $.joeltip.hideTip = function() {
        $.joeltip.hide_count++;
        $.joeltip.setHideTimer(options);
      }

      if(options.mode == 'hover')
        obj.hoverIntent({
          sensitivity: options.sensitivity,
          interval: options.interval,
          over: $.joeltip.showTip,
          out: $.joeltip.hideTip
        });
      else
      {
        obj.css({cursor: 'pointer'}).click(
          $.joeltip.showTip
        );
      }

    });
  }
});

$(document).ready(function(e) {
  $.ajaxSetup ({
      // Disable caching of AJAX responses */
      cache: false
  });
  $('body').append( $.joeltip.tip = $('<div id="joeltip" class="pngfix">&nbsp;</div>') );

  $.joeltip.tip.bind('mouseenter', function() {
    if($.joeltip.last_options.mode != 'hover')
      return;
    $.joeltip.clearHideTimeout();
  })
  .bind('mouseleave', function() {
    if($.joeltip.last_options.mode != 'hover')
      return;
    $.joeltip.hide_count++;
    $.joeltip.setHideTimer($.joeltip.last_options);
  });
});


})(jQuery);