"use strict";

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

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.createAsyncMeta = createAsyncMeta;
exports.createMeta = createMeta;
exports.createMetaRef = createMetaRef;
exports.createSceneMeta = createSceneMeta;
exports.createSceneStateMeta = createSceneStateMeta;
exports.createStateMeta = createStateMeta;

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

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

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

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

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

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

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

var _tsFns = require("ts-fns");

var _meta = require("./meta.js");

var _model = require("./model.js");

var _factory = require("./factory.js");

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

function createMeta() {
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
    args[_key] = arguments[_key];
  }

  var entries = args[0];

  if ((0, _tsFns.isArray)(entries) && !entries.some(function (entry) {
    return !(0, _tsFns.isInheritedOf)(entry, _model.Model);
  })) {
    return _factory.Factory.createMeta.apply(_factory.Factory, args);
  }

  if ((0, _tsFns.isInheritedOf)(entries, _model.Model)) {
    return _factory.Factory.createMeta.apply(_factory.Factory, args);
  }

  return new _meta.Meta(entries);
}
/**
 * if several metas referer to each other, we should create them as a group
 * @param {number} count
 * @param {function} create return objects to generate metas
 * @returns {Meta[]}
 * @example
 * const [Meta1, Meta2, Meta3] = createMetaRef((Meta1, Meta2, Meta3) => {
 *   return [
 *     // for Meta1
 *     createMeta({
 *       default: 0,
 *       needs() {
 *         return [Meta1, Meta2, Meta3]
 *       },
 *     }),
 *     // for Meta2
 *     createMeta({
 *       default: 1,
 *       needs() {
 *         return [Meta1, Meta2, Meta3]
 *       },
 *     }),
 *     // for Meta3
 *     createMeta({
 *       default: 2,
 *       needs() {
 *         return [Meta1, Meta2, Meta3]
 *       },
 *     }),
 *   ]
 * })
 */


function createMetaRef(create) {
  var count = create.length;
  var items = create(); // prepare

  if (!(0, _tsFns.isArray)(items) || items.length !== count) {
    throw new Error('[TySheMo]: createMetaRef should get an array with same length as count.');
  }

  var metaClasses = items.map(function (item) {
    return (0, _tsFns.getConstructorOf)(item);
  });
  var metas = metaClasses.map(function (M) {
    return new M();
  });
  var results = create.apply(void 0, (0, _toConsumableArray2.default)(metas));
  var output = results.map(function (item, i) {
    var meta = metas[i];
    return Object.setPrototypeOf(item, meta);
  });
  return output;
}
/**
 *
 * @param {*} defaultAttrs
 * @param {*} asyncGetter not supports `default, activate, init, state, compute, AsyncGetter`
 * @returns
 */


function createAsyncMeta(defaultAttrs, asyncGetter) {
  var ThisAsyncMeta = /*#__PURE__*/function (_AsyncMeta) {
    (0, _inherits2.default)(ThisAsyncMeta, _AsyncMeta);

    var _super = _createSuper(ThisAsyncMeta);

    function ThisAsyncMeta() {
      (0, _classCallCheck2.default)(this, ThisAsyncMeta);
      return _super.apply(this, arguments);
    }

    (0, _createClass2.default)(ThisAsyncMeta, [{
      key: "fetchAsyncAttrs",
      value: function fetchAsyncAttrs() {
        return asyncGetter().then(function (data) {
          return _objectSpread({}, data);
        });
      }
    }]);
    return ThisAsyncMeta;
  }(_meta.AsyncMeta);

  Object.assign(ThisAsyncMeta, defaultAttrs);
  return new ThisAsyncMeta();
}

function createSceneMeta(defaultAttrs, sceneMapping) {
  var ThisSceneMeta = /*#__PURE__*/function (_SceneMeta) {
    (0, _inherits2.default)(ThisSceneMeta, _SceneMeta);

    var _super2 = _createSuper(ThisSceneMeta);

    function ThisSceneMeta() {
      (0, _classCallCheck2.default)(this, ThisSceneMeta);
      return _super2.apply(this, arguments);
    }

    (0, _createClass2.default)(ThisSceneMeta, [{
      key: "defineScenes",
      value: function defineScenes() {
        return typeof sceneMapping === 'function' ? sceneMapping() : sceneMapping;
      }
    }]);
    return ThisSceneMeta;
  }(_meta.SceneMeta);

  Object.assign(ThisSceneMeta, defaultAttrs);
  return new ThisSceneMeta();
}

function createStateMeta(attrs) {
  return new _meta.StateMeta(attrs);
}

function createSceneStateMeta(defaultAttrs, sceneMapping) {
  var ThisSceneStateMeta = /*#__PURE__*/function (_SceneStateMeta) {
    (0, _inherits2.default)(ThisSceneStateMeta, _SceneStateMeta);

    var _super3 = _createSuper(ThisSceneStateMeta);

    function ThisSceneStateMeta() {
      (0, _classCallCheck2.default)(this, ThisSceneStateMeta);
      return _super3.apply(this, arguments);
    }

    (0, _createClass2.default)(ThisSceneStateMeta, [{
      key: "defineScenes",
      value: function defineScenes() {
        return typeof sceneMapping === 'function' ? sceneMapping() : sceneMapping;
      }
    }]);
    return ThisSceneStateMeta;
  }(_meta.SceneStateMeta);

  Object.assign(ThisSceneStateMeta, defaultAttrs);
  return new ThisSceneStateMeta();
}