SlideShow = Class.create({
  initialize: function(element, options) {
    this.element = $(element);
    
    this.options = Object.extend({
      animation : 'fade',  
      captions : true,
      controls : true,
      debug : true,
      delay : 3,
      fxDuration : 0.25,
      height : 300,
      transition : 'sinusoidal',
      width : 400
    }, options||{});

    this.index = 0;  
    
    this.build(); 
    
    if(this.images.length>1){     
      this.play();
    }
  },
  
  build : function() {
    this.images = this.element.select('img');
    this.element.down('ul').hide();
    this.element.setStyle({ 
      height : this.options.height+'px',
      overflow : 'hidden',
      position : 'relative',
      width : this.options.width+'px'    
    });
    
    this.nextImage = new Element('img').setStyle({
      display : 'none',
      height : this.options.height+'px',
      left : 0,
      position : 'absolute',
      width : this.options.width+'px',
      top : 0,
      'zIndex' : 1
    });
    
    this.currentImage = new Element('img').setStyle({
      height : this.options.height+'px',
      left : 0,
      position : 'absolute',
      width : this.options.width+'px',
      top : 0,
      'zIndex' : 0
    });
    
    
    if(this.images.length>1){
      if(this.options.captions || this.options.controls) {
        this.controlsPanel = new Element('div', { 'class' : 'ss-controls-panel' }).setStyle({
          top : '100%',
          position : 'absolute',
          'zIndex' : 4
        });
        this.element.insert(this.controlsPanel);      
      }  
    
      if(this.options.controls) {
        this.controls = new Element('div', { 'class' : 'ss-controls' });     
        this.slideInds = new Element('ul', { 'class' : 'ss-slide-ind' });
        this.prevBtn = new Element('a', { 'class' : 'prev-btn' }).update('previous slide');
        this.nextBtn = new Element('a', { 'class' : 'next-btn' }).update('next slide');      
           
        this.slideInds.insert(new Element('li').update(this.prevBtn));   
      
        this.images.each(function(el, idx) {
          a = new Element('a', { 'class' : 'ind', id : 'ind-'+(idx+1)}).update(idx+1);
       
          a.observe('click', function(e) {
            this.index = idx;
            this.pause();
            this.transition(idx);
          }.bindAsEventListener(this));   

          this.slideInds.insert(new Element('li').update(a));
        
        }.bind(this));
 
        this.prevBtn.observe('click', function(e) {
          this.pause();
          this.prev();    
        }.bind(this)); 
      
        this.nextBtn.observe('click', function(e) {
          this.pause();
          this.next();
        }.bind(this));
      
        this.slideInds.insert(new Element('li').update(this.nextBtn)); 
   
        this.pauseBtn = new Element('a', { 'class' : 'ss-pause' }).update('pause');
        this.pauseBtn.observe('click', function(e) {
          this.paused ? this.play() :  this.pause();
        }.bind(this));
      
        this.controls.insert(this.slideInds);
        this.controls.insert(this.pauseBtn);
        this.controlsPanel.insert(this.controls);

        var link = this.element.down('a.ind');
        if(link){
          link.addClassName('active');    
        }
      }
    
      if(this.options.captions) { 
        this.caption = new Element('div', { 'class' : 'ss-caption'}).update(this.images[this.index].title);
        this.caption[this.images[this.index].title ? 'show' : 'hide']();      
        this.controlsPanel.insert({top : this.caption});
      }
    }
    
    this.element.insert(this.nextImage);
    this.element.insert(this.currentImage); 
    this.currentImage.src = this.images[this.index].src;
    
    this.element.observe('mouseover', this.onMouseOver.bindAsEventListener(this));
    this.element.observe('mouseout', this.onMouseOut.bindAsEventListener(this));
    
  },
  onMouseOver : function(e){
    this.effect = new S2.FX.Morph(this.controlsPanel, {
      style : 'margin-top: -26px;'
    });
    this.effect.play();
  },
  onMouseOut : function(e){
    if(e.relatedTarget && e.relatedTarget.descendantOf(this.element)) return false;
    this.effect = new S2.FX.Morph(this.controlsPanel, {
      style : 'margin-top: 0;'
    });
    this.effect.play();
  },
  next : function() {
    this.index++;    
    if(this.index === this.images.length) this.index = 0;
    this.transition(this.index); 
  },
  
  pause : function() {
    this.paused = true;
    if(this.options.controls) this.pauseBtn.update("play");
    window.clearTimeout(this.timer);
    this.pauseBtn.addClassName('ss-paused');
  },
  
  play : function() {
    this.paused = false;
    if(this.options.controls) this.pauseBtn.update("pause"); 
    this.timer = this.next.bind(this).delay(this.options.delay);
    this.pauseBtn.removeClassName('ss-paused');    
  },

  prev : function() { 
    this.index--;     
    if(this.index < 0) this.index = this.images.length;
    this.transition(this.index);
  },
  
  transition : function(idx) {  
    switch(this.options.animation) {  
      case 'fade':
      default :
        this.nextImage.setStyle({
          opacity : 0
        }).show();
      
        this.effect = new S2.FX.Morph(this.nextImage, {
          after : function() {
            this.currentImage.src = this.images[idx].src;
            this.caption[this.images[idx].title ? 'show' : 'hide']();
            if(this.options.captions) this.caption.innerHTML = this.images[idx].title;            
            this.nextImage.hide();
            if(this.options.controls) this.updateIndicator();
            if(!this.paused) this.play();       
          }.bind(this), 
          before : function() { 
            this.nextImage.src = this.images[idx].src;
          }.bind(this),
          duration : this.options.fxDuration,
          style : 'opacity:1'
        }).play();

        break;
    } 
  },
  
  updateIndicator : function() {
    var active = this.element.down('ul.ss-slide-ind a.active');
    if(active){
      active.removeClassName('active');
    }
    var next = this.element.down('#ind-'+(this.index+1));
    if(next){
      next.addClassName('active');  
    }
  }
});