var Slideshow = Behavior.create({
  initialize: function(){
    this.frames = this.element.select(".frame");
    this._buildControls();
    this.frames.first().show();
    this._startSlideshow();
  },
  _startSlideshow: function(){
    if(!this.cycler){
      this.play.removeClassName('play').addClassName('pause');
      this.frameIndex = 0;
      this.cycler = new PeriodicalExecuter(this.next.bind(this), 15);
    }
  },
  _buildControls: function() {
    if(!this.controls) {
      this.forward = $a({href:"",title:"go forward a page"}).addClassName('control').addClassName('forward').update("&gt;&gt;").observe('click', this.advance.bindAsEventListener(this));
      this.back = $a({href: "",title:"go back a page"}).addClassName('control').addClassName('back').update("&lt;&lt;").observe('click', this.retreat.bindAsEventListener(this));
      this.play = $a({href: "",title:"play/pause"}).addClassName('control').addClassName('pause').update("p").observe('click', this.resume.bindAsEventListener(this));
      this.controls = $p({style: "position:absolute;bottom:0;left:0;margin:0;width:50px;z-index:10000"}).insert(this.back).insert("&nbsp;").insert(this.play).insert("&nbsp;").insert(this.forward);
      this.element.insert(this.controls);
    }
  },
  next: function(){
    new Effect.Fade($(this.frames[this.frameIndex]), {duration: 0.5, queue: { position: 'end', scope: 'slideshow'}});
    this.frameIndex = (this.frameIndex + 1) % this.frames.length;
    new Effect.Appear($(this.frames[this.frameIndex]), {duration: 0.5, queue: { position: 'end', scope: 'slideshow'}});
  },
  previous: function(){
    new Effect.Fade($(this.frames[this.frameIndex]), {duration: 0.5, queue: { position: 'end', scope: 'slideshow'}});
    this.frameIndex = (this.frameIndex - 1 + this.frames.length) % this.frames.length;
    new Effect.Appear($(this.frames[this.frameIndex]), {duration: 0.5, queue: { position: 'end', scope: 'slideshow'}});    
  },
  advance: function(e){
    e.stop();
    this.stopCycle();
    this.next();
  },
  retreat: function(e){
    e.stop();
    this.stopCycle();
    this.previous();
  },
  resume: function(e){
    e.stop();
    if(this.cycler)
      this.stopCycle();
    else {
      this.next();
      this._startSlideshow();
    }
  },
  stopCycle: function(){
    if(this.cycler){
      this.cycler.stop();
      this.play.removeClassName('pause').addClassName('play');
      delete this.cycler;
    }
  }
});

Event.addBehavior({
  '#frames': Slideshow
});