/*
 * Crossfade version 2.0
 * Copyright (C) 2007 Université de Lausanne
 * Written by Etienne Dysli
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * This program uses two wonderful libraries:
 * Prototype Copyright (c) 2005-2007 Sam Stephenson (http://prototypejs.org/)
 * Script.aculo.us Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us/, http://mir.aculo.us/)
 */


/* COMMENT UTILISER CE CODE
 *
 * Il vous faut:
 *
 * 1. Un élément div avec attribut id contenant les images à
 * animer. Il doit y avoir un div par diaporama.
 * ATTENTION: les images apparaissent dans l'ordre INVERSE dans lequel
 * elles sont mentionnées dans le document HTML!
 * Exemple:
 *   <div id="animation">
 *     <img src="image_1.jpg" />
 *     <img src="image_2.jpg" />
 *     <img src="image_3.jpg" />
 *   </div>
 * Affichera image_3 puis image_2 et image_1, et recommencera à image_3 etc.
 * Cela est dû au fait que les images sont "empilées" les unes sur les
 * autres par le browser lors du chargement. La dernière chargée est
 * alors visible au-dessus de la pile.
 *
 * 2. Prérequis CSS
 * Chaque groupe d'image "id" doit avoir le style suivant:
 *   #id img {
 *     position: absolute;
 *     top: 0;
 *     left: 0;
 *   }
 *
 * 3. Un morceau de code Javascript qui lance l'animation. Cet appel
 * DOIT apparaître APRES les éléments div contenant les images. Par
 * exemple à la fin de la page:
 * <script type="text/javascript">
 * new Slideshow('accueil_img',3.0,3.5);
 * new Slideshow('interne_img',0.5,3.0);
 * new Slideshow('actu_img',1.0,2.0);
 * </script>
 *
 * Il faut instancier un objet Slideshow par diaporama. Les paramètres
 * à donner sont, dans l'ordre:
 *   - l'identifiant de l'élément div
 *   - durée en secondes du fondu enchaîné entre deux images du groupe
 *   - durée en secondes de l'affichage de chaque image du groupe
 *
 * 4. La version 1.8.1 de Script.aculo.us
 */


/**
 * Class Slideshow, animates one image group.
 */
var Slideshow=Class.create({

	/**
	 * Constructor
	 *
	 * @param string id Identifier of the div element containing images
	 * @param int transition Crossfade duration in seconds
	 * @param int pause Image display duration in seconds
	 */
	initialize: function(id,transition,pause) {
	    this.id=id;
	    this.images=Array();
	    this.transition=transition;
	    this.pause=pause;
	    this.microcycle=0;
	    this.images=$$('#'+this.id+' img').reverse();
            this.randomnumber=Math.floor(Math.random()*this.images.length);
            this.images=this.images.slice(this.randomnumber,this.images.length).concat(this.images.slice(0,this.randomnumber));
	    this.microcycle=(this.transition+this.pause)*this.images.length;
	    this.current=0;
	    for(var j=0;j<this.images.length;j++) {
		this.images[j].style.zIndex=this.images.length-j;
	    }
	    this.loadEventQueue();
	    new PeriodicalExecuter((function(){this.loadEventQueue();}).bind(this),this.pause);
	},

	/**
	 * Loads the event queue with transitions.
	 * The event queue is specific to each Slideshow.
	 * Loads all transitions needed to make one complete cycle (first image -> ... -> last image -> first image)
	 */
	loadEventQueue: function() {
	    for(var i=0;i<this.images.length;i++) {
		new Effect.Fade(this.images[i],{queue: {position: 'end', scope: this.id}, duration: this.transition, delay: this.pause, beforeStart: (function(){this.beforeImage();}).bind(this), afterFinish: (function(){this.afterImage();}).bind(this)});
	    }
	},

	/**
	 * Sets images' z-indexes.
	 * The current image is on top, all others are piled below in order.
	 */
	beforeImage: function() {
	    for(var i=0;i<this.images.length;i++) {
		var image=this.images[(this.current+i)%this.images.length];
		image.style.zIndex=this.images.length-i;
	    }
	},

	/**
	 * Hides the current image below the stack and increments current image.
	 */
	afterImage: function() {
	    this.images[this.current].style.zIndex=0;
	    Element.show(this.images[this.current]);
	    Element.setOpacity(this.images[this.current],1.0);
	    this.current=(this.current+1)%this.images.length;
	}
    });

