var TT = {
 
  calculate: function(tt,mouse_x,mouse_y){
    var dimensions = Element.getDimensions( tt.tooltip );
    var element_width = dimensions.width;
    var element_height = dimensions.height;
    if(element_height == 0) element_height = tt.tooltip_height;
    if ( (element_width + mouse_x) >= ( TT.getWindowWidth() - tt.options.min_distance_x) ){
  	  mouse_x = mouse_x - element_width;
  	  mouse_x = mouse_x - 2*tt.options.min_distance_x;
    } else {
  	  mouse_x = mouse_x + tt.options.min_distance_x;
    }
    if ( (mouse_y - element_height) >= (tt.options.min_distance_y) ){
  	  mouse_y = mouse_y - element_height;
  	  mouse_y = mouse_y - 2*tt.options.min_distance_y;
    } else {
  	  mouse_y = mouse_y + tt.options.min_distance_y;
    } 
    return([mouse_x,mouse_y]); 
  },

  setStyles: function(tt,x, y)
  {
	  Element.setStyle(tt.tooltip, { position:'absolute',
	 								    top:(y  + tt.options.min_distance_y) + "px",
	 								    left:(x + tt.options.min_distance_x) + "px",
									    zIndex:tt.options.zindex
	 								  });
  },
  
 move: function(tt)
 {
  if(!tt.docked){
   var pos = TT.calculate(tt,tt.actual_x,tt.actual_y);   
   TT.setStyles(tt,pos[0],pos[1]);
  }else{
   var pos = TT.calculate(tt,tt.docked_x,tt.docked_y);   
   TT.setStyles(tt,pos[0],pos[1]);
  } 
 },  

  show: function(tt, notmove)
  { 
    if(!tt.tooltip){
      if($(tt.source)) {
        tt.created = false;
        tt.tooltip = $(tt.source);
      } else {
        tt.created = true;
        tt.tooltip = $(document.createElement("div"));
        if(tt.options.container)
         $(tt.options.container).appendChild(tt.tooltip);
        else 
         document.body.appendChild(tt.tooltip);
        if(!tt.options.ajax)
         tt.tooltip.appendChild(document.createTextNode(tt.source));
      }
     if(tt.options.css)
       tt.tooltip.addClassName(tt.options.css);
     if(tt.options.ajax)
       TT.loadAjax(tt);         
     new Element.show(tt.tooltip);
     if(!tt.finished){
      if(notmove){
      }else TT.move(tt);
      tt.element.setAttribute('tooltiped','yes');
     }  
    }  
  },
  
  loadAjax: function(tt)
  {
    new Ajax.Updater(tt.tooltip, tt.source, {parameters:tt.options.ajax_parameters||{},evalScripts:true,asynchronous: false}); 
    tt.tooltip_height = $(tt.tooltip.firstChild).getHeight();
  },
  
  hide: function(tt)
  {
   if(tt.tooltip){ 
    Element.hide(tt.tooltip);
    if(tt.created) tt.tooltip.remove();
   } 
  },  

  getWindowHeight: function()
  {
    var innerHeight;
	  if (navigator.appVersion.indexOf('MSIE')>0) {
		  innerHeight = document.body.clientHeight;
    } else {
		  innerHeight = window.innerHeight;
    }
    return innerHeight;	
  },

  getWindowWidth: function()
  {
    var innerWidth;
	  if (navigator.appVersion.indexOf('MSIE')>0) {
		  innerWidth = document.body.clientWidth;
    } else {
		  innerWidth = window.innerWidth;
    }
    return innerWidth;	
  }

};


