(function ($) {

$.fn.pushpin = function (options) {
  // Defaults
  var defaults = {
    top: 0,
    bottom: Infinity,
    offset: 0
  };

  // Remove pushpin event and classes
  if (options === "remove") {
    this.each(function () {
      if (id = $(this).data('pushpin-id')) {
        $(window).off('scroll.' + id);
        $(this).removeData('pushpin-id').removeClass('pin-top pinned pin-bottom').removeAttr('style');
      }
    });
    return false;
  }

  options = $.extend(defaults, options);

  $index = 0;
  return this.each(function() {
    var $uniqueId = Materialize.guid(),
        $this = $(this),
        $original_offset = $(this).offset().top;

    function removePinClasses(object) {
      object.removeClass('pin-top');
      object.removeClass('pinned');
      object.removeClass('pin-bottom');
    }

    function updateElements(objects, scrolled) {
      objects.each(function () {
        // Add position fixed (because its between top and bottom)
        if (options.top <= scrolled && options.bottom >= scrolled && !$(this).hasClass('pinned')) {
          removePinClasses($(this));
          $(this).css('top', options.offset);
          $(this).addClass('pinned');
        }

        // Add pin-top (when scrolled position is above top)
        if (scrolled < options.top && !$(this).hasClass('pin-top')) {
          removePinClasses($(this));
          $(this).css('top', 0);
          $(this).addClass('pin-top');
        }

        // Add pin-bottom (when scrolled position is below bottom)
        if (scrolled > options.bottom && !$(this).hasClass('pin-bottom')) {
          removePinClasses($(this));
          $(this).addClass('pin-bottom');
          $(this).css('top', options.bottom - $original_offset);
        }
      });
    }

    $(this).data('pushpin-id', $uniqueId);
    updateElements($this, $(window).scrollTop());
    $(window).on('scroll.' + $uniqueId, function () {
      var $scrolled = $(window).scrollTop() + options.offset;
      updateElements($this, $scrolled);
    });

  });

};

}( jQuery ));