// SimpleScroll Class
var SimpleScroll = function(datas) {
    SimpleScroll.superclass.constructor.call(this);
    
    this.addEvents(['beforeCompute', 'disable', 'enable'], (datas) ? datas.listeners : null);
    
    this.initialize(datas);
};
BOX.extend(SimpleScroll, BOX.Observable, {
    initialize: function(datas) {
        var that = this;
        
        this.scrollUnit = (typeof datas.scrollUnit == 'number') ? datas.scrollUnit : null;
        this.from = datas.from || 'top';
        this.postOnLoadCompute = false;
        
        datas.target.innerHTML = config.scroll.container.replace('%content%', datas.target.innerHTML);
        
        this.sParent = $(datas.target);
        this.sContent = this.sParent.children();
        
        if (datas.buttons) {
            this.sContainer = $(config.scroll.fullBar).appendTo(datas.targetScrollBar || datas.target);
            this.sUp = $('span.up', this.sContainer);
            this.sDown = $('span.down', this.sContainer);
        } else {
            this.sContainer = $(config.scroll.simpleBar).appendTo(datas.targetScrollBar || datas.target);
        }
        this.sFace = $('span.face', this.sContainer);
        
        var dragConfig = {
            root: this.sFace
        };
        var argNb = 2;
        if (this.from == 'top') {
            dragConfig.minX = 0;
            dragConfig.maxX = 0;
            dragConfig.minY = 0;
        } else {
            dragConfig.minX = 0;
            dragConfig.minY = 0;
            dragConfig.maxY = 0;
            argNb = 1;
        }
        
        this.drag = new SimpleDrag(dragConfig).addListener('drag', function(e, x, y) {
            var coord = arguments[argNb];
            if (coord == Math.round(that.sD)) {
                coord = that.sD;
            }
            var tFrom = Math.round(coord / that.sH * that.tH);
            that.sContent.css(that.from, - tFrom + 'px');
        });
        
        this.fireEvent('beforeCompute');
        
        this.compute();
        if ($('img', this.sParent).length && !onLoadIsDone) {
            $(W).load(function() {
                that.postOnLoadCompute = true;
                that.compute();
            });
        }
        
        this.sParent.bind('DOMMouseScroll', function(e) {that.wheel(e);}).bind('mousewheel', function(e) {that.wheel(e);});
        this.sContainer.click(function(e) {that.clickToPosition(e, this);});
        
        this.fireEvent('load');
    },
    
    checkForDisplayNone: function(el) {
        if (el) {
            if (!el.scrollHeight) {
                this.displayNone = $(el.parentNode);
                while (this.displayNone.parent().css('display') == 'none') {
                    this.displayNone = this.displayNone.parent();
                }
                this.displayNone.addClass('hideButDraw');
            }
        } else if (this.displayNone) {
            this.displayNone.removeClass('hideButDraw');
        }
    },
    
    enable: function() {
        this.sContent.removeClass('scrollNone').addClass('scrollContent');
        var max = {};
        if (this.from == 'top') {
            max.maxY = Math.round(this.sD);
        } else {
            max.maxX = Math.round(this.sD);
        }
        this.drag.setMinMax(max);
        var tFrom = this.getContentOffset();
        this.moveContentTo(tFrom);
        this.disabled = false;
        this.fireEvent('enable');
        this.sContainer.css('visibility', 'visible');
    },
    
    disable: function() {
        this.sContainer.css('visibility', 'hidden');
        this.sContent.removeClass('scrollContent').addClass('scrollNone');
        this.disabled = true;
        this.fireEvent('disable');
    },
    
    getContentOffset: function() {
        return parseInt(this.sContent.css(this.from), 10);
    },
    
    compute: function() {
        this.checkForDisplayNone(this.sContent[0]);
        
        var offsetFrom, dimension;
        if (this.from == 'top') {
            offsetFrom = 'offsetHeight';
            dimension = 'height';
        } else {
            offsetFrom = 'offsetWidth';
            dimension = 'width';
        }
        
        this.tH = this.sContent[0][offsetFrom];
        this.th = this.sParent[0][offsetFrom];
        this.tD = this.tH - this.th;
        
        this.sH = this.sContainer[0][offsetFrom];
        if (this.tH <= this.th) {
            this.sh = this.sH;
        } else {
            this.sh = this.th / this.tH * this.sH;
        }
        this.sD = this.sH - this.sh;
        
        if (!this.scrollUnit) {
            var unit = Math.ceil((this.sH - this.sh) / this.sH * this.sh);
            this.scrollUnit = (unit > 10) ? unit : 10;
        }
        
        this.sFaceOffset = this.sFace[0][offsetFrom] - this.sFace[dimension]();
        this.sFace.css(dimension, (Math.round(this.sh) - this.sFaceOffset) + 'px');
        
        this.offset = this.sContainer.offset()[this.from];
        
        if (this.tH <= this.th) {
            this.disable();
        } else {
            this.enable();
        }
        
        this.checkForDisplayNone();
    },
    
    moveContentTo: function(tFrom) {
        if (!this.disabled && !isNaN(tFrom)) {
            if (tFrom > 0) {tFrom = 0;}
            if (tFrom < - this.tD) {tFrom = - this.tD;}
            var sFrom = Math.round(Math.abs(tFrom) / this.tH * this.sH);
            this.sContent.css(this.from, tFrom + 'px');
            this.sFace.css(this.from, sFrom + 'px');
        }
    },
    
    moveScrollBarTo: function(sFrom) {
        if (!this.disabled && !isNaN(sFrom)) {
            if (sFrom < 0) {sFrom = 0;}
            if (sFrom > this.sD) {sFrom = Math.round(this.sD);}
            var tFrom = - Math.round(sFrom / this.sH * this.tH);
            this.sContent.css(this.from, tFrom + 'px');
            this.sFace.css(this.from, sFrom + 'px');
        }
    },
    
    wheel: function(e) {
        if (!this.disabled && !this.disabledWheel) {
            var s = e.detail ? - e.detail / 3 : e.wheelDelta / 120;
            var tFrom = Math.round(this.getContentOffset() + (s * this.scrollUnit));
            this.moveContentTo(tFrom);
            e.preventDefault();
        }
    },
    
    clickToPosition: function(e, el) {
        var t = e.target,
            sFrom, tFrom;
        if (t == el) {
            var coord = (this.from == 'top') ? e.pageY : e.pageX;
            sFrom = coord - this.offset - Math.round(this.sh / 2);
            this.moveScrollBarTo(sFrom);
        } else if ($(t).hasClass('up')) {
            tFrom = Math.round(this.getContentOffset() + this.scrollUnit);
            this.moveContentTo(tFrom);
        } else if ($(t).hasClass('down')) {
            tFrom = Math.round(this.getContentOffset() - this.scrollUnit);
            this.moveContentTo(tFrom);
        }
    }
});

BOX.SimpleScroll = SimpleScroll;