

var HoverTip = Class.create(
{
	element: null,
	
	tip: "",
	
	bubble: null, // DIV to contain tip contents
	
	active: false,
	
	initialize: function( element )
	{
		this.element = $( element );
		this.initOther();
		this.initDOM();
		this.initEvents();
	},
	
	initDOM: function()
	{
		this.bubble = new Element( "div" );
		this.bubble.addClassName( "hover-tip-bubble" );
		
		var p = new Element( "p" );
		p.update( this.tip );
		
		this.bubble.insert( p );
		this.bubble.hide();
		this.element.insert( { after: this.bubble } );
	},
	
	initOther: function()
	{
		this.tip = this.element.getAttribute( "title" );
		this.element.removeAttribute( "title" );
	},
	
	initEvents: function()
	{
		this.element.observe( "mouseover", this.handleMouseOver.bind( this ) );
		this.element.observe( "mouseout", this.handleMouseOut.bind( this ) );
		this.element.observe( "mousemove", this.handleMouseMove.bind( this ) );
	},
	
	activate: function( e )
	{
		this.bubble.show();
		this.moveBubbleTo( e.pointerX(), e.pointerY() );
		this.active = true;
	},
	
	deactivate: function()
	{
		this.bubble.hide();
		this.active = false;
	},
	
	isActive: function()
	{
		return this.active;
	},
	
	moveBubbleTo: function( x, y )
	{
		this.bubble.setStyle( { left: ( x + HoverTip.OFFSET_X ) + "px", top: ( y + HoverTip.OFFEST_Y ) + "px" } );
	},
	
	/**
	 * Event Handlers
	 */
	
	handleMouseOver: function( e )
	{
		Event.stop( e );
		if( !this.isActive() ) this.activate( e );
		else this.moveBubbleTo( e.pointerX(), e.pointerY() );
	},
	
	handleMouseOut: function( e )
	{
		Event.stop( e );
		this.deactivate();
	},
	
	handleMouseMove: function( e )
	{
		Event.stop( e );
		this.moveBubbleTo( e.pointerX(), e.pointerY() );
	}
});

HoverTip.OFFSET_X = 2;
HoverTip.OFFEST_Y = 14;

document.observe( "dom:loaded", function(){ $$( ".hover-tip" ).each( function( el ){ if( el.title ) new HoverTip( el ) } ) } );