/**
 * Densifies 2D geometries by length, deviation and/or angle in a 2D plane. The result geometry contains segments less than or equal to `maxSegementLength`, and it will not contain curves.
 * The piecewise approximation of curves will be within the specified deviation from the original curve,
 * and the angle between tangent segments does not exceed the specified value.
 *
 * If `maxAngleInDegrees` is not zero, vertices are added at points along the curve where the angle between tangent segments reaches this value.
 * These vertices are then connected by straight-line segments.
 *
 * If `maxSegmentLength` is zero, only curves are affected and other geometries remain unchanged.
 * The process always starts from the highest point on a segment, so equal segments will be densified in the same way.
 *
 * When the `maxSegmentLength`, `maxDeviation`, and `maxAngleInDegrees` parameters are all set to `0`,
 * curves are replaced with the line segments connecting the curve endpoints.
 *
 * Suggestion: to limit the number of segments that are produced, if you have an area of interest such as a visible extent,
 * clip the input geometries before densifying.
 *
 * ![Densify operator](https://developers.arcgis.com/javascript/latest/assets/references/core/operators/densify.png "Densify operator")
 *
 * @since 4.31
 */
import type { LengthUnit } from "../../core/units.js";
import type { GeometryUnion, GeometryWithoutMeshUnion } from "../types.js";

export interface Options {
  /**
   * The maximum angle allowed for densification by angle. The number must be greater than or equal to zero and is only applicable on curves. The default value of `0` disables densification by angle. The value will be capped at 90 degrees (π/2). This specifies the maximum angle that a new vertex can deviate from the original geometry.
   *
   * @default 0
   */
  maxAngleInDegrees?: number;
  /**
   * The maximum distance a newly placed vertex on a densified polyline can deviate from the original location on the curve.
   * The number must be greater than or equal to zero. Applicable only on curves.
   * The default of passing `0` disables densification by deviation.
   * Unless the `unit` option is set, the default is the geometry's spatial reference unit.
   *
   * @default 0
   */
  maxDeviation?: number;
  /**
   * The length unit of `maxSegmentLength` and `maxDeviation`.
   * The default is the input geometry's spatial reference unit.
   * An error will be thrown if this is set for Geographic Coordinate Systems.
   */
  unit?: LengthUnit;
}

/**
 * Performs the densify operation on the geometry.
 *
 * @param geometry - The geometry to be densified.
 * @param maxSegmentLength - The maximum distance between vertices when the input geometry is densified.
 * The number must be greater than or equal to zero.
 *
 * When the parameter is set to `0`, this operation only applies to curves and disables densification by length.
 * Curves are densified to straight segments using the given length.
 * And, curves are split into shorter subcurves such that the length of subcurves is shorter than `maxSegmentLength`.
 * After that the curves are replaced with straight segments.
 * Unless the `unit` option is set, the default is the spatial reference unit of `geometry`.
 * @param options - Additional options.
 * @returns Returns the densified geometry that does not contain any curves.
 * @example
 * // Returns a densified polyline.
 * const densified = densifyOperator.execute(polyline, 100);
 * @example
 * // Returns a polyline where all curve segments have been densified.
 * if (polyline.curvePaths) {
 *   const densified = densifyOperator.execute(polyline, 0, { maxAngleInDegrees: 1 });
 * }
 */
export function execute(geometry: GeometryUnion, maxSegmentLength: number, options?: Options): GeometryWithoutMeshUnion;

/**
 * Performs the Densify operation on the geometry set.
 *
 * @param geometries - The set of geometries to be densified.
 * All the geometries must have the same spatial reference.
 * @param maxSegmentLength - The maximum segment length allowed. The number must be greater than or equal to zero.
 *
 * When the parameter is set to `0`, this operation only applies to curves and disables densification by length.
 * Curves are densified to straight segments using the given length.
 * And, curves are split into shorter subcurves such that the length of subcurves is shorter than `maxSegmentLength`.
 * After that the curves are replaced with straight segments.
 * Unless the `unit` option is set, the default is the geometries spatial reference unit.
 * @param options - Additional options.
 * @returns Returns the densified geometries that do not contain any curves.
 */
export function executeMany(geometries: GeometryUnion[], maxSegmentLength: number, options?: Options): GeometryWithoutMeshUnion[];

/**
 * Indicates if the operator supports input geometries that contain curves.
 * The value will always be `true`. This will produce densified output geometries.
 */
export const supportsCurves: boolean;