"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = exports.Services = void 0;
var _AbstractStoreService = _interopRequireDefault(require("../Framework/Services/AbstractStoreService"));
var _AbstractUIService = _interopRequireDefault(require("../Framework/Services/AbstractUIService"));
var _AbstractConfiguratorService = _interopRequireDefault(require("../Framework/Services/AbstractConfiguratorService"));
var _AbstractAsyncService = _interopRequireDefault(require("../Framework/Services/AbstractAsyncService"));
var _AbstractInteractionService = _interopRequireDefault(require("../Framework/Services/AbstractInteractionService"));
var _AbstractAdminareaCommunicationService = _interopRequireDefault(require("../Framework/Services/AbstractAdminareaCommunicationService"));
var _AbstractVisualizationService = _interopRequireDefault(require("../Framework/Services/AbstractVisualizationService"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
 * Map of the provided services
 * @type {{}}
 * @private
 */
var services = {};

/**
 * Runs the init function after all the services are added
 * this provides the opportunity to access other services while doing the custom initialization
 * @private
 */
var runInitForCurrentServices = function runInitForCurrentServices() {
  var keys = Object.keys(services);
  for (var _i = 0, _keys = keys; _i < _keys.length; _i++) {
    var k = _keys[_i];
    var service = services[k];
    service.init && service.init();
  }
};
var ServiceLocator = exports["default"] = /*#__PURE__*/function () {
  function ServiceLocator() {
    _classCallCheck(this, ServiceLocator);
  }
  _createClass(ServiceLocator, null, [{
    key: "useServiceMap",
    value:
    /**
     * Instantiates the given services then calls the runInitForCurrentServices function
     * @param {{}} services The object that contains all the services
     */
    function useServiceMap(services) {
      var keys = Object.keys(services);
      for (var _i2 = 0, _keys2 = keys; _i2 < _keys2.length; _i2++) {
        var k = _keys2[_i2];
        var Service = services[k];
        this.provide(new Service());
      }
      runInitForCurrentServices();
    }
  }, {
    key: "provide",
    value: function provide(serviceInstance) {
      if (serviceInstance.constructor && serviceInstance.constructor.serviceName) {
        services[serviceInstance.constructor.serviceName] = serviceInstance;
      } else {
        throw new TypeError('The service must have a serviceName property in its constructor!');
      }
    }
  }, {
    key: "getServiceInstanceByName",
    value: function getServiceInstanceByName(serviceName) {
      if (services[serviceName]) {
        return services[serviceName];
      } else {
        throw new TypeError("Service does not exist: ".concat(serviceName));
      }
    }
  }, {
    key: "getServiceInstanceByConstructor",
    value: function getServiceInstanceByConstructor(constructor) {
      if (constructor.serviceName) {
        return this.getServiceInstanceByName(constructor.serviceName);
      } else {
        throw new TypeError('Missing service name parameter in the constructor!');
      }
    }

    /**
     *
     * @returns {AbstractStoreService}
     */
  }, {
    key: "getStoreService",
    value: function getStoreService() {
      return this.getServiceInstanceByConstructor(_AbstractStoreService["default"]);
    }

    /**
     *
     * @returns {AbstractUIService}
     */
  }, {
    key: "getUIService",
    value: function getUIService() {
      return this.getServiceInstanceByConstructor(_AbstractUIService["default"]);
    }

    /**
     *
     * @returns {AbstractInteractionService}
     */
  }, {
    key: "getInteractionService",
    value: function getInteractionService() {
      return this.getServiceInstanceByConstructor(_AbstractInteractionService["default"]);
    }

    /**
     *
     * @returns {AbstractConfiguratorService}
     */
  }, {
    key: "getConfiguratorService",
    value: function getConfiguratorService() {
      return this.getServiceInstanceByConstructor(_AbstractConfiguratorService["default"]);
    }

    /**
     *
     * @returns {AbstractAsyncService}
     */
  }, {
    key: "getAsyncService",
    value: function getAsyncService() {
      return this.getServiceInstanceByConstructor(_AbstractAsyncService["default"]);
    }

    /**
     *
     * @returns {AbstractAdminareaCommunicationService}
     */
  }, {
    key: "getAdminareaService",
    value: function getAdminareaService() {
      return this.getServiceInstanceByConstructor(_AbstractAdminareaCommunicationService["default"]);
    }

    /**
     *
     * @returns {AbstractVisualizationService}
     */
  }, {
    key: "getVisualizationService",
    value: function getVisualizationService() {
      return this.getServiceInstanceByConstructor(_AbstractVisualizationService["default"]);
    }
  }]);
  return ServiceLocator;
}();
/**
 * Service collection to get them in runtime
 */
var Services = exports.Services = /*#__PURE__*/function () {
  function Services() {
    _classCallCheck(this, Services);
  }
  _createClass(Services, null, [{
    key: "store",
    get:
    /**
     *
     * @returns {AbstractStoreService}
     */
    function get() {
      return ServiceLocator.getStoreService();
    }

    /**
     *
     * @returns {AbstractUIService}
     */
  }, {
    key: "ui",
    get: function get() {
      return ServiceLocator.getUIService();
    }

    /**
     *
     * @returns {AbstractInteractionService}
     */
  }, {
    key: "interaction",
    get: function get() {
      return ServiceLocator.getInteractionService();
    }

    /**
     *
     * @returns {AbstractConfiguratorService}
     */
  }, {
    key: "configurator",
    get: function get() {
      return ServiceLocator.getConfiguratorService();
    }

    /**
     *
     * @returns {AbstractAsyncService}
     */
  }, {
    key: "async",
    get: function get() {
      return ServiceLocator.getAsyncService();
    }

    /**
     *
     * @returns {AbstractAdminareaCommunicationService}
     */
  }, {
    key: "adminArea",
    get: function get() {
      return ServiceLocator.getAdminareaService();
    }

    /**
     *
     * @returns {AbstractVisualizationService}
     */
  }, {
    key: "visualization",
    get: function get() {
      return ServiceLocator.getVisualizationService();
    }

    /**
     *
     * @returns {DesignDataService}
     */
  }, {
    key: "designData",
    get: function get() {
      return this.get('DesignDataService');
    }

    /**
     *
     * @returns {AnalyticsService}
     */
  }, {
    key: "analytics",
    get: function get() {
      return this.get('AnalyticsService');
    }

    /**
     *
     * @returns {DesignerService}
     */
  }, {
    key: "designer",
    get: function get() {
      return this.get('DesignerService');
    }

    /**
     *
     * @param {string} serviceName
     * @returns {*}
     */
  }, {
    key: "get",
    value: function get(serviceName) {
      return ServiceLocator.getServiceInstanceByName(serviceName);
    }
  }]);
  return Services;
}(); // expose Services to the window in dev mode so it can be used from the console
if (process.env.NODE_ENV !== 'production') {
  window.Services = Services;
}