import type Point from "../../geometry/Point.js";
import type { EventedAccessor, EventedMixinProperties } from "../../core/Evented.js";
import type { EsriPromiseMixin, EsriPromiseMixinProperties } from "../../core/Promise.js";
import type { ScreenPoint } from "../../core/types.js";
import type { MapViewOrSceneView } from "../MapViewOrSceneView.js";

export interface DrawActionProperties extends EventedMixinProperties, EsriPromiseMixinProperties, Partial<Pick<DrawAction, "hasZ" | "view">> {}

/**
 * DrawAction is the base class for all draw actions. DrawActions use the view events to generate a set
 * of coordinates to create new geometries.
 * Each serves a different purpose, allowing you to create a different type geometry such as
 * [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html), [Multipoint](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Multipoint.html),
 * [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html), and [Polygon](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polygon.html).
 *
 * When the [draw.create("type of geometry")](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-draw-Draw.html#create) method is called,
 * an instance of the relevant draw action is returned. You can then listen to its events to create a new geometry that
 * meets criteria specified by the application.
 *
 * @since 4.7
 * @see [Sample - Prevent drawing a self-intersecting line](https://developers.arcgis.com/javascript/latest/sample-code/draw-line/)
 */
export default abstract class DrawAction extends DrawActionSuperclass {
  constructor(properties?: DrawActionProperties);
  /**
   * Controls whether the created geometry will have z coordinates or not.
   *
   * @default true
   */
  accessor hasZ: boolean;
  /**
   * Two-dimensional array of numbers representing the coordinates of each vertex
   * comprising the geometry being drawn.
   */
  get vertices(): number[][];
  /** A reference to the [MapView](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html). */
  accessor view: MapViewOrSceneView;
  /**
   * Indicates if the [redo()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-draw-DrawAction.html#redo) method can be called on the action instance.
   *
   * @returns Returns `true` if the [redo()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-draw-DrawAction.html#redo) method can be called.
   */
  canRedo(): boolean;
  /**
   * Indicates if the [undo()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-draw-DrawAction.html#undo) method can be called on the action instance.
   *
   * @returns Returns `true` if the [undo()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-draw-DrawAction.html#undo) method can be called.
   */
  canUndo(): boolean;
  /**
   * Maps the given screen point to a map point.
   *
   * @param screenPoint - The location on the screen.
   * @returns The result object containing, or `null` if the screen point could not be mapped.
   */
  getCoordsAndPointFromScreenPoint(screenPoint: ScreenPoint): FromScreenPointResult | null | undefined;
  /**
   * Maps the given screen point to a map point.
   *
   * @param screenPoint - The location on the screen.
   * @returns Array of x,y and z component (if hasZ is enabled) of the point associated with the given screen point
   *  or `null` if screen point could not be mapped.
   */
  getCoordsFromScreenPoint(screenPoint: ScreenPoint | null | undefined): number[] | null | undefined;
  /**
   * Incrementally redo actions recorded in the stack. Call [canRedo()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-draw-DrawAction.html#canRedo) prior to calling this method
   * to check if this method can be called on the action instance. Calling this method will fire the
   * {@link views/draw/DrawAction#event-vertex-add} or {@link views/draw/DrawAction#event-vertex-remove} events depending
   * on the last action.
   *
   * @example
   * if (action.canRedo()) {
   *   action.redo();
   * }
   */
  redo(): void;
  /**
   * Maps the given screen point to a map point.
   *
   * @param screenPoint - The location on the screen.
   * @returns MapPoint associated with the given screen point or null if screen point could not be mapped.
   */
  screenToMap(screenPoint: ScreenPoint): Point | null | undefined;
  /**
   * Incrementally undo actions recorded in the stack. Call [canUndo()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-draw-DrawAction.html#canUndo) prior to calling this method
   * to check if this method can be called on the action instance. Calling this method will fire the
   * {@link views/draw/DrawAction#event-vertex-add} or {@link views/draw/DrawAction#event-vertex-remove} events depending
   * on the last action.
   *
   * @example
   * if (action.canUndo()) {
   *   action.undo();
   * }
   */
  undo(): void;
}
declare const DrawActionSuperclass: typeof EventedAccessor & typeof EsriPromiseMixin

/**
 * The result object of the [getCoordsAndPointFromScreenPoint()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-draw-DrawAction.html#getCoordsAndPointFromScreenPoint) method. See the table
 * below for more details on each property.
 */
export interface FromScreenPointResult {
  /** The map point of the point associated with the given screen point. */
  mapPoint: Point;
  /** Array of x, y, and z component (if hasZ is enabled). */
  vertex: number[];
}