"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
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 _Style = _interopRequireDefault(require("../../Core/Style"));
var _C3DTilesLayer = require("../../Layer/C3DTilesLayer");
var _Widget2 = _interopRequireDefault(require("./Widget"));
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; }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function () { 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; } }
var DEFAULT_OPTIONS = {
  width: 200,
  position: 'top-right'
};

/**
 * A widget for dynamic 3DTiles styling
 *
 * To use it, you need to link the widgets' stylesheet to your html webpage. This stylesheet is included in
 * [itowns bundles](https://github.com/iTowns/itowns/releases) if you downloaded them, or it can be found in
 * `node_modules/itowns/examples/css` if you installed iTowns with npm. Otherwise, it can be found at
 * [this link](https://raw.githubusercontent.com/iTowns/itowns/master/examples/css/widgets.css). See
 * [this example](http://www.itowns-project.org/itowns/examples/#widgets_3dtiles_style) for more details.
 *
 * @extends Widget
 *
 * @property    {HTMLElement}   domElement      An html div containing the minimap.
 * @property    {HTMLElement}   parentElement   The parent HTML container of `this.domElement`.
 */
var C3DTilesStyle = /*#__PURE__*/function (_Widget) {
  (0, _inherits2["default"])(C3DTilesStyle, _Widget);
  var _super = _createSuper(C3DTilesStyle);
  /**
     *
     * @param {View} view view
     * @param {*} options options
     */
  function C3DTilesStyle(view, options) {
    var _this;
    (0, _classCallCheck2["default"])(this, C3DTilesStyle);
    _this = _super.call(this, view, options, DEFAULT_OPTIONS);
    _this.domElement.onclick = function (event) {
      return event.stopImmediatePropagation();
    };

    // create select of the C3DTilesLayers
    var selectC3DTilesLayer = document.createElement('select');
    _this.domElement.appendChild(selectC3DTilesLayer);

    /** @type {Map<HTMLElement, HTMLElement>} */
    var selectOptionLayerContent = new Map();
    var updateSelectedLayer = function () {
      var _iterator = _createForOfIteratorHelper(selectOptionLayerContent),
        _step;
      try {
        for (_iterator.s(); !(_step = _iterator.n()).done;) {
          var _step$value = (0, _slicedToArray2["default"])(_step.value, 2),
            sO = _step$value[0],
            lC = _step$value[1];
          lC.hidden = sO !== selectC3DTilesLayer.selectedOptions[0];
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }
    };
    selectC3DTilesLayer.onchange = updateSelectedLayer;
    view.getLayers().filter(function (el) {
      return el.isC3DTilesLayer === true;
    }).forEach(function (c3DTilesLayer) {
      var selectC3DTilesLayerOption = document.createElement('option');
      selectC3DTilesLayerOption.innerText = c3DTilesLayer.name;
      selectC3DTilesLayer.add(selectC3DTilesLayerOption);
      var layerContent = document.createElement('div');
      _this.domElement.appendChild(layerContent);

      // link select option to layer content
      selectOptionLayerContent.set(selectC3DTilesLayerOption, layerContent);

      // wait for C3DTileFeatures to load
      c3DTilesLayer.addEventListener(_C3DTilesLayer.C3DTILES_LAYER_EVENTS.ON_TILE_CONTENT_LOADED, function () {
        // reset
        while (layerContent.firstChild) {
          layerContent.firstChild.remove();
        }

        /** @type {Map<string,Array>} */
        var buffer = new Map(); // record what are the possible values for a key in batchTable
        // eslint-disable-next-line no-unused-vars
        var _iterator2 = _createForOfIteratorHelper(c3DTilesLayer.tilesC3DTileFeatures),
          _step2;
        try {
          for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
            var _step2$value = (0, _slicedToArray2["default"])(_step2.value, 2),
              tileId = _step2$value[0],
              tileC3DTileFeatures = _step2$value[1];
            // eslint-disable-next-line no-unused-vars
            var _iterator6 = _createForOfIteratorHelper(tileC3DTileFeatures),
              _step6;
            try {
              for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
                var _step6$value = (0, _slicedToArray2["default"])(_step6.value, 2),
                  batchId = _step6$value[0],
                  c3DTileFeature = _step6$value[1];
                // eslint-disable-next-line guard-for-in
                for (var key in c3DTileFeature.getInfo().batchTable) {
                  if (!buffer.has(key)) {
                    buffer.set(key, []);
                  }

                  // check possible value for this key
                  var value = c3DTileFeature.getInfo().batchTable[key];
                  if (!buffer.get(key).includes(value)) {
                    buffer.get(key).push(value);
                  }
                }
              }
            } catch (err) {
              _iterator6.e(err);
            } finally {
              _iterator6.f();
            }
          }

          /** @type {Map<HTMLElement, Function>} */
        } catch (err) {
          _iterator2.e(err);
        } finally {
          _iterator2.f();
        }
        var colorFunctions = new Map();
        var fillColorFunction = function fillColorFunction(c3DTileFeature) {
          var result = null;
          // eslint-disable-next-line no-unused-vars
          var _iterator3 = _createForOfIteratorHelper(colorFunctions),
            _step3;
          try {
            for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
              var _step3$value = (0, _slicedToArray2["default"])(_step3.value, 2),
                keyValue = _step3$value[0],
                colorFunction = _step3$value[1];
              result = colorFunction(c3DTileFeature) || result;
            }
          } catch (err) {
            _iterator3.e(err);
          } finally {
            _iterator3.f();
          }
          return result;
        };

        /** @type {Map<HTMLElement, Function>} */
        var opacityFunctions = new Map();
        var fillOpacityFunction = function fillOpacityFunction(c3DTileFeature) {
          var result = 1;
          // eslint-disable-next-line no-unused-vars
          var _iterator4 = _createForOfIteratorHelper(opacityFunctions),
            _step4;
          try {
            for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
              var _step4$value = (0, _slicedToArray2["default"])(_step4.value, 2),
                keyValue = _step4$value[0],
                opacityFunction = _step4$value[1];
              result = opacityFunction(c3DTileFeature) || result;
            }
          } catch (err) {
            _iterator4.e(err);
          } finally {
            _iterator4.f();
          }
          return result;
        };
        var appendInputColorAndOpacity = function appendInputColorAndOpacity(getKeyValue, key, possibleValues) {
          var inputColor = document.createElement('input');
          inputColor.setAttribute('type', 'color');
          layerContent.appendChild(inputColor);
          inputColor.onchange = function () {
            var keyValue = getKeyValue();
            if (!possibleValues.includes(keyValue)) {
              return;
            }
            var colorSelected = inputColor.value; // copy
            colorFunctions.set(keyValue, function (c3DTileFeature) {
              if (c3DTileFeature.getInfo().batchTable[key] == keyValue) {
                return colorSelected;
              }
              return null;
            });
            c3DTilesLayer.updateStyle();
            view.notifyChange();
          };
          var opacityElement = document.createElement('input');
          opacityElement.setAttribute('type', 'range');
          opacityElement.min = 0;
          opacityElement.max = 1;
          opacityElement.step = 0.1;
          opacityElement.value = 1;
          layerContent.appendChild(opacityElement);
          opacityElement.onchange = function () {
            var keyValue = getKeyValue();
            if (!possibleValues.includes(keyValue)) {
              return;
            }
            var opacitySelected = opacityElement.value; // copy
            opacityFunctions.set(keyValue, function (c3DTileFeature) {
              if (c3DTileFeature.getInfo().batchTable[key] == keyValue) {
                return opacitySelected;
              }
              return null;
            });
            c3DTilesLayer.updateStyle();
            view.notifyChange();
          };
          return {
            inputColor: inputColor,
            opacityElement: opacityElement
          };
        };
        var appendFilterSelect = function appendFilterSelect(key, values) {
          var label = document.createElement('label');
          label.innerText = key;
          layerContent.appendChild(label);
          var selectKey = document.createElement('select');
          layerContent.appendChild(selectKey);
          values.forEach(function (value) {
            var selectKeyOption = document.createElement('option');
            selectKeyOption.value = value;
            selectKeyOption.text = value;
            selectKey.add(selectKeyOption);
          });
          appendInputColorAndOpacity(function () {
            return selectKey.selectedOptions[0].value;
          }, key, values);
        };
        var appendFilterInputText = function appendFilterInputText(key, values) {
          var label = document.createElement('label');
          label.innerText = key;
          layerContent.appendChild(label);
          var inputText = document.createElement('input');
          inputText.setAttribute('type', 'text');
          layerContent.appendChild(inputText);
          var _appendInputColorAndO = appendInputColorAndOpacity(function () {
              return inputText.value;
            }, key, values),
            inputColor = _appendInputColorAndO.inputColor,
            opacityElement = _appendInputColorAndO.opacityElement;
          inputText.onchange = function () {
            if (!values.includes(inputText.value)) {
              return;
            }
            var colorSelected = inputColor.value; // copy
            var textSelected = inputText.value; // copy
            colorFunctions.set(textSelected, function (c3DTileFeature) {
              if (c3DTileFeature.getInfo().batchTable[key] == textSelected) {
                return colorSelected;
              }
              return null;
            });
            var opacitySelected = opacityElement.value; // copy
            opacityFunctions.set(textSelected, function (c3DTileFeature) {
              if (c3DTileFeature.getInfo().batchTable[key] == textSelected) {
                return opacitySelected;
              }
              return null;
            });
            c3DTilesLayer.updateStyle();
            view.notifyChange();
          };
        };

        // create ui from buffer
        var _iterator5 = _createForOfIteratorHelper(buffer),
          _step5;
        try {
          for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
            var _step5$value = (0, _slicedToArray2["default"])(_step5.value, 2),
              _key = _step5$value[0],
              values = _step5$value[1];
            if (values.length < C3DTilesStyle.MAX_SELECT_VALUE) {
              appendFilterSelect(_key, values);
            } else {
              appendFilterInputText(_key, values);
            }
          }

          // set style
        } catch (err) {
          _iterator5.e(err);
        } finally {
          _iterator5.f();
        }
        c3DTilesLayer.style = new _Style["default"]({
          fill: {
            color: fillColorFunction,
            opacity: fillOpacityFunction
          }
        });
      });
    });
    updateSelectedLayer();
    return _this;
  }
  (0, _createClass2["default"])(C3DTilesStyle, null, [{
    key: "MAX_SELECT_VALUE",
    get: function get() {
      return 10;
    }
  }]);
  return C3DTilesStyle;
}(_Widget2["default"]);
var _default = C3DTilesStyle;
exports["default"] = _default;