/*
---

script: Pager.js

description: TBD

requires:
- /Mootools

provides: [Pager]

...
*/
var Pager = new Class({
    Implements: [Options, Events],
    
    options: {
        mode: 'horizontal', // horizontal ou vertical
        loop: 'repeat', // none, repeat ou spin
        autoplay: true,
        'wait-time': 4000
    },
    
    initialize: function(element, options) {
        this.element = $(element);
        this.setOptions(options);
        
        this.build();
        this.fireEvent('ready');
    },
    
    build: function() {
        this.list = this.element.getElement('ul');
        this.pages = this.list.getChildren('li');
        this.running = false;
        
        this.size = this.element.getSize();
        this.element.setStyles({
            position: 'relative',
            overflow: 'hidden'
        });
        this.list.setStyles({
            position: 'absolute',
            left: 0,
            top: 0
        });
        
        this.current = 0;
        this.total = this.pages.length;
        
        this.props = (this.options.mode == 'horizontal')
            ? {coord: 'x', modifier: 'left'}
            : {coord: 'y', modifier: 'top'};
            
        var pos = 0;
        this.pages.each((function(el) {
            el.setStyles({
                position: 'absolute',
                left: 0,
                top: 0,
                width: this.size.x,
                height: this.size.y
            });
            el.setStyle(this.props.modifier, pos);
            pos += this.size[this.props.coord];
        }).bind(this));
        
        this.fx = new Fx.Morph(this.list, {
            transition: Fx.Transitions.Sine.easeInOut,
            link: 'chain'
        }).addEvent('complete', this.onComplete.bind(this));
        
        this.fireEvent('change', this.current);
        
        if (this.options.autoplay) {
            this.play();
        }
    },
    
    getCurrent: function() {
        return this.current;
    },
    
    getPage: function() {
        return this.pages[this.current];
    },
    
    count: function() {
        return this.total;
    },
    
    isFirst: function() {
        return (this.current == 0);
    },
    
    isLast: function() {
        return (this.current == this.total-1);
    },
    
    first: function() {
        return this.goto(0);
    },
    
    previous: function() {
        var page = this.current - 1;
        if (page >= 0 || this.options.loop == 'repeat') {
            return this.goto(page);
        } else if (this.options.loop == 'spin') {
            return this.last();
        }
        return false;
    },
    
    next: function() {
        var page = this.current + 1;
        if (page < this.total || this.options.loop == 'repeat') {
            return this.goto(page);
        } else if (this.options.loop == 'spin') {
            return this.first();
        }
        return false;
    },
    
    last: function() {
        return this.goto(this.total-1);
    },
    
    goto: function(page, now) {
        if (now) {
            this.current = page.limit(0, this.total-1);
            this.list.setStyle(this.props.modifier,
                               -(this.size[this.props.coord] * this.current));
            this.fireEvent('change', this.current);
            return;
        }
    
        if (page == -1 && this.isFirst()) {
            this.repeat = this.pages.getLast().clone()
                .setStyle(this.props.modifier,
                          -this.size[this.props.coord])
                .inject(this.list);
        } else if (page == this.total && this.isLast()) {
            this.repeat = this.pages[0].clone()
                .setStyle(this.props.modifier,
                          this.pages.length*this.size[this.props.coord])
                .inject(this.list);
        } else {
            page = page.limit(0, this.total-1);
        }
        
        if (page != this.current) {
            this.fireEvent('beforeChange');
            var anim = {};
            anim[this.props.modifier] = -(this.size[this.props.coord] * page);
            this.fx.start(anim);
            this.current = page;
            this.reset();
            return true;
        }
        return false;
    },
    
    isRunning: function() {
        return this.running;
    },
    
    togglePlayPause: function() {
        if (this.isRunning()) {
            this.pause();
        } else {
            this.play();
        }
    },
    
    play: function() {
        if (!this.timer) {
            this.timer = this.onTimer.delay(this.options['wait-time'], this);
            this.running = true;
        }
    },
    
    pause: function() {
        clearTimeout(this.timer);
        this.timer = false;
        this.running = false;
    },
    
    stop: function() {
        this.pause();
        this.goto(0, true);
    },
    
    reset: function() {
        if (this.isRunning()) {
            this.pause();
            this.play();
        }
    },
    
    onTimer: function() {
        this.timer = false;
        if (!this.next()) {
            this.pause();
        }
        
        if (this.current == 0) {
            this.fireEvent('begin');
        } else if (this.current == this.total-1) {
            this.fireEvent('end');
        }
    },
    
    onComplete: function() {
        if (this.repeat) {
            this.goto((this.current < 0 ? this.total-1 : 0), true);
            this.repeat.destroy();
            this.repeat = false;
        }
        this.fireEvent('change', this.current);
    }
});