var TT_W = Class.create();
TT_W.prototype = {
 initialize: function(element, source)
 { 
    this.options = Object.extend({
	    delay: 0,
      min_distance_x: 5,
      min_distance_y: 5,
      zindex: 1000
    }, arguments[2] || {});
    
    this.docked  = false;
    this.delayed = false;
    this.finished = false;
    this.element = $(element);
    this.source = source;
    if(this.element.getAttribute('tooltiped')==="yes") { return; }   
    if(this.options.ajax) this.options.delay = 600;

    this.eventMouseOut   = this.hide.bindAsEventListener(this);
    Event.observe(this.element, "mouseout", this.eventMouseOut);

    this.eventMouseClick  = this.dock.bindAsEventListener(this);
    Event.observe(this.element, "click", this.eventMouseClick); 
    
    this.eventMouseMove  = this.show.bindAsEventListener(this);
    Event.observe(this.element, "mousemove", this.eventMouseMove);      
 },
 
 showDelayed: function()
 {
  this.delayed = false;
  this.timer = null;
  this.show();
 }, 
 
 show: function(event)
 {
  if(event){
   Event.stop(event);
   this.actual_x = Event.pointerX(event);
   this.actual_y = Event.pointerY(event);  
  }
  
  if(this.options.delay>0)
  {
    this.delayed = true; 
    this.timer = setTimeout(this.showDelayed.bind(this),this.options.delay);
    this.options.delay = 0;
  }
  
  if(!this.delayed) { TT.show(this); TT.move(this);}
 },

 dock: function(event)
 {
  Event.stop(event);
  Event.stopObserving(this.element, "click", this.eventMouseClick);
  Event.stopObserving(this.element, "mousemove", this.eventMouseMove);
  Event.stopObserving(this.element, "mouseout", this.eventMouseOut);  
  this.docked = true;
  this.docked_x = Event.pointerX(event);
  this.docked_y = Event.pointerY(event);
  
  this.eventMouseClick   = this.hide.bindAsEventListener(this);
  Event.observe(document, "click", this.eventMouseClick);  
 },
 
 hide: function(event)
 {
  if(!this.docked){
    if(this.timer) clearTimeout(this.timer);
    this.finished = true;
    Event.stop(event);
    this.element.setAttribute('tooltiped','');     
    Event.stopObserving(this.element, "mousemove", this.eventMouseMove);
    Event.stopObserving(this.element, "click", this.eventMouseClick); 
    Event.stopObserving(this.element, "mouseout", this.eventMouseOut);
  } else {
    var pomel = $(Event.element(event));
    while(pomel != undefined){
     if(pomel === this.tooltip) return;
     pomel = pomel.up();
    }
    if(this.timer) clearTimeout(this.timer);
    this.finished = true;  
    this.element.setAttribute('tooltiped',''); 
    Event.stopObserving(document, "click", this.eventMouseClick);   
  }
  TT.hide(this);
 }
}


var TT_M = Class.create();
TT_M.prototype = {
 initialize: function(element,source)
 { 
    this.options = Object.extend({
      vertical: true,
      min_distance_x: 5,
      min_distance_y: 5,
      zindex: 1000
    }, arguments[2] || {});
    
    this.hiding = false;
    this.finished = false;
    this.element = $(element);
    this.source = source;
    if(this.element.getAttribute('tooltiped')==="yes") { return; }   

    this.eventMouseOut   = this.hideDelay.bindAsEventListener(this);
    Event.observe(this.element, "mouseout", this.eventMouseOut);
    
    this.show();      
     
 },
 
 show: function()
 {
  TT.show(this,true);
	Element.setStyle(this.tooltip, { position:'absolute',zIndex: 1000});
  if(this.options.vertical){
   Position.clone(this.element,this.tooltip,{setWidth: false, setHeight: false, offsetTop: this.element.getHeight()});
  }else{
   Position.clone(this.element,this.tooltip,{setWidth: false, setHeight: false, offsetLeft: this.element.getWidth()});
  }
 },
 
 hideDelay: function(event)
 {
  if(this.hiding) return;
  this.timer = setTimeout(this.hide.bind(this),300);
  this.hiding = true;
  this.eventMouseOver   = this.stopHide.bindAsEventListener(this);
  Event.observe(this.tooltip, "mouseover", this.eventMouseOver);  
  Event.observe(this.element, "mouseover", this.eventMouseOver);
 },

 stopHide: function(event)
 {
  if(!this.hiding) return;
  if(this.timer) clearTimeout(this.timer);
  this.hiding = false;
  Event.stopObserving(this.tooltip, "mouseover", this.eventMouseOver);
  Event.stopObserving(this.element, "mouseover", this.eventMouseOver);
  Event.observe(this.tooltip, "mouseout", this.eventMouseOut);  
 },
 
 hide: function()
 {
  this.finished = true;
  this.element.setAttribute('tooltiped','');     
  Event.stopObserving(this.element, "mouseout", this.eventMouseOut);
  Event.stopObserving(this.tooltip, "mouseout", this.eventMouseOut);
  TT.hide(this);
 } 
}

