﻿/* tooltip-0.2.js - Small tooltip library on top of Prototype 
 * by Jonathan Weiss <jw@innerewut.de> distributed under the BSD license. 
 *
 * This tooltip library works in two modes. If it gets a valid DOM element 
 * or DOM id as an argument it uses this element as the tooltip. This 
 * element will be placed (and shown) near the mouse pointer when a trigger-
 * element is moused-over.
 * If it gets only a text as an argument instead of a DOM id or DOM element
 * it will create a div with the classname 'tooltip' that holds the given text.
 * This newly created div will be used as the tooltip. This is usefull if you 
 * want to use tooltip.js to create popups out of title attributes.
 * 
 *
 * Usage: 
 *   <script src="/javascripts/prototype.js" type="text/javascript"></script>
 *   <script src="/javascripts/tooltip.js" type="text/javascript"></script>
 *   <script type="text/javascript">
 *     // with valid DOM id
 *     var my_tooltip = new Tooltip('id_of_trigger_element', 'id_of_tooltip_to_show_element')
 *
 *     // with text
 *     var my_other_tooltip = new Tooltip('id_of_trigger_element', 'a nice description')
 *
 *     // create popups for each element with a title attribute
 *    Event.observe(window,"load",function() {
 *      $$("*").findAll(function(node){
 *        return node.getAttribute('title');
 *      }).each(function(node){
 *        new Tooltip(node,node.title);
 *        node.removeAttribute("title");
 *      });
 *    });
 *    
 *   </script>
 * 
 * Now whenever you trigger a mouseOver on the `trigger` element, the tooltip element will
 * be shown. On o mouseOut the tooltip disappears. 
 * 
 * Example:
 * 
 *   <script src="/javascripts/prototype.js" type="text/javascript"></script>
 *   <script src="/javascripts/scriptaculous.js" type="text/javascript"></script>
 *   <script src="/javascripts/tooltip.js" type="text/javascript"></script>
 *
 *   <div id='tooltip' style="display:none; margin: 5px; background-color: red;">
 *     Detail infos on product 1....<br />
 *   </div>
 *
 *   <div id='product_1'>
 *     This is product 1
 *   </div>
 *
 *   <script type="text/javascript">
 *     var my_tooltip = new Tooltip('product_1', 'tooltip')
 *   </script>
 *
 * You can use my_tooltip.destroy() to remove the event observers and thereby the tooltip.
 */
 
var Tooltip = Class.create();

