"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
exports.getHeaderAttribute = getHeaderAttribute;
var THREE = _interopRequireWildcard(require("three"));
var _GeoidGrid = _interopRequireDefault(require("../Core/Geographic/GeoidGrid"));
var _Extent = _interopRequireDefault(require("../Core/Geographic/Extent"));
var _GTXParser = require("./GTXParser");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function getHeaderAttribute(header, attributeName) {
  const attributeRow = header[header.indexOf(header.find(element => element.includes(attributeName)))].split(' ').filter(value => value !== '');
  return parseFloat(attributeRow[attributeRow.length - 1]);
}

/**
 * The `GDFParser` module provides a `[parse]{@link module:GDFParser.parse}` method. This method takes the content of a
 * GDF file in, and returns a `{@link GeoidGrid}`. the `{@link GeoidGrid}` contains all the necessary attributes and
 * methods to access the GDF data in iTowns.
 *
 * @module GDFParser
 */
var _default = {
  /**
   * Parses a GDF file content and returns a corresponding `{@link GeoidGrid}`.
   *
   * @param   {string}    gdf                             The content of the GDF file to parse.
   * @param   {Object}    options                         An object gathering the optional parameters to pass to
                                                          * the parser.
   * @param   {Object}    [options.in={}]                 Information on the GDF data.
   * @param   {string}    [options.in.crs='EPSG:4326']    The Coordinates Reference System (CRS) of the GDF data.
                                                          * It must be a geographic CRS, and must be given as an EPSG
                                                          * code.
   *
   * @returns {Promise<GeoidGrid>}    A promise resolving with a `{@link GeoidGrid}`, which contains all the necessary
                                      * attributes and methods to access GDF file data.
   */
  parse(gdf) {
    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
      in: {}
    };
    const rows = gdf.split('\n');
    const firstMeasureLine = rows.indexOf(rows.find(row => row.includes('end_of_head'))) + 1;
    const rawHeaderData = rows.slice(0, firstMeasureLine);

    // ---------- GET METADATA FROM THE FILE : ----------

    const metadata = {
      minX: getHeaderAttribute(rawHeaderData, 'longlimit_west'),
      maxX: getHeaderAttribute(rawHeaderData, 'longlimit_east'),
      minY: getHeaderAttribute(rawHeaderData, 'latlimit_south'),
      maxY: getHeaderAttribute(rawHeaderData, 'latlimit_north'),
      stepX: getHeaderAttribute(rawHeaderData, 'gridstep'),
      stepY: getHeaderAttribute(rawHeaderData, 'gridstep'),
      nRows: getHeaderAttribute(rawHeaderData, 'latitude_parallels'),
      nColumns: getHeaderAttribute(rawHeaderData, 'longitude_parallels')
    };

    // ---------- BUILD A DATA VIEWER FROM THE TEXT DATA : ----------

    const data = new DataView(new ArrayBuffer(_GTXParser.BYTES_PER_DOUBLE * metadata.nRows * metadata.nColumns));
    let index = 0;
    for (let row of rows.slice(firstMeasureLine, rows.length)) {
      row = row.split(' ').filter(value => value !== '');
      if (!row.length) {
        continue;
      }
      data.setFloat64(index * _GTXParser.BYTES_PER_DOUBLE, parseFloat(row[2]));
      index++;
    }

    // ---------- CREATE A GeoidGrid FOR THE GIVEN FILE DATA : ----------

    const dataExtent = new _Extent.default(options.in.crs || 'EPSG:4326', metadata.minX, metadata.maxX, metadata.minY, metadata.maxY);
    const dataStep = new THREE.Vector2(metadata.stepX, metadata.stepY);
    return Promise.resolve(new _GeoidGrid.default(dataExtent, dataStep, (verticalIndex, horizontalIndex) => data.getFloat64((metadata.nColumns * (metadata.nRows - verticalIndex - 1) + horizontalIndex) * _GTXParser.BYTES_PER_DOUBLE)));
  }
};
exports.default = _default;