import type SpatialReference from "../../geometry/SpatialReference.js";
import type { JSONSupport } from "../../core/JSONSupport.js";
import type { GeometryUnion } from "../../geometry/types.js";
import type { GeometryOperationLengthUnit } from "./types.js";
import type { SpatialReferenceProperties } from "../../geometry/SpatialReference.js";
import type { MeshProperties } from "../../geometry/Mesh.js";
import type { PolylineProperties } from "../../geometry/Polyline.js";
import type { PolygonProperties } from "../../geometry/Polygon.js";
import type { PointProperties } from "../../geometry/Point.js";
import type { MultipointProperties } from "../../geometry/Multipoint.js";
import type { ExtentProperties } from "../../geometry/Extent.js";

export interface BufferParametersProperties extends Partial<Pick<BufferParameters, "distances" | "geodesic" | "unionResults" | "unit">> {
  /**
   * The spatial reference in which the geometries are buffered.
   *
   * If `bufferSpatialReference` is not specified, the geometries are buffered in the spatial
   * reference specified by `outSpatialReference`. If `outSpatialReference` is also not specified,
   * they are buffered in the spatial reference of the features.
   */
  bufferSpatialReference?: SpatialReferenceProperties | null;
  /** The input geometries to buffer. */
  geometries?: ((ExtentProperties & { type: "extent" }) | (MultipointProperties & { type: "multipoint" }) | (PointProperties & { type: "point" }) | (PolygonProperties & { type: "polygon" }) | (PolylineProperties & { type: "polyline" }) | (MeshProperties & { type: "mesh" }))[];
  /**
   * The spatial reference for the returned geometries.
   *
   * If `outSpatialReference` is not specified, the output geometries are in the spatial reference
   * specified by `bufferSpatialReference`. If `bufferSpatialReference` also is not specified, they
   * are in the spatial reference of the features.
   */
  outSpatialReference?: SpatialReferenceProperties | null;
}

/**
 * Sets the distances, units, and other parameters for the [buffer()](https://developers.arcgis.com/javascript/latest/references/core/rest/geometryService/#buffer)
 * method on the [geometryService](https://developers.arcgis.com/javascript/latest/references/core/rest/geometryService/).
 *
 * @since 4.20
 * @see [buffer()](https://developers.arcgis.com/javascript/latest/references/core/rest/geometryService/#buffer)
 * @see [ArcGIS REST API - Buffer](https://developers.arcgis.com/rest/services-reference/buffer.htm)
 */
export default class BufferParameters extends JSONSupport {
  constructor(properties?: BufferParametersProperties);
  /**
   * The spatial reference in which the geometries are buffered.
   *
   * If `bufferSpatialReference` is not specified, the geometries are buffered in the spatial
   * reference specified by `outSpatialReference`. If `outSpatialReference` is also not specified,
   * they are buffered in the spatial reference of the features.
   */
  get bufferSpatialReference(): SpatialReference | null | undefined;
  set bufferSpatialReference(value: SpatialReferenceProperties | null | undefined);
  /** The distances the input features are buffered. The distance units are specified by `unit`. */
  accessor distances: number[] | null | undefined;
  /**
   * If the input geometries are in a geographic coordinate system, set geodesic to `true` to
   * generate a buffer polygon using a geodesic distance. The `bufferSpatialReference` property is
   * ignored when geodesic is set to `true`. Requires ArcGIS Server 10.1 or greater geometry service.
   * For more information, see the ArcGIS REST API documentation on the GeometryService buffer
   * operation and the geodesic property.
   *
   * @default false
   */
  accessor geodesic: boolean;
  /** The input geometries to buffer. */
  get geometries(): GeometryUnion[];
  set geometries(value: ((ExtentProperties & { type: "extent" }) | (MultipointProperties & { type: "multipoint" }) | (PointProperties & { type: "point" }) | (PolygonProperties & { type: "polygon" }) | (PolylineProperties & { type: "polyline" }) | (MeshProperties & { type: "mesh" }))[]);
  /**
   * The spatial reference for the returned geometries.
   *
   * If `outSpatialReference` is not specified, the output geometries are in the spatial reference
   * specified by `bufferSpatialReference`. If `bufferSpatialReference` also is not specified, they
   * are in the spatial reference of the features.
   */
  get outSpatialReference(): SpatialReference | null | undefined;
  set outSpatialReference(value: SpatialReferenceProperties | null | undefined);
  /**
   * If `true`, all geometries buffered at a given distance are unioned into a single (possibly
   * multipart) polygon, and the unioned geometry is placed in the output array.
   *
   * @default false
   */
  accessor unionResults: boolean;
  /**
   * The units for calculating each buffer distance. If `unit` is not specified, the units are
   * derived from `bufferSpatialReference`. If `bufferSpatialReference` is not specified,
   * the units are derived from the features.
   *
   * For a list of valid units, see [esriSRUnitType Constants](https://resources.arcgis.com/en/help/arcobjects-cpp/componenthelp/index.html#/esriSRUnitType_Constants/000w00000042000000/) and [esriSRUnit2Type Constants](https://resources.arcgis.com/en/help/arcobjects-cpp/componenthelp/index.html#/esriSRUnit2Type_Constants/000w00000041000000/).
   */
  accessor unit: GeometryOperationLengthUnit | null | undefined;
}