var Slideshow = Class.create({
default_options: $H({ duration: 4, pause: 0.5 }),
initialize: function(id, images, options) {
  this.setCurIndex(0);
  this.oldIndex = 0;
  this.container_id = id;
  options = this.default_options.merge(options || {});
  this.duration = options.get('duration');
  this.pause = options.get('pause');
  var id_prefix = id+"_slide_";
  this.nextImage = this.nextImage.bind(this);
  this.pausedNext = this.pause ? this.pausedNext.bind(this) : this.nextImage;
  if (options.get('clear')) $(id).innerHTML = '';
  var link = options.get('link');
  this.images = images.map(function(path, index) {
    var img = document.createElement('img');
    var child = img;
    img.src = path;
    if (link) {
      var ahref = document.createElement('a');
      ahref.href = link;
      ahref.appendChild(img);
      child = ahref;
    }
    img.id = id_prefix + index;
    img.className = "slideshow-img";
    $(id).appendChild(child);
    img = $(img);
    img.hide();
    return img.id
  });
  $(this.images[0]).show();
  var startAfter = options.get('startAfter') || 0;
  this.nextImage.delay(startAfter);
},
stopEffects: function() {
 if (this.paused) {
   clearTimeout(this.paused);
   this.paused = null;
 }
 if (this.curEffect) this.curEffect.cancel();
},
startEffects: function(extraFadeIndex) {
  var effects = [
    new Effect.Fade(this.images[this.oldIndex], { sync: true }),
    new Effect.Appear(this.images[this.curIndex], { sync: true })
  ];
  if (extraFadeIndex) {
    effects.push(new Effect.Fade(this.images[extraFadeIndex], { sync: true }));
  }
  this.curEffect = new Effect.Parallel(effects,
      { duration: this.duration, afterFinish: this.pausedNext });
},
nextIndex: function() {
  this.oldIndex = this.curIndex;
  this.setCurIndex((this.curIndex + 1) % this.images.length);

},
nextImage: function() {
  this.paused = null;
  this.nextIndex();
  this.startEffects();
},
pausedNext: function() { this.paused = this.nextImage.delay(this.pause); },
setIndex: function(index) { // call from buttons
  if (this.curIndex == index) return;
  this.stopEffects();
  var oldIndex = (this.oldIndex == index) ? null : this.oldIndex;
  this.oldIndex = this.curIndex;
  this.setCurIndex(index);
  this.startEffects(oldIndex);
},
setCurIndex: function(index) { // replace/override as desired
  this.curIndex = index;
}
});
