/** =zoom gallery
************************************************************/
(function() {
var se = scrollableElement('html','body');
function scrollTo(selector) {
  var targetOffset = $(selector).offset().top;
  $('html').animate({scrollTop: targetOffset}, 500);
}
function scrollableElement(els) {
  for (var i = 0, argLength = arguments.length; i < argLength; i++) {
    var el = arguments[i],
        $scrollElement = $(el);
    if ($scrollElement.scrollTop() > 0) {
      return el;
    } else {
      $scrollElement.scrollTop(1);
      var isScrollable = $scrollElement.scrollTop() > 0;
      $scrollElement.scrollTop(0);
      if (isScrollable) {
        return el;
      }
    }
  }
  return [];
}

$(document).ready(function() {
  $('.wrapper-inner').after('<img id="bg-blank" src="/assets/styles/images/bg-blank.png" alt=""/><img class="hide" id="zoom-shadow" src="/assets/styles/images/zoom-top-shadow.png" alt="" />');

});

var $doc = $(document),
    $zoomGallery = $('.zoom-gallery');
if (!$zoomGallery.length) { return; }

var $body = $('.body:first'),
    $slideshow = $zoomGallery.find('.slideshow'),
    $slides = $zoomGallery.find('.slides'),
    $closeViewer = $('<a href="#" class="close-viewer" title="Click to close or use the ESC key">Close</a>').prependTo('.wrapper-inner'),
    $controls = $zoomGallery.find('h4, .controls'),
    $footer = $('.footer'),
    slideAmount = 0,
    zoomHeight = 0,
    speed = 400,
    imgHeights = [],
    viewerContent = [],
    switcherDelay,
    waitImg = '/assets/styles/images/icons/slideshow-wait.png',
    zoomImg = '/assets/styles/images/icons/slideshow-zoom.png',
    $zoomViewer = null,
    max = Math.max;

FM.waiting = 'yes';
FM.zoomed = false;

// set up the transparent overlay for the slides

  $('<div class="hover-show"><img class="zoom" src="' + zoomImg + '" alt="" /><div class="overlay"></div></div>')
    .appendTo($zoomGallery);

  var $hovershow = $('.hover-show');
  $('.hover-show, .overlay')
    .width($slides.width())
    .height($slides.height() - 30);

  // bind events to the overlay
  var waitRe = new RegExp(waitImg);

  // make sure cycle is paused when hovered over the overlay
  $hovershow
  .bind('mouseenter', function(event) {
    $slides.trigger('mouseenter');
  })
  .bind('mouseleave', function(event) {
    if (FM.waiting !== 'clicked') {
      $(this).hide();
    }
    $slides.trigger('mouseleave');
  });

  $slides
  .mouseenter(function() {
    $hovershow.show();
    $('.overlay').css('opacity', .3).show();
  })
  .find('a').click(function() {
    return false;
  });

  // bind click to overlay for triggering the sliding
  $('.hover-show, .close-viewer').click(function() {
    if (FM.waiting) {
      $('img.zoom').attr('src', waitImg);
      FM.waiting = 'clicked';
    } else if (!$('#zoom-gallery-content').is(':animated')) {
  		var tmpId= $slideshow.find('.slide:visible')[0];
		  $('.make-it, #zoom-gallery-content').fadeToggle();
      $('.title-square, .breadcrumb').trigger('slide', {direction: 'left'});
      FM.zoomed = !FM.zoomed;

      // add support for keybaord
      if (FM.zoomed) {
        $doc.bind('keyup.zoomed', function(event) {
          var keyedUp = event.which;
          $.each(keyBindings, function(key, val) {
            if (keyedUp == key) {
              keyBindings[keyedUp]();
            }
          });
        });
      } else {
        $doc.unbind('keyup.zoomed');
      }
    }
    return false;
  });

// initialize the zoomviewer

  var slideshow = document.getElementById('slides'),
      slides = $slides.find('.slide').get(),
      slength = slides.length;

  FM.zoomViewer.parent_weblog = 'programs';

  var programIds = [];
  for (var i=0; i < slength; i++) {
    if( /program-/.test(slides[i].className) ) {
       var programs = slides[i].className.split('program-');
       for (var j=1; j < programs.length; j++) {
         programIds.push(programs[j].replace(/\s/g,''));
       }
    }
  }

  FM.zoomViewer.program_id = programIds.join('|');

  // get full img heights
  function getZoomedHeight(options) {
    var opts = $.extend({}, {selector: '.zoom-viewer .slides img', attribute: 'src'}, options);
    $(opts.selector).each(function(index) {
      var $link = $(this);
      var newSrc = this[opts.attribute],
          imgHeight = +newSrc.slice(newSrc.lastIndexOf('x')+1,newSrc.lastIndexOf('.'));
      imgHeights[index] = imgHeight;
      zoomHeight = (imgHeight > zoomHeight) ? imgHeight : zoomHeight;
    });
    var windowOffset = $(window).height() - $body.offset().top;
    zoomHeight = max(windowOffset, zoomHeight);
    return zoomHeight;
  }

  // wait until window load so we don't make people wait...
  $(window).bind('load', function(event) {

    getZoomedHeight({
      selector: '.slideshow .slides a', attribute: 'href'
    });

    // load initial set of large images
    $.get('/zoom/', FM.zoomViewer, function(html) {
      // prep and dump the large images
      FM.controls = FM.controls.replace(/-slide/g,'-zoomed');
      $zoomViewer = $(html).prependTo($zoomGallery);
      $('img.zoom')[0].src = zoomImg; // change the hover img from hourglass to zoom
      // initialize large image cycle
      FM.runCycle({
        prev: '#prev-zoomed',
        next: '#next-zoomed',
        pagerSelector: '.controls ul',
        timeout: 0,
        container: $zoomViewer.find('.slides'),
        onBefore: function(curr, next, opts) {
          if (opts.addSlide) { // <-- important!
            while(FM.addedSlides.length) {
              opts.addSlide(FM.addedSlides.pop());
            }
          }
        },
        after: function(curr, next, opts, fflag) {
          var currentProgramId = 'program-' + next.className.split('program-').pop();
          setSwitcherHeading(currentProgramId);
        }
      });
      FM.programs = {};
      var $programLinks = $('.program-switcher ul a'),
          programsLength = $programLinks.length;

      for (var i = 0; i < programsLength; i++) {
        var thisProgram = $programLinks[i],
            thisProgramId = thisProgram.hash.slice(1);
        FM.programs[thisProgramId] = {title: thisProgram.innerHTML};
        if (thisProgramId == $('.switcher-heading a')[0].className) {
          FM.programs[thisProgramId].loaded = true;
        }
      }
      delete FM.zoomViewer.init;
      if (FM.waiting == 'clicked') {
        $('img.zoom').attr('src', zoomImg);
        FM.waiting = false;
        $('.hover-show').triggerHandler('click');
      }
      delete FM.waiting;


      //convert video links to actual videos
      $doc.trigger('convertToVideo');
    }); // end loading of initial zoomed images

/** =program switcher
************************************************************/

    // toggle program switcher items' visibility
    $doc.bind('programSwitcherVisibility', function(event, toggle) {
      var $switcherMenu = $('.program-switcher .switcher-menu');
      $('.program-switcher').removeClass('expanded');
      if ($(event.target).parents('.switcher-heading').length || toggle) {
        if ($switcherMenu.is(':hidden')) {
          $('.program-switcher').addClass('expanded');
        }
        $switcherMenu.slideToggle(speed);
      } else {
        $('.program-switcher .switcher-menu').slideUp(speed);
      }
    });

    $doc.bind('jumpToProgram', function(event, activeSlideClass) {
      var activeSlideIndex = $zoomViewer.find('.slide').index($zoomViewer.find('.slides .' + activeSlideClass + ':first')) || 0;
      $zoomViewer.find('.slides').cycle(activeSlideIndex);
    });

    $('.switcher-heading a').live('click', function(event) {
      $(this).trigger('programSwitcherVisibility');
      return false;
    });

    $('.program-switcher ul').live('mouseover', function(event) {
      clearTimeout(switcherDelay);
    }).live('mouseout', function(event) {
      switcherDelay = setTimeout(function() {
        $doc.trigger('programSwitcherVisibility', [false]);
      }, 1200);
    });

    $('.program-switcher ul a').live('click', function() {
      var program = this.hash.slice(1);
      var $link = $(this);

      getProgramSlides(program);
      $doc.trigger('programSwitcherVisibility', [false]);

      return false;
    });

    function setSwitcherHeading(programId) {
      var switcherHeadingLink = $('.switcher-heading a')[0];
      if (switcherHeadingLink && switcherHeadingLink.className != programId) {
        switcherHeadingLink.className = programId;
        switcherHeadingLink.innerHTML = FM.programs[programId].title;
      }
    }
    function getProgramSlides(programId) {
      if (typeof FM.programs[programId].loaded == 'undefined') {
        $('.program-switcher').addClass('program-loading');
        FM.zoomViewer.program_id = programId.split('-')[1];
        $.get('/zoom/', FM.zoomViewer, function(html) {
          // mark the program as loaded

          FM.programs[programId].loaded = true;

          // add slides to the cycle list.
          var $programSlides = $(html);
          $programSlides.appendTo('body');
          var $trimmedSlides = $programSlides.filter(function() {
            return $(this).children().length;
          });
          FM.addedSlides = $trimmedSlides.get();

          $zoomViewer.find('.slides').cycle(1);
					$doc.trigger('convertToVideo');
          $doc.trigger('jumpToProgram', [programId]);
          $('.program-switcher').removeClass('program-loading');

          // readjust the height of the zoom gallery
          getZoomedHeight();
          $body.animate({height: zoomHeight+40}, speed);

        });
      } else {
        $doc.trigger('jumpToProgram', [programId]);
      }
    }

/** =Video handling
************************************************************/
    $doc.bind('convertToVideo', function(event) {
			if (typeof $.fn.media == 'undefined') {
		    $.getScript('/assets/scripts/jquery.metadata.js', function() {
	        $.getScript('/assets/scripts/jquery.media.js', function() {
	          $doc.trigger('convertToVideo');
	        });
	      });
			} else {
				$.extend($.fn.media.defaults, FM.mediaOptions);
	      $('a.video').media({
					width: 820
				});
			}

    });

/** =open and close the big picture viewer
************************************************************/

    // get element info for proper sliding in and out of viewport
    $doc.bind('getinfo', function(event) {
      var $tgt = $(event.target);
      var elinfo = {
        'offsetLeft': $tgt.offset().left,
        'left': parseInt($tgt.css('left'),10),
        'position': $tgt.css('position'),
        'width': $tgt.outerWidth()
      };
      $tgt
      .data('info', elinfo);
    });

    $('#zoom-gallery-content, .breadcrumb, .title-square').each(function() {
      $(this).trigger('getinfo');
    });


    // Slide Elements
    var $activeClassElements = $('.wrapper-inner, .body, .body-inner, .slideshow'),
        sliding = false,
        slidingTimer;

    $doc.bind('slide', function(event, options) {
      
      if (FM.waiting) {
        return false;
      }
      /* clear and then set the timer */
      clearTimeout(slidingTimer);
      slidingTimer = setTimeout(function() {
        sliding = false;
      }, (speed*2)+100);

      /* do this only if not already in motion. */
      if (!sliding) {
        // set div class="body" height so it doesn't collapse when everything slides out
        $body.height($body.height());

        // fadeout the background
        $('#bg-blank, #zoom-shadow').fadeToggle(speed*2);
        $footer.fadeOut(speed*4);
      }

      /* do this stuff for each matched element */
      var $tgt = $(event.target),
          tgtLeft = parseInt($tgt.css('left'),10),
          windowWidth = $(window).width();

      // show/hide body content
      if (options.direction == 'fade') {
        $tgt.fadeToggle(speed*2);
      }

      // show original stuff
      if (tgtLeft != $tgt.data('info').left) {
        if (!sliding) {
          scrollTo('.wrapper:first');
        }
        $slides.trigger('zoomOut');
        $activeClassElements.removeClass('gallery-active');

        //animate left property
        $tgt.animate({left: $tgt.data('info').left}, speed*2, function() {
          $tgt.css('position', $tgt.data('info').position);
          $body.css('height','auto');
           
          if (!$footer.is(':animated')) {
            $footer.fadeIn(speed*2);
          }
        });

      // show large images / hide original stuff
      } else {
        if (!sliding) {
          $body.height($body.height());
          $('.wrapper-inner').addClass('gallery-active');
        }
        if (options.direction == 'left') {
          $('.body, .body-inner').addClass('gallery-active');
          $tgt.css('position', 'absolute');
          slideAmount = -($tgt.data('info').offsetLeft + 500);
          $tgt.animate({left: slideAmount}, speed*2, function() {
            $activeClassElements.addClass('gallery-active');
            $doc.trigger('zoomIn');
          });
        } else if (options.direction == 'right'){
          $tgt.animate({left: windowAmount}, speed*2);
        }
      }
      sliding = true;

    });

    // Zoom the viewer in

    $doc.bind('zoomIn', function(event) {
      //make the matching slide visible
      var activeSlide = $slides.find('.slide:visible')[0];
      var activeSlideClass = activeSlide
          ? (activeSlide.className.match(/slide-\w+/) && activeSlide.className.match(/slide-\w+/)[0])
          : false;
      $doc.trigger('jumpToProgram', [activeSlideClass]);

      //zoom in the images
      $zoomViewer.hide().removeClass('hide-alt').fadeIn(speed);
      $closeViewer.fadeIn();
      $zoomGallery.find('h4, .controls').animate({top: 0}, speed);
      $slideshow.slideUp(speed, function() {
        $hovershow.addClass('hide-alt');
        $body.animate({height: zoomHeight+40}, speed);
        scrollTo('.body:first');
      });

    });

    // Zoom the viewer out
    $doc.bind('zoomOut', function(event) {
      $zoomViewer.addClass('hide-alt');
      $zoomGallery.find('h4, .controls').css('top', '320px');
      $closeViewer.fadeOut();
      $slideshow.animate({height: '350px'}, speed);
      $slides.slideDown(speed);
      $hovershow.hide().removeClass('hide-alt');
    });

  }); // end window bind

  var keyBindings = {
    '27': function() {
      // escape key
      $closeViewer.triggerHandler('click');
    },
    '37': function() {
      // left arrow
      $('#next-zoomed').triggerHandler('click');
    },
    '39': function() {
      //right arrow
      $('#prev-zoomed').triggerHandler('click');
    }
  };

})();
