

var Scroller = function() {
    return this.initialize.apply(this, arguments);
}

Scroller.prototype = {
    settings : {
        direction : 'vertical',
        speed : 12,
        wheelSpeed : 24,
        buttonEvent : 'click',
        nextButtonHTML: '<a>next</a>',
        prevButtonHTML: '<a>prev</a>'
    },
    
    initialize: function (obj, settings) {
        var self = this;
        self.settings = jQuery.extend(self.settings, settings);

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

        var container = $(obj)[0];
        if (! container) return;
        self.container = container;
        self.container.style.overflow = 'hidden';
        
        if( $('> div.Scroller-wrap', container).length > 0 ) return;
        var wrapper = $('<div class="Scroller-wrap">')[0];
        var $children = $(container).children();
        $children.each( function(i,child) {
            $(child).remove();
            $(child).appendTo(wrapper);
        });
        $(container).append(wrapper);

        self.wrapper = wrapper;

        self.setLength = self.container.scrollWidth;
        
        $(container).mousewheel( function(e){ self.wheel(e); } );
        
        self.nextButton = $(self.settings.nextButtonHTML).addClass('scroller-next').appendTo(container);
        self.prevButton = $(self.settings.prevButtonHTML).addClass('scroller-prev').appendTo(container)
        self.checkScrollNeeded();
        $(self.nextButton).bind('mousedown', function(e){self.scrollDown(e)}).
            bind('mouseup', function(e){self.stopScroll(e)});

        $(self.prevButton).bind('mousedown', function(e){self.scrollUp(e)}).
            bind('mouseup', function(e){self.stopScroll(e)});

        $(window).resize( function(){ self.checkScrollNeeded() } );
               
    },

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

    },

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

    scrollEnd: function() {
        var self = this;
        var d = (self.settings.direction.toLowerCase() == 'vertical')?
            'Height' : 'Width';
        return eval("self.container.scroll"+d);
    },

    moveUp: function(s) {
        var self = this;
        var l = (self.settings.direction.toLowerCase() == 'vertical') ?
            $(self.container).height() : $(self.container).width();
        var scroll_end = self.scrollEnd() - l;

        self.scrollCursor -= s;
        self.scrollCursor = (self.scrollCursor) < 0 ? 0 : self.scrollCursor;
        self.update();
    },

    moveDown: function(s) {
        var self = this;
        var l = (self.settings.direction.toLowerCase() == 'vertical') ?
            $(self.container).height() : $(self.container).width();
        var scroll_end = self.scrollEnd() - l;
        
        self.scrollCursor += s;
        self.scrollCursor = (self.scrollCursor) >= scroll_end ? scroll_end : self.scrollCursor;
        self.update();
    },

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

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

    resetScroll: function() {
        self.scrollCursor = 0;
        self.update();
    },

    wheel: function(event){
        var self = this;
        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)
            self.handleWheel(delta);
        if (event.preventDefault)
            event.preventDefault();
        event.returnValue = false;
    },

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

    checkScrollNeeded: function() {
        var self = this;
        var scrolling = self.scrollNeeded();
        if( scrolling ) {
            $(self.nextButton).show();
            $(self.prevButton).show();
        }
        else {
            self.scrollCursor = 0; self.update();
            $(self.nextButton).hide();
            $(self.prevButton).hide();
        }
    },

    scrollNeeded: function() {
        var self = this;
        var l = (self.settings.direction.toLowerCase() == 'vertical') ?
            $(self.container).height() : $(self.container).width();
        if( self.scrollEnd() > l) 
            return true;

        return false;
    }
        
};


jQuery.Scroller = {
    list : []
};
jQuery.fn.Scroller = function(settings) {
    return this.each( function (i,el) {
        jQuery.Scroller.list.push (
            new Scroller(el, settings )
        );
    });
}

