/**
 * This class performs geodetic computations for Earth and 70+ non-Earth spheroids. Methods include
 * geodesic length, area, point-distance and point-to-point computations.
 *
 * @deprecated since version 4.33. Use [geometry operators](https://developers.arcgis.com/javascript/latest/spatial-analysis/intro-geometry-operators/) instead.
 * @since 4.12
 * @see [Geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Geometry.html)
 */
import type Point from "../Point.js";
import type Polygon from "../Polygon.js";
import type Polyline from "../Polyline.js";
import type { AreaUnit, LengthUnit } from "../../core/units.js";

/**
 * Geodetically computes the area for one or more polygons.
 *
 * @deprecated since version 4.33. Use [geodeticAreaOperator](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-operators-geodeticAreaOperator.html) instead.
 * @param polygons - The polygons to compute the area for.
 * @param unit - = "square-meters" - Output area units.
 * @returns An array of areas corresponding to the source polygons.
 * @since 4.12
 * @example
 * // Display the area of the Bermuda Triangle.
 * const MIAMI    = { lat: 25.775278, lon: -80.208889 };  // Florida
 * const HAMILTON = { lat: 32.293, lon: -64.782 };        // Bermuda
 * const SANJUAN  = { lat: 18.406389, lon:  -66.063889 }; // Puerto Rico
 * const polygon = new Polygon({
 *   rings: [[
 *     [MIAMI.lon, MIAMI.lat],
 *     [HAMILTON.lon, HAMILTON.lat],
 *     [SANJUAN.lon, SANJUAN.lat],
 *     [MIAMI.lon, MIAMI.lat]
 *   ]]
 * });
 * const areas = geodesicUtils.geodesicAreas([polygon], "square-kilometers");
 * const area = Math.round(areas[0]);
 * console.log("Area: ", area, " km²"); // Area: 1150498 km²
 */
export function geodesicAreas(polygons: Polygon[], unit?: AreaUnit): number[];

/**
 * Geodetically computes polygon perimeter or polyline length for one or more geometries.
 *
 * @deprecated since version 4.33. Use [geodeticLengthOperator](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-operators-geodeticLengthOperator.html) instead.
 * @param geometries - The input polylines or polygons.
 * @param unit - = "meters" - Output linear units.
 * @returns An array of lengths/perimeters corresponding to the input geometries.
 * @since 4.12
 * @example
 * // Display the perimeter of the Bermuda Triangle.
 * const MIAMI    = { lat: 25.775278, lon: -80.208889 };  // Florida
 * const HAMILTON = { lat: 32.293, lon: -64.782 };        // Bermuda
 * const SANJUAN  = { lat: 18.406389, lon:  -66.063889 }; // Puerto Rico
 * const polygon = new Polygon({
 *   rings: [[
 *     [MIAMI.lon, MIAMI.lat],
 *     [HAMILTON.lon, HAMILTON.lat],
 *     [SANJUAN.lon, SANJUAN.lat],
 *     [MIAMI.lon, MIAMI.lat]
 *   ]]
 * });
 * const perimeters = geodesicUtils.geodesicLengths([polygon], "kilometers");
 * const perimeter = Math.round(perimeters[0]);
 * console.log("Perimeter: ", perimeter, " km"); // Perimeter: 4879 km
 */
export function geodesicLengths(geometries: Polyline[] | Polygon[], unit?: LengthUnit): number[];

