"use strict";

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

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

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

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

var _Extent = _interopRequireDefault(require("../Core/Geographic/Extent"));

var uid = 0;
/**
 * @classdesc
 * Sources are object containing informations on how to fetch resources, from a
 * set source.
 *
 * To extend a Source, it is necessary to implement two functions:
 * `urlFromExtent` and `extentInsideLimit`.
 *
 * @property {boolean} isSource - Used to checkout whether this source is a
 * Source. Default is true. You should not change this, as it is used internally
 * for optimisation.
 * @property {number} uid - Unique uid mainly used to store data linked to this
 * source into Cache.
 * @property {string} url - The url of the resources that are fetched.
 * @property {string} format - The format of the resources that are fetched.
 * @property {function} fetcher - The method used to fetch the resources from
 * the source. iTowns provides some methods in {@link Fetcher}, but it can be
 * specified a custom one. This method should return a `Promise` containing the
 * fetched resource. If this property is set, it overrides the chosen fetcher
 * method with `format`.
 * @property {Object} networkOptions - Fetch options (passed directly to
 * `fetch()`), see [the syntax for more information]{@link
 * https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Syntax}.
 * By default, set to `{ crossOrigin: 'anonymous' }`.
 * @property {string} projection - The projection of the resources.
 * @property {string} attribution - The intellectual property rights for the
 * resources.
 * @property {Extent} extent - The extent of the resources.
 * @property {function} parser - The method used to parse the resources attached
 * to the layer. iTowns provides some parsers, visible in the `Parser/` folder.
 * If the method is custom, it should return a `Promise` containing the parsed
 * resource. If this property is set, it overrides the default selected parser
 * method with `source.format`. If `source.format` is also empty, no parsing
 * action is done.
 * <br><br>
 * When calling this method, two parameters are passed:
 * <ul>
 *  <li>the fetched data, i.e. the data to parse</li>
 *  <li>an object containing severals properties, set when this method is
 *  called: it is specific to each call, so the value of each property can vary
 *  depending on the current fetched tile for example</li>
 * </ul>
 *
 * The properties of the second parameter are:
 * <ul>
 *  <li>`buildExtent : boolean` - True if the layer does not inherit from {@link
 *  GeometryLayer}.</li>
 *  <li>`crsIn : string` - The projection of the source.</li>
 *  <li>`crsOut : string` - The projection of the layer.</li>
 *  <li>`filteringExtent : Extent` - If the layer inherits from {@link
 *  GeometryLayer}, it is set to the extent of destination, otherwise it is
 *  undefined.</li>
 *  <li>`filter : function` - Property of the layer.</li>
 *  <li>`mergeFeatures : boolean (default true)` - Property of the layer,
 *  default to true.</li>
 *  <li>`withNormal : boolean` - True if the layer inherits from {@link
 *  GeometryLayer}.</li>
 *  <li>`withAltitude : boolean` - True if the layer inherits from {@link
 *  GeometryLayer}.</li>
 *  <li>`isInverted : string` - Property of the source.</li>
 * </ul>
 */

var Source =
/*#__PURE__*/
function () {
  /**
   * @param {Object} source - An object that can contain all properties of a
   * Source. Only the `url` property is mandatory.
   *
   * @constructor
   */
  function Source(source) {
    (0, _classCallCheck2["default"])(this, Source);
    this.isSource = true;

    if (!source.url) {
      throw new Error('New Source: url is required');
    }

    this.uid = uid++;
    this.url = source.url;
    this.format = source.format;
    this.fetcher = source.fetcher;
    this.parser = source.parser;
    this.networkOptions = source.networkOptions || {
      crossOrigin: 'anonymous'
    };
    this.projection = source.projection;
    this.attribution = source.attribution;

    if (source.extent && !(source.extent instanceof _Extent["default"])) {
      this.extent = new _Extent["default"](this.projection, source.extent);
    } else {
      this.extent = source.extent;
    }
  }

  (0, _createClass2["default"])(Source, [{
    key: "handlingError",
    value: function handlingError(err) {
      console.warn("err ".concat(this), err);
    }
    /**
     * Generates an url from an extent. This url is a link to fetch the
     * resources inside the extent.
     *
     * @param {Extent} extent - Extent to convert in url.
      * @return {string} The URL constructed from the extent.
     */
    // eslint-disable-next-line

  }, {
    key: "urlFromExtent",
    value: function urlFromExtent() {
      throw new Error('In extended Source, you have to implement the method urlFromExtent!');
    }
    /**
     * Tests if an extent is inside the source limits.
     *
     * @param {Extent} extent - Extent to test.
      * @return {boolean} True if the extent is inside the limit, false otherwise.
     */
    // eslint-disable-next-line

  }, {
    key: "extentInsideLimit",
    value: function extentInsideLimit() {
      throw new Error('In extented Source, you have to implement the method extentInsideLimit!');
    }
    /**
     * Tests if an array of extents is inside the source limits.
     *
     * @param {Array.<Extent>} extents - Array of extents to test.
      * @return {boolean} True if all extents are inside, false otherwise.
     */

  }, {
    key: "extentsInsideLimit",
    value: function extentsInsideLimit(extents) {
      var _iteratorNormalCompletion = true;
      var _didIteratorError = false;
      var _iteratorError = undefined;

      try {
        for (var _iterator = extents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
          var extent = _step.value;

          if (!this.extentInsideLimit(extent)) {
            return false;
          }
        }
      } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion && _iterator["return"] != null) {
            _iterator["return"]();
          }
        } finally {
          if (_didIteratorError) {
            throw _iteratorError;
          }
        }
      }

      return true;
    }
  }]);
  return Source;
}();

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