/* 
# Slip-n-slide photo gallery
# Version: 0.1
# Author: Nick Grossman
# URL: http://wrkng.net/slip-n-slide
# License: GPL 3 http://www.gnu.org/licenses/gpl-3.0.html
*/

/* Requires EXT Javascript framework 2.0 */


/* SlipNSlide Photo Gallery
#
# @extEl: an Ext Element object.
#
 */

SlipNSlide = function(extEl, beginning) {
  // get refs 
  var container = extEl;
  var list = Ext.get(Ext.query('UL', container.dom)[0]);
  var listItems = Ext.select(Ext.query('LI', list.dom));
  var images = Ext.select(Ext.query('IMG', container.dom));
  var firstItem = Ext.get(listItems.elements[0]);
  var lastItem = Ext.get(listItems.elements[listItems.elements.length - 1]);
  var selectedImage;
  
  var prev = Ext.get(Ext.query('.js-prev-photos')[0]);
  var next = Ext.get(Ext.query('.js-next-photos')[0]);
  var main; /* will become ext element for main image */
  var selectedAbsolutePosition = 0; /* select first image to start */
  var selectedRelativePosition = 0; 
  
  if (!container || !list || !images) {
    return false;
  }
    
  // initialize
  _init(this);
  function _init(context) {
  
    // create main image
    frame = container.insertHtml('afterBegin', '<div class="slip-n-slide-frame"><span></span></div>', true);
    main = frame.insertHtml('beforeEnd', '<img class="full" />', true);
    
    // create next and prev buttons
    
    // set images buttons display mode
    listItems.setVisibilityMode(Ext.Element.DISPLAY);
    
    // load first image into main pane.
    if (beginning)
        selectedImage = images.elements[0];
    else
        selectedImage = images.elements[listItems.elements.length - 1];

    _loadImage({}, selectedImage, {});
    
    // update source list (hide all but first 3)
    _initializeSourceList();
  
    // attach handlers
    images.on('click', _loadImage, this);
    next.on('click', _nextClick, this, {preventDefault: true});
    prev.on('click', _prevClick, this, {preventDefault: true});
    images.on('mouseover', _imageMouseover, this);
    images.on('mouseout', _imageMouseout, this);
    
  }
  
  function _imageMouseover(e, el, o) {
    Ext.get(el).addClass('hover');
  }
  
  function _imageMouseout(e, el, o) {
    Ext.get(el).removeClass('hover');  
  }

  function _loadImage(e, el, o) {
    selectedImage = Ext.get(el);
     
    // set main image to full-size version of thumb
    main.hide();
    main.dom.src = el.src.replace('/thumbs', '');
    main.fadeIn();
    
    // remove highlighting from all listitems
    images.removeClass('selected');  
    
    // highlight selected item in list
    selectedImage.addClass('selected');
    
    // update current position
    selectedAbsolutePosition = _findAbsolutePosition(selectedImage);
    selectedRelativePosition = selectedAbsolutePosition % 3;
  
  }
  
  function _initializeSourceList() {

     var start = selectedAbsolutePosition - selectedRelativePosition;
     var end = start + 2;
     
     _updateSourceList(start,end);  
  }
  
  function _prevClick() {
  
    var start;
    var end;
    
    // make sure clicking next moves you to the prev group of 3
    start = selectedAbsolutePosition - 3 - selectedRelativePosition;
    end = selectedAbsolutePosition - 1 - selectedRelativePosition;      

    if (!firstItem.isDisplayed()) {
    
      // update source list
      _updateSourceList(start,end);
      
      // load image
      _loadImage({}, images.elements[end], {});
      
    }
    
  }
  
  function _nextClick() {
  
    var start;
    var end;
    
    // make sure clicking next moves you to the next group of 3
    start = selectedAbsolutePosition + 3 - selectedRelativePosition;
    end = selectedAbsolutePosition + 5 - selectedRelativePosition;      

    // only update source list if last image isn't already on screen
    if (!lastItem.isDisplayed()) {
    
      // update source list
      _updateSourceList(start,end);
    
      // load image
      _loadImage({}, images.elements[start], {});
    
    }
    
  }
  
  function _updateSourceList(start, end) {
    
    // loop through list of LIs and hide if they're not
    // in the range
    listItems.each(function(extEl, list, i) {      
      if (i < start || i > end) {
        extEl.hide();
      } else if (extEl.dom.id == selectedImage.dom.parentNode.id) {
        // don't fade in currently selected image.
        extEl.show();
      } else {
        // fade in new images
        extEl.fadeIn();
      }
    });
      
    // disable next / prev buttons
    if (lastItem.isDisplayed()) {
      next.addClass('disabled');
    } else {
      next.removeClass('disabled');
    }
    
    if (firstItem.isDisplayed()) {
      prev.addClass('disabled');
    } else {
      prev.removeClass('disabled');
    }
        
  }
  
  function _findAbsolutePosition(selection) {
    // loop through list of photos, return the position of the 
    // currently selected photo
    var counter = 0;
    var position;
    
    images.each(function(extEl) {
      if(selection.dom.id == extEl.dom.id) {
        position = counter;
      }
      counter++;
    }); 
      
    return position;
  }
  
  return this;
}
