
Prototype.require('Object.Event');

if (!Control) var Control = {};

/**
 * Tooltip controller
 * 
 * Usage:
 *  var tooltip = new Control.Tooltip($('tooltip'));
 *  
 * Options:
 *  - hide : the hide function
 *  - show : the show function
 *  - anchor : the relative object that the tooltip will be positioned (pointer|target)
 *  - fps : the refresh rate
 *  - tooltipOffsetX, tooltipOffsetY : position of the tooltip arrow from the center
 *  - offsetX, offsetY : custom offset to add
 *  
 * Events
 *  - no events
 */
Control.Tooltip = Class.create({
	initialize: function(target, tooltip, options) {
		this.options = this.options || {};
		
		this._target = $(target);
		this._tooltip = $(tooltip);

		Object.extend(this.options, {
			//delay: 0.5,
			hide: Element.hide,
			show: Element.show,
			anchor: 'pointer', //pointer| target,
			fps : 20,
			tooltipOffsetX : 0,
			tooltipOffsetY : 0,
			offsetX : 0,
			offsetY : 0
		});
		Object.extend(this.options, options || {});
	
		
		this._offsetX = this.options.tooltipOffsetX - (this._tooltip.getWidth() /2) + this.options.offsetX;
		this._offsetY = this.options.tooltipOffsetY - (this._tooltip.getHeight() /2) + this.options.offsetY;
		
		// hide the tool-tip by default
		this._display = false;
		this._tooltip.hide();
		this._tooltip.absolutize();
		
		this._updater = null;

		Event.observe(this._target, 'mouseover', this.onMouseOver.bindAsEventListener(this));
		Event.observe(this._target, 'mouseout', this.onMouseOut.bindAsEventListener(this));
	},
	destroy: function() {
		Event.stopObserving(this._target, 'mouseover', this.onMouseOver);
		Event.stopObserving(this._target, 'mouseout', this.onMouseOut);
	},
	onMouseOver: function(event){	
		if(!this.display) {
			this._display = true;
			//appear if not visible
			this._show(this._tooltip);

			this._updater = new PeriodicalExecuter(this.refresh.bind(this), 1 / this.options.fps);
			//this.refresh();
		}
	},
	onMouseOut: function(event){
		if(this._display) {
			this._display = false;
			//appear if not visible
			this._hide(this._tooltip);
			this._updater.stop();
		}
	},
	refresh: function() {
		if(this._display) {
			var offset = this._target.cumulativeOffset();
			var dimensions = this._target.getDimensions();
			
			//If the pointer is not on the target simulate a mouseout event
			if( !this._target
			|| offset.left > Control.pointerX
			|| offset.top  > Control.pointerY
			|| offset.left + dimensions.width < Control.pointerX
			|| offset.top + dimensions.height < Control.pointerY
			) {
				this.onMouseOut();
				return;
			}

			moveInfo($(this._tooltip));
		}
	},
	_show: function(element) {
		element = $(element);
		if(this.options.show && !element.visible()) {
			this.options.show(element);
		}
	},
	_hide: function(element) {
		element = $(element);
		if(this.options.hide && element.visible()) {
			this.options.hide(element);
		}
	}
});

//Object.Event.extend(Control.Tooltip);
Prototype.provide('Control.Tooltip', Control.Tooltip);