(function ($, undefined) {

  $.fn.overlay = function (contentUrl, callback, opts) {

    opts = $.extend({'closeOnEsc': true, 'closeOnExteriorClick': true, 'width': "420px", 'useIframe': false, 'destroyOnHide': true}, opts);

    return this.each(function () {

      if (!contentUrl) {
        throw "Please provide a contentURL";
      }

      var ele = $(this);

      if (ele.css('position') === 'absolute') {
        throw "Parent of an overlay cannot be positioned absolute";
      }

      var overlayHtml = function (data) {
        var type = opts.isIframe ? '<iframe></iframe>' : '<div></div>';
        var overlay = $(type).addClass('twitch_subwindow');

        if (typeof data === 'object') {
          data.appendTo(overlay);
        } else {
          overlay.html(data);
        }

        if (opts.id) {
          overlay.attr('id', opts.id);
        }

        overlay.css('width', opts.width);

        var container = $('<div></div>').addClass('twitch_subwindow_container');

        ele.prepend(container).show();
        container.prepend(overlay).show();

        ele.scrollTop(0);

        if (opts.focusOnLoad) {
          $(opts.focusOnLoad).focus();
        }

        if (opts.closeOnEsc) {
          ele.on('keyup.overlay', function (e) {
            if (e.keyCode === 27) {
              ele.trigger('overlay.hide');
            }
          });
        }

        if (opts.closeOnExteriorClick) {
          $('body.overlay').on('click.overlay', function (e) {
            if ($(e.target).hasClass('twitch_subwindow_container')) {
              ele.trigger('overlay.hide');
            }
          });
        }

        ele.on('overlay.hide', function (e) {
          e.stopPropagation();
          if (!opts.destroyOnHide) {
            overlay.hide();
            container.hide();
          }
          else {
            overlay.remove();
            container.remove();
          }
        });

        if (typeof callback === 'function') {
          callback(overlay, container);
        }
      };

      if (typeof contentUrl === 'string') {
        $.get(contentUrl).success(overlayHtml);
      } else {
        overlayHtml(contentUrl);
      }
    });
  };

  $.fn.teardownOverlay = function () {

    return this.each(function () {
      var ele = $(this);
      ele.off('keyup.overlay');
      $('body.overlay').off('click.overlay');
      ele.off('overlay.hide');
    });

  };

}(jQuery));
