ToolTip = ElementContainer.extend ( {
	constructor:function ( text, isHtml, trace, constrain ) {
		this.base ( 'tooltip' );
		this.delay = 400;
		if ( isHtml ) {
			this.element.innerHTML = text;
		} else {
			this.element.appendChild ( CT (text) );
		}
		this.trace = (trace?true:false); // force bool
		this.setConstrainByParent ( constrain );
		this.boundPopup = this.popup.bind ( this );
		this.boundPopout = this.popout.bind ( this );
		this.hide ();
	},
	
	popup:function ( event ) {
		this.startMouseTrace ( event );
		this.show.delay = setTimeout ( this.show.bind(this), this.delay );
	},
	
	show:function () {
		this.base ();
	},
	
	popout:function () {
		if ( this.show.delay ) {
			clearTimeout ( this.show.delay );
		}
		this.hide ();
		this.stopMouseTrace ();
	},
	
	attachTo:function ( element, delay ) {
		if ( typeof delay != 'undefined' ) {
			this.delay = delay;
		}
		Event.observe (element,
		'mouseover',
			function( event ) { 
				this.boundPopup (event); 
			}.bind(this),
			false
		);
		Event.observe (element,'mouseout',this.boundPopout,false);
	},
	
	detachFrom:function ( element ) {
		Event.stopObserving ( element, 'mouseover', this.boundPopup, false );
		Event.stopObserving ( element, 'mouseout', this.boundPopup, false );
	},
	
	updateMouseXY:function ( x, y ) {
		if ( !this.trace && this.isVisible () ) {
			return;
		}
		this.setPosition ( x, y );
	}
} );

ToolTip.implement ( Hidable );
ToolTip.implement ( Movable );
ToolTip.implement ( Tracable );
ToolTip.create = function ( hookElement, text, isHtml, trace, constrain ) {
	var ret = new ToolTip ( text, isHtml, trace, constrain );
	document.body.appendChild ( ret.getElement () );
	ret.attachTo ( hookElement );
};