Tooltip.prototype = {
initialize: function(element, tool_tip) {
var options = Object.extend({
	default_css: false,
	margin: "0px",
	padding: "5px",
	backgroundColor: "#d6d6fc",
	min_distance_x: 5,
	min_distance_y: 5,
	delta_x: Prototype.Browser.IE ? -2 : 0,
	delta_y: Prototype.Browser.IE ? -2 : 0,
	zindex: 1000,
	
	// want some shadow?
	enableShadow: true,
	backgroundColorForShadow: "#f6f6f6",		
	shadow_distance: 1
}, arguments[2] || {});

this.element      = $(element);

this.options      = options;

// use the supplied tooltip element or create our own div
if($(tool_tip)) 
{
  this.tool_tip = $(tool_tip);
} 
else 
{
  this.tool_tip = $(document.createElement("div")); 
  document.body.appendChild(this.tool_tip);
  this.tool_tip.addClassName("tooltip");
  this.tool_tip.appendChild(document.createTextNode(tool_tip));
}

// shadow
this.tool_shadow = $(document.createElement("div")); 
document.body.appendChild(this.tool_shadow);
this.tool_shadow.appendChild(document.createTextNode(" "));

// hide the tool-tip by default
this.tool_tip.hide();
this.tool_shadow.hide();

this.eventMouseOver = this.showTooltip.bindAsEventListener(this);
this.eventMouseOut   = this.hideTooltip.bindAsEventListener(this);
this.eventMouseMove  = this.moveTooltip.bindAsEventListener(this);

this.registerEvents();
},

destroy: function() {
Event.stopObserving(this.element, "mouseover", this.eventMouseOver);
Event.stopObserving(this.element, "mouseout", this.eventMouseOut);
Event.stopObserving(this.element, "mousemove", this.eventMouseMove);
},

registerEvents: function() {
Event.observe(this.element, "mouseover", this.eventMouseOver);
Event.observe(this.element, "mouseout", this.eventMouseOut);
Event.observe(this.element, "mousemove", this.eventMouseMove);
},

moveTooltip: function(event){
	Event.stop(event);
	// get Mouse position
	var mouse_x = Event.pointerX(event);
	var mouse_y = Event.pointerY(event); 

	// decide if wee need to switch sides for the tooltip 
	var dimensions = Element.getDimensions( this.tool_tip );
	var element_width = dimensions.width;
	var element_height = dimensions.height;

	if ( (element_width + mouse_x) >= ( this.getWindowWidth() - this.options.min_distance_x) ){ // too big for X
	  mouse_x = mouse_x - element_width;
	  // apply min_distance to make sure that the mouse is not on the tool-tip
	  mouse_x = mouse_x - this.options.min_distance_x;
	} else {
	  mouse_x = mouse_x + this.options.min_distance_x;
	}

	if ( (element_height + mouse_y) >= ( this.getWindowHeight() - this.options.min_distance_y) )
	{ 
		// too big for Y
		mouse_y = mouse_y - element_height;
		// apply min_distance to make sure that the mouse is not on the tool-tip 
		mouse_y = mouse_y - this.options.min_distance_y;
	} 
	else 
	{
		mouse_y = mouse_y + this.options.min_distance_y;
	} 

	// now set the right styles 
	this.setStyles(mouse_x, mouse_y);
},

	
showTooltip: function(event) {
	Event.stop(event);
	this.moveTooltip(event);
	new Element.show(this.tool_tip);
	if(this.options.enableShadow)
		new Element.show(this.tool_shadow);
},

setStyles: function(x, y) 
{
	// set the right styles to position the tool tip
	Element.setStyle(
		this.tool_tip, 
		{ 
			position:'absolute',
			top:y + this.options.delta_y + "px",
			left:x + this.options.delta_x + "px",
			zIndex:this.options.zindex
		}
	);

	// set the right styles to position the tool tip's shadow  
	if(this.options.enableShadow)
	{
		var dimensions = this.tool_tip.getDimensions();
		Element.setStyle(
			this.tool_shadow, 
			{ 
				position:'absolute', 
				top:y + this.options.delta_y + this.options.shadow_distance + "px",
				left:x + this.options.delta_x + this.options.shadow_distance + "px",
				width:dimensions.width + "px",
				height:dimensions.height + "px",
				zIndex:this.options.zindex - 1
			}
		);	
	}

	// apply default theme if wanted  
	if (this.options.default_css)
	{
		Element.setStyle(
			this.tool_tip, 
			{ 
				margin:this.options.margin,
				padding:this.options.padding,
				backgroundColor:this.options.backgroundColor,
				zIndex:this.options.zindex
			}
		);	
		
		if(this.options.enableShadow)
			Element.setStyle(
				this.tool_shadow, 
				{ 
					backgroundColor:this.options.backgroundColorForShadow
				}
			);		
	}
	else
	{
		if(this.options.enableShadow)
			this.tool_shadow.className = this.tool_tip.getAttribute("shadowClass");
	}	
},

hideTooltip: function(event){
	new Element.hide(this.tool_tip);
	if(this.options.enableShadow)
		new Element.hide(this.tool_shadow);
},

getWindowHeight: function()
{ 
    return Prototype.Browser.IE ? document.documentElement.clientHeight : window.innerHeight;
},

getWindowWidth: function()
{
    return Prototype.Browser.IE ? document.documentElement.clientWidth : window.innerWidth;
} 

} 
 

