
	var InfoBox	= Class.create();
	InfoBox.prototype = {
		
		el_infobox		: null,
		el_infobox_text	: null,
		el_last_touched	: null,
		at_oldtitle		: null,
		options			: {
					from			: 'title',
					elements		: 'infobox',
					className		: 'infoboxPopup',
					onload			: true,
					width			: 300,
					height			: null,
					maxChars		: null,
					followMouse		: true,
					offsetX			: 10,
					offsetY			: 10,
					style			: {
						position		: 'absolute',
						visibility		: 'hidden',
						opacity			: 0.9,
						color			: '#ffffff'
					}
		},
		
		initialize:function(options) {
			try {
				
				this.options = Object.extend( this.options, options || {} );
				
				if(this.options.width) this.options.style.width		= this.options.width + 'px';
				if(this.options.height) this.options.style.height	= this.options.height + 'px';
				
				if( this.options.onload ) {
					Event.observe( window,'load', this.buildInfoBox.bindAsEventListener(this) );
					Event.observe( window,'load', this.bindEvents.bindAsEventListener(this) );
				} else  {
					this.buildInfoBox();
					this.bindEvents();
				}

			} catch( e ) {
				alert('InfoBox failed to initialize (' + e.message + ')');
			}
		},
		
		buildInfoBox: function () {
			
			popupElement				= document.getElementsByClassName( this.options.className );

			if( popupElement.length == 0 ) {
				
				// check if box already exist !
				var infobox		= Builder.node('div', { className:this.options.className }, [
					Builder.node( 'div', { className: this.options.className + 'Top'}, [
						Builder.node( 'div', { className: this.options.className + 'Top'} )
					] ),
					Builder.node( 'div', { className: this.options.className + 'TextContent'}, [
						this.el_infobox_text = Builder.node( 'div', { className: this.options.className + 'Text'} )
						] ),
					Builder.node( 'div', { className: this.options.className + 'Bottom'}, [
						Builder.node( 'div', { className: this.options.className + 'Bottom'} )
					] ),
				]);
				Element.setStyle( infobox, this.options.style );
				
				document.body.appendChild( infobox );
			} else  {
				infobox					= popupElement[0];
				this.el_infobox_text	= infobox.getElementsByClassName( this.options.className + 'Text' )[0];
			}
			
			this.el_infobox		= infobox;
			infobox				= null;
		},
		
		bindEvents: function() {

			elements		= document.getElementsByClassName( this.options.elements );

			for( var i=0; i < elements.length; i++ ) {
				Event.observe( elements[i], 'mouseover', this.show.bindAsEventListener( this, elements[i] ) );
				Event.observe( elements[i], 'mouseout', this.hide.bindAsEventListener( this, elements[i] ) );

				if( this.options.followMouse )
					Event.observe( elements[i], "mousemove", this.calcAndPlace.bindAsEventListener(this), false);
			}
		},
		
		show: function(e) {

			element			= Event.element(e);

			title			= element.getAttribute( this.options.from );
			this.at_oldtitle		= title;
			
			if( !title) return false;
			title			= this.options.maxChars ? title.substring( 0, this.options.maxChars) + ( title.length > this.options.maxChars ? '...' : '') : title;

			if( title == '') 
				return false;

			element.setAttribute( this.options.from, '');
			
			this.el_last_touched	= element;

			Element.update( this.el_infobox_text, title );
			
			if( !this.options.followMouse )
				this.calcAndPlace( );
				
			Element.setStyle( this.el_infobox, { visibility: 'visible' } );
		},
		
		hide: function(e) {
			element		= Event.element(e);
			Element.setStyle( this.el_infobox, { visibility: 'hidden' } );
			element.setAttribute( this.options.from, this.at_oldtitle);
		},
		
		calcAndPlace: function(e) {

			if( this.el_last_touched ) {
				
				elementPosToViewport	= Position.page( this.el_last_touched );
				elementViewportLeft		= elementPosToViewport[0];
				elementViewportTop		= elementPosToViewport[1];
				infoboxWidth			= this.el_infobox.offsetWidth;
				infoboxHeight			= this.el_infobox.offsetHeight;
				
				if( this.options.followMouse ) {
					elementLeft				= Event.pointerX(e);
					elementTop				= Event.pointerY(e);
				} else {
					elementPosToTop			= Position.cumulativeOffset( this.el_last_touched );
					elementLeft				= elementPosToTop[0];
					elementTop				= elementPosToTop[1];
				}
	
				viewportWidth		=  self.innerWidth || (document.documentElement.clientWidth || document.body.clientWidth); 
	
				positionTop			= (elementViewportTop > infoboxHeight ) ? ( elementTop - infoboxHeight ) : ( elementTop + this.options.offsetY );
				positionLeft		= ( ( elementViewportLeft + infoboxWidth ) < ( viewportWidth - this.options.offsetX )) ? ( elementLeft + this.options.offsetX ) : ( elementLeft - infoboxWidth - this.options.offsetX );
				
				Element.setStyle( this.el_infobox, {left: positionLeft + 'px', top: positionTop + 'px' } );
			}
		}
	}
	
