var Slideshow = Class.create();

Slideshow.prototype = {
    initialize: function(elements, photos, speed, opacityspeed) {
        this.elements = elements;
        this.photos = photos;
        this.speed = speed / 1000;
        this.opacityspeed = opacityspeed / 1000;
        this.displayPool = photos.shuffle();
        this.nextContainerId = 0;

        for (var index = 0, len = this.photos.length; index < len; ++index) {
            Preloader.add(this.photos[index].src);
        }
        Preloader.load();
        new PeriodicalExecuter(this.nextContainer.bind(this), ((this.speed * 1000) / this.elements.length) / 1000);
    },
    nextContainer: function(container) {
        this.display(this.elements[this.nextContainerId]);
        this.nextContainerId = (++this.nextContainerId) % this.elements.length;
    }
    ,
    display: function(container) {
        var img = this.displayPool.pop();
        var ahref = new Element('a');

        if (img.href != null) {
            ahref.href = img.href;
            ahref.target = 'blank';
        }
        Element.setStyle(ahref, { position: 'absolute', left: 0, top: 0, opacity: 0, width: container.getWidth() + 'px', height: container.getHeight() + 'px'});

        var imgelement = new Element('img');

        imgelement.src = img.src;
        ahref.appendChild(imgelement);
        ahref.addClassName("fadepicture")

        var olda = container.select('a');
        var oldimg = container.select('img');
        if (olda[0].hasClassName("fadepicture")) {
            this.displayPool.push({ 'src': oldimg[0].src, 'href': olda[0].href });
            this.displayPool = this.displayPool.shuffle();
        }
        container.appendChild(ahref);

        fadeineffect = new Effect.Opacity(ahref, { from: 0, to: 1.0, duration: this.opacityspeed });
        fadeouteffect = new Effect.Opacity(olda[0], { from: 1.0, to: 0.0, duration: this.opacityspeed, delay: this.opacityspeed, afterFinish: function(el) { el.element.parentNode.removeChild(el.element) } });
    }
}

Array.prototype.shuffle = function() {
    return this.sortBy(Math.random);
};

var Preloader = {
  callbacks: [],
  images: [],
  loadedImages: [],
  imagesLoaded: 0,

  add: function(image){
    if (typeof image == 'string') this.images.push(image);
    if (typeof image == 'array' || typeof image == 'object') {
      for (var i=0; i< image.length; i++){
        this.images.push(image[i]);
      }
    }
  },
  onFinish: function(func){
    if (typeof func == 'function') this.callbacks.push(func);
    if (typeof func == 'array' || typeof func == 'object'){
      for (var i=0; i< func.length; i++){
        this.callbacks.push(func[i]);
      }
    }
  },
  load: function(){
    for(var i=0; i<this.images.length; i++){
      this.loadedImages[i] = new Image();
      this.loadedImages[i].onload = function(){ Preloader.checkFinished.apply(Preloader) }
      this.loadedImages[i].src = this.images[i];
    }
  },

  checkFinished: function(){
    this.imagesLoaded++;
    if (this.imagesLoaded == this.images.length) this.fireFinish();
  },
  fireFinish: function(){
    for (var i=0; i<this.callbacks.length; i++){
      this.callbacks[i]();
    }
    this.images = [];
    this.loadedImages = [];
    this.imagesLoaded = 0;
    this.callbacks = [];
  }
}
