"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.WidgetManager = void 0;

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _constants = require("./constants");

var _deepEqual = require("../utils/deep-equal");

function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

var PLACEMENTS = {
  'top-left': {
    top: 0,
    left: 0
  },
  'top-right': {
    top: 0,
    right: 0
  },
  'bottom-left': {
    bottom: 0,
    left: 0
  },
  'bottom-right': {
    bottom: 0,
    right: 0
  },
  fill: {
    top: 0,
    left: 0,
    bottom: 0,
    right: 0
  }
};
var DEFAULT_PLACEMENT = 'top-left';
var ROOT_CONTAINER_ID = '__root';

var WidgetManager = function () {
  function WidgetManager(_ref) {
    var deck = _ref.deck,
        parentElement = _ref.parentElement;
    (0, _classCallCheck2.default)(this, WidgetManager);
    this.deck = void 0;
    this.parentElement = void 0;
    this.defaultWidgets = [];
    this.widgets = [];
    this.resolvedWidgets = [];
    this.containers = {};
    this.lastViewports = {};
    this.deck = deck;
    this.parentElement = parentElement;
  }

  var _proto = WidgetManager.prototype;

  _proto.getWidgets = function getWidgets() {
    return this.resolvedWidgets;
  };

  _proto.setProps = function setProps(props) {
    if (props.widgets && !(0, _deepEqual.deepEqual)(props.widgets, this.widgets, 1)) {
      this._setWidgets(props.widgets);
    }
  };

  _proto.finalize = function finalize() {
    var _iterator = _createForOfIteratorHelper(this.getWidgets()),
        _step;

    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        var widget = _step.value;

        this._remove(widget);
      }
    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }

    this.defaultWidgets.length = 0;
    this.resolvedWidgets.length = 0;

    for (var _id in this.containers) {
      this.containers[_id].remove();
    }
  };

  _proto.addDefault = function addDefault(widget) {
    if (!this.defaultWidgets.find(function (w) {
      return w.id === widget.id;
    })) {
      this._add(widget);

      this.defaultWidgets.push(widget);

      this._setWidgets(this.widgets);
    }
  };

  _proto._setWidgets = function _setWidgets(nextWidgets) {
    var oldWidgetMap = {};

    var _iterator2 = _createForOfIteratorHelper(this.resolvedWidgets),
        _step2;

    try {
      for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
        var widget = _step2.value;
        oldWidgetMap[widget.id] = widget;
      }
    } catch (err) {
      _iterator2.e(err);
    } finally {
      _iterator2.f();
    }

    this.resolvedWidgets.length = 0;

    var _iterator3 = _createForOfIteratorHelper(this.defaultWidgets),
        _step3;

    try {
      for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
        var _widget = _step3.value;
        oldWidgetMap[_widget.id] = null;
        this.resolvedWidgets.push(_widget);
      }
    } catch (err) {
      _iterator3.e(err);
    } finally {
      _iterator3.f();
    }

    var _iterator4 = _createForOfIteratorHelper(nextWidgets),
        _step4;

    try {
      for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
        var _widget2 = _step4.value;
        var _oldWidget = oldWidgetMap[_widget2.id];

        if (!_oldWidget) {
          this._add(_widget2);
        } else if (_oldWidget.viewId !== _widget2.viewId || _oldWidget.placement !== _widget2.placement) {
          this._remove(_oldWidget);

          this._add(_widget2);
        } else if (_widget2 !== _oldWidget) {
          _oldWidget.setProps(_widget2.props);

          _widget2 = _oldWidget;
        }

        oldWidgetMap[_widget2.id] = null;
        this.resolvedWidgets.push(_widget2);
      }
    } catch (err) {
      _iterator4.e(err);
    } finally {
      _iterator4.f();
    }

    for (var _id2 in oldWidgetMap) {
      var oldWidget = oldWidgetMap[_id2];

      if (oldWidget) {
        this._remove(oldWidget);
      }
    }

    this.widgets = nextWidgets;
  };

  _proto._add = function _add(widget) {
    var _widget$viewId = widget.viewId,
        viewId = _widget$viewId === void 0 ? null : _widget$viewId,
        _widget$placement = widget.placement,
        placement = _widget$placement === void 0 ? DEFAULT_PLACEMENT : _widget$placement;
    var element = widget.onAdd({
      deck: this.deck,
      viewId: viewId
    });

    if (element) {
      this._getContainer(viewId, placement).append(element);
    }

    widget._element = element;
  };

  _proto._remove = function _remove(widget) {
    widget.onRemove();

    if (widget._element) {
      widget._element.remove();
    }

    widget._element = undefined;
  };

  _proto._getContainer = function _getContainer(viewId, placement) {
    var containerId = viewId || ROOT_CONTAINER_ID;
    var viewContainer = this.containers[containerId];

    if (!viewContainer) {
      var _this$parentElement;

      viewContainer = document.createElement('div');
      viewContainer.style.pointerEvents = 'none';
      viewContainer.style.position = 'absolute';
      viewContainer.style.overflow = 'hidden';
      (_this$parentElement = this.parentElement) === null || _this$parentElement === void 0 ? void 0 : _this$parentElement.append(viewContainer);
      this.containers[containerId] = viewContainer;
    }

    var container = viewContainer.querySelector(".".concat(placement));

    if (!container) {
      container = document.createElement('div');
      container.className = placement;
      container.style.position = 'absolute';
      Object.assign(container.style, PLACEMENTS[placement]);
      viewContainer.append(container);
    }

    return container;
  };

  _proto._updateContainers = function _updateContainers() {
    var canvasWidth = this.deck.width;
    var canvasHeight = this.deck.height;

    for (var _id3 in this.containers) {
      var _viewport = this.lastViewports[_id3] || null;

      var visible = _id3 === ROOT_CONTAINER_ID || _viewport;
      var container = this.containers[_id3];

      if (visible) {
        container.style.display = 'block';
        container.style.left = "".concat(_viewport ? _viewport.x : 0, "px");
        container.style.top = "".concat(_viewport ? _viewport.y : 0, "px");
        container.style.width = "".concat(_viewport ? _viewport.width : canvasWidth, "px");
        container.style.height = "".concat(_viewport ? _viewport.height : canvasHeight, "px");
      } else {
        container.style.display = 'none';
      }
    }
  };

  _proto.onRedraw = function onRedraw(_ref2) {
    var viewports = _ref2.viewports,
        layers = _ref2.layers;
    var viewportsById = viewports.reduce(function (acc, v) {
      acc[v.id] = v;
      return acc;
    }, {});
    var lastViewports = this.lastViewports;

    var _iterator5 = _createForOfIteratorHelper(this.getWidgets()),
        _step5;

    try {
      for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
        var widget = _step5.value;
        var viewId = widget.viewId;

        if (viewId) {
          var _viewport2 = viewportsById[viewId];

          if (_viewport2) {
            var _widget$onRedraw;

            if (widget.onViewportChange && !_viewport2.equals(lastViewports[viewId])) {
              widget.onViewportChange(_viewport2);
            }

            (_widget$onRedraw = widget.onRedraw) === null || _widget$onRedraw === void 0 ? void 0 : _widget$onRedraw.call(widget, {
              viewports: [_viewport2],
              layers: layers
            });
          }
        } else {
          var _widget$onRedraw2;

          if (widget.onViewportChange) {
            var _iterator6 = _createForOfIteratorHelper(viewports),
                _step6;

            try {
              for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
                var _viewport3 = _step6.value;

                if (!_viewport3.equals(lastViewports[_viewport3.id])) {
                  widget.onViewportChange(_viewport3);
                }
              }
            } catch (err) {
              _iterator6.e(err);
            } finally {
              _iterator6.f();
            }
          }

          (_widget$onRedraw2 = widget.onRedraw) === null || _widget$onRedraw2 === void 0 ? void 0 : _widget$onRedraw2.call(widget, {
            viewports: viewports,
            layers: layers
          });
        }
      }
    } catch (err) {
      _iterator5.e(err);
    } finally {
      _iterator5.f();
    }

    this.lastViewports = viewportsById;

    this._updateContainers();
  };

  _proto.onHover = function onHover(info, event) {
    var _iterator7 = _createForOfIteratorHelper(this.getWidgets()),
        _step7;

    try {
      for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
        var _info$viewport;

        var widget = _step7.value;
        var viewId = widget.viewId;

        if (!viewId || viewId === ((_info$viewport = info.viewport) === null || _info$viewport === void 0 ? void 0 : _info$viewport.id)) {
          var _widget$onHover;

          (_widget$onHover = widget.onHover) === null || _widget$onHover === void 0 ? void 0 : _widget$onHover.call(widget, info, event);
        }
      }
    } catch (err) {
      _iterator7.e(err);
    } finally {
      _iterator7.f();
    }
  };

  _proto.onEvent = function onEvent(info, event) {
    var eventOptions = _constants.EVENTS[event.type];

    if (!eventOptions) {
      return;
    }

    var _iterator8 = _createForOfIteratorHelper(this.getWidgets()),
        _step8;

    try {
      for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
        var _info$viewport2;

        var widget = _step8.value;
        var viewId = widget.viewId;

        if (!viewId || viewId === ((_info$viewport2 = info.viewport) === null || _info$viewport2 === void 0 ? void 0 : _info$viewport2.id)) {
          var _widget$eventOptions$;

          (_widget$eventOptions$ = widget[eventOptions.handler]) === null || _widget$eventOptions$ === void 0 ? void 0 : _widget$eventOptions$.call(widget, info, event);
        }
      }
    } catch (err) {
      _iterator8.e(err);
    } finally {
      _iterator8.f();
    }
  };

  return WidgetManager;
}();

exports.WidgetManager = WidgetManager;
//# sourceMappingURL=widget-manager.js.map