/*
 * jQuery clueTip plugin
 * Version 0.2  (05/16/2007)
 * @requires jQuery v1.1.1
 * @requires Dimensions plugin 
 *
 * 
 * Copyright (c) 2007 Karl Swedberg
 * Inspired by Cody Lindley's jTip (http://www.codylindley.com)
 * Thanks to Shelane Enos for the feature ideas 
 * Thanks to Jonathan Chaffer, as always, for the help.
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */

(function($) { 
    
  var $cluetip, $cluetipInner, $cluetipOuter;

  $.fn.cluetip = function(options) {
    
    // set up default options
    var defaults = {
      width: 500,
      local: false,
      attribute: 'rel',
      titleAttribute: 'title',
      hoverClass: '',
      waitImage: '/images/uploads/wait.gif',
      sticky: false,
      closePosition: 'top',
      closeText: '<img src=\"/images/uploads/action_stop.gif\" alt=\"Close\" border=\"0\" />',
      truncate: '',
      dataType: 'html',
      pngFix: false,
      ajaxProcess: function(data) {
        data = $(data).not('style, meta, link, script, title');
        return data;
        }
    };
    
    return this.each(function() {
      
      $.extend(defaults, options);

      // create the cluetip divs
      if (!$cluetip) {
        $cluetipInner = $('<div id="cluetip-inner"></div>');
        $cluetipOuter = $('<div id="cluetip-outer"></div>')
        .append($cluetipInner);
        
        $cluetip = $('<div></div>')
          .attr({'id': 'cluetip'})
          .css({position: 'absolute'})
        .append($cluetipOuter)
        .appendTo('body')
        .hide();
      }
      if (defaults.pngFix) {
        $('#cluetip').pngfix();
      }
      var $this = $(this);      
      var tipAttribute = $this.attr(defaults.attribute);
      if (!tipAttribute) return true;
      
      // vertical measurements
      var tipHeight, wHeight;
      var sTop, offTop, posY;

      // horizontal measurements
      var tipWidth = parseInt(defaults.width, 10);
      var offWidth = this.offsetWidth;
      var offLeft, posX, docWidth;
      
      var tipTitle = (defaults.attribute != 'title') ? $this.attr(defaults.titleAttribute) : '';
      var localContent;
      
      // close cluetip and reset title attribute if one exists
      var cluetipClose = function() {
        $cluetipOuter.css('backgroundImage', 'url(' + defaults.waitImage + ')');
        $cluetipInner.empty().parent().parent().hide();
        if (tipTitle) {
          $this.attr('title', tipTitle);
        }
      };

      var cluetipShow = function(bpY) {
        tipHeight = $cluetip.outerHeight();

        if ($this.css('display') == 'block') {
          $cluetip.css({top: (bpY - 10) + 'px'});

        }
        else {
          $cluetip.css({top: posY + 'px'});
        }

        if (defaults.truncate) {
          var $truncloaded = $cluetipInner.text().slice(0,defaults.truncate) + '...';
          $cluetipInner.html($truncloaded);
        }

        if ( posY + tipHeight > sTop + wHeight ) {
          $cluetip.css({top: (sTop + wHeight - tipHeight - 10) + 'px'});
        } 

        if (defaults.sticky) {
          var $closeLink = $('<a href="#" id="cluetip-close">' + defaults.closeText + '</a>');
          (defaults.closePosition == 'bottom') ? $cluetipInner.append($closeLink) : $cluetipInner.prepend($closeLink);
          $closeLink.click(function() {
            cluetipClose();
            return false;
          });
        }
        if (tipTitle) { 
          $cluetipInner.prepend('<h3 id="cluetip-title">' + tipTitle + '</h3>');
        }
        $cluetip.show();
        $cluetipOuter.css('backgroundImage', 'none');         
      };

      
// ON CLICK ...
      $this.click(function() {
        if (tipAttribute == $this.attr('href')) {
          return false;
        }
      });
// ON MOUSE OVER ...
      $this.hover(function(event) {
        
        if (tipAttribute == $this.attr('href')) {
          $this.css('cursor', 'help');
        }
        if (tipTitle) {
          $this.removeAttr('title');          
        }
        if (defaults.hoverClass) {
          $this.addClass(defaults.hoverClass)
        }
        
        sTop = $(document).scrollTop();
        offTop = $this.offset().top;
        offLeft = $this.offset().left;
        docWidth = $(document).width();
        posX = (offWidth > offLeft && offLeft > tipWidth)
          || offLeft + offWidth + tipWidth > docWidth 
          ? offLeft - tipWidth - 15 
          : offWidth + offLeft + 15;
        posY = offTop - 10;

        $cluetip.css({width: defaults.width});
        if ($this.css('display') != 'block' && posX >=0) {
          $cluetip.css({left: posX + 'px'});
        } else {
          if (event.pageX + tipWidth > docWidth) {
            $cluetip.css({left: (event.pageX - tipWidth - 30) + 'px'})
          } else {
            $cluetip.css({left: (event.pageX + 30) + 'px'});
          }
          var pY = event.pageY;
        }
        wHeight = $(window).height();

        
// load external file via ajax
        if (!defaults.local && tipAttribute.indexOf('#') != 0) {

          $.ajax({
            url: tipAttribute,
            success: function(data) {
              $cluetipInner.html(defaults.ajaxProcess(data));
              cluetipShow(pY);
            }
          });

// load an element from the same page
        } else if (defaults.local && tipAttribute.indexOf('#') == 0){
          var localContent = $(tipAttribute).html();
          $cluetipInner.html(localContent);
          cluetipShow(pY);
        }
 // on mouseout...    
      }, function() {
        if (defaults.sticky == false) {
          cluetipClose();
        };
        if (defaults.hoverClass) {
          $this.removeClass(defaults.hoverClass);
        }
      });
      
    });
  };  
  
})(jQuery);
