(function (paw, utils) {
  function PawPopup(id, settings) {
    var self = this;
    this.isFullScreen = false;
    this.id = id;
    this.settings = paw.lang.append(
      {
        destroyOnClose: true,
        markupDef: undefined,
        Component: undefined,
        styleClass: undefined,
        title: undefined,
        bind: undefined,
        popupActions: undefined,
        draggable: true,
        type: "modal",
        maximizable: true,
        popupIconActions: [],
        $content: undefined,
        contentStyleClass: undefined,
      },
      settings || {}
    );

    if (this.settings.maximizable) {
      this.settings.popupIconActions.push({
        icon: "paw-popup-size-control fa fa-expand-alt",
        onSelected: function (action, e) {
          e.stopPropagation();
          e.stopImmediatePropagation();

          if (self.isFullScreen) {
            self.$popup.removeClass("paw-popup-fullscreen");
            action.$$elt
              .removeClass("fa-compress-alt")
              .addClass("fa-expand-alt");
            self.isFullScreen = false;
            self.resize();
            self.$popup.removeAttr("data-drag-lock");
            return;
          }
          self.$popup.addClass("paw-popup-fullscreen");
          action.$$elt.removeClass("fa-expand-alt").addClass("fa-compress-alt");
          self.isFullScreen = true;
          self.$popup.attr("data-drag-lock", "true");
          self.resize();
        },
      });
    }

    this.$popup = null;
    this.component = null;
    this.isOpened = false;

    this.onEscKey = function (e) {
      if (e.key === "Escape") {
        self.hide();
      }
    };

    this.onResize = function (e) {
      self.resize(e);
    };

    this.resizeDebouncer = utils.async.debouncer(function (e) {
      if (
        utils.value.isSet(this.component) &&
        utils.value.isFunction(self.component.onResized)
      ) {
        self.component.onResized(e);
      }
      if (utils.value.isFunction(this.settings.onResized)) {
        this.settings.onResized(e);
      }
    });
    this.isInit = false;
  }

  PawPopup.prototype.show = function () {
    var self = this;

    if (this.isOpened) {
      return;
    }
    $().customModal({
      id: this.id,
      destroyOnClose: this.settings.destroyOnClose,
      showCloseButton: true,
      type: this.settings.type,
      title: this.settings.title,
      content: '<div class="paw-popup-content"></div>',
      closeOtherModals: false,
      buttons: this.settings.actions,
      draggable: this.settings.draggable,
      onClose: function () {
        if (utils.value.isFunction(self.settings.onClose)) {
          self.settings.onClose();
        }
        if (self.settings.destroyOnClose) {
          self.destroy();
          self.isInit = false;
        }
        self.isOpened = false;
      },
    });
    if (this.isInit) {
      this.isOpened = true;
      return;
    }

    this.$popup = $("#" + this.id);

    this.$popup.addClass("paw-popup");
    if (utils.value.isSet(this.settings.styleClass)) {
      this.$popup.addClass(this.settings.styleClass);
    }

    if (utils.value.isSet(this.settings.popupIconActions)) {
      var $iconTray = this.$popup.find(".custom-modal-icon-tray");
      utils.iterable.iterate(this.settings.popupIconActions, function (action) {
        var $action = $(
          '<span class="paw-popup-icon-action custom-modal-icon ' +
            action.icon +
            '" title="' +
            (action.title || "") +
            '"></span>'
        );
        $iconTray.prepend($action);
        action.$$elt = $action;
        if (utils.value.isFunction(action.onSelected)) {
          $action.on("click", function (e) {
            action.onSelected(action, e);
          });
        }
      });
    }

    var $holder = this.$popup.find(".paw-popup-content");

    if (utils.value.isSet(this.settings.contentStyleClass)) {
      $holder.addClass(this.settings.contentStyleClass);
    }

    if (utils.value.isSet(this.settings.message)) {
      $holder.html(
        '<div class="paw-popup-message">' + this.settings.message + "</div>"
      );
    } else if (utils.value.isFunction(this.settings.markupDef)) {
      $holder.html(this.settings.markupDef(this.settings.bind).join("\n"));
    } else if (utils.value.isSet(this.settings.Component)) {
      this.component = new this.settings.Component($holder, this);
      if (utils.value.isSet(this.settings.bind)) {
        utils.iterable.iterate(this.settings.bind, function (v, k) {
          self.component[k] = v;
        });
      }
      if (utils.value.isFunction(this.component.onBinded)) {
        this.component.onBinded();
      }

      if (utils.value.isFunction(this.component.markupDef)) {
        $holder.html(this.component.markupDef().join("\n"));
      }

      if (utils.value.isFunction(this.component.init)) {
        this.component.init();
      }
    } else if (utils.value.isSet(this.settings.$content)) {
      $holder.append(this.settings.$content);
      if (this.settings.$content.hasClass("hidden")) {
        this.settings.$content.removeClass("hidden");
      }
    }

    if (utils.value.isSet(this.settings.popupActions)) {
      var actionsCount = this.settings.popupActions.length;
      var $actions = $(
        '<div class="paw-area-h paw-popup-actions"><div class="paw-col-d"></div></div>'
      );
      utils.iterable.iterate(this.settings.popupActions, function (action) {
        var $action = $(
          '<button id="' +
            action.id +
            '" class="' +
            (action.styleClass || "btn btn-primary") +
            ' paw-popup-action">' +
            action.label +
            "</button>"
        );
        $action.on("click", function (e) {
          action.onSelected(action, $action, e);
        });
        var $aholder = $('<div class="paw-col paw-popup-action-holder"></div>');
        $aholder.append($action);
        $actions.append($aholder);
      });
      $holder.append($actions);
    }

    $(document).on("keyup", this.onEscKey);
    $(window).on("resize", this.onResize);

    this.isOpened = true;
    this.isInit = true;
  };

  PawPopup.prototype.hide = function () {
    this.$popup.customModal("close");
  };

  PawPopup.prototype.destroy = function () {
    if (
      utils.value.isSet(this.component) &&
      utils.value.isFunction(this.component.destroy)
    ) {
      this.component.destroy();
    }

    if (utils.value.isSet(this.$popup)) {
      this.$popup
        .find(".custom-modal-icon-tray > .paw-popup-icon-action")
        .off("click");
      this.$popup.find(".paw-popup-action").off();
    }
    $(document).off("keyup", this.onEscKey);
    $(window).off("resize", this.onResize);
  };

  PawPopup.prototype.resize = function (e) {
    if (
      utils.value.isSet(this.component) &&
      utils.value.isFunction(this.component.onResize)
    ) {
      this.component.onResize(e);
    }
    if (utils.value.isFunction(this.settings.onResize)) {
      this.settings.onResize(e);
    }
    this.resizeDebouncer(e);
  };

  paw.com.Popup = PawPopup;
})(paw, paw.utils);
