'use strict';

var length = require('@turf/length');
var lineSliceAlong = require('@turf/line-slice-along');
var meta = require('@turf/meta');
var helpers = require('@turf/helpers');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var length__default = /*#__PURE__*/_interopDefaultLegacy(length);
var lineSliceAlong__default = /*#__PURE__*/_interopDefaultLegacy(lineSliceAlong);

/**
 * Divides a {@link LineString} into chunks of a specified length.
 * If the line is shorter than the segment length then the original line is returned.
 *
 * @name lineChunk
 * @param {FeatureCollection|Geometry|Feature<LineString|MultiLineString>} geojson the lines to split
 * @param {number} segmentLength how long to make each segment
 * @param {Object} [options={}] Optional parameters
 * @param {string} [options.units='kilometers'] units can be degrees, radians, miles, or kilometers
 * @param {boolean} [options.reverse=false] reverses coordinates to start the first chunked segment at the end
 * @returns {FeatureCollection<LineString>} collection of line segments
 * @example
 * var line = turf.lineString([[-95, 40], [-93, 45], [-85, 50]]);
 *
 * var chunk = turf.lineChunk(line, 15, {units: 'miles'});
 *
 * //addToMap
 * var addToMap = [chunk];
 */
function lineChunk(geojson, segmentLength, options) {
  // Optional parameters
  options = options || {};
  if (!helpers.isObject(options)) throw new Error("options is invalid");
  var units = options.units;
  var reverse = options.reverse;

  // Validation
  if (!geojson) throw new Error("geojson is required");
  if (segmentLength <= 0)
    throw new Error("segmentLength must be greater than 0");

  // Container
  var results = [];

  // Flatten each feature to simple LineString
  meta.flattenEach(geojson, function (feature) {
    // reverses coordinates to start the first chunked segment at the end
    if (reverse)
      feature.geometry.coordinates = feature.geometry.coordinates.reverse();

    sliceLineSegments(feature, segmentLength, units, function (segment) {
      results.push(segment);
    });
  });
  return helpers.featureCollection(results);
}

/**
 * Slice Line Segments
 *
 * @private
 * @param {Feature<LineString>} line GeoJSON LineString
 * @param {number} segmentLength how long to make each segment
 * @param {string}[units='kilometers'] units can be degrees, radians, miles, or kilometers
 * @param {Function} callback iterate over sliced line segments
 * @returns {void}
 */
function sliceLineSegments(line, segmentLength, units, callback) {
  var lineLength = length__default['default'](line, { units: units });

  // If the line is shorter than the segment length then the orginal line is returned.
  if (lineLength <= segmentLength) return callback(line);

  var numberOfSegments = lineLength / segmentLength;

  // If numberOfSegments is integer, no need to plus 1
  if (!Number.isInteger(numberOfSegments)) {
    numberOfSegments = Math.floor(numberOfSegments) + 1;
  }

  for (var i = 0; i < numberOfSegments; i++) {
    var outline = lineSliceAlong__default['default'](
      line,
      segmentLength * i,
      segmentLength * (i + 1),
      { units: units }
    );
    callback(outline, i);
  }
}

module.exports = lineChunk;
module.exports.default = lineChunk;
