// Add shuffle() to Array
Object.extend(Array.prototype, {
  shuffle: function() {
    for (var i = 0, length = this.length; i < length; i++) {
      var rand_i = Math.floor(Math.random() * length);
      var temp = this[i];
      this[i] = this[rand_i];
      this[rand_i] = temp;
    }
  }
});

// ImageCrossfader
// Takes a link/button, an image and a list of image URLs to fade
var ImageCrossfader = Class.create();
ImageCrossfader.prototype = {
  initialize: function(clicker, container, imgUrls, beforeFadeHandler) {
    this.clicker = $(clicker);
    this.container = $(container);
    this.imgUrls = imgUrls;
    this.beforeFadeHandler = beforeFadeHandler || Prototype.emptyFunction;
    this.imgs = imgUrls.collect(function() { return new Image(); });
    this.imgIx = 0;
    
    this.cacheNextImgs(1);
    
    this._clone = this.container.cloneNode(true);
    Position.absolutize(this.container);
    this.container.parentNode.insertBefore(this._clone, this.container);
    
    Event.observe(clicker, 'click', this.fadeImage.bindAsEventListener(this));
  },
  
  fadeImage: function(event) {
    this._clone.src = this.getNextImgUrl();
    this.cacheNextImgs(2);
    this.beforeFadeHandler(this._clone.src);
    Effect.Fade(this.container, { to: 0.001, afterFinish: this.updateImages.bind(this) });
    Event.stop(event);
  },
  
  updateImages: function() {
    this.container.src = this._clone.src;
    this.container.setOpacity(0.999);
    this.container.show();
  },
  
  getNextImgUrl: function() {
    var nextUrl = this.imgUrls[this.imgIx];
    this.imgIx = (this.imgIx + 1) % this.imgUrls.length;
    return nextUrl;
  },
  
  cacheNextImgs: function(cacheBufferSize) {
    for (var i = 0; i < cacheBufferSize; i++) {
      var nextImgIx = (this.imgIx + i) % this.imgUrls.length;
      this.imgs[nextImgIx].src = this.imgUrls[nextImgIx];
    }
  }
}
