"use strict";

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

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

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

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

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 _mapboxGlStyleSpec = require("@mapbox/mapbox-gl-style-spec");

var _Style = _interopRequireDefault(require("../Core/Style"));

var _TMSSource2 = _interopRequireDefault(require("./TMSSource"));

var _Fetcher = _interopRequireDefault(require("../Provider/Fetcher"));

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 { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }

function toTMSUrl(url) {
  return url.replace(/\{/g, '${');
}

function checkStopsValues(obj, target) {
  for (var p in obj) {
    if (obj[p].stops) {
      obj[p].stops.forEach(function (s) {
        return target.push(s[0]);
      });
    }
  }
}
/**
 * @classdesc
 * VectorTilesSource are object containing informations on how to fetch vector
 * tiles resources.
 *
 * @property {function} filter - function to filter vector tiles layers, the
 * parameter function is a layer.
 * @property {boolean} [symbolToCircle=false] - If true, all symbols from a tile
 * will be considered as circle, and render as circles.
 */


var VectorTilesSource = /*#__PURE__*/function (_TMSSource) {
  (0, _inherits2["default"])(VectorTilesSource, _TMSSource);

  var _super = _createSuper(VectorTilesSource);

  /**
   * @param {Object} source - An object that can contain all properties of a
   * VectorTilesSource and {@link Source}.
   * @param {string|Object} source.style - The URL of the JSON style, of the
   * JSON style directly.
   * @param {string} [source.sprite] - The base URL to load informations about
   * the sprite of the style. If this is set, it overrides the `sprite` value
   * of the `source.style`.
   * @param {string} [source.url] - The base URL to load the tiles. If no url
   * is specified, it reads it from the loaded style. Read [the Mapbox Style
   * Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/)
   * for more informations.
   *
   * @constructor
   */
  function VectorTilesSource(source) {
    var _this;

    (0, _classCallCheck2["default"])(this, VectorTilesSource);
    source.format = 'application/x-protobuf;type=mapbox-vector';
    source.crs = 'EPSG:3857';
    source.isInverted = true;
    source.url = source.url || '.';
    _this = _super.call(this, source);

    var ffilter = source.filter || function () {
      return true;
    };

    _this.layers = {};
    _this.styles = {};
    var promise;

    if (source.style) {
      if (typeof source.style == 'string') {
        promise = _Fetcher["default"].json(source.style, _this.networkOptions);
      } else {
        promise = Promise.resolve(source.style);
      }
    } else {
      throw new Error('New VectorTilesSource: style is required');
    }

    _this.whenReady = promise.then(function (style) {
      var baseurl = source.sprite || style.sprite;

      if (baseurl) {
        return _Fetcher["default"].json("".concat(baseurl, ".json"), _this.networkOptions).then(function (sprites) {
          _this.sprites = sprites;
          return _Fetcher["default"].texture("".concat(baseurl, ".png"), _this.networkOptions).then(function (texture) {
            _this.sprites.img = texture.image;
            return style;
          });
        });
      }

      return style;
    }).then(function (style) {
      var s = Object.keys(style.sources)[0];
      var os = style.sources[s];
      style.layers.forEach(function (layer, order) {
        layer.sourceUid = _this.uid;

        if (layer.type === 'background') {
          _this.backgroundLayer = layer;
        } else if (ffilter(layer)) {
          // TODO: add support for expressions
          // https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions
          var stops = [];
          checkStopsValues(layer.layout, stops);
          checkStopsValues(layer.paint, stops);
          var minStop = Math.min.apply(Math, (0, _toConsumableArray2["default"])(stops)); // if none is found, default to 0

          minStop = minStop == Infinity ? 0 : minStop; // compare to layer.minzoom and take the highest

          minStop = layer.minzoom == undefined ? minStop : Math.max(layer.minzoom, minStop);
          stops.push(minStop);
          stops.push(layer.maxzoom == undefined ? 24 : layer.maxzoom);
          stops.sort(function (a, b) {
            return a - b;
          }); // remove all value < minStop

          stops = stops.filter(function (s) {
            return s >= minStop;
          });
          _this.styles[layer.id] = [];

          for (var i = 0; i < stops.length - 1; i++) {
            if (stops[i] == stops[i + 1]) {
              continue;
            }

            var _style = new _Style["default"]();

            _style.zoom.min = stops[i];
            _style.zoom.max = stops[i + 1];

            _style.setFromVectorTileLayer(layer, _this.sprites, order, _this.symbolToCircle);

            _this.styles[layer.id].push(_style);
          }

          if (!_this.layers[layer['source-layer']]) {
            _this.layers[layer['source-layer']] = [];
          }

          _this.layers[layer['source-layer']].push({
            id: layer.id,
            order: order,
            filterExpression: (0, _mapboxGlStyleSpec.featureFilter)(layer.filter),
            zoom: {
              min: stops[0],
              max: stops[stops.length - 1]
            }
          });
        }
      });

      if (_this.url == '.') {
        if (os.url) {
          return _Fetcher["default"].json(os.url, _this.networkOptions).then(function (tileJSON) {
            if (tileJSON.tiles[0]) {
              _this.url = toTMSUrl(tileJSON.tiles[0]);
            }
          });
        } else if (os.tiles[0]) {
          _this.url = toTMSUrl(os.tiles[0]);
        }
      }
    });
    return _this;
  }

  return VectorTilesSource;
}(_TMSSource2["default"]);

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