var Scrollable = Class.create(
{
    initialize: function(options) {
        
        // init event list
        this.queue = new Array();
        
        // current position
        this.position = 0;
        
        // semaphore
        this.is_moving = false;
        
        // load options
        this.container  = $(options.container);
        this.size       = options.size;
        this.items      = $(options.items);
        this.hoverClass = options.hoverClass;
        
        // calc paging
        this.pages = Math.ceil(this.items.childElements().length / this.size);
        
        // get move offset
        this.offset = this.items.childElements()[0].getWidth();
        
        // max position
        this.max_position = this.items.childElements().length - this.size;
        
        
        // get and init controllers
        this.nextBtns     = this.container.adjacent('a.next');
        this.prevBtns     = this.container.adjacent('a.prev');
        this.navContainer = this.container.adjacent('div.navi')[0];
        
        this.initControllers();
        
        // add mouse over and out
        this.items.select('div').invoke('observe', 'mouseover', function(event) {
                                            elem = $(event.target);
                                            
                                            if(elem.tagName != 'DIV')
                                                div = elem.up('div');
                                            else
                                                div = elem;
                                            
                                            div.addClassName(this.hoverClass);
                                        }.bind(this));
        
        this.items.select('div').invoke('observe', 'mouseout', function(event) {
                                            elem = $(event.target);
                                            
                                            if(elem.tagName != 'DIV')
                                                div = elem.up('div');
                                            else
                                                div = elem;
                                            
                                            div.removeClassName(this.hoverClass);
                                        }.bind(this));
    },
    
    initControllers: function() {
        
        if(this.pages > 1) {
            
            // Controll buttons
            /* this.nextBtns.invoke('observe', 'click', this.moveNextElement.bind(this));
            this.prevBtns.invoke('observe', 'click', this.movePrevElement.bind(this)); */
            
            this.nextBtns.invoke('observe', 'click', this.moveNextPage.bind(this));
            this.prevBtns.invoke('observe', 'click', this.movePrevPage.bind(this));
            
            
            this.nextBtns.invoke('observe', 'dblclick', function(evt) { evt.stop(); });
            this.prevBtns.invoke('observe', 'dblclick', function(evt) { evt.stop(); });
            
            // Generate pages
            for(i = 0; i < this.pages; i++) {
                
                a = new Element('a', { href: (i+1) });
                a.observe('click', this.movePage.bind(this));
                
                if(i == 0)
                    a.addClassName('active');
                
                this.navContainer.insert({ 'bottom': a });
             }
        }
        else {
            this.nextBtns.invoke('hide');
            this.prevBtns.invoke('hide');
        }
        
    },
    
    moveNextElement: function() {
        this.queue.push(1);
            
        if(this.queue.length == 1)
            this.processEventList();
    },
    
    movePrevElement: function() {
        this.queue.push(-1);
            
        if(this.queue.length == 1)
            this.processEventList();
    },
    
    movePage: function(event) {
        event.stop();
        this.moveToPage($(event.target).readAttribute('href'));
    },
    
    moveNextPage: function(event) {
        
        event.stop();
        
        page = this.getCurrentPage();
        
        if(page+1 <= this.pages)
            this.moveToPage(page+1);
    },
    
    movePrevPage: function(event) {
        event.stop();
        
        page = this.getCurrentPage();
        
        if(page-1 > 0)
            this.moveToPage(page-1);
    },
    
    moveToPage: function(page) {
        
        // check if it is last page
        new_pos = (page-1) * this.size;
        new_pos = new_pos >= this.max_position ? this.max_position : new_pos;
        
        this.queue.push(new_pos - this.position);
        
        if(this.queue.length == 1)
            this.processEventList();
    },
    
    processEventList: function() {
        
        if(this.is_moving)
            return;
        
        if(this.queue.length > 0) {
            
            position = this.position + this.queue[0];
            
            if(position <= this.max_position && position >= 0) 
            
                new Effect.Move(this.items, { x: -this.offset * position,
                                              duration: 0.4,
                                              mode: 'absolute',
                                              transition: Effect.Transitions.sinoidal,
                                              beforeStart: function() {
                                                  this.is_moving = true;
                                              }.bind(this),
                                              afterFinish: function() {
                                                              this.queue.pop();
                                                              this.position = position;
                                                              this.updatePages();
                                                              this.is_moving = false;
                                                              this.processEventList();
                                                           }.bind(this) 
                });
            else {
                this.queue.pop();
                this.updatePages();
                this.processEventList();
            }
            
        }
        
    },
    
    getItemsOffset: function() {
        return parseInt(this.items.getStyle('left'), 10);
    },
    
    getCurrentPage: function() {
        if(this.position == this.max_position)
            return this.pages;
        else
            return Math.ceil((this.position+1) / this.size);
    },
    
    updatePages: function() {
        
        page = this.getCurrentPage(); 
        
        this.navContainer.select('a').each(function(elem) {
                                               
                                            if(elem.readAttribute('href') == page)
                                                elem.addClassName('active');
                                            else if(elem.hasClassName('active'))
                                                elem.removeClassName('active');
                                           
                                           });
    }
});

