"use strict";

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); }
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.createInitialDesignDataFromDesignAreas = createInitialDesignDataFromDesignAreas;
exports.processConfigurationModes = processConfigurationModes;
exports.recalculateDesignAreas = recalculateDesignAreas;
exports.recalculateSingleDesignArea = recalculateSingleDesignArea;
var _isObject = _interopRequireDefault(require("lodash/isObject"));
var _isArray = _interopRequireDefault(require("lodash/isArray"));
var _get = _interopRequireDefault(require("lodash/get"));
var _find = _interopRequireDefault(require("lodash/find"));
var _first = _interopRequireDefault(require("lodash/first"));
var _isPositiveNumber = require("../../../Utils/Math/isPositiveNumber");
var _Selectors = require("./Selectors");
var _Selectors2 = require("../Configurator/Selectors");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, 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); }
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
/**
 * Creates the state from the JSON object returned by the server.
 *
 * Loops through the design views and builds a merged list from the design areas (that will contains only
 * one instance from all the available areas across the design views). It sets the designView origin for
 * every design area object, so later it can be identified.
 *
 * @param configurationModes
 * @returns {{filteredDesignAreas: Object[], selectedDesignArea: {}}}
 */
function processConfigurationModes(configurationModes) {
  if (!(0, _isObject["default"])(configurationModes) || !(0, _isArray["default"])(configurationModes.designViews)) {
    // eslint-disable-next-line no-console
    console.warn('Invalid argument: configurationModes!', configurationModes);
    return {};
  }
  var designViews = configurationModes.designViews,
    uploadMaxSize = configurationModes.uploadMaxSize,
    maxZoom2d = configurationModes.maxZoom2d;
  var filteredDesignAreas = [];
  var designAreaMap = {};
  var _iterator = _createForOfIteratorHelper(designViews),
    _step;
  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var designView = _step.value;
      var designAreas = (0, _get["default"])(designView, 'designAreas') || [];
      var _iterator2 = _createForOfIteratorHelper(designAreas),
        _step2;
      try {
        for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
          var designArea = _step2.value;
          var identifier = designArea.identifier;
          if (identifier && !designAreaMap[identifier]) {
            // for the first occurrence of the design area, just add it to the list and the area map
            var da = _objectSpread(_objectSpread({}, designArea), {}, {
              designView: designView
            });
            designAreaMap[identifier] = da;
            filteredDesignAreas.push(da);
          } else {
            // try to guess the main view for the design area
            var defaultViewIdentifier = (0, _get["default"])(designArea, 'defaultViewIdentifier'); // 2D
            var selectedCameraView = (0, _get["default"])(designArea, 'customData.selectedCameraView'); // 3D
            var viewIdentifier = defaultViewIdentifier || selectedCameraView;
            if (viewIdentifier && viewIdentifier === designView.identifier || !viewIdentifier && designAreas.length === 1 // it's the only area of the view
            ) {
              Object.assign(designAreaMap[identifier], designArea, {
                designView: designView
              });
            }
          }
        }
      } catch (err) {
        _iterator2.e(err);
      } finally {
        _iterator2.f();
      }
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }
  sortDesignAreas(filteredDesignAreas);
  return {
    filteredDesignAreas: filteredDesignAreas,
    selectedDesignArea: {},
    uploadMaxSize: uploadMaxSize,
    initialCanvasPosition: filteredDesignAreas,
    maxZoom2d: maxZoom2d
  };
}
var sortDesignAreas = function sortDesignAreas(designAreas) {
  return designAreas.sort(function (a, b) {
    if (a.sequenceNumber !== b.sequenceNumber) {
      return parseInt(a.sequenceNumber) < parseInt(b.sequenceNumber) ? -1 : 1;
    } else {
      return 0;
    }
  });
};
var createDesignAreaPatch = function createDesignAreaPatch(designArea, sizeRatio, visualMode) {
  var widthRatio = sizeRatio.widthRatio,
    heightRatio = sizeRatio.heightRatio,
    aspectRatio = sizeRatio.aspectRatio;
  var position = _objectSpread({}, designArea.position);
  var baseShape = _objectSpread({}, designArea.baseShape);
  position.width = Math.round(designArea.position.width * widthRatio);
  position.height = Math.round(position.width / aspectRatio);

  // skip update if width or height is not valid
  if (!((0, _isPositiveNumber.isPositiveNumber)(position.width) && (0, _isPositiveNumber.isPositiveNumber)(position.height))) {
    return false;
  }
  if (visualMode.is2D()) {
    // adjust the base shape size to fit the selected design area
    var _position$angle = position.angle,
      angle = _position$angle === void 0 ? 0 : _position$angle;
    var sinAbs = Math.abs(Math.sin(angle));
    var cosAbs = Math.abs(Math.cos(angle));
    var bbWidthRatio = sinAbs * heightRatio + cosAbs * widthRatio;
    var bbHeightRatio = cosAbs * heightRatio + sinAbs * widthRatio;
    baseShape.width = Math.round(designArea.baseShape.width * bbWidthRatio);
    baseShape.height = Math.round(designArea.baseShape.height * bbHeightRatio);
    position.x = position.x * bbWidthRatio;
    position.y = position.y * bbHeightRatio;

    // recalculate control points if they are being used
    if (baseShape.useControlPoints && designArea.baseShape.points) {
      baseShape.points = {};
      for (var _i = 0, _Object$entries = Object.entries(designArea.baseShape.points); _i < _Object$entries.length; _i++) {
        var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
          pointKey = _Object$entries$_i[0],
          pointCoords = _Object$entries$_i[1];
        baseShape.points[pointKey] = {
          x: pointCoords.x * bbWidthRatio,
          y: pointCoords.y * bbHeightRatio
        };
      }
    }
  }
  return {
    position: position,
    baseShape: baseShape
  };
};
function recalculateSingleDesignArea(state, designArea) {
  var visualMode = (0, _Selectors2.visualizationModeCheck)(state);
  var designProductionMethods = designArea.designProductionMethods;
  var sizeObject = designArea.width && designArea.height ? designArea : (0, _first["default"])(designProductionMethods) || {};
  var dpm = (0, _Selectors.getSelectedDesignProductionMethodForDesignArea)(state, designArea);
  var widthRatio = dpm.width / sizeObject.width;
  var heightRatio = dpm.height / sizeObject.height;
  var aspectRatio = dpm.width / dpm.height;
  var sizeRatio = {
    widthRatio: widthRatio,
    heightRatio: heightRatio,
    aspectRatio: aspectRatio
  };
  var patch = createDesignAreaPatch(designArea, sizeRatio, visualMode);
  return _objectSpread(_objectSpread({}, designArea), patch);
}
function recalculateDesignAreas(designAreaState, designProductionMethodMap, visualMode) {
  var designAreas = designAreaState.selectedDesignArea.identifier ? [designAreaState.selectedDesignArea] : designAreaState.filteredDesignAreas;
  var filteredDesignAreas = _toConsumableArray(designAreaState.filteredDesignAreas);
  var selectedDesignArea = designAreaState.selectedDesignArea;
  var _iterator3 = _createForOfIteratorHelper(designAreas),
    _step3;
  try {
    var _loop = function _loop() {
      var _designArea = _step3.value;
      var designArea = _objectSpread({}, _designArea);
      var designProductionMethods = designArea.designProductionMethods;
      var sizeObject = designArea.width && designArea.height ? designArea : (0, _first["default"])(designProductionMethods) || {};
      var dpm = designProductionMethodMap[designArea.identifier];
      var widthRatio = dpm.width / sizeObject.width;
      var heightRatio = dpm.height / sizeObject.height;
      var aspectRatio = dpm.width / dpm.height;
      var sizeRatio = {
        widthRatio: widthRatio,
        heightRatio: heightRatio,
        aspectRatio: aspectRatio
      };
      var original = (0, _find["default"])(designAreaState.initialCanvasPosition, {
        identifier: designArea.identifier
      });
      var patch = createDesignAreaPatch(original, sizeRatio, visualMode);
      if (!patch) {
        return 1; // continue
      }
      var designView = _objectSpread(_objectSpread({}, designArea.designView), {}, {
        designAreas: designArea.designView.designAreas.map(function (da) {
          return da !== designArea && da.identifier === designArea.identifier ? _objectSpread(_objectSpread({}, da), patch) : da;
        })
      });
      Object.assign(designArea, _objectSpread(_objectSpread({}, patch), {}, {
        designView: designView
      }));
      var index = filteredDesignAreas.indexOf(_designArea);
      if (index !== -1) {
        filteredDesignAreas[index] = designArea;
      }
      if (selectedDesignArea && selectedDesignArea.identifier === designArea.identifier) {
        selectedDesignArea = designArea;
      }
    };
    for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
      if (_loop()) continue;
    }
  } catch (err) {
    _iterator3.e(err);
  } finally {
    _iterator3.f();
  }
  return _objectSpread(_objectSpread({}, designAreaState), {}, {
    selectedDesignArea: selectedDesignArea,
    filteredDesignAreas: filteredDesignAreas
  });
}
function createInitialDesignDataFromDesignAreas(designAreas) {
  var designData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var initialDesignData = {};
  var _iterator4 = _createForOfIteratorHelper(designAreas),
    _step4;
  try {
    for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
      var area = _step4.value;
      var data = (0, _isObject["default"])(designData) ? _objectSpread({}, designData[area.identifier]) : {};
      var preSelection = (0, _Selectors.getDesignAreaPreSelection)(area.identifier);
      var method = void 0;
      if (preSelection.productionMethod) {
        var preSelectionMethod = (0, _find["default"])(area.designProductionMethods, {
          identifier: preSelection.productionMethod
        });
        if (preSelectionMethod) {
          method = preSelectionMethod;
        }
      }
      if (!method) {
        method = (0, _find["default"])(area.designProductionMethods, {
          isDefault: true
        }) || (0, _first["default"])(area.designProductionMethods);
      }
      if (!data.canvasData) {
        data.canvasData = null;
      }
      if (!data.designProductionMethodIdentifier || !data.canvasData || !(0, _find["default"])(area.designProductionMethods, {
        identifier: data.designProductionMethodIdentifier
      })) {
        data.designProductionMethodIdentifier = method ? method.identifier : 'print';
        data.canvasData = null;
      }
      var preselectedColorAmount = data.colorAmount ? data.colorAmount : preSelection.colorAmount;
      var colorAmount = (0, _Selectors.getDesignAreaColorAmount)(+(0, _get["default"])(method, 'options.maxColorAmount', 0), +preselectedColorAmount);
      if (colorAmount !== null) {
        data.colorAmount = colorAmount;
      }
      initialDesignData[area.identifier] = data;
    }
  } catch (err) {
    _iterator4.e(err);
  } finally {
    _iterator4.f();
  }
  return initialDesignData;
}