﻿(function (transition) {
    var sIndex = 0,
        direction = 1,  //1 = open; -1 = close
        sequence,
        transitioning = false,
        fromType = 'content',
        fromEl,
        activeEl,

        $loading = $('<span class="now-loading" />'),
        loadingTimer,
        
    // constants
        TILE_SPEED = 250,
        FADE_IN_SPEED = 500,
        FADE_OUT_SPEED = 200;

    var sequencer = function (fn, duration, callback) {

        var el = (direction == 1) ? sequence.eq(sIndex++) : sequence.eq(--sIndex);
        if (el.length) {
            fn.call(
                el,
                duration,
                function () {
                    sequencer(fn, duration, callback);
                });
        } else {
            if (callback) {
                callback.call();
            }
        }
    };
    
    //  prepare cloned element to linger on screen last
    var getSpotlight = function (el, container) {
        if (el && el.length) {
            //clone and absolute position
            // fix body height
            var grid = el.parent(),
                clone = el.clone(),
                pos = el.position();
            
            grid.css('height', grid.height());
            
            clone.css({
                position: 'absolute',
                top: pos.top + 'px',
                left: pos.left + 'px'
            });
            //  todo: better way to cache content area
            clone.appendTo(grid);
            return clone;
        } else {
            return null;
        }
    };
    
    var init = function () {
        // set active grid item on click
        $('body').delegate('.grid-item', 'click', function (e) {
            activeEl = $(this);
        });
        $loading.appendTo('#main');
        transition.next = null;
    };
      
    $(document).ready(init);

    transition.tileIn = function (els, callback) {
        sIndex = 0;
        direction = 1;
        sequence = $(els);
        sequencer($.fn.fadeIn, TILE_SPEED, callback);
    };
    
    transition.tileOut = function (els, callback) {
        sIndex = els.length;
        direction = -1;
        sequence = $(els);
        sequencer($.fn.fadeOut, TILE_SPEED, callback);
    };
    
    transition.fadeIn = function (el, callback) {
      el.fadeIn(FADE_IN_SPEED, callback);
    };
  
    transition.fadeOut = function (el, callback) {
      el.fadeOut(FADE_OUT_SPEED, callback);
    };

    transition.reset = function (callback) {
        window.clearTimeout(loadingTimer);
        transition.next = null;
        // skip to the end of any current animations
        $(':animated').stop(true, true);

        transitioning = false;
        callback();
    };

    transition.isReady = function () {
        return !transitioning;
    };
    
    //  BEGIN CONTENT TRANSITIONS
    
    transition.toContent = function(container, newElCallback) {
      transitioning = true;
        
      var build = function() {
          if (transition.next) {
              if (!transitioning) {
                  return false; 
              }
              $loading.hide();
              window.clearTimeout(loadingTimer);
              transition.next();
              transition.fadeIn(transition.newEl, function() {
                transitioning = false;
              });
              if (newElCallback) {
                newElCallback();
              }
              fromEl = transition.newEl;
              fromType = 'content';
              return true;
          } else {
              loadingTimer = window.setTimeout(build, 200); // polling
              $loading.show();
          }
      };
      
      if (!fromEl) {
        return build();
      }
      
      switch(fromType) {
        case 'content':
          transition.fadeOut(fromEl, function() {
              return build();
          });
          break;
          
        case 'grid':
          //  check for active el..
          if (activeEl) {
              // collect non-spotlight grid items
              var gridItems = fromEl.find('.grid-item');
              var spotlight = getSpotlight(activeEl);
              // tile out issue, spotlight active item, reveal card
              transition.tileOut(gridItems, function () {
                  //spotlight active element... then callback to card transition
                  spotlight.fadeOut(FADE_OUT_SPEED, function () {
                      spotlight.remove();
                      $('body').css({ height: 'auto' });
                      activeEl = null;
                      return build();
                  });
              });
          } else {
              // tile out issue, reveal the card
              transition.fadeOut(fromEl, function(){
                return build();
              });
          }

          break;

        default:
          break;
      }
    };
    
    
    transition.toGrid = function(container, newElCallback) {
      transitioning = true;

      var build = function() {
          if (transition.next) {
              if (!transitioning) {
                  return false;
              }
              $loading.hide();
              window.clearTimeout(loadingTimer);
              transition.next();
              transition.tileIn(container.find('.grid-item'), function() {
                transitioning = false;
              });
              if (newElCallback) {
              	  newElCallback();
                }
                fromEl = transition.newEl;
                fromType = 'grid';
                return true;
          } else {
              loadingTimer = window.setTimeout(build, 200); // polling
              $loading.show();
          }        
      }
      
      if (!fromEl) {
        return build();
      }
      
      switch(fromType) {
        case 'content':
        case 'grid':
          transition.fadeOut(fromEl, function() {
              return build();
          });
          break;
        default:
          break;
      }
    };
    
    

})(idw.transition = idw.transition || {});