/**
 * Computes and returns a densified polyline or polygon.
 *
 * @deprecated since version 4.33. Use [geodeticDensifyOperator](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-operators-geodeticDensifyOperator.html) instead.
 * @param geometry - The input polyline or polygon.
 * @param maxSegmentLength - The maximum length (in meters) between vertices.
 * @returns The densified polyline or polygon.
 * @since 4.12
 * @example
 * // Densify the polygon representing Bermuda Triangle with maximum segment size of 100km.
 * const MIAMI    = { lat: 25.775278, lon: -80.208889 };  // Florida
 * const HAMILTON = { lat: 32.293, lon: -64.782 };        // Bermuda
 * const SANJUAN  = { lat: 18.406389, lon:  -66.063889 }; // Puerto Rico
 * const polygon = new Polygon({
 *   rings: [[
 *     [MIAMI.lon, MIAMI.lat],
 *     [HAMILTON.lon, HAMILTON.lat],
 *     [SANJUAN.lon, SANJUAN.lat],
 *     [MIAMI.lon, MIAMI.lat]
 *   ]]
 * });
 * const densifiedPolygon = geodesicUtils.geodesicDensify(polygon, 100000);
 * const vertexCountBefore = polygon.rings[0].length;
 * const vertexCountAfter = densifiedPolygon.rings[0].length;
 * console.log("Before: ", vertexCountBefore, ", After: ", vertexCountAfter); // Before: 4, After: 51
 */
export function geodesicDensify(geometry: Polygon | Polyline, maxSegmentLength: number): Polygon | Polyline;

/**
 * Geodetically computes the direction and distance between two known locations.
 * Both input points must have the same geographic coordinate system.
 *
 * @deprecated since version 4.33. Use [geodeticUtilsOperator's calculateDistanceAndAzimuth](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-operators-geodeticUtilsOperator.html#calculateDistanceAndAzimuth) method instead.
 * @param from - The origin location.
 * @param to - The destination location.
 * @param unit - = "meters" - Output linear units.
 * @returns Computed distance and direction between the two known locations.
 *
 *   Name           | Type   | Description
 *   ---------------|--------|-------------
 *   distance       | number | The distance between the two locations.
 *   azimuth        | number | The azimuth (or "bearing") in degrees. Values range from 0° to 360°.
 *   reverseAzimuth | number | The reverse azimuth in degrees. Values range from 0° to 360°.
 * @since 4.12
 * @example
 * // Display the distance and direction between Los Angeles and New York City.
 * const LA = {
 *   latitude: 34.05,
 *   longitude: -118.25
 * };
 * const NY = {
 *   latitude: 40.7127,
 *   longitude: -74.0059
 * };
 * const join = geodesicUtils.geodesicDistance(
 *   new Point({ x: LA.longitude, y: LA.latitude }),
 *   new Point({ x: NY.longitude, y: NY.latitude }),
 *   "kilometers"
 * );
 * const { distance, azimuth } = join;
 * console.log("Distance: ", distance, ", Direction: ", azimuth);
 */
export function geodesicDistance(from: Point, to: Point, unit?: LengthUnit): InverseGeodeticSolverResult;

/**
 * Geodetically computes the location at a defined distance and direction from a known location.
 *
 * @deprecated since version 4.33. Use [geodeticUtilsOperator's pointFromDistance](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-operators-geodeticUtilsOperator.html#pointFromDistance) method instead.
 * @param point - Origin location.
 * @param distance - Distance from the origin in meters.
 * @param azimuth - Direction from the origin in degrees.
 * @returns The computed point.
 * @since 4.12
 * @example
 * // Display the location of a point 10km East of Los Angeles.
 * const LA = {
 *   latitude: 34.05,
 *   longitude: -118.25
 * };
 * const destination = geodesicUtils.pointFromDistance(
 *   new Point({ x: LA.longitude, y: LA.latitude }),
 *   10000,
 *   90
 * );
 * const { latitude, longitude } = destination;
 * console.log("Latitude: ", latitude, ", Longitude: ", longitude);
 */
export function pointFromDistance(point: Point, distance: number, azimuth: number): Point;

/**
 * Computed distance and direction between two known locations.
 *
 * @deprecated since version 4.33. Use [geodeticUtilsOperator's CalculateDistanceAndAzimuthResult](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-operators-geodeticUtilsOperator.html#CalculateDistanceAndAzimuthResult) instead.
 */
export interface InverseGeodeticSolverResult {
  /** The distance between the two locations. */
  readonly distance: number;
  /** The azimuth (or "bearing") in degrees. Value will be in the range of 0-360°. */
  readonly azimuth?: number;
  /** The azimuth in degrees in the reverse direction. Value will be in the range of 0-360°. */
  readonly reverseAzimuth?: number;
}