var Slideshow = Class.create();
Slideshow.prototype =
{
  _timer: null,
  _container: null,
  _currentSlide: null,
  _playing: false,
  _options: {},
  
  initialize: function(container, options)
  {
    this._container = $(container);
    this._container.setStyle({position: 'relative', overflow: 'hidden'});
    
    $A(this._container.getElementsByClassName('slide')).each(function(slide){
      slide.hide();
      slide.setStyle({position: 'absolute', left: '0', top: '0', overflow: 'hidden'});
    });
    this._currentSlide = this._container.down('.slide');
    this._currentSlide.show();
    
    this._options.speed = 3.0;
    this._options.duration = 1.0;
    this._options = Object.extend(this._options, options||{});
    
    this._fireOnSlideChange();
    this._afterNextSlide();
  },
  
  showAndStop: function(id)
  {
    this.stopShow();
    this._currentSlide.hide();
    this._currentSlide = $(id);
    this._currentSlide.show();
    this._fireOnSlideChange();
    this._afterNextSlide();
  },
  
  showAndPlay: function(id)
  {
    this.stopShow();
    this._currentSlide.hide();
    this._currentSlide = $(id);
    this._currentSlide.show();
    this._fireOnSlideChange();
    this._afterNextSlide();
    this.startShow();
  },
  
  stopShow: function()
  {
    clearTimeout(this._timer);
    this._playing = false;
  },
  
  startShow: function()
  {
    this._playing = true;
    this._delayNextSlide();
  },
  
  toggleShow: function()
  {
    if(this._playing)
      this.stopShow();
    else
      this.startShow();
  },
  
  previousSlide: function()
  {
    var oldSlide = this._currentSlide;
    var newSlide = this._currentSlide.previous('.slide');
    if(newSlide == null || typeof(newSlide) == 'undefined')
      $A(this._container.immediateDescendants()).each(function(element){ if(element.hasClassName('slide')){ newSlide = element; }});
    this._currentSlide = newSlide;
    var effects =
    [
      new Effect.Fade(oldSlide, {sync: true}),
      new Effect.Appear(newSlide, {sync: true})
    ];
    this._fireOnSlideChange();
    new Effect.Parallel(effects, {duration: this._options.duration, afterFinish: this._afterNextSlide.bind(this)});

  },
  
  nextSlide: function()
  {      
    var oldSlide = this._currentSlide;
    var newSlide = this._currentSlide.next('.slide');
    if(newSlide == null || typeof(newSlide) == 'undefined')
      newSlide = this._container.down('.slide');
    this._currentSlide = newSlide;
    var effects =
    [
      new Effect.Fade(oldSlide, {sync: true}),
      new Effect.Appear(newSlide, {sync: true})
    ];
    this._fireOnSlideChange();
    new Effect.Parallel(effects, {duration: this._options.duration, afterFinish: this._afterNextSlide.bind(this)});
  },
  
  _afterNextSlide: function()
  {
    if(this._playing)
      this._delayNextSlide();
  },
  
  _delayNextSlide: function()
  {
    this._timer = setTimeout(this.nextSlide.bind(this), this._options.speed*1000);
  },
  
  _fireOnSlideChange: function()
  {
    if(this._options.onSlideChange)
      this._options.onSlideChange(this._currentSlide, this);
  }
}
