/*  Home, classes and functions for the home page.
 *  (c) 2011 Takashi Okamoto - BuzaMoto
 *
 *  This file was written by BuzaMoto for Knoll, Inc.
 *
 *--------------------------------------------------------------------------*/
 
var ExpandableChair = Class.create({
  initialize: function(container) {
    this.container = container;
    this.thumb = { src: this.container.down('img').getAttribute('src') };
    this.full = { src: this.thumb.src.replace(/-sm/, '') };
    this.container.observe('click', this.handleContainerClick.bind(this));
    this.container.observe('mouseover', this.handleContainerMouseOver.bind(this));
    this.container.observe('mouseout', this.handleContainerMouseOut.bind(this));
    this.container.setOpacity(0.5);
  },
  
  remove: function() {
    if ($(this.container.id)) {
      this.container.remove();
    }
  },
  
  attach: function(parent) {
    if (!$(parent).select('div#'+this.container.id)) {
      $(parent).insert(this.container);
    }
  },
  
  hide: function() {
    if (this.container.visible()) {
      this.container.hide();
    }
  },
  
  show: function() {
    if (!this.container.visible()) {
      this.container.show();
    }
  },
  
  loaded: function() {
    return (this.full.image && this.full.image.loaded);
  },
  
  loadFullImage: function() {
    if (this.loaded()) {
      this.handleFullImageLoaded();
    } else {
      this.full.image = new Element('img');
      this.full.image.observe('load', this.handleFullImageLoaded.bind(this));
      this.full.image.setAttribute('src', this.full.src);
    }
  },
  
  handleFullImageLoaded: function(event) {
    Event.fire(document, 'chair:imageLoaded', this.full.image);
  },
  
  handleContainerClick: function(event) {
    Event.fire(document, 'chair:clicked', this);
    Event.stop(event);
  },
  
  handleContainerMouseOver: function(event) {
    Event.fire(document, 'chair:mouseover', this);
    Event.stop(event);
  },
  
  handleContainerMouseOut: function(event) {
    Event.fire(document, 'chair:mouseout', this);
    Event.stop(event);
  }
});

