Tooltip = Class.create({
  initialize: function(element, options) {
	this.size_is_set = false;
    this.options = options || {};
    this.options.anchorPosition = this.options.anchorPosition || 'left';
    this.options.delay          = this.options.delay  || {show: 300, hide: 300};
    this.options.delta          = this.options.delta || {x: 0, y: 0};
    
    this.tooltip = this.create($(element));
    this.hideWithTimer  = this.hideWithTimer.bind(this);
    
    this.hideHandler = this.hide.bind(this);
    this.showHandler = this.show.bind(this);
    this.tooltip.observe('mouseover', this.clearTimer.bind(this))
                .observe('mouseout',  this.hideWithTimer);
    
  },
  
  attachTo: function(element) {
    this.detach();
    this.object = $(element);

    //document.body.insert(this.tooltip);
	$(document.body).insert(this.tooltip);
    this.object.observe("mouseover", this.showHandler);
    this.object.observe("mouseout", this.hideWithTimer);
  },
  
  detach: function() {
    if (!this.object) return;
    this.object.stopObserving("mouseover", this.showHandler);
    this.object.stopObserving("mouseout", this.hideWithTimer);
  },
  
  show: function() {
    this.clearTimer();
    this.computePosition();
	this.resizeForIE();
    this.tooltip.show();
  },
  
  hide: function() {
    this.clearTimer();
    this.tooltip.hide();
  },
  
  hideWithTimer: function() {
    this.clearTimer();
    this.timer = setTimeout(this.hideHandler, this.options.delay.hide || 0);
  },
   
  clearTimer: function() {
    if (this.timer) {
      clearTimeout(this.timer);
      this.timer = null;
    }
  },
  
  //  Private function to get tooltip absolute position
  computePosition: function() {
    var size   = this.tooltip.getDimensions(),
        point;
    var offset = this.object.cumulativeOffset(),
        dim    = this.object.getDimensions();
    var delta  = this.options.delta;
    switch (this.options.anchorPosition) {
      case 'left':   point = {x:offset.first() + dim.width + delta.x, y: offset.last() + dim.height/2 + delta.y}; break;
      case 'right':  point = {x:offset.first() + delta.x, y: offset.last() + dim.height/2 + delta.y}; break;
      case 'top':    point = {x:offset.first() + dim.width/2 + delta.x, y: offset.last() + dim.height + delta.y}; break;
      case 'bottom': point = {x:offset.first() + dim.width/2 + delta.x, y: offset.last() + delta.y}; break;
    }     
    var style = this.tooltip.style;
    switch (this.options.anchorPosition) {
      case 'left':   style.left = point.x + 'px'; break;
      case 'right':  style.left = point.x - size.width - 10 + 'px'; break;
      case 'top':
      case 'bottom': style.left = point.x - size.width / 2 + 6 + 'px';
    }
    
    switch (this.options.anchorPosition) {
      case 'left':  
      case 'right':  style.top = point.y - size.height / 2 + 'px';  break;
      case 'top':    style.top = point.y + 5 + 'px'; break;
      case 'bottom': style.top = point.y - size.height - 15 + 'px'; break;
    }
  },

  resizeForIE: function() {
	if (this.size_is_set)
		return;
	else
		this.size_is_set = true;
    var size   = this.tooltip.getDimensions();
	this.tooltip.down('.north').style.width = size.width - 50;
	this.tooltip.down('.south').style.width = size.width - 50;
  },

  create: function(element){
    var tooltip = new Element('div')
      .insert("<div class='north'>&nbsp;</div>")
      .insert("<div class='west'><div class='east'><div class='content'>" + '' + "</div></div></div>")
      .insert("<div class='south'>&nbsp;</div>")
      .insert("<div class='nw'>&nbsp;</div>")
      .insert("<div class='ne'>&nbsp;</div>")
      .insert("<div class='sw'>&nbsp;</div>")
      .insert("<div class='se'>&nbsp;</div>")
      .insert("<div class='" + this.options.anchorPosition + "-arrow'>&nbsp;</div>")
      .setStyle({position: 'absolute', zIndex: 999999999})
      .addClassName('tooltip-me')
      .hide();
    tooltip.down('.content').insert(element);
    element.show();
    return tooltip;
  }
});
