$(document).ready(function() {
  $('#quilt > *').wrapAll('<div id="quilt-scroller"></div>'); // SB wrapInner, but that isn't working
  $('#quilt-scroller')
    .append('<div id="quilt-scroller-right"></div>')
    .append('<div id="quilt-element-overlay-backdrop"></div>')
    .append('<div id="quilt-element-loading-indicator"></div>');
  
  $.getJSON('/CMSModules/Quaeris/Quilts/positions.html', function(positions) {
    // "Constants"
    var unitWidth = 76;
    var unitHeight = 44;
    var elementPadding = 2;
    var cycleWidth = unitWidth * 57;
    var visibleQuiltWidth = 950;
    var zoomDuration = 250;
    var fadeDuration = 150;
    var currentSection = 0;
    var averageSectionWidth = cycleWidth / positions.length;
    var sectionWidthSafetyMargin = 300; // Allow for somewhat abnormal section widths.
    
    var $elements = $('#quilt .quilt-element');
    // The elements will move around in the DOM later. We need to remember which section they were originally in.
    var sections = [];
    $('#quilt .quilt-section').each(function(index) {
      sections[index] = $(this).find('.quilt-element');
    });

    // Given the index number of a section, move elements as necessary to place that section in the quilt.
    function placeSection(sectionNumber) {
      function placeElement($elt, topIndex, leftIndex, size, cycleNumber) {
        var sizeFactor = 1;
        if (size == 'medium') sizeFactor = 2;
        if (size == 'large') sizeFactor = 4;

        var top = topIndex * unitHeight;
        var left = cycleNumber * cycleWidth + leftIndex * unitWidth;
        var width = unitWidth * sizeFactor - elementPadding * 2;
        var height = unitHeight * sizeFactor - elementPadding * 2;

        $elt.css({
          top: top,
          left: left,
          width: width,
          height: height,
          display: 'block'
        });
      }

      var positionIndex = ((sectionNumber % positions.length) + positions.length) % positions.length;
      var sectionIndex = ((sectionNumber % sections.length) + sections.length) % sections.length;
      var positionSubset = positions[positionIndex];
      var $sectionElements = sections[sectionIndex];
      var cycleNumber = (sectionNumber - positionIndex) / positions.length;
      
      $sectionElements.filter('.quilt-element-large').each(function(index) {
        placeElement(
          $(this),
          positionSubset.large[index].top,
          positionSubset.large[index].left,
          'large',
          cycleNumber
        );
      });
      $sectionElements.filter('.quilt-element-medium').each(function(index) {
        placeElement(
          $(this),
          positionSubset.medium[index].top,
          positionSubset.medium[index].left,
          'medium',
          cycleNumber
        );
      });
      $sectionElements.filter('.quilt-element-small').each(function(index) {
        placeElement(
          $(this),
          positionSubset.small[index].top,
          positionSubset.small[index].left,
          'small',
          cycleNumber
        );
      });
      
    }

    // Initial positioning of elements
    placeSection(currentSection);
    placeSection(currentSection + 1);
    placeSection(currentSection + 2);
    placeSection(currentSection + 3);
    
    function setScrollerPosition(deltaLeft, absolute, callback, duration, easing) {
      if (duration == null) {
        duration = 200;
      }
      if (easing == null) {
        easing = 'linear';
      }

      //$('#quilt-scroller').stop(true, true);
      var curLeft = parseFloat($('#quilt-scroller').css('left'));
      var newLeft = curLeft + deltaLeft;
      if (absolute) {
        newLeft = deltaLeft;
      }
      
      var newSection = Math.floor(-(newLeft + sectionWidthSafetyMargin) / averageSectionWidth);
      if (newSection != currentSection) {
        currentSection = newSection;
        placeSection(currentSection);
        placeSection(currentSection + 1);
        placeSection(currentSection + 2);
        placeSection(currentSection + 3);
      }

      $('#quilt-scroller').animate({left: newLeft}, duration, easing, callback);
    }
  
    var hovering = false;
    $('<div class="scroll-region" id="scroll-forward"></div>').appendTo('#quilt').hover(function() {
      hovering = true;
    
      function scroll() {
        if (hovering && !$zoomElt) {
          setScrollerPosition(-unitWidth, false, scroll);
        }
      }
      scroll();
      return false;
    }, function() {
      hovering = false;
      $('#quilt-scroller').stop();
    });
    
    $('<div class="scroll-region" id="scroll-back"></div>').appendTo('#quilt').hover(function() {
      hovering = true;
    
      function scroll() {
        if (hovering && !$zoomElt) {
          setScrollerPosition(unitWidth, false, scroll);
        }
      }
      scroll();
      return false;
    }, function() {
      hovering = false;
      $('#quilt-scroller').stop();
    });
    
    // Handle bug in IE6 where scrolling doesn't happen.
    if (jQuery.browser.msie && parseInt(jQuery.browser.version) <= 6) {
      $('.scroll-region').css({'opacity': '0.01', 'background-color': '#fff'});
		}
    
    var $zoomElt = null;

    $elements.click(function(event) {
      if ($(':animated').length == 0 && !$zoomElt) {
        expandElement(this);
        event.stopPropagation();
      }
    });
    $('#quilt').click(function(event) {
      if ($(':animated').length == 0 && $zoomElt) {
        contractElement();
        event.stopPropagation();
      }
    });
    
    function expandElement(zoomElt) {
      $zoomElt = $(zoomElt);
      $zoomElt.data('origLeft', parseFloat($zoomElt.css('left')));
      $zoomElt.data('origTop', parseFloat($zoomElt.css('top')));
      $zoomElt.data('origWidth', $zoomElt.width() + elementPadding * 2);
      $zoomElt.data('origHeight', $zoomElt.height() + elementPadding * 2);

      var $zoomImg = $zoomElt.find('img');
      $zoomImg.data('origSrc', $zoomImg.attr('src'));
      
      $('#quilt-element-loading-indicator').appendTo($zoomElt).show();
      $(new Image()).one('load', function() {
        $('#quilt-element-loading-indicator').hide();
        $zoomImg.attr('src', $zoomImg.attr('rel'));

        // Split the elements into two groups: to the left of the enlarged one, and to the right.
        var leftElementsRightmost = -100000;
        var rightElementsLeftmost = 100000;
        $elements.each(function() {
          var testElt = this;
          var testEltWidth = $(testElt).width() + elementPadding * 2;
          if (testElt == $zoomElt[0] || $(testElt).is(':hidden')) return;
          var testEltLeft = parseFloat($(testElt).css('left'));
          if (testEltLeft < $zoomElt.data('origLeft')) {
            if (leftElementsRightmost < testEltLeft + testEltWidth) {
              leftElementsRightmost = testEltLeft + testEltWidth;
            }
          }
          else {
            $('#quilt-scroller-right').append(testElt);
            if (testEltLeft < rightElementsLeftmost) {
              rightElementsLeftmost = testEltLeft;
            }
          }
        });

        var gapSize = leftElementsRightmost - rightElementsLeftmost + unitWidth * 8;
      
        $('#quilt-scroller').data('origLeft', parseFloat($('#quilt-scroller').css('left')));
        var newLeft = $('#quilt-scroller').data('origLeft');
        if ($zoomElt.data('origLeft') + unitWidth * 8 > visibleQuiltWidth - $('#quilt-scroller').data('origLeft')) {
          // Element cannot grow right; grow left instead.
          newLeft = visibleQuiltWidth - unitWidth * 8 - leftElementsRightmost;
        }
        else {
          // Grow element to right.
          if ($zoomElt.data('origLeft') < - $('#quilt-scroller').data('origLeft')) {
            newLeft -= $('#quilt-scroller').data('origLeft') + $zoomElt.data('origLeft');
          }
          newLeft -= leftElementsRightmost - $zoomElt.data('origLeft');
        }
      
        $('#quilt-scroller').animate({
          left: newLeft
        }, {
          duration: zoomDuration,
          queue: false
        });

        $('#quilt-scroller-right').animate({
          left: gapSize
        }, {
          duration: zoomDuration,
          queue: false
        });

        $zoomElt.animate({
          left: '+=' + (leftElementsRightmost - $zoomElt.data('origLeft'))
        }, {
          duration: zoomDuration,
          queue: false
        });

        $zoomElt.animate({
          width: unitWidth * 8 - elementPadding * 2,
          height: unitHeight * 8 - elementPadding * 2,
          top: 0
        }, {
          duration: zoomDuration,
          queue: false,
          complete: showOverlay
        });
      
        function showOverlay(callback) {
          var $overlay = $zoomElt.find('.quilt-element-overlay');
          if ($overlay.length) {
            $('#quilt-element-overlay-backdrop').appendTo($zoomElt).css('display', 'block').fadeTo(fadeDuration, 0.5);
            $overlay.fadeIn(fadeDuration, callback);
          }
          else if ($.isFunction(callback)) {
            callback();
          }
        }
      }).attr('src', $zoomImg.attr('rel'));
    }
    
    function contractElement() {
      var $zoomImg = $zoomElt.find('img');

      function hideOverlay(callback) {
        var $overlay = $zoomElt.find('.quilt-element-overlay');
        if ($overlay.length) {
          $('#quilt-element-overlay-backdrop').fadeOut(fadeDuration);
          $overlay.fadeOut(fadeDuration, callback);
        }
        else if ($.isFunction(callback)) {
          callback();
        }
      }

      hideOverlay(function() {
        $zoomElt.animate({
          width: $zoomElt.data('origWidth') - elementPadding * 2,
          height: $zoomElt.data('origHeight') - elementPadding * 2,
          top: $zoomElt.data('origTop')
        }, {
          duration: zoomDuration,
          queue: false
        });

        $zoomElt.animate({
          left: $zoomElt.data('origLeft')
        }, {
          duration: zoomDuration,
          queue: false
        });

        $('#quilt-scroller-right').animate({
          left: 0
        }, {
          duration: zoomDuration,
          // easing: 'easeInQuad',
          queue: false,
          complete: function() {
            $('#quilt-scroller-right .quilt-element').appendTo('#quilt-scroller');
            $zoomElt = null;
            $zoomImg.attr('src', $zoomImg.data('origSrc'));
          }
        });

        $('#quilt-scroller').animate({
          left: $('#quilt-scroller').data('origLeft')
        }, {
          duration: zoomDuration,
          queue: false
        });
      });
    }
    
    //setScrollerPosition(-520, true, null, 2000, 'easeOutQuart');
	setScrollerPosition(-1220, true, null, 2000, 'easeOutQuart');
  });
  
});
