
/**
 * JG 5/13/2009 New ToolTip Structure
 * JR 11/4/2009 Refactored this class and added some utility methods for manipulating Tooltips via JavaScript
 * 
 * involves a singleton delegate listenign to mouse events on the page
 * This allows us to register content dynamically with the delegate as AJAX calls may
 * contain tool tips.  it also allows for lazy rendering of tool tip text to keep the DOM clean
 */
var ToolTipDelegate = Class.create( {
	CLASS_HAS_TOOL_TIP: 'hasToolTip',
	
	initialize: function initializeToolTipDelegate(){
		this.tips = new Hash();
		this.display = $('ToolTipContainer');
	},
	
	GetContent: function GetContent( key ){
		return this.tips.get( key );
	},
		
	SetKeyAndContent: function SetKeyAndContent( key, content ){
		this.tips.set( key, content );
	},
		
	RegisterKeyAndContent: function RegisterKeyAndContent( key, content ){
		this.SetKeyAndContent( key, content );
		var element = $( key );
		if( element ){
			Element.addClassName( element, this.CLASS_HAS_TOOL_TIP );
			
			Element.observe( element, 'mouseover', this.ShowToolTip.bind( this ) );
			Element.observe( element, 'mousemove', this.TrackToolTip.bind( this ) );
			Element.observe( element, 'mouseout', this.HideToolTip.bind( this ) );
		}
	},
		
	ShowToolTip: function ShowToolTip( e ){
		var element = this.GetToolTipElement( e ); 
		if( element ){
			var tip = this.GetContent( element.id );
			if(typeof tip == 'function'){
				tip = tip(e);
			}
			if( tip ){
				this.display.update( tip );
				this.PositionToolTip( e );
				this.display.show();
			}
		}
	},
	
	TrackToolTip: function TrackToolTip( e ){
		var element = this.GetToolTipElement( e ); 
		if( element ){
			this.PositionToolTip( e );
		}
		else{
			this.HideToolTip( e );
		}
	},
	
	HideToolTip: function HideToolTip( e ){
		this.display.hide();
	},
	
	PositionToolTip: function PositionToolTip( e ){
		//fix if the tip moves off screen
		var tipTop = ( e.pointerY() + 10 );
		var tipLeft = ( e.pointerX() + 10 );
		var screenBottom = document.body.scrollTop + document.body.clientHeight;
		var tipBottom = tipTop + this.display.offsetHeight;
		var screenRight = document.body.scrollLeft + document.body.clientWidth;
		var tipRight = tipLeft + this.display.offsetWidth;		
		if( tipBottom > screenBottom ){
			tipTop = e.pointerY() - 10 - this.display.getHeight();
		}
		if( tipRight > screenRight ){
			tipLeft = e.pointerX() - 10 - this.display.getWidth();
		}
		this.display.setStyle( {
			left : tipLeft + 'px',
			top : tipTop + 'px'
		} );
	},

	GetToolTipElement: function GetToolTipElement( e ){
		var element = Event.element( e );
		return Element.hasClassName( element, this.CLASS_HAS_TOOL_TIP ) ? element : Element.up( element, '.' + this.CLASS_HAS_TOOL_TIP );
	}
} );

ToolTipDelegate.GetInstance = function ToolTipDelegateGetInstance(){
	if( ! ToolTipDelegate._Instance ){
		ToolTipDelegate._Instance = new ToolTipDelegate();
	}
	return ToolTipDelegate._Instance;
};
