var ajs = ajs || { };
ajs.menu = ajs.menu || { };
ajs.gallery = ajs.gallery || { };

ajs.menu.Menu = Class.create({
  initialize: function(element) {
    this.element = element;
    this.items = [ ];
    this.marker = new ajs.menu.Marker(this.element.select('div#menu_marker').first());

    var itemElements = this.element.select('li');
    for (var i = 0; i < itemElements.length; i++) {
      var itemElem = itemElements[i];
      itemElem.observe('menu:over', this.itemSelect.bindAsEventListener(this));
      itemElem.observe('menu:out', this.itemUnselect.bindAsEventListener(this));
      if (itemElem.hasClassName('selected')) {
        this.marker.setHomePosition(itemElem.positionedOffset().left,
                                    itemElem.getWidth());
      }
      var item = new ajs.menu.MenuItem(itemElem);
      this.items.push(item);
    }
  },

  itemSelect: function(event) {
    var item = event.memo.item;
    this.marker.move(item.positionedOffset().left, item.getWidth());
  },

  itemUnselect: function(event) {
    var item = event.memo.item;
    this.marker.moveToHome();
  }
});

ajs.menu.MenuItem = Class.create({
  initialize: function(element) {
    this.element = element;
    element.down().observe('mouseenter', this.mouseEnter.bindAsEventListener(this));
    element.down().observe('mouseleave', this.mouseLeave.bindAsEventListener(this));
  },

  mouseEnter: function(event) {
    this.element.fire('menu:over', { item: this.element });
  },
  mouseLeave: function(event) {
    this.element.fire('menu:out', { item: this.element });
  }
});

ajs.menu.Marker = Class.create({
  duration: 0.5,
  markerWidth: 93,

  initialize: function(element) {
    this._element = element;
    this._currentX = 0;
    this._effect = null;
  },

  move: function(targetX, itemW) {
    this._currentX = targetX - (this.markerWidth - itemW) / 2;
    this._animate();
  },

  setHomePosition: function(x, homeItemW) {
    this._homePos = x - (this.markerWidth - homeItemW) / 2;
    this.moveToHome();
  },

  moveToHome: function() {
    this._currentX = this._homePos;
    this._animate();
  },

  _animate: function() {
    if (this._effect) this._effect.cancel();
    this._effect = new Effect.Move(this._element, { x: this._currentX,
                                                    y: 37,
                                                    mode: 'absolute',
                                                    duration: this.duration });
  }
});

ajs.gallery.Gallery = Class.create({
  initialize: function(element) {
    this.element = element;
    this.thumbnails = element.select('a.thumbnail');
    this.thumbnails.each(function(e, i) {
      new ajs.gallery.Picture(e, i);
    });
  }
});

ajs.gallery.Picture = Class.create({
  duration: 0.5,

  initialize: function(element, index) {
    this.element = element;
    this.image = element.firstDescendant();
    this.effect = null;

    element.removeClassName('resizable');
    this.originalPos = this.image.positionedOffset();

    var left = this.originalPos.left - (344 - 84);
    this.targetPos = {
      left: left,
      top: 0
    };

    element.observe('mouseenter', this.mouseEnter.bind(this));
    element.observe('mouseleave', this.mouseLeave.bind(this));
  },

  mouseEnter: function(e) {
    this.enlargeImage();
  },

  mouseLeave: function(e) {
    this.shrinkImage();
  },

  enlargeImage: function() {
    if (this.effect) this.effect.cancel();
    this.image.absolutize();
    // this.image.setStyle({ top: this.originalPos.top + 'px', left: this.originalPos.left + 'px' });
    this.effect = new Effect.Morph(this.image, {
      style: 'left: ' + this.targetPos.left + 'px; '
        + 'top: ' + this.targetPos.top + 'px; '
        + 'width: 344px; height: 344px;',
      duration: this.duration
    });
  },

  shrinkImage: function() {
    if (this.effect) this.effect.cancel();
    this.effect = new Effect.Morph(this.image, {
      style: 'left: ' + this.originalPos.left + 'px; '
        + 'top: ' + this.originalPos.top + 'px; '
        + 'width: 84px; height: 84px;',
      duration: this.duration,
      afterFinish: function(effect) {
        //effect.element.setStyle({ position: 'static' });
        effect.element.relativize();
      }
    });
  }
});
