(function () {
  var currGalleryLink = null;
  var customOverImgs = null;
  var customStartIndex = null;
  var wrapper = $("#slideshow-wrapper");
  var pageHasWrapper = wrapper.length > 0;
  var overlay = $("#slideshow-overlay");
  var inner = $("#slideshow-overlay-inner");
  var imgs = wrapper.find("img");
  var preload = wrapper.find(".slideshow-preloader");
  var overPreload = inner.find(".slideshow-preloader");
  var currIndex = Math.floor(Math.random()*imgs.length);
  var currOverIndex;
  var overlays = {};
  var depth = 1;
  var duration = 1200;
  var delay = 3000;
  var timer;
  var paused = false;

  $(window).bind("load", loadInit);
  $(window).bind("scroll", scrollHandler);

  function loadInit () {
    if (pageHasWrapper) wrapper.bind("click", showOverlay);
    $("a.custom-slideshow").bind("click", showCustomGallery);
    overlay.bind("click", hideOverlay);
    inner.bind("click", innerClick);
    nextImage();
  }

  function scrollHandler (e) {
    overlay.css({ top: $(window).scrollTop(), left: $(window).scrollLeft() });
  }

  function showCustomGallery () {
    var link = $(this);
    if (link !== currGalleryLink) {
      customOverImgs = [];
      currGalleryLink = link;
      var galleryDir = link.attr("data-dir");
      var galleryList = link.attr("data-list").split(",");
      $.each(galleryList, function(index, value) {
        customOverImgs.push( galleryDir + $.trim(value));
      }); 
    }
    customStartIndex = 0;
    showOverlay();
    return false;
  }

  function innerClick (e) {
    nextOverlayImg();
    e.stopPropagation();
  }
  
  function showOverlay () {
    if (pageHasWrapper) pause();
    overlay.css({ display: "block", opacity: 0 });
    overlay.cssmate({ opacity: 1 }, 500, "easeOutQuint");
    var startIndex = customStartIndex !== null ? customStartIndex : currIndex;
    loadOverlayImg(startIndex);
  }
  
  function hideOverlay () {
    customOverImgs = null;
    customStartIndex = null;
    if (pageHasWrapper) resume();
    overlay.cssmate({ opacity: 0 }, 200, "easeOutQuint", function () {
      overlay.css({ display: "none"});
      overlayCleanup();
    });
  }
  
  function loadOverlayImg (index) {
    var src = "";
    if (customOverImgs) {
      src = customOverImgs[index];
    } else {
      var img = imgs[index];
      src = $(img).attr("src").replace("/small/", "/large/");
    }
    var newImg;
    // check for previously loaded overlay
    if (!!overlays[src]) {
      newImg = overlays[src];
      newImg.css({ display: "block", opacity: 0, zIndex: depth++ });
      inner.append(newImg);
      newImg.cssmate({ opacity: 1 }, 1000, "easeOutQuint");
    // otherwise load new image
    } else {
      // preloader
      overPreload.css({ display: "block", opacity: 0, zIndex: depth++ });
      overPreload.cssmate({ opacity: 1 }, 500, "easeOutQuint");
      // new image overlay
      newImg = new Image();
      newImg = overlays[src] = $(newImg);
      newImg.css({ display: "block", opacity: 0, zIndex: depth++ });
      newImg.load(function () {
        // fade in after image loads
        inner.append(newImg);
        newImg.cssmate({ opacity: 1 }, 1000, "easeOutQuint");
      }).attr("src", src);
    }
    currOverIndex = index;
  }
  
  function nextOverlayImg () {
    var index = currOverIndex+1;
    var overlaysLength = customOverImgs ? customOverImgs.length : imgs.length;
    if (index === overlaysLength) index = 0;
    loadOverlayImg(index);
  }
  
  function overlayCleanup () {
    overPreload.css({ display: "none", opacity: 0 });
    var thisImg;
    inner.find("img").each(function (key, value) {
      thisImg = $(this);
      thisImg.cssmate({ opacity: 0 });
      thisImg.css({ display: "none" });
    });
  }
  
  function nextImage () {
    currIndex++;
    if (currIndex == imgs.length) currIndex = 0;
    var img = $(imgs[currIndex]);
    img.css({ display: "block", opacity: 0, zIndex: depth++ });
    img.cssmate({ opacity: 1 }, duration, "ease", imageCleanup);
    if (!paused) timer = setTimeout(nextImage, duration+delay);
  }
  
  function pause () {
    paused = true;
    clearTimeout(timer);
  }
  
  function resume () {
    paused = false;
    timer = setTimeout(nextImage, duration+delay);
  }
  
  function imageCleanup () {
    if (preload) {
      preload.hide();
    }
    var i=0;
    imgs.each( function () {
      if (i !== currIndex) $(this).css({ display: "none", opacity: 0 });
      i++;
    });
  }
})();

