var Slideshow = Class.create({
  initialize: function(id, options) {
    this.options = Object.extend({
      slideClass: "slide",
      duration: 3
    }, options || {});
    
    this.slideshow    = $(id);
    this.slides       = this.slideshow.select(".slide");

    this.activeSlide  = this.slides[0];

    this.startSlideshow();
  },
  
  getActiveSlide: function() {
    return this.activeSlide;
  },
  
  slides: function() {
    return this.slides;
  },
  
  slideshow: function() {
    return this.slideshow;
  },
  
  transitionOutSlide: function(element) {
    element.fade({ duration: 1.0, from: 1, to: 0, afterFinish: function(effect) {
      effect.element.removeClassName("active");
    }});
  },
  
  transitionInSlide: function(element) {
    this.activeSlide = element;
    this.activeSlide.setStyle({display: 'block'});
    element.fade({ duration: 1.0, from: 0, to: 1, afterFinish: function(effect) {
      effect.element.addClassName("active");  
    }});
  },
  
  setupSlideshow: function() {
    var slides = this.slides;
    this.slides.each(function(e) { 
      if (e != slides.first()) { e.setStyle( {opacity: 0} ); };
    });
    
    this.slides.first().addClassName("active");
  },
  
  startSlideshow: function() {
    this.setupSlideshow();
    new PeriodicalExecuter(this.advanceNextSlide.bind(this), this.options.duration);
  },
  
  determineNextSlide: function () {
    var active_slide_position = this.slides.indexOf(this.activeSlide);
    if (active_slide_position == this.slides.length-1) {
      return this.slides.first();
    } else {
      return this.slides[active_slide_position+1];
    }
  },
  
  // this is where the magic happens...
  advanceNextSlide: function() {
    this.transitionOutSlide(this.activeSlide);
    this.activeSlide = this.determineNextSlide();
    this.transitionInSlide(this.activeSlide);
  }
});
// Your library here
