// Copyright (c) 2008 Anders Toxboe & Benjamin Media

var Scroller = Class.create();
Scroller.prototype = {
  initialize: function(element, options) {
    if (!($(element) != undefined)) return false;

    this.element = $(element);
    this.images_container = $$('#' + element + ' .images')[0];
    this.gutter_menu_elements = toArray($$('#' + element + ' .gutter ul li a'));
    this.indicator = $$('#' + element + ' .gutter .indicator')[0];

    this.options = Object.extend({className: 'scroll_image', duration: 3}, options);
    this.images = toArray(document.getElementsByClassName(this.options.className, this.images_container));
    
    this.selectedItem = null;
    this.hovering = false;
    this.changingImages = false;
    this.nextImageWaiting = null;
    
    this.prepareImages();
    this.prepareMenu();

    this.indicator.move = function(move_to, object) {
      if (!this.moving && !object.changingImages) {
        this.morph('margin-top: ' + move_to + 'px', {
          duration: 0.2,
          beforeStart: (function() {this.moving = true;}).bind(this),
          afterFinish: (function() {this.moving = false;}).bind(this),
          queue: { position: 'end', scope: 'catwalk', limit: 2 }
        });
      }
    }

    this.indicator.move(this.gutter_menu_elements.first().myOffset(), this);

    this.registerCallback();
  },

  prepareImages: function() {
    this.currentImage = this.images.first();
    this.images_container.style.position = 'relative';
    this.images_container.style.height = this.images.max(function(image) {
      var visible = Element.visible(image), height;
      Element.setStyle(image, {position: 'absolute', width: '100%', left: '0px'});
      if (!visible) Element.show(image);
      height = Element.getHeight(image);
      if (!visible) Element.hide(image);
      return height;
    }).toString() + 'px';
  },

  prepareMenu: function () {
    var indicator = this.indicator;
    var this_element_id = this.element.id;
    var gutter_offset = toArray($$('#' + this_element_id + ' .gutter'))[0].cumulativeOffset()[1];
    var scroller = this;
    this.gutter_menu_elements.each(function(element) {
      element.myOffset = function() {return this.cumulativeOffset()[1] - gutter_offset;}
      element.onmouseover = function() {
/*        indicator.selectedItem = this.getAttribute('rel');
        indicator.move(this.myOffset(), this);*/
        scroller.hovering = true;
        scroller.changeImage($(this.getAttribute('rel')));
      }
      element.onmouseout = function() {
        scroller.hovering = false;
      }
    });
  },

  linkForImage: function(image_id) {
    link = null;
    this.gutter_menu_elements.each(function(element) {
      if (element.getAttribute('rel') == image_id) link = element;
    })
    return link;
  },

  nextImage: function() {
    return this.images[(this.images.indexOf(this.currentImage) + 1) % this.images.length];
  },

  registerCallback: function() {
    this.timeoutID = window.setTimeout(this.tick.bind(this), this.options.duration * 1000);
  },

  changeImage: function(nextImage) {
    var currentImage = this.currentImage;

    if (!this.changingImages) {
      window.clearTimeout(this.timeoutID)
      new Effect.Parallel([
        new Effect.Fade(currentImage, {sync: true}),
        new Effect.Appear(nextImage, {sync: true})
      ], {
        duration: 0.5,
        beforeStart: (function(effect) {
          this.indicator.move(this.linkForImage(nextImage.id).myOffset(), this);
          this.changingImages = true;
          this.linkForImage(this.currentImage.id).className = '';
          this.linkForImage(nextImage.id).className += 'current';
        }).bind(this),
        afterFinish: (function(effect) {
          this.currentImage = nextImage;
          this.changingImages = false;
          
          if (this.nextImageWaiting == nextImage) {
            this.nextImageWaiting = null;
          } else if (this.nextImageWaiting != undefined) {
            this.changeImage(this.nextImageWaiting);
          }
          
          this.registerCallback();
        }).bind(this),
        queue: { position: 'end', scope: 'catwalk', limit: 2 }
      })    
    } else {
      this.nextImageWaiting = nextImage;
    }
  },

  tick: function() {
    if (!this.indicator.moving && !this.hovering) {
      var currentImage = this.currentImage;
      var nextImage = this.nextImage();
      this.changeImage(nextImage);
    } else {
      this.registerCallback();
    }
  }
}

Event.observe(window, 'load', function() {
  new Scroller('catwalk_scroller');
})

function toArray(list) {
  array_list = new Array();
  for (var i = 0; i < list.length; i++) {
    array_list[i] = list[i];
  }
  return array_list;
}