/*
 * Copyright (c) 2008 Cordinc Ltd (www.cordinc.com)
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
 
/*
 * cordinc_tooltip.js, v1.0.2 - 27 August 2008
 * For help see www.cordinc.com/projects/tooltips.html
 */
var Tooltip = Class.create({
  initialize: function(target, tooltip) {
    var options = Object.extend({
      start_effect: function(element) {},
      end_effect: function(element) {},
      zindex: 1000,
      offset: {x:0, y:0},
      hook: {target:'topRight', tip:'bottomLeft'},
      trigger: false, 
      DOM_location: false,
      className: false,
      delay: {}
    }, arguments[2] || {});

    this.target = $(target);
    this.tooltip = $(tooltip);
    this.options = options;
    this.event_target = this.options.trigger?$(this.options.trigger):this.target;

    if (this.options.className) {
      this.tooltip.addClassName(this.options.className);
    }
    this.tooltip.hide();
    this.display=false;

    this.mouse_over = this.displayTooltip.bindAsEventListener(this);
    this.mouse_out = this.removeTooltip.bindAsEventListener(this);
    this.event_target.observe("mouseover", this.mouse_over);
    this.event_target.observe("mouseout", this.mouse_out);
  },

  displayTooltip: function(event){
    event.stop();
    
    if (this.display) {return;}
    if (this.options.delay.start) {
      var self = this;
      this.timer_id = setTimeout(function(){self.timer_id = false; self.showTooltip(event);}, this.options.delay.start*1000);
    } else {
      this.showTooltip(event);
    }
  },

  showTooltip: function(event) {
    this.display=true;
    position = this.positionTooltip(event);
    
    this.clone = this.tooltip.cloneNode(true);
    parentId = this.options.DOM_location?$(this.options.DOM_location.parentId):this.target.parentNode;
    successorId = this.options.DOM_location?$(this.options.DOM_location.successorId):this.target;
    parentId.insertBefore(this.clone, successorId);       
    
    this.clone.setStyle({ position:'absolute',
                      top:position.top + "px",
                      left:position.left + "px",
                      display: "inline",
                      zIndex:this.options.zindex});
                      
    if (this.options.start_effect) {
        this.options.start_effect(this.clone);
    }
  },

  positionTooltip: function(event) {
    target_position = this.target.cumulativeOffset();
    
    tooltip_dimensions = this.tooltip.getDimensions();
    target_dimensions = this.target.getDimensions();

    this.positionModify(target_position, target_dimensions, this.options.hook.target, 1);
    this.positionModify(target_position, tooltip_dimensions, this.options.hook.tip, -1);

    target_position.top += this.options.offset.y;
    target_position.left += this.options.offset.x;

    return target_position; 
  },

  positionModify: function(position, box, corner, neg) {
    if (corner == 'topRight') {
      position.left += box.width*neg;
    } else if (corner == 'topLeft') {
    } else if (corner == 'bottomLeft') {
      position.top += box.height*neg;
    } else if (corner == 'bottomRight') {
      position.top += box.height*neg;
      position.left += box.width*neg;
    } else if (corner == 'topMid') {
      position.left += (box.width/2)*neg;
    } else if (corner == 'leftMid') {
      position.top += (box.height/2)*neg;
    } else if (corner == 'bottomMid') {
      position.top += box.height*neg;
      position.left += (box.width/2)*neg;
    } else if (corner == 'rightMid') {
      position.top += (box.height/2)*neg;
      position.left += box.width*neg;
    }
  },

  removeTooltip: function(event) {
    if (this.timer_id) {
      clearTimeout(this.timer_id);
      this.timer_id = false;
      return;
    } 

    if (this.options.end_effect) {
        this.options.end_effect(this.clone);
    } 
    
    if (this.options.delay.end) {
      var self = this;
      setTimeout(function(){self.clearTooltip();}, this.options.delay.end*1000);
    } else {
      this.clearTooltip();
    }
  },
  
  clearTooltip: function() {
    this.clone.remove();
    this.clone = null;
    this.display=false;
  },

  destroy: function() {
    this.event_target.stopObserving("mouseover", this.mouse_over);
    this.event_target.stopObserving("mouseout", this.mouse_out);
    this.clearTooltip();
  }
})
