﻿//nemScollBar.js
//2008 Paul Graves paul.graves@nemisys.uk.com
//Css styles scrollbar within an overflown div
//code adapted from http://www.solutoire.com/experiments/scrollbar/index.html

var nemScrollbox = new Class({
    initialize: function(el) {
        this.scrollBox = el;
        this.steps = this.scrollBox.getScrollSize().y - this.scrollBox.getSize().y;
        this.scroll = false;
        if (this.steps > 0) {
            this.scroller = new Element("DIV", { 'class': 'nemScroll' });
            this.scrollbar = new Element("DIV", { 'class': 'nemScrollbar', 'html': '&nbsp;' });

            this.scroller.inject(this.scrollBox, 'after');
            this.scrollbarUp = new Element("DIV", { 'class': 'nemScrollbarUp', 'html': '&nbsp;' });
            this.scrollbarDown = new Element("DIV", { 'class': 'nemScrollbarDown', 'html': '&nbsp;' });

            this.scrollbarHandle = new Element("DIV", { 'class': 'nemScrollbarHandle', 'html': '&nbsp;' });
            this.scrollbarHandle.setStyle('margin-top', this.scrollBox.getStyle('margin-top').toInt() - 21);
            this.scroller.grab(this.scrollbarUp);
            this.scroller.grab(this.scrollbar);
            this.scroller.grab(this.scrollbarDown);
            // this.scrollbarUp.inject(this.scrollbar, "before");
            this.scrollbar.grab(this.scrollbarHandle);
            // this.scrollbarDown.inject(this.scrollbar, "after");

            this.scrollbar.setStyle('height', this.scrollBox.getStyle('height').toInt() - this.scrollbarUp.getStyle('height').toInt() - this.scrollbarDown.getStyle('height').toInt());
            this.scrollbarUp.setStyle('margin-top', this.scrollBox.getStyle('margin-top'));

            this.slider = new Slider(this.scrollbar, this.scrollbarHandle, {
                steps: this.steps,
                mode: 'vertical',
                onChange: (function(step) {
                    // Scrolls the content element in x or y direction.
                    var x = 0;
                    var y = step;
                    this.scrollBox.scrollTo(x, y);
                }).bind(this)
            }).set(0);

            var scrollWheel = (function(e) {
                e = new Event(e).stop();
                var step = this.slider.step - e.wheel * 5;
                this.slider.set(step);
            });

            this.scrollbarUp.addEvent('mousedown', (function() { this.scroll=true;this.scrollClick(-1) }).bind(this));
            this.scrollbarUp.addEvent('mouseup', (function() { this.scroll=false}).bind(this));
            this.scrollbarUp.addEvent('mouseleave',  (function() { this.scroll=false}).bind(this));
            this.scrollbarDown.addEvent('mousedown', (function() { this.scroll=true;this.scrollClick(1) }).bind(this));
            this.scrollbarDown.addEvent('mouseup',  (function() { this.scroll=false}).bind(this));
            this.scrollbarDown.addEvent('mouseleave', (function() { this.scroll = false }).bind(this));
            
            this.scrollBox.addEvent('mousewheel', scrollWheel.bind(this));
            this.scrollbar.addEvent('mousewheel', scrollWheel.bind(this));
            // Stops the handle dragging process when the mouse leaves the document body.
            $(document.body).addEvent('mouseleave', (function() { this.slider.drag.stop() }).bind(this));
        }
    },
    scrollClick: function(direction) {
        var step = this.slider.step + direction * 5;
        this.slider.set(step);

        if (this.scroll)
            (function() { this.scrollClick(direction); }).delay(100, this);
           
    },
    
    makeScrollbar: function(content, scrollbar, handle, ignoreMouse) {
        var steps = content.getScrollSize().y - content.getSize().y;
        var slider = new Slider(scrollbar, handle, {
            steps: steps,
            mode: 'vertical',
            onChange: function(step) {
                // Scrolls the content element in x or y direction.
                var x = 0;
                var y = step;
                content.scrollTo(x, y);
            }
        }).set(0);
        if (!(ignoreMouse)) {
            // Scroll the content element when the mousewheel is used within the 
            // content or the scrollbar element.
            $$(content, scrollbar).addEvent('mousewheel', function(e) {
                e = new Event(e).stop();
                var step = slider.step - e.wheel * 30;
                slider.set(step);
            });
        }
        // Stops the handle dragging process when the mouse leaves the document body.
        $(document.body).addEvent('mouseleave', function() { slider.drag.stop() });
    }
});
