(function ($) {

$.fn.materialbox = function () {

  return this.each(function() {

    if ($(this).hasClass('initialized')) {
      return;
    }

    $(this).addClass('initialized');

    var overlayActive = false;
    var doneAnimating = true;
    var inDuration = 275;
    var outDuration = 200;
    var origin = $(this);
    var placeholder = $('<div></div>').addClass('material-placeholder');
    var originalWidth = 0;
    var originalHeight = 0;
    var ancestorsChanged;
    var ancestor;
    origin.wrap(placeholder);

    origin.on('click', function(){
      var placeholder = origin.parent('.material-placeholder');
      var windowWidth = window.innerWidth;
      var windowHeight = window.innerHeight;
      var originalWidth = origin.width();
      var originalHeight = origin.height();

      // If already modal, return to original
      if (doneAnimating === false) {
        returnToOriginal();
        return false;
      }
      else if (overlayActive && doneAnimating===true) {
        returnToOriginal();
        return false;
      }

      // Set states
      doneAnimating = false;
      origin.addClass('active');
      overlayActive = true;

      // Set positioning for placeholder
      placeholder.css({
        width: placeholder[0].getBoundingClientRect().width,
        height: placeholder[0].getBoundingClientRect().height,
        position: 'relative',
        top: 0,
        left: 0
      });

      // Find ancestor with overflow: hidden; and remove it
      ancestorsChanged = undefined;
      ancestor = placeholder[0].parentNode;
      var count = 0;
      while (ancestor !== null && !$(ancestor).is(document)) {
        var curr = $(ancestor);
        if (curr.css('overflow') !== 'visible') {
          curr.css('overflow', 'visible');
          if (ancestorsChanged === undefined) {
            ancestorsChanged = curr;
          }
          else {
            ancestorsChanged = ancestorsChanged.add(curr);
          }
        }
        ancestor = ancestor.parentNode;
      }

      // Set css on origin
      origin.css({position: 'absolute', 'z-index': 1000})
      .data('width', originalWidth)
      .data('height', originalHeight);

      // Add overlay
      var overlay = $('<div id="materialbox-overlay"></div>')
        .css({
          opacity: 0
        })
        .click(function(){
          if (doneAnimating === true)
          returnToOriginal();
        });
        // Animate Overlay
        // Put before in origin image to preserve z-index layering.
        origin.before(overlay);
        overlay.velocity({opacity: 1},
                         {duration: inDuration, queue: false, easing: 'easeOutQuad'} );

      // Add and animate caption if it exists
      if (origin.data('caption') !== "") {
        var $photo_caption = $('<div class="materialbox-caption"></div>');
        $photo_caption.text(origin.data('caption'));
        $('body').append($photo_caption);
        $photo_caption.css({ "display": "inline" });
        $photo_caption.velocity({opacity: 1}, {duration: inDuration, queue: false, easing: 'easeOutQuad'});
      }

      // Resize Image
      var ratio = 0;
      var widthPercent = originalWidth / windowWidth;
      var heightPercent = originalHeight / windowHeight;
      var newWidth = 0;
      var newHeight = 0;

      if (widthPercent > heightPercent) {
        ratio = originalHeight / originalWidth;
        newWidth = windowWidth * 0.9;
        newHeight = windowWidth * 0.9 * ratio;
      }
      else {
        ratio = originalWidth / originalHeight;
        newWidth = (windowHeight * 0.9) * ratio;
        newHeight = windowHeight * 0.9;
      }

      // Animate image + set z-index
      if(origin.hasClass('responsive-img')) {
        origin.velocity({'max-width': newWidth, 'width': originalWidth}, {duration: 0, queue: false,
          complete: function(){
            origin.css({left: 0, top: 0})
            .velocity(
              {
                height: newHeight,
                width: newWidth,
                left: $(document).scrollLeft() + windowWidth/2 - origin.parent('.material-placeholder').offset().left - newWidth/2,
                top: $(document).scrollTop() + windowHeight/2 - origin.parent('.material-placeholder').offset().top - newHeight/ 2
              },
              {
                duration: inDuration,
                queue: false,
                easing: 'easeOutQuad',
                complete: function(){doneAnimating = true;}
              }
            );
          } // End Complete
        }); // End Velocity
      }
      else {
        origin.css('left', 0)
        .css('top', 0)
        .velocity(
          {
            height: newHeight,
            width: newWidth,
            left: $(document).scrollLeft() + windowWidth/2 - origin.parent('.material-placeholder').offset().left - newWidth/2,
            top: $(document).scrollTop() + windowHeight/2 - origin.parent('.material-placeholder').offset().top - newHeight/ 2
          },
          {
            duration: inDuration,
            queue: false,
            easing: 'easeOutQuad',
            complete: function(){doneAnimating = true;}
          }
          ); // End Velocity
      }

  }); // End origin on click

    // Return on scroll
    $(window).scroll(function() {
      if (overlayActive) {
        returnToOriginal();
      }
    });

    // Return on ESC
    $(document).keyup(function(e) {

      if (e.keyCode === 27 && doneAnimating === true) {   // ESC key
        if (overlayActive) {
          returnToOriginal();
        }
      }
    });

    // This function returns the modaled image to the original spot
    function returnToOriginal() {

        doneAnimating = false;

        var placeholder = origin.parent('.material-placeholder');
        var windowWidth = window.innerWidth;
        var windowHeight = window.innerHeight;
        var originalWidth = origin.data('width');
        var originalHeight = origin.data('height');

        origin.velocity("stop", true);
        $('#materialbox-overlay').velocity("stop", true);
        $('.materialbox-caption').velocity("stop", true);

        $('#materialbox-overlay').velocity({opacity: 0}, {
          duration: outDuration, // Delay prevents animation overlapping
          queue: false, easing: 'easeOutQuad',
          complete: function(){
            // Remove Overlay
            overlayActive = false;
            $(this).remove();
          }
        });

        // Resize Image
        origin.velocity(
          {
            width: originalWidth,
            height: originalHeight,
            left: 0,
            top: 0
          },
          {
            duration: outDuration,
            queue: false, easing: 'easeOutQuad'
          }
        );

        // Remove Caption + reset css settings on image
        $('.materialbox-caption').velocity({opacity: 0}, {
          duration: outDuration, // Delay prevents animation overlapping
          queue: false, easing: 'easeOutQuad',
          complete: function(){
            placeholder.css({
              height: '',
              width: '',
              position: '',
              top: '',
              left: ''
            });

            origin.css({
              height: '',
              top: '',
              left: '',
              width: '',
              'max-width': '',
              position: '',
              'z-index': ''
            });

            // Remove class
            origin.removeClass('active');
            doneAnimating = true;
            $(this).remove();

            // Remove overflow overrides on ancestors
            if (ancestorsChanged) {
              ancestorsChanged.css('overflow', '');
            }
          }
        });

      }
      });

};

$(document).ready(function(){

$('.materialboxed').materialbox();

});

}( jQuery ));