var Scroller = Class.create();
 
Scroller.ids = new Object();
 
Scroller.i = 0;
 
Scroller.prototype = {
  initialize: function(el) {
    this.outerBox = el;
    this.decorate();
  },
  
  decorate: function() {
    $(this.outerBox).makePositioned(); 
    
    Scroller.i = Scroller.i + 1;
    this.myIndex = Scroller.i;
    
    this.innerBox = document.createElement("DIV");
    this.innerBox.className="scroll-innerBox";
    $(this.innerBox).makePositioned();  
    this.innerBox.style.cssFloat=this.innerBox.style.styleFloat='left'; 
    this.innerBox.id="scroll-innerBox-"+Scroller.i;
    this.innerBox.style.top = "0px";
    
    while (this.outerBox.hasChildNodes()) {
        this.innerBox.appendChild(this.outerBox.firstChild);
    }
    this.innerBox.style.overflow="hidden";
    this.outerBox.style.overflow="hidden";
 
    this.track=document.createElement('div');
    this.track.className="scroll-track";
    $(this.track).makePositioned();
    this.track.style.cssFloat=this.track.style.styleFloat='left';
    this.track.id="scroll-track-"+Scroller.i;
    this.track.appendChild(document.createComment(''));
 
    this.tracktop=document.createElement('div');
    this.tracktop.className="scroll-track-top";
    $(this.tracktop).makePositioned();
    this.tracktop.style.cssFloat=this.tracktop.style.styleFloat='left';
    this.tracktop.id="scroll-track-top-"+Scroller.i;
    this.tracktop.appendChild(document.createComment(''));
    
    this.trackbot=document.createElement('div');
    this.trackbot.className="scroll-track-bot";
    $(this.trackbot).makePositioned();
    this.trackbot.style.cssFloat=this.trackbot.style.styleFloat='left';
    this.trackbot.id="scroll-track-bot-"+Scroller.i;
    this.trackbot.appendChild(document.createComment(''));
 
    this.handle=document.createElement('div');
    this.handle.className="scroll-handle-container";
    this.handle.id="scroll-handle-container"+Scroller.i;
 
    this.handle_middle=document.createElement('div');
    this.handle_middle.className="scroll-handle";
    $(this.handle_middle).makePositioned();
    this.handle_middle.id="scroll-handle-"+Scroller.i;
    this.handle_middle.appendChild(document.createComment(''));
 
    this.handletop=document.createElement('div');
    this.handletop.className="scroll-handle-top";
    $(this.handletop).makePositioned();
    this.handletop.id="scroll-handle-top-"+Scroller.i;
    this.handletop.appendChild(document.createComment(''));
 
    this.handlebot=document.createElement('div');
    this.handlebot.className="scroll-handle-bot";
    $(this.handlebot).makePositioned();
    this.handlebot.id="scroll-handle-bot-"+Scroller.i;
    this.handlebot.appendChild(document.createComment(''));
 
    this.track.hide();
    this.tracktop.hide();
    this.trackbot.hide();
 
    this.outerBox.appendChild(this.innerBox);
    this.outerBox.appendChild(this.tracktop);
    this.handle.appendChild(this.handletop);
    this.handle.appendChild(this.handle_middle);
    this.handle.appendChild(this.handlebot);
    this.track.appendChild(this.handle);
    this.outerBox.appendChild(this.track);
    this.outerBox.appendChild(this.trackbot);
 
    this.slider = new Control.Slider($(this.handle).id, $(this.track).id, {axis:'vertical',
                                     minimum: 0,
                                     maximum: $(this.outerBox).clientHeight});
    this.slider.options.onSlide = this.slider.options.onChange = this.onChange.bind(this);
    setTimeout(this.resetScrollbar.bind(this, false), 10);
 
    this.domMouseCB = this.MouseWheelEvent.bindAsEventListener(this, this.slider);
    this.mouseWheelCB = this.MouseWheelEvent.bindAsEventListener(this, this.slider);
    this.trackTopCB = this.tracktopEvent.bindAsEventListener(this, this.slider);
    this.trackBotCB = this.trackbotEvent.bindAsEventListener(this, this.slider);
    
    $(this.outerBox).observe('DOMMouseScroll', this.domMouseCB); 
    $(this.outerBox).observe('mousewheel', this.mouseWheelCB);
    $(this.tracktop).observe('mousedown', this.trackTopCB);
    $(this.trackbot).observe('mousedown', this.trackBotCB);
  },
  
  release: function() {
    $(this.outerBox).stopObserving('DOMMouseScroll', this.domMouseCB);
    $(this.outerBox).stopObserving('mousewheel', this.mouseWheelCB);
    $(this.tracktop).stopObserving('mousedown', this.trackTopCB);
    $(this.trackbot).stopObserving('mousedown', this.trackBotCB);
  },
 
  slideToTop: function() {
    this.slider.setValue(0);
  },
  
  resetScrollbar: function(repeat) {
        this.track.hide();
        this.tracktop.hide();
        this.trackbot.hide();
        this.enableScroll = false;
        this.innerHeight = $(this.outerBox).clientHeight;
        this.innerBox.style.height = this.innerHeight + "px";
        var newWidth = $(this.outerBox).clientWidth;
 
        var tth = Element.getStyle(this.tracktop,"height");
        if (tth)
           tth = tth.replace("px","");
        else
           tth = 0;
    
        var hth = Element.getStyle(this.handletop,"height");
        if (hth)
           hth = hth.replace("px","");
        else
           hth = 0;
    
        if (this.innerHeight < this.innerBox.scrollHeight) {
            this.viewportHeight = this.innerHeight - tth*2;
            this.slider.trackLength = this.viewportHeight;
            this.track.style.height = this.viewportHeight + "px";       
            this.handleHeight = Math.round(this.viewportHeight * this.innerHeight / this.innerBox.scrollHeight);    
            if(this.handleHeight < (hth*2))
                this.handleHeight = (hth*2);
            if (this.handleHeight < 10)
                 this.handleHeight = 10;
            this.handle.style.height = this.handleHeight + "px";
            this.handle_middle.style.height = this.handleHeight - hth*2 + "px";
            this.handletop.style.height = hth + "px";
            this.slider.handleLength = this.handleHeight;
            this.track.style.display = 'inline';
            this.tracktop.style.display = 'inline';
            this.trackbot.style.display = 'inline';
            this.ieDecreaseBy = 1;   
            if (this.outerBox.currentStyle) {
                var borderWidth = this.outerBox.currentStyle["borderWidth"].replace("px","");
                if(!isNaN(borderWidth)) {
                    this.ieDecreaseBy = (borderWidth) * 2;
                }
            }
            newWidth = ($(this.outerBox).clientWidth - $(this.track).clientWidth - this.ieDecreaseBy);
            this.enableScroll = true;
        }
        this.innerBox.style.width = newWidth + "px";
        if(repeat) {
            setTimeout(this.resetScrollbar.bind(this, false), 10);
        }
  },
  
    MouseWheelEvent: function(event, slider) {
        var delta = 0;
        if (!event) 
            event = window.event;
        if (event.wheelDelta) { 
            delta = event.wheelDelta / 120;
        } else if (event.detail) { 
            delta = -event.detail / 3;
        }
        if (delta)
            slider.setValueBy(-delta / 100);		
        Event.stop(event);
    },
 
    trackbotEvent: function(event, slider) {
        if (Event.isLeftClick(event)) { 
            slider.setValueBy(0.2);
            Event.stop(event);
        }
    },
 
    tracktopEvent: function(event, slider) {
        if (Event.isLeftClick(event)) {
            slider.setValueBy(-0.2);
            Event.stop(event);
        }
    },
 
    onChange: function(val) {
        if(this.enableScroll)
            this.innerBox.scrollTop = Math.round (val * (this.innerBox.scrollHeight-this.innerBox.offsetHeight));
    }
}
 
Scroller.setAll = function () {
    $$('.makeScroll').each(function(item) {
        Scroller.ids[item.id] = new Scroller(item);
    });
}
 
Scroller.updateAll = function () {
    $H(Scroller.ids).each(function(pair) {
        Scroller.ids[pair.key].resetScrollbar(true);
    });
}
 
Scroller.reset = function (body_id) {
    if ($(body_id).className.match(new RegExp("(^|\\s)makeScroll(\\s|$)"))) {
       if (Scroller.ids[body_id])
           Scroller.ids[body_id].release();
           
        Scroller.ids[body_id] = new Scroller($(body_id));
    }
}
 
Scroller.scrollToTop = function (body_id) {
    if ($(body_id).className.match(new RegExp("(^|\\s)makeScroll(\\s|$)"))) {
       if (Scroller.ids[body_id])
           Scroller.ids[body_id].slideToTop();
    }
}
 
Event.observe(window, "load", Scroller.setAll);
Event.observe(window, "resize", Scroller.updateAll);
