﻿var Slider = Class.create();
Object.extend(Slider.prototype, {
    initialize: function(el, opts) {
        var defaults = { queueCommands: true };
        this.opts = Object.extend(defaults, opts);
        this.wrapper = $(el);
        this.viewport = this.wrapper.select("div")[0];
        this.list = this.wrapper.select('ul')[0];

        this.slides = this.list.select('li');
        this.list.insert({ top: this.slides[this.slides.length - 1].clone(true).addClassName('cloned') });
        this.list.insert({ bottom: this.slides[0].clone(true).addClassName('cloned') });
        this.slides = this.list.select('li');

        this.commandQueue = $A();
        this.isAnimating = false;
        this.currentSlide = this.opts.startIndex;

        var w = 0;
        this.slides.each(function(s) {
            w += s.getWidth();
        });
    
        this.wrapper.setStyle({ height: this.slides[this.currentSlide].getHeight() + "px" });
        this.viewport.setStyle({ position: 'absolute', height: this.slides[this.currentSlide].getHeight() + "px" });
        this.list.setStyle({ position: 'absolute', width: w + "px", left: (-1 * this.getXPos(this.currentSlide)) + "px" });
    },
    next: function() {
        if (this.isAnimating) {
            if (this.opts.queueCommands) {
                this.commandQueue.push(this.next);
            }
            return;
        }
        if (this.currentSlide < this.slides.length - 1) {
            this.currentSlide++;
            this.move();
        }
    },
    previous: function() {
        if (this.isAnimating) {
            if (this.opts.queueCommands) {
                this.commandQueue.push(this.previous);
            }
            return;
        }
        if (this.currentSlide > 0) {
            this.currentSlide--;
            this.move();
        }
    },
    move: function() {
        this.moveAndResizeViewport(-1 * this.getXPos(this.currentSlide), this.slides[this.currentSlide].getHeight(), function() {
            this.isAnimating = false;
            if (this.currentSlide == 0 || this.currentSlide == this.slides.length - 1) {
                this.currentSlide = this.currentSlide == 0 ? this.slides.length - 2 : 1;
                var newPos = -1 * this.getXPos(this.currentSlide);
                this.list.setStyle({ left: newPos + 'px' });
            }
            
            if (Object.isFunction(this.opts.afterFinish)) {
                this.opts.afterFinish(this.currentSlide);
            }
            
            if (this.commandQueue.length > 0) {
                this.commandQueue.shift().call(this);
            }
        } .bind(this));
    },
    getXPos: function(slideNumber) {
        var pos = 0;
        for (var i = 0; i < slideNumber; i++) {
            pos += this.slides[slideNumber].getWidth();
        }
        return pos;
    },
    moveAndResizeViewport: function(viewportX, viewportHeight, afterFinishCallback) {
        this.isAnimating = true;
        var fx = $A();
        fx.push(new Effect.Move(this.list, { x: viewportX, y: 0, mode: 'absolute', sync: true }));
        fx.push(new Effect.Morph(this.viewport, { style: { height: viewportHeight + "px" }, sync: true }));
        fx.push(new Effect.Morph(this.wrapper, { style: { height: viewportHeight + "px" }, sync: true }));
        new Effect.Parallel(fx, { afterFinish: afterFinishCallback });
    }
});
