"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

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

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = exports.EMPTY_TEXTURE_ZOOM = void 0;

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

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

var THREE = _interopRequireWildcard(require("three"));

var _LayeredMaterial = require("./LayeredMaterial");

var _XbilParser = require("../Parser/XbilParser");

var _Crs = _interopRequireDefault(require("../Core/Geographic/Crs"));

function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function () {}; 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 it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, 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; }

var EMPTY_TEXTURE_ZOOM = -1;
exports.EMPTY_TEXTURE_ZOOM = EMPTY_TEXTURE_ZOOM;
var pitch = new THREE.Vector4();

function defineLayerProperty(layer, property, initValue, defaultValue) {
  var _value = initValue !== undefined ? initValue : defaultValue;

  Object.defineProperty(layer, property, {
    get: function get() {
      return _value;
    },
    set: function set(value) {
      if (_value !== value) {
        _value = value;
      }
    }
  });
}

var MaterialLayer = /*#__PURE__*/function () {
  function MaterialLayer(material, layer) {
    var _this = this;

    (0, _classCallCheck2["default"])(this, MaterialLayer);
    this.id = layer.id;
    this.textureOffset = 0; // will be updated in updateUniforms()

    this.crs = layer.parent.tileMatrixSets.indexOf(_Crs["default"].formatToTms(layer.projection));

    if (this.crs == -1) {
      console.error('Unknown crs:', layer.projection);
    } // Define color properties


    var _valueOpacity = layer.opacity !== undefined ? layer.opacity : true;

    Object.defineProperty(this, 'opacity', {
      get: function get() {
        return _valueOpacity;
      },
      set: function set(value) {
        if (_valueOpacity !== value) {
          if (value === 0 || _valueOpacity === 0) {
            _this.material.layersNeedUpdate = true;
          }

          _valueOpacity = value;
        }
      }
    });

    var _valueVisibility = layer.visible !== undefined ? layer.visible : true;

    Object.defineProperty(this, 'visible', {
      get: function get() {
        return _valueVisibility;
      },
      set: function set(value) {
        if (_valueVisibility !== value) {
          _this.material.layersNeedUpdate = true;
          _valueVisibility = value;
        }
      }
    });
    defineLayerProperty(this, 'effect', layer.fx, 0);
    var defaultEle = {
      bias: 0,
      scale: 1,
      mode: _LayeredMaterial.ELEVATION_MODES.DATA,
      zmin: 0,
      zmax: Infinity
    };
    var scaleFactor = 1.0; // Define elevation properties

    if (layer.useRgbaTextureElevation) {
      defaultEle.mode = _LayeredMaterial.ELEVATION_MODES.RGBA;
      defaultEle.zmax = 5000;
      throw new Error('Restore this feature');
    } else if (layer.useColorTextureElevation) {
      scaleFactor = layer.colorTextureElevationMaxZ - layer.colorTextureElevationMinZ;
      defaultEle.mode = _LayeredMaterial.ELEVATION_MODES.COLOR;
      defaultEle.bias = layer.colorTextureElevationMinZ;
    }

    defineLayerProperty(this, 'bias', layer.bias, defaultEle.bias);
    defineLayerProperty(this, 'scale', layer.scale * scaleFactor, defaultEle.scale * scaleFactor);
    defineLayerProperty(this, 'mode', layer.mode, defaultEle.mode);
    defineLayerProperty(this, 'zmin', layer.zmin, defaultEle.zmin);
    defineLayerProperty(this, 'zmax', layer.zmax, defaultEle.zmax);
    this.textures = [];
    this.offsetScales = [];
    this.level = EMPTY_TEXTURE_ZOOM;
    this.material = material;
  }

  (0, _createClass2["default"])(MaterialLayer, [{
    key: "initFromParent",
    value: function initFromParent(parent, extents) {
      if (parent && parent.level > this.level) {
        var index = 0;

        var _iterator = _createForOfIteratorHelper(extents),
            _step;

        try {
          for (_iterator.s(); !(_step = _iterator.n()).done;) {
            var c = _step.value;

            var _iterator2 = _createForOfIteratorHelper(parent.textures),
                _step2;

            try {
              for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
                var texture = _step2.value;

                if (c.isInside(texture.extent)) {
                  this.setTexture(index++, texture, c.offsetToParent(texture.extent));
                  break;
                }
              }
            } catch (err) {
              _iterator2.e(err);
            } finally {
              _iterator2.f();
            }
          }
        } catch (err) {
          _iterator.e(err);
        } finally {
          _iterator.f();
        }
      }
    }
  }, {
    key: "replaceNoDataValueFromParent",
    value: function replaceNoDataValueFromParent(parent, nodatavalue) {
      if (nodatavalue == undefined) {
        return;
      }

      var dataElevation = this.textures[0].image.data;
      var parentTexture = parent && parent.textures[0];

      if (dataElevation && parentTexture && !(0, _XbilParser.checkNodeElevationTextureValidity)(dataElevation, nodatavalue)) {
        var extent = this.textures[0].extent;
        extent.offsetToParent(parentTexture.extent, pitch);
        (0, _XbilParser.insertSignificantValuesFromParent)(dataElevation, parentTexture.image.data, nodatavalue, pitch);
      }
    }
  }, {
    key: "dispose",
    value: function dispose() {
      // TODO: WARNING  verify if textures to dispose aren't attached with ancestor
      var _iterator3 = _createForOfIteratorHelper(this.textures),
          _step3;

      try {
        for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
          var texture = _step3.value;

          if (texture.isTexture) {
            texture.dispose();
          }
        }
      } catch (err) {
        _iterator3.e(err);
      } finally {
        _iterator3.f();
      }

      this.level = EMPTY_TEXTURE_ZOOM;
      this.textures = [];
      this.offsetScales = [];
      this.material.layersNeedUpdate = true;
    }
  }, {
    key: "setTexture",
    value: function setTexture(index, texture, offsetScale) {
      this.level = texture && index == 0 ? texture.extent.zoom : this.level;
      this.textures[index] = texture || null;
      this.offsetScales[index] = offsetScale;
      this.material.layersNeedUpdate = true;
    }
  }, {
    key: "setTextures",
    value: function setTextures(textures, pitchs) {
      this.dispose(false);

      for (var i = 0, il = textures.length; i < il; ++i) {
        this.setTexture(i, textures[i], pitchs[i]);
      }
    }
  }]);
  return MaterialLayer;
}();

var _default = MaterialLayer;
exports["default"] = _default;