var SlideShow = new Class({
    initialize: function(elements, captions, options) {
        if (elements.length <= 1) return;
        
        this.container = $(elements.getLast().parentNode);
        this.elements = elements;
        this.captions = captions;
        this.options = Object.extend(Object.extend({}, SlideShow.DefaultOptions), options || {});
        
        this._setupElements();
        this._setupContainer();
    },
    
    start: function() {
        if (this.elements == null) return;
        this.slideShowElements[0].start();
    },
    
    _setupContainer: function() {
        // container of the elements being cycled through must have position relative and overflow hidden
        this.container.setStyles({
            position: "relative",
            overflow: "hidden"
        });
        
        // element used to maintain the slideshows correct size
        var sizer = new Element("div", {
            styles: {
                width: this.elements[0].getSize().size.x,
                height: this.elements[0].getSize().size.y
            }
        });
        
        sizer.injectInside(this.container);
    },
    
    _setupElements: function() {
        this.slideShowElements = [];
        
        var temp;
        
        // setup each element
        this.elements.each(function(element) {
            var slideShowElement = this._setupElement(element)
            if (temp) temp.next = slideShowElement;
            temp = slideShowElement;
        }.bind(this));
        
        // the next element of the last is the first element
        temp.next = this.slideShowElements[0];
    },
    
    _setupElement: function(element) {
        element.setStyles({
            position: "absolute",
            top: 0,
            left: 0,
            opacity: element == this.elements[0] ? 1 : 0,
            display: "block",
            zIndex: 98
        });
        
        var slideShowElement = new SlideShow.Element(element, this.captions[this.elements.indexOf(element)], this);
        this.slideShowElements.push(slideShowElement);
        
        return slideShowElement;
    },
    
    _resetAll: function() {
        this.slideShowElements.each(function (slideShowElement){
            slideShowElement.element.style.zIndex = 98;
        });
    }
});

SlideShow.Element = new Class({
    initialize: function(element, caption, parent) {
        this.element = $(element);       
        this.caption = $(caption);
        this.parent = parent; 
        this.effect = new Fx.Style(this.element, "opacity", { duration: this.parent.options.fadeDuration });
    },
    
    start: function() {        
        this.effect.start(1);
        
        setTimeout(function() {
            this.parent.slideShowElements.each(function (slideShowElement){
                slideShowElement.caption.style.display = "none";
            });
            
            this.caption.style.display = "block";
        }.bind(this), this.parent.options.fadeDuration);
        
        setTimeout(function() {
            this.parent._resetAll();
            
            this.element.style.zIndex = 99;
            this.next.element.style.zIndex = 100;
                
            this.next.element.setOpacity(0);
            this.next.start();
        }.bind(this), this.parent.options.imageDelay);
    }
});

SlideShow.DefaultOptions = {
    imageDelay: 6000,
    fadeDuration: 1000
};