var ExpandableChairsController = (function() {
  var chairs = [];
  var expanded = false;
  var hoveredChair = null;
  
  function chairClickHandler(event) {
    var chair = event.memo;
    $('chairFullView-spinner').show();
    $('chairFullView-container').hide();
    $('fullImage-caption').down('p').update($(chair.container.id+'-caption').innerHTML);
    $('fullImage-caption').down('div').update($(chair.container.id+'-link').innerHTML);
    if (!expanded) {
      expandView({
        duration: 1,
        afterFinish: function() {
          loadFullChair(chair);
        }
      });
    } else {
      loadFullChair(chair);
    }
  }
  
  function loadFullChair(chair) {
    if (chair.loaded()) {
      showFullChair(chair);
    } else {
      chair.loadFullImage();
    }
  }
  
  function showFullChair(img) {
    $('fullImage-container').update(img);
    $('chairFullView-container').appear({ duration: 0.4 });
    $('chairFullView-spinner').hide();
  }
  
  function chairMouseOverHandler(event) {
    if (hoveredChair) {
      fadeThumb(hoveredChair.container);
    }
    hoveredChair = event.memo;
    if (hoveredChair.container.getOpacity() == 0.5)
      appearThumb(hoveredChair.container);
  }
  
  function chairMouseOutHandler(event) {
    fadeThumb(event.memo.container);
    hoveredChair = null;
  }
  
  function fadeThumb(container) {
    new Effect.Opacity(container, {
      from: 1.0, to: 0.5, duration: 0.2, queue: { position: 'end', scope: container.id, limit: 2 }
    });
  }
  
  function appearThumb(container) {
    new Effect.Opacity(container, {
      from: 0.5, to: 1.0, duration: 0.4, queue: { position: 'end', scope: container.id, limit: 2 }
    });
  }
  
  function expandView(options) {
    if (typeof options != 'object') options = { duration: 1 };
    new Effect.Parallel([
      new Effect.Move('chairPreview-left',  { sync: true, y: 0, x: -235, mode: 'relative' }),
      new Effect.Move('chairPreview-right', { sync: true, y: 0, x:  235, mode: 'relative' })
    ], options);
    expanded = true;
  }
  
  function collapseView(options) {
    if (typeof options != 'object') options = { duration: 1 };
    if (typeof options.beforeStart == 'undefined') {
      options.beforeStart = function() {
        $('chairFullView-container').fade({ duration: 0.2 });
      };
    }
    new Effect.Parallel([
      new Effect.Move('chairPreview-left',  { sync: true, y: 0, x:  235, mode: 'relative' }),
      new Effect.Move('chairPreview-right', { sync: true, y: 0, x: -235, mode: 'relative' })
    ], options);
    expanded = false;
  }
  
  function chairImageLoadedHandler(event) {
    var loadedImage = event.memo;
    showFullChair(loadedImage);
  }
  
  // observers
  Event.observe(document, 'chair:clicked', chairClickHandler);
  Event.observe(document, 'chair:mouseover', chairMouseOverHandler);
  Event.observe(document, 'chair:mouseout', chairMouseOutHandler);
  Event.observe(document, 'chair:imageLoaded', chairImageLoadedHandler);
  
  return {
    addChair: function(chair) {
      if (chair instanceof ExpandableChair) {
        chairs.push(chair);
        return chair;
      } else {
        throw new Error('Chair must be instance of ExpandableChair');
      }
    },
    
    removeChair: function(chair) {
      for (var i = 0, len = chairs.length; i < len; ++i) {
        if (chairs[i] == chair) {
          chairs[i] = null;
          chairs = chairs.compact();
          return chair;
        }
      }
      return null;
    },
    
    hideAll: function() {
      for (var i = 0, len = chairs.length; i < len; ++i) {
        chairs[i].container.setOpacity(0.0);
      }
    },
    
    showAll: function() {
      for (var i = 0, len = chairs.length; i < len; ++i) {
        chairs[i].container.setOpacity(1.0);
      }
    },
    
    getChairAt: function(index) {
      return chairs[index];
    },
    
    getChairIndex: function(chair) {
      var index = -1;
      for (var i = 0, len = chairs.length; i < len; ++i) {
        if (chairs[i] == chair) {
          index = i;
          break;
        }
      }
      return index;
    },
    
    size: function() {
      return chairs.length;
    },
    
    getRandomizedChairs: function() {
      return fisherYates(chairs);
    },
    
    expand: expandView,
    collapse: collapseView
  }
})();

(function() {
  Event.observe(document, 'dom:loaded', function(event) {
    // fetch all chairs
    var chairs = $('chairComponents').childElements();
    chairs.invoke('remove');
    
    chairs = fisherYates(chairs);
    for (var i = 0; i < 16; ++i) {
      if ((i+1)%4 == 0) chairs[i].addClassName('last');
      $('chairPreview-left').insert(chairs[i]);
    }
    for (i = 16; i < 32; ++i) {
      if ((i+1)%4 == 0) chairs[i].addClassName('last');
      $('chairPreview-right').insert(chairs[i]);
    }
    
    $$('div.expandableChair').each(function(chairContainer) {
      ExpandableChairsController.addChair(new ExpandableChair(chairContainer));
    });
    ExpandableChairsController.hideAll();
    var chair;
    var randChairs = ExpandableChairsController.getRandomizedChairs();
    for (var i = 0, len = randChairs.length; i < len; ++i) {
      (function(index) {
        new Effect.Opacity(randChairs[i].container, { duration: 0.6, delay: index/16, to: 0.5 })
      })(i);
    }
    
    $('chairFullView-container').select('a.close-button').each(function(closeButton) {
      closeButton.observe('click', function(event) {
        ExpandableChairsController.collapse();
        Event.stop(event);
      });
    });
    
  });
})();
