// JavaScript Document

/*
 * Tooltip - jQuery plugin for simple tooltip showing over HTML elements
 * Revision 0.7b
 *
 * Copyright (c) 2008 Berny Cantos a.k.a. xPheRe
 *
 * Licensed under the GPL license:
 *   http://www.gnu.org/licenses/gpl.html
 *
 * If this library suits your needs and 
 * 
 * Library was modified by Peter Naydenov - 14.12.2008
 * Was added a tooltip source. Default value is 'rel'
 */
(function($) {

  $.tooltip = {
    /* Default tooltip settings */
    defaults: {
      'class': 'tooltip', 		// Tooltip class added to destiny HTML element
      css: {}, 				// CSS applied to destiny HTML element
      event: 'mouseover', 		// Event the tooltip must respond to
      smart: false, 			// If the tooltip content is generated in a 'smart' way
      track: true, 			// If the tooltip must follow mouse position
      offset: { x: 12, y: 18 }, 	// Offset from current mouse position, only applied if track set to true
      html: false, 			// If html source set TRUE. If not - library works on default.
      attribute: 'rel'			// Attribute source of tooltip
    },

    /* 
    * Shortcut to setup default settings
    * Example:
    *		$.tooltip.setup({event: 'click', track: 'false'});
    */
    setup: function(opt) { $.extend($.tooltip.defaults, opt) }
  };

  /* The TIP object */
  var tip = function(src, opt) {
    var self = this;
    var html = '';
    src = $(src);

    if (opt.html) opt.text = $(src).attr(opt.attribute);

    /* Use metadata plugin (if loaded) to modify local options */
    if ($.metadata) { opt = $.extend({}, opt, src.metadata().tooltip) };

    /* Tries to generate the content from the HTML element attributes */
    if (opt.smart) {
      
      /* Tooltip title from 'title' attribute */
      /*if (!opt.title)*/ { opt.title = src.attr('title') };
      /* Tooltip text from 'alt' attribute */
      if (!opt.text) { opt.text = src.attr('alt') };
      /* url from 'href' attributes. Great for link tags */
      /*if (!opt.href) */{ opt.href = src.attr('href') };
    };

    /* Generates HTML content */
    var html = '';
    if (opt.title) { html += '<div class="title">' + opt.title + '</div>' };
    if (opt.text) { html += '<div class="text">' + opt.text + '</div>' };
    if (opt.href) { html += '<div class="url">' + opt.href + '</div>' };
    /* If no content where generated, no tooltip is created */
    if (html == '') { delete this; return };

    /* Removes attributes disabling default tooltips from the browser */
    src
			.removeAttr('title')
			.removeAttr('alt')

    $.data(src, 'tooltip', self)
    self.dst = opt.dst;

    src
			.bind(opt.event + '.tooltip', over)
			.bind('mouseout.tooltip', out)
			.bind('focus.tooltip', over)
			.bind('blur.tooltip', out)
			.bind('click.tooltip', hide)

    /* Destroy existent timers */
    function destroy_timers() {
      if (self.timein) {
        clearTimeout(self.timein);
        delete self.timein
      };
      if (self.timeout) {
        clearTimeout(self.timeout);
        delete self.timeout
      };
    };

    /* Called when the 'show tooltip' event is raised */
    function over(ev) {
      destroy_timers();
      if (self.st == out) { return }
      self.st = over;
      /* No destiny defined, must create a new HTML element */
      if (!self.dst) {
        self.dst = $('<div>')
					.appendTo(document.body)
					.css({ visibility: 'hidden' })
      };
      self.ev = ev;
      /* Wait some time and show the tooltip */
      self.timein = setTimeout(show, opt['in'] || 0)
    };

    /* Shows the tooltip */
    function show() {
      destroy_timers();
      /* No destiny, no showing */
      if (!self.dst) { return }
      /* Modifies tooltip CSS and content */
      self.dst
				.addClass(opt['class'])
				.css(opt.css)
				.html(html);
      /* If a duration is defined */
      if (opt.duration > 0) {
        self.timein = setTimeout(hide, opt.duration)
      };
      /* Keep track of mouse position if 'track' is activated */
      if (opt.track) {
        self.dst
					.css({
					  position: 'absolute',
					  visibility: 'visible'
					})
        src
					.bind('mousemove.tooltip', move);
        $('body')
					.bind('click.tooltip', hide)
      };

      /* Calculates width and height */
      self.w = self.dst.width();
      self.h = self.dst.height();
      /* 'on show' callback */
      if (opt.onshow) { opt.onshow.apply(self.dst) };
      if (opt.track) { move() };
    };

    /* Called when the tooltip must hide */
    function out() {
      destroy_timers();
      if (self.st != over) { return }
      /* Wait some time and hides the tooltip */
      self.timeout = setTimeout(hide, opt['out'] || 0)
    };

    /* Hides the tooltip */
    function hide() {
      destroy_timers();
      /* Unbind all events in body from the tooltip namespace */
      $('body').unbind('.tooltip');
      /* Unbind mousemove events */
      $('src').unbind('mousemove.tooltip');
      /* No destiny, no hiding */
      if (!self.dst) { return };
      /* Clear destiny contents */
      self.dst.empty();
      /* 'on hide' callback */
      if (opt.onhide) { opt.onhide.apply(self.dst) }
      /* If destiny was dinamicly created, destroy it */
      if (self.dst != opt.dst) {
        self.dst.remove();
        delete self.dst
      };
    };

    /* Moves the tooltip to follow the cursor */
    function move(ev) {
      if (!ev) { ev = self.ev } else { self.ev = ev }
      if (!self.dst) { return }
      var p = {
        x: ev.pageX + opt.offset.x, y: ev.pageY + opt.offset.y,
        w: self.w, h: self.h
      };
      w = window;
      var v = {
        x: w.scrollX, y: w.scrollY,
        w: w.innerWidth - 20/*(w.scrollMaxY > 0 ? 30 : 20)*/,
        h: w.innerHeight - 20/*(w.scrollMaxX > 0 ? 20 : 10)*/
      };
      /* Better not to go offscreen */
      if (p.x + p.w > v.x + v.w) { p.x = v.x + v.w - p.w }
      if (p.y + p.h > v.y + v.h) { p.y = ev.pageY - p.h - opt.offset.y }
      if (p.x < v.x) { p.x = v.x }
      if (p.y < v.y) { p.y = v.y }
      self.dst.css({ top: p.y, left: p.x })
    };
  };

  /* 
  * Change tooltip local settings
  * Example:
  * 		$('a').tooltip('setup', {event: 'click'})
  */
  function setup() {
    return this.each(function() {
      t = $.data(this, 'tooltip');
      if (t) { $.extend(t.opt, opt) }
      return this
    })
  };

  /* 
  * Removes tooltip
  * Example:
  * 		$('div').tooltip('remove')
  */
  function remove() {
    return
    this
				.unbind('.tooltip')
				.removeData('tooltip')
  };

  /* 
  * Creates a tooltip
  * Example:
  * 		$('div').tooltip('create')
  */
  function create(opt) {
    remove.apply(this);
    opt = $.extend({}, $.tooltip.defaults, opt);
    return this.each(function() {
      new tip(this, opt);
    });
  };

  /*
  * Extends jQuery functions
  */
  $.fn.tooltip = function(a, o) {
    /* If called with only one non-string parameter (or none), it assumes 'create' by default */
    if (!o && (typeof a != 'string')) {
      o = a;
      a = 'create'
    };
    /* Call the selected function */
    return (f = ({
      setup: setup,
      remove: remove,
      create: create
    })[a]) && f.apply(this, [o])
  };

})(jQuery);