
if(typeof(Prototype) == 'undefined' ||
    parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]) < 1.5)
    throw(metaInfo.name + ' requires Prototype library >= 1.5.0.');

var Scroller = Class.create();
Scroller.prototype = {
    
    initialize: function (element) {
        /* Options */
        this.direction = 'vertical';
        this.speed = 8;        
        this.wheelSpeed = 20;
        this.upButton = 'scrollUp';
        this.downButton = 'scrollDown'; 
        this.fadeButtons = false;
        this.fadeBoundary = 120;
        this.scrollOnClick = true;
        this.scrollOnHover = false;
        this.widthOffset = 0; // Scroller will have width of window minus this amount
        this.wraparound = false;
        this.wrapHiddenClass = 'ScrollHidden';

        /* Private  */
        this.timeoutID = 0;
        this.container = null;
        this.wrapper = null
        this.scrollCursor = 0;
        this.scrollLength = 0;
        this.setWidth = 0;

        Object.extend(this, arguments[1] || {});

        var container = $(element);
        if (! container) return;
        this.container = container;
               
        var wrapper = container.cloneNode(true);
        wrapper.setAttribute('id', '');
        wrapper.setAttribute('class','');
        container.innerHTML = '';
        container.appendChild(wrapper);
        this.wrapper = wrapper;
        
        this.container.style.overflow = 'hidden';
        if( this.direction == 'horizontal' ) {
            wrapper.style.width = Element.getWidth(wrapper) + 'px';
            this.scrollLength = this.container.scrollWidth;
            this.dimension = 'width';
        }
        else {
            var h = Element.getHeight(wrapper);
            var sh = wrapper.scrollHeight;
            this.scrollLength = (sh > h)? sh : h;
            this.dimension = 'height';
        }

        this.wrapLength = this.container.scrollLength;
        if(this.wraparound == true ) {
            this.cloneContent();
        }
        
        if(this.widthOffset > 0){
            Event.observe(window, 'resize', this.resizeScroller.bind(this));
            this.resizeScroller();
        }
        
        Event.observe(container, 'DOMMouseScroll', this.wheel.bind(this));            
        Event.observe(container, 'mousewheel', this.wheel.bind(this));
        
        this.upButton = $(this.upButton);
        this.downButton =  $(this.downButton);
        if( !this.upButton ) {
            this.upButton = document.createElement('img');
            this.upButton.src = '/img/up.png';
            $(this.upButton).className = 'rollover scrollerUp';
            Element.up(this.container).appendChild(this.upButton);
        }
        if( !this.downButton ) {
            this.downButton = document.createElement('img');
            this.downButton.src = '/img/down.png';
            $(this.downButton).className = 'rollover scrollerDown';
            Element.up(this.container).appendChild(this.downButton);
        }
        this.checkScrollNeeded();
        if( this.fadeButtons == true )  {
            Element.hide(this.upButton); Element.hide(this.downButton);
            Event.observe(document.body, 'mousemove', this.buttonFadeCheck.bindAsEventListener(this));
        }
        if( this.scrollOnHover == true ) {
            Event.observe(this.upButton, 'mouseover', this.scrollUp.bind(this));
            Event.observe(this.upButton, 'mouseout', this.stopScroll.bind(this));
            Event.observe(this.downButton, 'mouseover', this.scrollDown.bind(this));
            Event.observe(this.downButton, 'mouseout', this.stopScroll.bind(this));
        }
        else {
            Event.observe(this.upButton, 'mousedown', this.scrollUp.bind(this));
            Event.observe(this.upButton, 'mouseup', this.stopScroll.bind(this));
            Event.observe(this.downButton, 'mousedown', this.scrollDown.bind(this));
            Event.observe(this.downButton, 'mouseup', this.stopScroll.bind(this));
        }
        Event.observe(this.container, 'mouseout', this.stopScroll.bind(this));
                
    },

    update: function(){
        if( this.direction.toLowerCase() == 'vertical' ) {
            this.container.scrollTop = this.scrollCursor;            
        }
        else{
            this.container.scrollLeft = this.scrollCursor;
        }

    },

    stopScroll: function() {
        clearTimeout(this.timeoutID);
    },

    moveUp: function(s) {
        var dim = Element.getDimensions(this.container);
        var scroll_end = this.scrollLength - dim[this.dimension];

        this.scrollCursor -= s;
        if( this.wraparound ==true ) {            
            if( this.scrollCursor <= 0 ) {
                this.scrollCursor = parseInt(this.wrapLength - s);
            }
        }
        else {            
            this.scrollCursor = (this.scrollCursor) < 0 ? 0 : this.scrollCursor;
        }
        this.update();
    },

    moveDown: function(s) {
        var dim = Element.getDimensions(this.container);
        var scroll_end = this.scrollLength - dim[this.dimension];
        
        this.scrollCursor += s;
        if( this.wraparound == true ) {            
            if( this.scrollCursor >= parseInt(this.wrapLength+s) ) {
                this.scrollCursor = 0;                
            }            
        }
        else {
            this.scrollCursor = (this.scrollCursor > scroll_end) ? scroll_end : this.scrollCursor;
        }
        this.update();
    },

    scrollUp: function() {
        this.moveUp(this.speed);
        var self = this;
        this.timeoutID = setTimeout(function(){self.scrollUp();}, 60);        
    },

    scrollDown: function() {
        this.moveDown(this.speed);
        var self = this;
        this.timeoutID = setTimeout(function(){self.scrollDown();}, 60);                    
    },

    reset: function() {
        this.scrollCursor = 0;       
        this.update();
        if( this.direction == 'horizontal' ) {
            this.wrapper.style.width = Element.getWidth(this.wrapper) + 'px';
            this.scrollLength = this.container.scrollWidth;
            this.dimension = 'width';
        }
        else {
            var h = Element.getHeight(this.wrapper);
            var sh = this.wrapper.scrollHeight;
            this.scrollLength = (sh > h)? sh : h;
            this.dimension = 'height';
        }
        this.wrapLength = this.container.scrollLength;
        this.checkScrollNeeded();
    },

    resizeScroller: function() {
        w = getWindowWidth();
        size = w - this.widthOffset;
        this.container.style.width = size + 'px';
        this.checkScrollNeeded();
    },

    wheel: function(event){
        var delta = 0;
        if (!event) event = window.event;
        if (event.wheelDelta) {
            delta = event.wheelDelta/120; 
            if (window.opera) delta = -delta;
        } else if (event.detail) {
            delta = -event.detail/3;
        }
        if (delta)
            this.handleWheel(delta);
        if (event.preventDefault)
            event.preventDefault();
        event.returnValue = false;
    },

    handleWheel: function(delta) {
        if (delta < 0) { // down
            this.moveDown(this.wheelSpeed);            
        }
        else { //up            
            this.moveUp(this.wheelSpeed);
        }
    },

    buttonFadeCheck: function(e) {
        var x = Event.pointerX(e); var y = Event.pointerY(e);
        var upButton = Element.down(this.upButton);
        var downButton = Element.down(this.downButton);
        if(!Position.within(this.container, x,y)) {
            Element.hide(upButton); Element.hide(downButton);
            return; 
        }
        var x = x - Position.page(this.container)[0] - Position.realOffset(this.container)[0];
        var width = Element.getWidth(this.container);
        if( x > width - this.fadeBoundary ) {                        
            if(! Element.visible(downButton))
                Element.show(downButton);
        }
        else Element.hide(downButton);
        
        if(  x < this.fadeBoundary ) {
            if(! Element.visible(upButton))
                Element.show(upButton);
        }
        else Element.hide(upButton);
    },

    checkScrollNeeded: function() {
        
        if( this.wraparound == true) {
            var wrapcontent = document.getElementsByClassName(this.wrapHiddenClass);
            wrapcontent.each(Element.hide);
        }

        var scrolling = this.scrollNeeded();
        if( scrolling ) {
            Element.show(this.upButton);
            Element.show(this.downButton);
            if( wrapcontent) {
                wrapcontent.each(Element.show);                
            }
            if(ie6) {
                enableAlpha(this.upButton); Element.addClassName(this.upButton,'transpng');
                enableAlpha(this.downButton); Element.addClassName(this.upButton,'transpng');
            }
        }
        else {
            this.scrollCursor = 0; this.update();
            Element.hide(this.upButton);
            Element.hide(this.downButton);
        }
    },

    scrollNeeded: function() {
        var dim = Element.getDimensions(this.container);
        if( this.scrollLength > dim[this.dimension]) 
            return true;

        return false;
    },

    cloneContent: function() {
        var children = Element.immediateDescendants(this.wrapper);
        children.each( function(child) {
            Element.setStyle({'float':'left'});
            var copy = child.cloneNode(true);
            Element.addClassName(copy, this.wrapHiddenClass);
            this.wrapper.appendChild(copy);
        }.bind(this));
        this.wrapper.style.width = parseInt(Element.getWidth(this.wrapper) * 2.5) + 'px';
    }
    
};


// Get width of window
function getWindowWidth() { 
    if (self.innerWidth) { 
        return self.innerWidth;         
    } 
    else if (document.documentElement && document.documentElement.clientWidth) { 
        return document.documentElement.clientWidth;         
    } 
    else if (document.body) { 
        return document.body.clientWidth;         
    } 
} 

var scrollers = new Array();
Event.onDOMReady(function() {
    $$('.scroller').each( function( scroller ) {
        scrollers[scrollers.length] = new Scroller(scroller);
    });
});
