import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
import _createClass from '@babel/runtime/helpers/createClass';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import './index-bbdfb97a.js';
import { fabric } from 'fabric';
import { Vector3, Vector2 } from '@crystaldesign/web-planner-logic';
import { getLogger, DivaUtils } from '@crystaldesign/diva-core';
import 'react';
import 'react-dynamic-multi-render';
import 'react/jsx-runtime';
import 'mobx-react-lite';
import '@babel/runtime/helpers/asyncToGenerator';
import '@babel/runtime/helpers/slicedToArray';
import '@babel/runtime/helpers/objectWithoutProperties';
import '@babel/runtime/regenerator';
import '@babel/runtime/helpers/toConsumableArray';
import '@crystaldesign/diva-utils';
import 'mobx';
import 'classnames';
import 'qrcode.react';
import '@babel/runtime/helpers/typeof';
import 'flat';
import 'react-switch';
import 'react-countup';

var LOG = getLogger('Planner', 'Planner2DGrid');
var Planner2DGrid = /*#__PURE__*/function () {
  function Planner2DGrid(getConfiguratorState, getPlannerElementById, getPlannerViewConfig, forceViewToEnterPlannerMode, plannerPaletteViewInfo, settingsState) {
    var _this = this;
    _classCallCheck(this, Planner2DGrid);
    _defineProperty(this, "autoDockingDistance", 20);
    //Auto docking innerhalb von 10 cm
    _defineProperty(this, "dimGroupWidthName", 'DimensionGroup_Width');
    _defineProperty(this, "dimGroupHeightName", 'DimensionGroup_Height');
    _defineProperty(this, "canvas", void 0);
    _defineProperty(this, "canvas2DGridID", 'wcConfigurator-grid-2D-canvas');
    _defineProperty(this, "borderFactorHori", 0.7);
    //70 % des screens soll von der Planung ausgefüllt werden
    _defineProperty(this, "borderFactorVert", 0.64);
    //70 % des screens soll von der Planung ausgefüllt werden
    _defineProperty(this, "maxZoom", 4);
    _defineProperty(this, "deltaRotDeg", void 0);
    _defineProperty(this, "inDragMode", false);
    _defineProperty(this, "currZoomFactor", 1);
    _defineProperty(this, "currCenteringOffset", new Vector2(0, 0));
    //This saves the offset value that is used for centerings the whole set
    _defineProperty(this, "zoomFactorBBoxDimLastFrame", new Vector2(0, 0));
    //Saves the bbox from the last update zoom factor. Only zoom if dimension is bigger than 15 cm.
    _defineProperty(this, "plannerPaletteViewInfo", void 0);
    _defineProperty(this, "settingsState", void 0);
    //methods from outside-------------------------------------------------------------------
    _defineProperty(this, "getConfiguratorState", void 0);
    _defineProperty(this, "updatePlannerTrans", void 0);
    _defineProperty(this, "getPlannerElementById", void 0);
    _defineProperty(this, "getPlannerViewConfig", void 0);
    _defineProperty(this, "forceViewToEnterPlannerMode", void 0);
    /**
     * This function is called when the dragging of an element on the 2D Grid has started. If the configurator is not in planner mode - switch to planner mode.
     */
    //----------------------------------------------User Interaction (Dragging and Rotation)--------------------------------------------------\\
    /**
     *
     * This function is called when a drag start is detected. The whole system is set up to detect drag movement on a shape.
     */
    _defineProperty(this, "onDragStarted", function (setId, elementId) {
      _this.inDragMode = true;
      LOG.debug('On Drag Started');
      if (!['PLANNER', 'PRODUCTS', 'PROMOTED', 'ACC_PLANNER', 'PLANNER_2.0'].includes(_this.getConfiguratorState())) {
        //Inform view to switch to planenr mode
        _this.forceViewToEnterPlannerMode(true);
      }
      var element = _this.getPlannerElementById(setId, elementId);
      if (element) _this.updatePlannerTrans(setId, elementId, new Vector3(0, 0, 0), 0, 0, 'START', _this.autoDockingDistance);
    });
    /**
     * This function is calledn when the Element is currently dragged on the 2D Grid.
     * The moving Information is updated in the logic
     * @param setId
     * @param elementId
     * @param deltaMoveOnScreen
     */
    _defineProperty(this, "onDragMove", function (setId, elementId, deltaMoveOnScreen) {
      var element = _this.getPlannerElementById(setId, elementId);
      if (element) {
        _this.updatePlannerTrans(setId, elementId, new Vector3(deltaMoveOnScreen.x / _this.currZoomFactor, 0, deltaMoveOnScreen.y / _this.currZoomFactor), 0, 45, 'UPDATE', _this.autoDockingDistance);
      }
    });
    /**
     * This function is called when the Element has stopped being dragged
     * @param setId
     * @param elementId
     */
    _defineProperty(this, "onDragEnd", function (setId, elementId) {
      LOG.debug('On Drag END');
      _this.inDragMode = false;
      _this.updatePlannerTrans(setId, elementId, new Vector3(0, 0, 0), 0, 0, 'END', _this.autoDockingDistance);
    });
    _defineProperty(this, "resetSelectedElementsOnEnterPlannerMode", function () {
      return false;
    });
    /**
     * Converts the current planning into a base64 JPG string
     */
    _defineProperty(this, "getContentAsJPG", function () {
      if (_this.canvas) {
        var oldCanvasBackground = _this.canvas.backgroundColor;
        var oldCanvasWidth = _this.canvas.width;
        var oldCanvasHeight = _this.canvas.height;
        _this.canvas.backgroundColor = '#fff';
        var objectsOnCanvas = _this.canvas.getObjects();
        var textWidthObj = undefined;
        var textHeightObj = undefined;
        for (var i = 0; i < objectsOnCanvas.length; i++) {
          var groupObj = objectsOnCanvas[i];
          if (groupObj.name == _this.dimGroupHeightName || groupObj.name == _this.dimGroupWidthName) {
            groupObj.dirty = true;
            for (var j = 0; j < groupObj.getObjects().length; j++) {
              if (groupObj.getObjects()[j].type == 'text') {
                var textObj = groupObj.getObjects()[j];
                if (groupObj.name == _this.dimGroupHeightName) textHeightObj = textObj;else if (groupObj.name == _this.dimGroupWidthName) textWidthObj = textObj;
              }
            }
            //groupObj.bringToFront();
          }
        }
        var oldFontWidth = 0;
        var oldFontWidthTop = 0;
        var oldFontHeight = 0;
        var fontSize = 30;
        var deltaDistDont = 13;
        var doMake2DImgSmaller = false;
        if (_this.canvas.width && _this.canvas.width < 500) {
          fontSize = 17;
          deltaDistDont = 7;
          doMake2DImgSmaller = true;
        }
        if (textWidthObj != undefined) {
          oldFontWidth = textWidthObj.fontSize;
          oldFontWidthTop = textWidthObj.top;
          textWidthObj.fontSize = fontSize;
          textWidthObj.dirty = true;
          textWidthObj.top = textWidthObj.top + deltaDistDont;
        }
        if (textHeightObj != undefined) {
          oldFontHeight = textHeightObj.fontSize;
          textHeightObj.fontSize = fontSize;
          textHeightObj.dirty = true;
        }
        LOG.debug('This.canvas.width: ' + _this.canvas.width + '; this.canvas.height: ' + _this.canvas.height);
        if (_this.canvas.width && doMake2DImgSmaller) _this.canvas.setWidth(_this.canvas.width * 1.15);
        if (_this.canvas.height && doMake2DImgSmaller) _this.canvas.setHeight(_this.canvas.height * 1.15);
        _this.canvas.renderAll();
        var dataURL = _this.canvas.toDataURL({
          format: 'jpeg',
          quality: 0.8
        });
        if (textWidthObj != undefined) {
          textWidthObj.fontSize = oldFontWidth;
          textWidthObj.top = oldFontWidthTop;
          textWidthObj.group.dirty = true;
        }
        if (textHeightObj != undefined) {
          textHeightObj.fontSize = oldFontHeight;
          textHeightObj.group.dirty = true;
        }
        _this.canvas.backgroundColor = oldCanvasBackground;
        if (oldCanvasWidth) _this.canvas.setWidth(oldCanvasWidth);
        if (oldCanvasHeight) _this.canvas.setHeight(oldCanvasHeight);
        _this.canvas.renderAll();
        return dataURL;
      }
      return '';
    });
    this.getConfiguratorState = getConfiguratorState;
    this.getPlannerElementById = getPlannerElementById;
    this.getPlannerViewConfig = getPlannerViewConfig;
    this.forceViewToEnterPlannerMode = forceViewToEnterPlannerMode;
    this.updatePlannerTrans = undefined;
    this.deltaRotDeg = this.getPlannerViewConfig().deltaRotDeg2D;
    this.plannerPaletteViewInfo = plannerPaletteViewInfo;
    this.settingsState = settingsState;
  }

  /**
   * Method used for initializing the 3D Grid. All necessary document Elements are created.
   * @param updatePlannerTrans
   */
  return _createClass(Planner2DGrid, [{
    key: "initialize",
    value: function initialize(updatePlannerTrans) {
      this.updatePlannerTrans = updatePlannerTrans;
      if (!this.canvas) {
        this.canvas = new fabric.Canvas(this.canvas2DGridID);
      } else {
        if (this.canvas) this.canvas.clear();
      }
    }

    //-------------------------------------------------Clean Up---------------------------------------------------------------------------

    /**
     * Clears the 2D Canvas of fabric. It clears both, User Interface elements and Fabric Shapes.
     */
  }, {
    key: "clearView",
    value: function clearView() {
      if (this.canvas) this.canvas.clear();
    }
  }, {
    key: "handleRotation",
    value:
    /**
     * This function is called when clicking on a rotation button. This class knows how big is the angle to rotate the element.
     * It informs the plannerLogic to update the rotation of an element. The planner logic then informs the view with the new rotation value.
     * @param elementId     The element ID of the current selected Element
     * @param direction     The rotation direction
     */

    function handleRotation(setId, elementId, direction) {
      this.updatePlannerTrans(setId, elementId, new Vector3(0, 0, 0), 0, this.deltaRotDeg, 'START', 0);
      switch (direction) {
        case 'CLOCKWISE':
          this.updatePlannerTrans(setId, elementId, new Vector3(0, 0, 0), this.deltaRotDeg, this.deltaRotDeg, 'UPDATE', 0);
          break;
        case 'COUNTERCLOCKWISE':
          this.updatePlannerTrans(setId, elementId, new Vector3(0, 0, 0), -this.deltaRotDeg, this.deltaRotDeg, 'UPDATE', 0);
          break;
      }
      this.updatePlannerTrans(setId, elementId, new Vector3(0, 0, 0), 0, this.deltaRotDeg, 'END', 10);
    }

    /**
     * This function updates all userInterface elments on the 2D Grid.
     * The position Number is rendered, the dimension lines.
     * Furthermore, the trash icon and rotation icons for the current selected elements are rendered.
     * @param plannerElements
     * @param selectedElements
     * @param selectableElements
     * @param setAllElementsSelectable
     * @param selectedDP
     */
  }, {
    key: "updateUI",
    value: function updateUI(plannerUIHandler, allPlannerElementsDict, selectedElementsDict, selectableElementsDict, setAllElementsSelectable) {
      var _this2 = this;
      if (this.inDragMode) return;
      plannerUIHandler.clear2D3DViewerUI();
      LOG.debug('UpdateUI', 'Planner2DGrid');
      allPlannerElementsDict.forEach(function (allPlannedElements, setId) {
        for (var i = 0; i < allPlannedElements.length; i++) {
          if (allPlannedElements[i].getSVGShapeOLF2D()) {
            var plannerElement = allPlannedElements[i];
            var elementIsSelected = false;
            var elementIsSelectable = setAllElementsSelectable;
            if (selectedElementsDict.has(setId)) {
              var selectedElements = selectedElementsDict.get(setId);
              for (var j = 0; j < selectedElements.length; j++) {
                if (plannerElement.getElementId() == selectedElements[j].getElementId()) {
                  elementIsSelected = true;
                  break;
                }
              }
            }
            if (!elementIsSelected && !elementIsSelectable) {
              if (selectableElementsDict.has(setId)) {
                var selectableElements = selectableElementsDict.get(setId);
                for (var j = 0; j < selectableElements.length; j++) {
                  if (plannerElement.getElementId() == selectableElements[j].getElementId()) {
                    elementIsSelectable = true;
                    break;
                  }
                }
              }
            }
            _this2.addPosNrUI(plannerUIHandler, plannerElement, elementIsSelected, elementIsSelectable);
            _this2.addDPUI(plannerUIHandler, plannerElement);
            if (elementIsSelected) {
              if (['PLANNER', 'PRODUCTS', 'PROMOTED', 'PLANNER_2.0'].includes(_this2.getConfiguratorState())) {
                _this2.addDelIcon(plannerUIHandler, plannerElement);
                _this2.addRotIcon(plannerUIHandler, plannerElement);
              }
              _this2.addElemOutline(plannerUIHandler, plannerElement, true, false);
            } else if (elementIsSelectable) {
              _this2.addElemOutline(plannerUIHandler, plannerElement, false, true);
            }
            if (_this2.getConfiguratorState() == 'ACC_PLANNER' && (plannerElement.getIsDockedAccessoire() || plannerElement.getIsNotDockedAccessoire())) {
              _this2.addDelIcon(plannerUIHandler, plannerElement);
            }
          }
        }
      });
    }

    /**
     * Returns the world corner to use for positioning UI elements.
     * @param plannerElement
     * @param useOltCorner  When true: OLT corner (for outline/draggable bbox with OLT dimensions).
     *                      When false: corner aligned with displayed shape (OLF when HasOLFPolygon, for posNr/trash/DPs).
     */
  }, {
    key: "getWorldCorner",
    value: function getWorldCorner(plannerElement, useOltCorner) {
      if (useOltCorner && plannerElement.HasOLFPolygon) return plannerElement.WorldPosCornerIgnoreOLF;
      if (!useOltCorner && plannerElement.HasOLFPolygon) return plannerElement.getWorldPosCornerOLF();
      return plannerElement.getWorldPosCorner();
    }

    /**
     * This function adds a full transparent outline div Element over the fabric elements.
     * The function distinguishes between the outline of the current selected element and the rest.
     * The outline of the current selected element is draggable and the outline of the rest is selectable.
     * @param plannerElement    The current selected Element
     * @param isSelected
     */
  }, {
    key: "addElemOutline",
    value: function addElemOutline(plannerUIHandler, plannerElement, isSelected, isSelectable) {
      if (plannerElement.getIsDockedAccessoire() && this.getConfiguratorState() !== 'ACC_PLANNER') return;
      var cornerO = this.getWorldCorner(plannerElement, true);
      var outlineW = plannerElement.getWidth();
      var outlineD = plannerElement.getDepth();
      var screenPosElem = this.worldPosToScreenPos(new Vector2(cornerO.x, cornerO.z));
      plannerUIHandler.addElemOutlineUI(plannerElement.getSetId(), plannerElement.getElementId(), plannerElement.getRotDeg(), screenPosElem, new Vector2(Math.round(outlineW * this.currZoomFactor), Math.round(outlineD * this.currZoomFactor)), this.getIconState(isSelected, isSelectable), this.onDragStarted, this.onDragMove, this.onDragEnd, '2D');
    }
  }, {
    key: "getIconState",
    value: function getIconState(elementIsSelected, elementIsSelectable) {
      if (elementIsSelected) return 'selected';
      if (elementIsSelectable) return 'selectable';
      return 'unselectable';
    }

    /**
     * Computes the position of the position number of the element.
     * @param plannerElement
     * @param elementIsSelected
     * @param elementIsSelectable
     */
  }, {
    key: "addPosNrUI",
    value: function addPosNrUI(viewPlannerUI, plannerElement, elementIsSelected, elementIsSelectable) {
      var _viewPlannerUI$getPos;
      if (plannerElement.getIsDockedAccessoire() && this.getConfiguratorState() !== 'ACC_PLANNER') return;
      var configuration = this.getPlannerViewConfig();
      var screenPosElem = new Vector2(0, 0, 'pixel');
      if (configuration.posNumIcon == 'TOP_LEFT_BACK') {
        var cornerP = this.getWorldCorner(plannerElement, false);
        screenPosElem = this.worldPosToScreenPos(new Vector2(cornerP.x, cornerP.z));
      }
      viewPlannerUI.addPosNrUI(plannerElement.getSetId(), plannerElement.getElementId(), plannerElement.getIsDockedAccessoire(), screenPosElem, plannerElement.getRotDeg(), this.currZoomFactor, (_viewPlannerUI$getPos = viewPlannerUI.getPosNrByBasketId(plannerElement.getBasketId())) === null || _viewPlannerUI$getPos === void 0 ? void 0 : _viewPlannerUI$getPos.toString(), this.getIconState(elementIsSelected, elementIsSelectable), '2D');
    }

    /**
     *This function adds the trash symbol to the 2D planner
     * @param plannerElement    The current selected elemet.
     * @param screenPosPosNr    If the trash icon has to be placed over the posNum icon - this param holds all necessary information over the position and size of the posNum Icon
     */
  }, {
    key: "addDelIcon",
    value: function addDelIcon(plannerUIHandler, plannerElement) {
      if (plannerElement.getIsDockedAccessoire() && this.getConfiguratorState() != 'ACC_PLANNER') return;
      var screenPos = new Vector2(0, 0);
      var cornerD = this.getWorldCorner(plannerElement, false);
      var screenPosElem = this.worldPosToScreenPos(new Vector2(cornerD.x, cornerD.z));
      switch (this.getPlannerViewConfig().posTrashRotIcon) {
        case 'POSNUM_TOP':
          screenPos = screenPosElem;
          break;
        case 'TOP_RIGHT_BACK':
          var offsetVec = new Vector2(plannerElement.getWidth() * this.currZoomFactor, 0);
          offsetVec = Vector2.rotateOrigin(offsetVec, plannerElement.getRotDeg());
          screenPos = new Vector2(screenPosElem.x + offsetVec.x, screenPosElem.y + offsetVec.y);
          break;
      }
      plannerUIHandler.addTrashIconUI(plannerElement.getSetId(), plannerElement.getElementId(), plannerElement.getRotDeg(), screenPos, '2D');
    }

    /**
     * This function is used to add the rotation icon to the 2D Grid.
     * @param plannerElement    The current selected planner Element
     * @param screenPosPosNr    The information of the position and size of the posNr Icon
     * @param screenPosTrashIcon    The information about position and size of the trash Icon
     */
  }, {
    key: "addRotIcon",
    value: function addRotIcon(plannerUIHandler, plannerElement) {
      if (!plannerElement.getIsDockedAccessoire() || plannerElement.getIsNotDockedAccessoire()) {
        plannerUIHandler.addRotationIconUI(plannerElement.getSetId(), plannerElement.getElementId(), plannerElement.getRotDeg(), 'RotateC', new Vector2(0, 0), '2D');
        plannerUIHandler.addRotationIconUI(plannerElement.getSetId(), plannerElement.getElementId(), plannerElement.getRotDeg(), 'RotateCC', new Vector2(0, 0), '2D');
      }
    }

    /**
     * This function adds all Docking Point user interfaces to the 2D Grid
     * @param plannerElement    The current selected planner element
     * @param selectedDP        This parameter is null when no DP is selected. If a DP is selected it is rendered in another optic.
     */
  }, {
    key: "addDPUI",
    value: function addDPUI(plannerUIHandler, plannerElement) {
      var allFreeDPs = plannerElement.getAllDockingPoints();
      for (var i = 0; i < allFreeDPs.length; i++) {
        var _this$plannerPaletteV;
        var dp = allFreeDPs[i];
        if ((_this$plannerPaletteV = this.plannerPaletteViewInfo) !== null && _this$plannerPaletteV !== void 0 && (_this$plannerPaletteV = _this$plannerPaletteV.plannerConfiguration.hideAVButtons) !== null && _this$plannerPaletteV !== void 0 && _this$plannerPaletteV.includes(dp.Type)) continue;
        if (!dp.IsDocking && (dp.Type == 'AVR' || dp.Type == 'AVL')) {
          var corner = this.getWorldCorner(plannerElement, false);
          var screenPosDP = this.worldPosToScreenPos(new Vector2(corner.x + dp.LocalWorldPos.x, corner.z + dp.LocalWorldPos.z));
          var rotCenter = this.worldPosToScreenPos(new Vector2(corner.x, corner.z));
          screenPosDP = Vector2.rotateAround(screenPosDP, rotCenter, plannerElement.getRotDeg());
          plannerUIHandler.addDP(plannerElement.getSetId(), plannerElement.getElementId(), dp.DpId, dp.Type, 'NOT_DOCKING', undefined, plannerElement.getRotDeg(), dp.RotDeg, screenPosDP, '2D');
        } else if ((dp.Type == 'AVO' || dp.Type == 'AVU' || dp.Type == 'AVC' || dp.Type == 'AVN' || dp.Type == 'AVS') && (!dp.IsDocking || !plannerElement.getIsDockedAccessoire())) {
          if (!['PLANNER', 'PRODUCTS', 'PROMOTED', 'PLANNER_2.0'].includes(this.getConfiguratorState())) continue;
          var cornerAcc = this.getWorldCorner(plannerElement, false);
          var _screenPosDP = this.worldPosToScreenPos(new Vector2(cornerAcc.x + dp.LocalWorldPos.x, cornerAcc.z + dp.LocalWorldPos.z));
          var _rotCenter = this.worldPosToScreenPos(new Vector2(cornerAcc.x, cornerAcc.z));
          _screenPosDP = Vector2.rotateAround(_screenPosDP, _rotCenter, plannerElement.getRotDeg());
          plannerUIHandler.addDP(plannerElement.getSetId(), plannerElement.getElementId(), dp.DpId, 'ACC', dp.IsDocking ? 'DOCKING' : 'NOT_DOCKING', dp.OnElementId, plannerElement.getRotDeg(), dp.RotDeg, _screenPosDP, '2D');
        }
      }
    }

    /**
     * This function computes the current zoom factor. This depends on the bounding box information of the current planning and its world position
     * @param boundingBox       The bounding box that holds size and position information of the planning
     */
  }, {
    key: "calcZoomFactor",
    value: function calcZoomFactor(boundingBox) {
      var factor = 1;
      var aspectRatioBBox = boundingBox.size.x / boundingBox.size.z;
      var height = this.canvas.getHeight() - 62;
      var aspectRatioScreen = this.canvas.getWidth() / height;
      if (aspectRatioBBox >= aspectRatioScreen) {
        factor = this.canvas.getWidth() * this.borderFactorHori / boundingBox.size.x;
        //Sometimes there are problems with the height when the screen is not high enough. This causes the dimension lines to overlap with the navigation icons on the ground.
        //Therefore check if it is enough space up and down
        LOG.debug('ATTENTION: ' + (height - boundingBox.size.z * DivaUtils.UnitRecalc / factor));
      } else {
        factor = height * this.borderFactorVert / boundingBox.size.z;
      }

      //Do not change the zoom if it only changes a little bit (e.g. when changing the size of an arm rest)
      if (Math.abs(boundingBox.size.x - this.zoomFactorBBoxDimLastFrame.x) < 0.01 && Math.abs(boundingBox.size.z - this.zoomFactorBBoxDimLastFrame.y) < 0.01) this.currZoomFactor = factor;else if (Math.abs(boundingBox.size.z - this.zoomFactorBBoxDimLastFrame.y) > 30 || Math.abs(boundingBox.size.x - this.zoomFactorBBoxDimLastFrame.x) > 30) this.currZoomFactor = factor;
      this.zoomFactorBBoxDimLastFrame = new Vector2(boundingBox.size.x, boundingBox.size.z);
    }

    /**
     * This function corrects the background position of the 2D grid. It is important that the world point 0/0 is always on the same position on the 2D grid.
     */
  }, {
    key: "correctBackgroundPos",
    value: function correctBackgroundPos(plannerUIHandler) {
      plannerUIHandler.update2DGridBackground({
        zoom: this.currZoomFactor,
        position: new Vector2(this.currCenteringOffset.x / this.currZoomFactor, this.currCenteringOffset.y / this.currZoomFactor)
      });
    }

    /**
     * This function computes the correct position on the screen based on a world position
     * @param worldPos  The world Position in 2D
     */
  }, {
    key: "worldPosToScreenPos",
    value: function worldPosToScreenPos(worldPos) {
      var screenPos = new Vector2(worldPos.x * this.currZoomFactor, worldPos.y * this.currZoomFactor);
      screenPos.x += this.currCenteringOffset.x;
      screenPos.y += this.currCenteringOffset.y;
      return screenPos;
    }

    /**
     * This function computes the dimension lines in 2D (horizontal and vertical)
     * @param setGroup      Set Group that contains all fabricShapes
     * @param boundingBox   Size and position information of the whole planning
     */
  }, {
    key: "drawDimensions",
    value: function drawDimensions(setGroup, boundingBox) {
      if (boundingBox.size.x == 0 || boundingBox.size.z == 0) return;
      var marginW = 25;
      var marginH = 25;
      var arrowSize = 10;
      var angle = 0,
        dimensionGroup = null,
        line = null,
        text = null;
      var sizeWidth = setGroup.width * this.currZoomFactor;
      var sizeHeight = setGroup.height * this.currZoomFactor;
      //if(debugGrid) debug("size: " + size.x + "  " + size.y + "  " + size.z);

      var textW = 0;
      var textH = 0;
      if (boundingBox.digitsAfterComma == 0 || boundingBox.digitsAfterComma == undefined) {
        textW = Math.round(boundingBox.size.x);
        textH = Math.round(boundingBox.size.z);
      } else if (boundingBox.digitsAfterComma == 1) {
        textW = Math.round(boundingBox.size.x * 10) / 10;
        textH = Math.round(boundingBox.size.z * 10) / 10;
      } else if (boundingBox.digitsAfterComma == 2) {
        textW = Math.round(boundingBox.size.x * 100) / 100;
        textH = Math.round(boundingBox.size.z * 100) / 100;
      } else if (boundingBox.digitsAfterComma == 3) {
        textW = Math.round(boundingBox.size.x * 1000) / 1000;
        textH = Math.round(boundingBox.size.z * 1000) / 1000;
      } else if (boundingBox.digitsAfterComma == 4) {
        textW = Math.round(boundingBox.size.x * 10000) / 10000;
        textH = Math.round(boundingBox.size.z * 10000) / 10000;
      }
      var lineOpts = {
        originX: 'center',
        originY: 'center',
        stroke: 'grey',
        strokeWidth: 1
      };
      dimensionGroup = new fabric.Group([], {
        name: this.dimGroupHeightName,
        originX: 'left',
        originY: 'top',
        width: 100,
        angle: angle,
        left: setGroup.left - 50,
        //substract the width for correct visualization
        top: setGroup.top,
        height: sizeHeight,
        hasControls: false,
        hasBorders: false,
        selectable: false,
        lockRotation: true,
        lockMovementX: true,
        lockMovementY: true,
        lockUniScaling: true,
        lockScalingX: true,
        lockScalingY: true,
        hoverCursor: 'default'
      });
      var line;
      line = new fabric.Line([-marginH, -sizeHeight / 2, -marginH, sizeHeight / 2], lineOpts);
      dimensionGroup.add(line);
      line = new fabric.Line([-marginH, -sizeHeight / 2, -marginH + arrowSize / 2, -sizeHeight / 2 + arrowSize], lineOpts);
      dimensionGroup.add(line);
      line = new fabric.Line([-marginH, -sizeHeight / 2, -marginH - arrowSize / 2, -sizeHeight / 2 + arrowSize], lineOpts);
      dimensionGroup.add(line);
      line = new fabric.Line([-marginH, sizeHeight / 2, -marginH + arrowSize / 2, sizeHeight / 2 - arrowSize], lineOpts);
      dimensionGroup.add(line);
      line = new fabric.Line([-marginH, sizeHeight / 2, -marginH - arrowSize / 2, sizeHeight / 2 - arrowSize], lineOpts);
      dimensionGroup.add(line);
      text = new fabric.Text(textH + ' cm', {
        stroke: 'grey',
        angle: -90,
        fontSize: 19,
        fontFamily: 'sans-serif',
        left: -marginH - 3,
        top: 0,
        originX: 'center',
        originY: 'bottom'
      });
      dimensionGroup.add(text);
      this.canvas.add(dimensionGroup);
      dimensionGroup.bringToFront();
      dimensionGroup = new fabric.Group([], {
        name: this.dimGroupWidthName,
        originX: 'left',
        originY: 'top',
        angle: angle,
        left: setGroup.left,
        top: setGroup.top + sizeHeight,
        width: sizeWidth,
        height: 100,
        hasControls: false,
        hasBorders: false,
        selectable: false,
        lockRotation: true,
        lockMovementX: true,
        lockMovementY: true,
        lockUniScaling: true,
        lockScalingX: true,
        lockScalingY: true,
        hoverCursor: 'default'
      });
      line = new fabric.Line([-sizeWidth / 2, -marginW, sizeWidth / 2, -marginW], lineOpts);
      dimensionGroup.add(line);
      line = new fabric.Line([-sizeWidth / 2, -marginW, -sizeWidth / 2 + arrowSize, -marginW + arrowSize / 2], lineOpts);
      dimensionGroup.add(line);
      line = new fabric.Line([-sizeWidth / 2, -marginW, -sizeWidth / 2 + arrowSize, -marginW - arrowSize / 2], lineOpts);
      dimensionGroup.add(line);
      line = new fabric.Line([sizeWidth / 2, -marginW, sizeWidth / 2 - arrowSize, -marginW + arrowSize / 2], lineOpts);
      dimensionGroup.add(line);
      line = new fabric.Line([sizeWidth / 2, -marginW, sizeWidth / 2 - arrowSize, -marginW - arrowSize / 2], lineOpts);
      dimensionGroup.add(line);
      text = new fabric.Text(textW + ' cm', {
        stroke: 'grey',
        fontSize: 19,
        fontFamily: 'sans-serif',
        left: 0,
        top: -marginW + 24,
        originX: 'center',
        originY: 'bottom'
      });
      dimensionGroup.add(text);
      this.canvas.add(dimensionGroup);
      dimensionGroup.bringToFront();
    }

    /**
     * This function is called in order to render the whole canvas with all planner shapes. First it cleans everything and then it updates everything.
     * @param plannerElements   All planner elements in the scene
     * @param boundingBox       The size and position information of the current planning
     */
  }, {
    key: "updatePlannerView",
    value: function updatePlannerView(plannerUIHandler, plannerElementsDict, boundingBox) {
      var _this3 = this;
      LOG.debug('UpdatePlanner2DGrid', 'Planner2DGrid');
      this.clearView();
      var curCanvasSize = plannerUIHandler.getCanvas2DGridSize();
      if (this.canvas.getWidth() != curCanvasSize.x) this.canvas.setWidth(curCanvasSize.x);
      if (this.canvas.getHeight() != curCanvasSize.y) this.canvas.setHeight(curCanvasSize.y);
      if (plannerElementsDict.size == 0) return;
      var allplannerSVGs = [];
      plannerElementsDict.forEach(function (plannerElements, setId) {
        for (var i = 0; i < plannerElements.length; i++) {
          if (plannerElements[i].getSVGShapeOLF2D()) {
            var svgShape2D = plannerElements[i].getSVGShapeOLF2D();
            svgShape2D.scaleX = 1 / DivaUtils.UnitRecalc;
            svgShape2D.scaleY = 1 / DivaUtils.UnitRecalc;
            var corner = _this3.getWorldCorner(plannerElements[i], false);
            svgShape2D.left = corner.x - boundingBox.worldPos.x;
            svgShape2D.top = corner.z - boundingBox.worldPos.y;
            svgShape2D.angle = plannerElements[i].getRotDeg();
            allplannerSVGs.push(svgShape2D);
          }
        }
      });
      this.calcZoomFactor(boundingBox);
      if (this.currZoomFactor > this.maxZoom) this.currZoomFactor = this.maxZoom;
      var screenPosSet = new Vector2(boundingBox.worldPos.x * this.currZoomFactor, boundingBox.worldPos.y * this.currZoomFactor);
      var setGroup = new fabric.Group(allplannerSVGs, {
        originX: 'left',
        originY: 'top',
        left: screenPosSet.x,
        top: screenPosSet.y,
        opacity: 1,
        scaleX: this.currZoomFactor,
        scaleY: this.currZoomFactor,
        hasControls: false,
        selectable: false,
        hoverCursor: 'default'
      });
      var offsetX = this.canvas.getWidth() / 2 - (setGroup.left + setGroup.width * this.currZoomFactor / 2);
      var offsetY = this.canvas.getHeight() / 2 - (setGroup.top + setGroup.height * this.currZoomFactor / 2);
      this.currCenteringOffset = new Vector2(offsetX, offsetY);
      setGroup.left += offsetX;
      setGroup.top += offsetY;
      this.canvas.add(setGroup);
      setGroup.bringToFront();
      this.correctBackgroundPos(plannerUIHandler);
      this.drawDimensions(setGroup, boundingBox);
      this.canvas.renderAll();
    }
  }]);
}();

export { Planner2DGrid as default };
