var Slideshow = Class.create();
Object.extend(Slideshow.prototype, {

	/**
	 * Stores the current state of the slideshow
	 */
	state: new String(),

	/**
	 * Stores current timeout id
	 */
	timeoutId: null,	
	
    /**
     * Initializes slideshow
     *
     */
    initialize: function(options) {
        // save options        
        if( this.setOptions ){
            this.setOptions(options);
        } else {
            this.options = options || {};
        }
        
        // set some options
        this.options.slideContainer = $(this.options.slideContainer);
        this.options.delay = this.options.delay ? parseInt(this.options.delay) : 4000;
        this.options.delay = this.options.delay < 1000 ? 1000 : this.options.delay;
        
        this.currentFrame = 0;
        this.startFrame = 0;
    	this.lis = this.options.slideContainer.getElementsByTagName('li');
    	for( i=0; i < this.lis.length; i++ ){
    		if( i!=0 ){
    		    Element.hide(this.lis[i]);
    		} else {
	    		Element.show(this.lis[i]);
	    	}
    	}
    	this.endFrame = this.lis.length-1;
    	
    	// prepare the control
    	if( this.options.controlId ){
    		this.control = new Object();
    		var buttons = $$('#' + this.options.controlId + ' li');
    		this.control.prev = buttons[0];
    		this.control.play = buttons[1];
    		this.control.stop = buttons[2];
    		this.control.next = buttons[3];
    		
    		Element.hide(this.control.stop);
    		
    		Event.observe(this.control.play, 'click', this.play.bindAsEventListener(this));
    		Event.observe(this.control.stop, 'click', this.stop.bindAsEventListener(this));
    		Event.observe(this.control.next, 'click', this.next.bindAsEventListener(this));
    		Event.observe(this.control.prev, 'click', this.prev.bindAsEventListener(this));
    		
    	} else {
		   	// begin the show
		   	this.play();
		}
		   	
    },


    /**
     * Runs the slideshow
     *
     */
    play: function(evt){
    	if( evt ){ Event.stop(evt); }
    	
    	// only set interval if it hasn't been set yet
    	if( !this.timeoutId ){
        	this.timeoutId = setInterval(this.showFrame.bind(this), this.options.delay);
        	this.state = 'play';

        	// show / hide controls
        	try{
	        	Element.hide(this.control.play);
	        	Element.show(this.control.stop);
        	}catch(e){
        	}
		}
    },

    /**
     * Stops the slideshow
     *
     */
    stop: function(evt){
    	if( evt ){ Event.stop(evt); }
    	
		// clear the interval
        clearInterval(this.timeoutId);
        this.timeoutId = null;

        this.state = 'stop';
		
		// show / hide controls
		try{
	      	Element.hide(this.control.stop);
	      	Element.show(this.control.play);
		}catch(e){
		}
        
    },

    /**
     * Command to show the next picture
     *
     */
    next: function(evt){
    	if( evt ){ Event.stop(evt); }
    	
    	// stop and show next image
    	this.stop();
        this.showFrame(1);
    },

    /**
     * Command to show the previous picture
     *
     */
    prev: function(evt){
    	if( evt ){ Event.stop(evt); }
    	
    	// stop and show prev image
    	this.stop();
        this.showFrame(-1);
    },


    /**
     * Gets the previous frame
     *
     */
    getPrevFrame: function(){
        frame = this.currentFrame;
        if( frame == this.startFrame){ 
            frame = this.endFrame; 
        } else { 
            frame--; 
        }
        return frame;
    },


    /**
     * Gets the next frame
     *
     */
    getNextFrame: function(){
        frame = this.currentFrame;
        if( frame == this.endFrame ){ 
            frame = this.startFrame; 
        } else { 
            frame++; 
        }
        return frame;
    },
    
    /**
     * Show the next frame
     *
     */
    showFrame: function(dir){
            frame = (dir == -1) ? this.getPrevFrame() : this.getNextFrame();
            
            // get the image and check if it has completed loading
            var img = this.lis[frame].down();
            if( img.complete ){
                // animate
                Effect.Appear(this.lis[frame]);
                Effect.Fade(this.lis[this.currentFrame]);
                this.currentFrame = frame;
            } else {
            }
            
    }    
    
});