RBjs.Hint = new function()
{
    var me = this;
    this.hint_cache = {};
   
    this.hint_absolute_container = null;
    this.hint_html_container = null;
    
    this.ini = function()
    {
        if( me.hint_absolute_container != null ) return;
        me.hint_absolute_container = window.document.createElement( 'DIV' );
        me.hint_absolute_container.id = 'hint_absolute_container';
        me.hint_absolute_container.innerHTML = 
        '<div class="hint_top"></div>\
            <div class="hint_center">\
                <div id="hint_html_container">\
                </div>\
            </div>\
         <div class="hint_bottom"></div>';
        
        document.body.appendChild( me.hint_absolute_container );
         
        me.hint_html_container = document.getElementById( 'hint_html_container' );
    }
    
    /* from prototype 1.6 
       source: http://www.prototypejs.org/
    */
    this.cumulativeOffset = function(element)
    {
        var valueT = 0, valueL = 0;
        do {
          valueT += element.offsetTop  || 0;
          valueL += element.offsetLeft || 0;
          element = element.offsetParent;
        } while (element);
        return {'top': valueT, 'left': valueL};
    }
    
    this.hide = function()
    {
        me.ini();
        
        me.hint_absolute_container.style.display = 'none';    
    }
    
    this.show = function( event )
    {
        me.ini();
        
        me.hint_absolute_container.style.display = 'none';
        
        var obj = (event.target) ? event.target : event.srcElement;
        var hint_inline_text = obj.getAttribute('hint');
        
        var obj_xy = me.cumulativeOffset( obj );
        var dx = parseInt( obj.getAttribute('hint-dx') );
        var dy = parseInt( obj.getAttribute('hint-dy') );
        
        dx = isNaN(dx) ? 0 : dx;
        dy = isNaN(dy) ? 0 : dy; 
        
        me.hint_absolute_container.style.left = obj_xy['left'] + dx + 'px';
        me.hint_absolute_container.style.top = -1000 + 'px';
        
        me.hint_absolute_container.style.display = 'block';
        
        if( hint_inline_text ) {
            me.hint_html_container.innerHTML = hint_inline_text;
            
            var offH = me.hint_absolute_container.offsetHeight;
            me.hint_absolute_container.style.top = obj_xy['top'] - offH + dy + 'px';
        } else {
            
            
            var key = obj.id;
            
            if( !key ) return;
            
            /*            
            if( me.hint_cache[key] ) {
                 me.hint_absolute_container = me.hint_cache[key];
            } else {
                 me.hint_absolute_container = me.hint_cache[key];
            }
            */
            
            var hint_div = document.getElementById( key + '_hint' );
            if( !hint_div ) return;
            
            me.hint_html_container.innerHTML = hint_div.innerHTML;
            
            var offH = me.hint_absolute_container.offsetHeight;
            me.hint_absolute_container.style.top = obj_xy['top'] - offH + dy + 'px';
        }
        
    }
}