/**
 * @fileoverview  JavaScript Slideshow
 *
 * Simple slideshow using prototype and scriptaculous.
 * 
 * Usage:
 * ------
 * <script src="prototype.js"></script>
 * <script src="effects.js"></script>
 * <script src="slideshow.js"></script>
 * <style type="text/css">
 *     #slideshow { position: relative; width: 100px; height: 100px; }
 *     #slideshow div { position: absolute; left: 0; top: 0; }
 * </style>
 * <div class="slideshow" id="slideshow">
 *     <div class="slide"><img src="slide1.jpg"></div>
 *     <div class="slide"><img src="slide2.jpg"></div>
 *     <div class="slide"><img src="slide3.jpg"></div>
 * </div>
 * <script type="text/javascript">new Slideshow('slideshow', 3000);</script>
 *
 * See also: http://blog.remvee.net/post/17
 *
 * @package    Slideshow
 * @author     R.W. van 't Veer
 * @author     Murat Purc (murat@purc.de)
 * @copyright  (c) 2006 - R.W. van 't Veer
 *
 * Changes:
 * 2006-06-20 by Murat Purc (murat@purc.de), Added handling of Elements having display none styles.
 * 2008-09-28 by Murat Purc (murat@purc.de), Refactoring of code
 * 2009-03-05 by Murat Purc (murat@purc.de), Further refactoring
 */


/**
 * Class Slideshow
 */
Slideshow = Class.create({

    /**
     * Array of slide elements
     * @type  {array}
     */
    _aSlides: [],

    /**
     * Actual position
     * @type  {int}
     */
    _current: 0,

    /**
     * Time to wait between fades
     * @type  {int}
     */
    _timeout: 4000,


    /**
     * Constructor
     * 
     * @param  {string}  slideshow  Id of element which contains the images
     * @param  {int}     timeout    Time between two slides
     */
    initialize: function (slideshow, timeout) {
        this._aSlides = $(slideshow).select('div.slide');
        var that = this;
        this._aSlides.each(function(item, pos){
            $(item).setStyle({zIndex: (that._aSlides.length - pos + 1)}).hide();
        });
        this._timeout = timeout;

        $(slideshow).show();

        this._displayImage();
    },


    /**
     * Runs fade effect and prepares next fade
     */
    _next: function() {
        var that = this;
        this._aSlides.each(function(item, pos){
            var slide = that._aSlides[(that._current + pos) % that._aSlides.length];
            $(slide).setStyle({zIndex: (that._aSlides.length - pos)});
        });

        Effect.Fade(this._aSlides[this._current], {
            afterFinish: function(effect) {
                $(effect.element).setStyle({zIndex: 0}).show().setOpacity(1);
            }
        });

        this._current = (this._current + 1) % this._aSlides.length;

        this._displayImage();
    },


    /**
     * Displays current element and sets timer for next slide
     */
    _displayImage: function(){
        $(this._aSlides[this._current]).setStyle({display: 'inline'});
        setTimeout((function(){this._next();}).bind(this), this._timeout);
    }

});
