import type Point from "./Point.js";
import type Polygon from "./Polygon.js";
import type { PolygonProperties } from "./Polygon.js";
import type { PointProperties } from "./Point.js";

export interface CircleProperties extends PolygonProperties, Partial<Pick<Circle, "geodesic" | "numberOfPoints" | "radius" | "radiusUnit">> {
  /**
   * The center point of the circle. The center must be specified either as a
   * [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) or an array of longitude/latitude coordinates.
   * The spatial reference of the center will determine the [spatial reference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Circle.html#spatialReference) of
   * the circle. If you provide an array of longitude/latitude coordinates, the spatial
   * reference will default to WGS84 (wkid 4326).
   */
  center?: PointProperties | [
      number,
      number
  ] | null;
}

/**
 * A circle is a [Polygon](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polygon.html) created by specifying a [center point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Circle.html#center)
 * and a [radius](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Circle.html#radius). The point
 * can be provided as a [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) object or an array of latitude/longitude values.
 *
 * The [SpatialReference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-SpatialReference.html) of the center will determine the [spatial reference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Circle.html#spatialReference) of
 * the circle. If you provide an array of longitude/latitude coordinates as the center, the spatial
 * reference will default to WGS84 (wkid 4326). You cannot set the [spatialReference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Circle.html#spatialReference) property of the circle itself.
 * It must always be set in the center point.
 *
 * @since 4.0
 * @see [Polygon](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polygon.html)
 * @example
 * // Add a red circle to the map centered at -113°E, 36°N with a radius of 100 kilometers.
 * const circle = new Circle({
 *   center: [-113, 36],
 *   geodesic: true,
 *   numberOfPoints: 100,
 *   radius: 100,
 *   radiusUnit: "kilometers"
 * });
 *
 * view.graphics.add(new Graphic({
 *   geometry: circle,
 *   symbol: {
 *     type: "simple-fill",
 *     style: "none",
 *     outline: {
 *       width: 3,
 *       color: "red"
 *     }
 *   }
 * }));
 */
export default class Circle extends Polygon {
  constructor(properties?: CircleProperties);
  /**
   * The center point of the circle. The center must be specified either as a
   * [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) or an array of longitude/latitude coordinates.
   * The spatial reference of the center will determine the [spatial reference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Circle.html#spatialReference) of
   * the circle. If you provide an array of longitude/latitude coordinates, the spatial
   * reference will default to WGS84 (wkid 4326).
   */
  get center(): Point | null | undefined;
  set center(value: PointProperties | [
      number,
      number
  ] | null | undefined);
  /**
   * Applicable when the spatial reference of the center point is either set to Web
   * Mercator (wkid: 3857) or geographic/geodesic (wkid: 4326). When  either of
   * those spatial references is used, set geodesic to `true` to minimize
   * distortion. Other coordinate
   * systems will not create geodesic circles.
   *
   * @default false
   */
  accessor geodesic: boolean;
  /**
   * This value defines the number of points
   * along the curve of the circle.
   *
   * @default 60
   */
  accessor numberOfPoints: number;
  /**
   * The radius of the circle.
   *
   * @default 1000
   */
  accessor radius: number;
  /**
   * Unit of the radius.
   *
   * @default "meters"
   */
  accessor radiusUnit: "feet" | "kilometers" | "meters" | "miles" | "nautical-miles" | "yards";
  /**
   * Creates a deep clone of Circle.
   *
   * @returns A new instance of a Circle object equal to the object used to call `.clone()`.
   */
  clone(): Circle;
}