Pager = new Class({
    
    pages:          [],
    handlers:       [],
    page_to_links:  [],
    current_page:   0,
    previous_page:  0,
    index_offset:   0,
    working:        false,
    
    options: {
        handlers:       false,
        forward_button: false,
        back_button:    false,
        page_to_links:  false,
        height:         100,
        width:          100,
        units:          'px',
        duration:       500,
        zindex:         10000,
        start_page:     0,
        orientation:    'horz',
        page_to_class:  'page_to',
        transition:     Fx.Transitions.Quad.easeInOut
    },
    
    initialize: function(pages, options){
        this.setOptions(options);
        
        this.current_page   = this.options.start_page;
        
        for(var i = 0; i < pages.length; i++){
            this._buildPages(i, pages[i]);
        }
        
        pages[0].getParent().setStyles({
            height: this.options.height + this.options.units,
            width:  this.options.width + this.options.units,
            position: 'relative',
            overflow: 'hidden'
        });
      
        if(this.options.handlers){
            for(var i = 0; i < this.options.handlers.length; i++){
                this.handlers.splice(i, 0, this.options.handlers[i]);
            }
        }
        this._buildHandlers();
        
        if(this.options.forward_button){
            this.options.forward_button.addEvent('click', function(e){
                e = new Event(e).stop();
                this.nextPage();
            }.bind(this));
        }
        
        if(this.options.back_button){
            this.options.back_button.addEvent('click', function(e){
                e = new Event(e).stop();
                this.previousPage();
            }.bind(this));
        }
        
        if(this.options.page_to_links){
            for(var i = 0; i < this.options.page_to_links.length; i++){
                this.page_to_links.push(this.options.page_to_links[i]);
            }
            this._buildPageToLinks();
        }        
        
        if(this.options.start_page > 0){
            var direction       = (this.options.start_page == this.pages.length - 1) ? 'backward' : 'forward';
            this.pageTo(this.current_page, direction);
        }
    },
    
    _buildPages: function(index, page){
        if($type(page) == 'element'){
            var obj = {
                element:    page,
                effect:     new Fx.Styles(page, {
                    duration:   this.options.duration,
                    transition: this.options.transition
                })
            };
            page.setStyles({
                height:     this.options.height + this.options.units,
                width:      this.options.width + this.options.units,
                position:   'absolute',
                top:        0 + this.options.units,
                left:       0 + this.options.units,
                'z-index':  --this.options.zindex
            });
            this.pages.splice(index, 0, obj);
        }
        return this;
    },
    
    _buildHandlers: function(){
        this.handlers.each(function(handler, index){
            handler.removeEvents();
            handler.addEvent('click', function(e){
                e = new Event(e);
                if(index !== this.current_page){
                    var direction = this._setDirection(index);
                    this.pageTo(index, direction);
                }
                e.stop();
            }.bind(this));
        }.bind(this));
        return this;
    },
        
    _buildPageToLinks: function(){
        var links = this.pages[0].element.getParent().getElements('.'+ this.options.page_to_class);
        links.each(function(link, i){
            link.removeEvents();
            link.addEvent('click', function(e){
                e = new Event(e).stop();
                var page = 0;
                switch(link.rel){
                    case 'next':
                    case 'forward':
                        page = this.current_page * 1 + 1;
                        break;
                    case 'back':
                    case 'previous':
                    case 'backward':
                        page = this.current_page * 1 - 1;
                        break;
                    default:
                        page = link.rel * 1 + this.index_offset;
                }
                console.log(page);
                direction = this._setDirection(page);
                this.pageTo(page, direction);
            }.bind(this));
        }.bind(this)); 
    },
    
    _setDirection: function(index){
        var direction = 'forward';
        var x = -99;
        if(this.current_page == 0 && index == this.pages.length - 1){
            direction   = 'backward';
            x = 1;
        }else if(this.current_page == this.pages.length - 1 && index == 0 ){
            x = 2;
            direction   = (this.current_page < index) ? 'backward' : 'forward';                 
        }else{
            x = 3;
            direction   = (this.current_page > index) ? 'backward' : 'forward';                        
        }
        return direction;
    },
    
    _placePage: function(index, direction){
        switch(this.options.orientation){
            case 'horz':
                var top = 0;
                var left = (direction == 'forward') ? this.options.width : -this.options.width;
                break;
            case 'vert':
                var top = (direction == 'forward') ? this.options.height : -this.options.height;
                var left = 0; 
        }
        this.pages[index].element.setStyles({
            top:    top + this.options.units,
            left:   left + this.options.units
        });
        return {
            current_top: 0,
            current_left: 0,
            previous_top: top * -1,
            previous_left: left * -1 
        };
    },
    
    _fixOverflow: function(index, set_overflow){
        this.pages[index].element.setStyles({
            overflow:   (set_overflow) ? 'auto' : 'hidden'
        });
    },
    
    _fixIndexes: function(new_index){
        if(new_index < this.current_page + 1){
            ++this.index_offset;
            this.previous_page = ++this.current_page;
        }
    },
    
    addNewPage: function(options){
        new_page_options = {
            index:      0,
            page:       false,
            handler:    false,
            go_to:      false
        };
        
        for(var x in options){
            new_page_options[x] = options[x];
        }
        
        this._fixIndexes(new_page_options.index);
        
        if(new_page_options.index < 0){
            new_page_options.index = 0;
        }else if(new_page_options.index > this.pages.length - 1){
            new_page_options.index = this.pages.length;
        }
                
        if(new_page_options.handler){
            this.handlers.splice(new_page_options.index, 0, new_page_options.handler);
        }
        
        this._buildPages(new_page_options.index, new_page_options.page)._buildHandlers();
        this._buildPageToLinks();
        if(new_page_options.go_to){
            var direction = this._setDirection(new_page_options.index);
            this.pageTo(new_page_options.index, direction);
        }
    },
    
    nextPage: function(){
        this.previous_page = this.current_page++;
        this.pageTo(this.current_page, 'forward');
    },
    
    previousPage: function(){        
        this.previous_page = this.current_page--;
        this.pageTo(this.current_page, 'backward');
    },
    
    pageTo: function(index, direction){
        if(!this.working /*&& this.pages[index]*/){
            this.working = true;
            switch(direction){
                case 'forward':
                    this.current_page = (index > (this.pages.length - 1)) ? 0 : index;
                    break;
                case 'backward':
                    this.current_page = (index < 0) ? (this.pages.length - 1) : index;
                    break;
            }            
            
            this.pages[this.current_page].element.setStyle('z-index',  this.options.zindex + 100);
            
            //fix firefox overflow issues
            this._fixOverflow(this.previous_page, false);
            
            var new_pos = this._placePage(this.current_page, direction);
            this.pages[this.previous_page].effect.start({
                'left':         new_pos.previous_left + this.options.units,
                'top':          new_pos.previous_top + this.options.units,
                'visibility':   'hidden'
            });
            this.pages[this.current_page].effect.start({
                'left':         new_pos.current_left + this.options.units,
                'top':          new_pos.current_top + this.options.units,
                'visibility':   'visible'
            }).chain(function(){
                //ff overflow fix
                this._fixOverflow(this.current_page, true); 
            }.bind(this));
            this.previous_page = this.current_page;
            this.working = false;
        }
        return this;
    }
});
Pager.implement(new Options);

