/*
 This work is licensed under the Creative Commons Attribution 3.0 License.
 To view a copy of this license, visit 
 http://creativecommons.org/licenses/by/3.0/
 
 Copyright Riccardo Attilio Galli http://www.sideralis.org
*/

/**
 * Creates a div element whose content can be scrolled
 * 
 * @id the id of the newly created object
 * @width integer representing a width in pixel
 * @height integer representing a width in pixel
*/

ScrollableDIV=function(id,width,height) {
    this.upTimeout=null;
    this.downTimeout=null;
    
    this._id=id;
    
    var HACK=";height:"+(height-20)+"px;";
    
    this._scrollCode='\
\
<div id=">>ID<<_middle" style="height:>>HEIGHT<<px;position:relative;overflow:hidden;"> \
      <div style="'+HACK+'">  \
        <div id=">>ID<<_content" style="position:absolute;left:0;top:0;">  \
            aaa a a awewe we we <!-- HERE WILL BE INSERTED THE CONTENT-->  \
            <div></div> \
        </div>  \
      </div>  \
      \
      <div id=">>ID<<_bar" style="position:relative;height:20px;bottom:0;border-top:1px black solid;">  \
        <div style="display:inline"><a href="#" onmouseover="BOX_ACTIONS.startMotionUp(\'>>ID<<\');"  \
            onmouseout="BOX_ACTIONS.stopMotionUp(\'>>ID<<\')">up</a></div>  \
        <div style="position:absolute;display:inline;right:0"><a href="#" onmouseover="BOX_ACTIONS.startMotionDown(\'>>ID<<\');"  \
            onmouseout="BOX_ACTIONS.stopMotionDown(\'>>ID<<\')">down</a></div> \
        <div style="clear:both" />  \
      </div> \
</div>';
    
    
    this._outerBox=document.createElement('div');
    this._outerBox.style.width=""+width+"px";
    this._outerBox.id=id;
    
    var tmpStr=this._scrollCode.replace(/>>ID<</g,id).replace(/>>HEIGHT<</g,height);
    
    this._outerBox.innerHTML=tmpStr;
    
    
}

/**
 * Returns the scrollable div main container (a div element)
 */
ScrollableDIV.prototype.getDiv=function(){
    return this._outerBox;
}

/**
 * Find the tag with id "id", remove his child and replace it with the the document node
 *  (getElementById is not used because this function could be called while document has not
 *  finished loading.
 *
 * @tag tag of the element we're searching
 * @id id attribute of the element we're serching
 * @newNode DOM element who's going to replace the current content of <tag id="id">
*/
ScrollableDIV.prototype._findAndReplace=function(tag,id,newNode) {
    var x=this._outerBox.getElementsByTagName(tag);
    for (i=0;i<x.length;i++) {
        if(x[i].id==id) {
            //remove all children of x[i]
            for (k=x[i].childNodes.length-1;k>=0;k--) {
                x[i].removeChild(x[i].childNodes[k]);
            }
            
            // make sure newNode isn't child of anyone
            if (newNode.parentNode) {
                newNode.parentNode.removeChild(newNode);
            }
            x[i].appendChild(newNode);
            break;
        }
    }
}

/**
 * Sets the content of the scrollable div, searching in the DOM the element whose id is the one
 *  passed to this function. This element is removed from his previous parent and
 *  inserted in the scrollable div.
 *
 * @id the id property of the DOM element used as content
 */
ScrollableDIV.prototype.setContentById=function(id) {
    var contentElem=document.getElementById(id);
    this._findAndReplace('div',this._id+"_content",contentElem);
}

ScrollableDIV.prototype.setBarById=function(id) {
    var barElem=document.getElementById(id);
    this._findAndReplace('div',this._id+"_bar",barElem);
}

/**
 * Sets the content of the scrollable div
 *
 * @htmlString a string containing valid (x)html code
 */
ScrollableDIV.prototype.setContent=function(htmlString) {
    var elem=document.createElement('div');
    elem.innerHTML=htmlString;
    this._findAndReplace('div',this._id+"_content",elem);
}

ScrollableDIV.prototype.setBar=function(htmlString) {
    var elem=document.createElement('div');
    elem.innerHTML=htmlString;
    this._findAndReplace('div',this._id+"_bar",elem);
}

ScrollableDIV.prototype.appendTo=function(id) {
    document.getElementById(id).appendChild(this.getDiv());
}


BOX_ACTIONS = {
    up : function(innerDiv) {
            if(innerDiv.offsetTop+innerDiv.offsetHeight>=20) {
                innerDiv.style.top=parseInt(innerDiv.style.top)-5+"px";
            }
        },
    
    down : function(innerDiv){
            if(innerDiv.offsetTop<0) {
                innerDiv.style.top=parseInt(innerDiv.style.top)+5+"px";
            }
        },
    
    startMotionUp : function(scrollerId){
            var innerDivId=scrollerId+"_content";
            var obj=this;
            upTimeout=setInterval(function(){obj.up(document.getElementById(innerDivId));},20);
            this._up_timeouts[scrollerId]=upTimeout;
        },
    
    startMotionDown : function(scrollerId){
            var innerDivId=scrollerId+"_content";
            var obj=this;
            downTimeout=setInterval(function(){obj.down(document.getElementById(innerDivId));},20);
            this._down_timeouts[scrollerId]=downTimeout;
        },
    
    stopMotionUp : function(scrollerId) {
            if (this._up_timeouts[scrollerId]) {
                clearInterval(this._up_timeouts[scrollerId]);
                this._up_timeouts[scrollerId]=null;
            }
        },

    stopMotionDown : function(scrollerId) {
            if (this._down_timeouts[scrollerId]) {
                clearInterval(this._down_timeouts[scrollerId]);
                this._down_timeouts[scrollerId]=null;
            }
        },
    
    _up_timeouts : {},
    _down_timeouts : {}

}

