import type Layer from "../../layers/Layer.js";
import type Point from "../../geometry/Point.js";
import type LayerView from "../layers/LayerView.js";

/** @since 5.0 */
export type PointerType = "mouse" | "touch" | "pen";

/**
 * Indicates which mouse button was clicked.
 * See [MouseEvent.button](https://developer.mozilla.org/docs/Web/API/MouseEvent/button).
 *
 * Value | Description
 * ------|------------
 * 0 | left click (or touch)
 * 1 | middle click
 * 2 | right click
 * 3 | back click
 * 4 | forward click
 * -1 | unknown button
 *
 * @since 5.0
 */
export type MouseButton = 0 | 1 | 2 | 3 | 4 | -1;

/**
 * Base interface for view input events.
 *
 * @since 5.0
 */
export interface ViewEvent<T extends Event = Event> {
  /**
   * Time stamp (in milliseconds) at which the event was created.
   *
   * @since 5.0
   */
  timestamp: number;
  /**
   * A standard [DOM Event](https://developer.mozilla.org/docs/Web/API/Event).
   *
   * @since 5.0
   */
  native: T;
  /**
   * Prevents the event bubbling up the event chain.
   *
   * @since 5.0
   */
  stopPropagation(): void;
  /**
   * A function that can be called to defer event propagation until
   * the passed in asynchronous function is completed. Calling defer will stall the entire event pipeline and should
   * be used with caution.
   *
   * @since 5.0
   */
  defer: EventDefer;
}

/**
 * @param operation - An asynchronous operation.
 * @returns The result of calling the passed in operation.
 * @since 4.33
 * @example
 * view.on("click", (event) => {
 *   event.defer(async () => {
 *     const hitTestResult = await view.hitTest(event);
 *
 *     if (hitTestResult.results.length) {
 *       // stop the event from propagating
 *       event.stopPropagation();
 *       console.log("found hit, stopping propagation to prevent popup", hitTestResult.results[0]);
 *     }
 *   });
 * });
 * @since 5.0
 */
export type EventDefer = <T>(operation: EventDeferredOperation<T>) => Promise<T>;

/**
 * Asynchronous function passed to the defer method of an event.
 *
 * @returns The event pipeline is deferred until the promise is resolved.
 * @since 4.33
 * @see [EventDefer](https://developers.arcgis.com/javascript/latest/references/core/views/input/types/#EventDefer)
 */
export type EventDeferredOperation<T> = () => Promise<T>;

/**
 * Event payload for the view's [View.@click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-click) event.
 *
 * @since 5.0
 */
export interface ClickEvent extends ViewEvent<PointerEvent | MouseEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "click";
  /**
   * Indicates which mouse button was clicked.
   *
   * @since 5.0
   */
  button: MouseButton;
  /**
   * Indicates the current mouse button state.
   *
   * Value | Description
   * ------|------------
   * 0 | left click (or touch)
   * 1 | middle click
   * 2 | right click
   *
   * @since 5.0
   */
  buttons: number;
  /**
   * The horizontal screen coordinate of the click on the view.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The vertical screen coordinate of the click on the view.
   *
   * @since 5.0
   */
  y: number;
  /**
   * The point location of the click on the view in the spatial
   * reference of the map.
   *
   * @since 5.0
   */
  mapPoint: Point;
}

/**
 * Event payload for the view's [View.@double-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-double-click) event.
 *
 * @since 5.0
 */
export interface DoubleClickEvent extends ViewEvent<PointerEvent | MouseEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "double-click";
  /**
   * Indicates which mouse button was clicked.
   *
   * @since 5.0
   */
  button: MouseButton;
  /**
   * Indicates the current mouse button state.
   *
   * Value | Description
   * ------|------------
   * 0 | left click (or touch)
   * 1 | middle click
   * 2 | right click
   *
   * @since 5.0
   */
  buttons: number;
  /**
   * The horizontal screen coordinate of the click on the view.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The vertical screen coordinate of the click on the view.
   *
   * @since 5.0
   */
  y: number;
  /**
   * The point location of the click on the view in the spatial
   * reference of the map.
   *
   * @since 5.0
   */
  mapPoint: Point;
}

/**
 * Event payload for the view's [View.@immediate-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-immediate-click) event.
 *
 * @since 5.0
 */
export interface ImmediateClickEvent extends ViewEvent<PointerEvent | MouseEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "immediate-click";
  /**
   * Indicates which mouse button was clicked.
   * See [MouseEvent.button](https://developer.mozilla.org/docs/Web/API/MouseEvent/button).
   *
   * Value | Description
   * ------|------------
   * 0 | left click (or touch)
   * 1 | middle click
   * 2 | right click
   *
   * @since 5.0
   */
  button: MouseButton;
  /**
   * Indicates which buttons are pressed when the event is triggered.
   * See [MouseEvent.buttons](https://developer.mozilla.org/docs/Web/API/MouseEvent/buttons).
   *
   * @since 5.0
   */
  buttons: number;
  /**
   * The horizontal screen coordinate of the click on the view.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The vertical screen coordinate of the click on the view.
   *
   * @since 5.0
   */
  y: number;
  /**
   * The point location of the click on the view in the spatial
   * reference of the map.
   *
   * @since 5.0
   */
  mapPoint: Point;
}

/**
 * Event payload for the view's [View.@immediate-double-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-immediate-double-click) event.
 *
 * @since 5.0
 */
export interface ImmediateDoubleClickEvent extends ViewEvent<PointerEvent | MouseEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "immediate-double-click";
  /**
   * Indicates which mouse button was clicked.
   * See [MouseEvent.button](https://developer.mozilla.org/docs/Web/API/MouseEvent/button).
   *
   * Value | Description
   * ------|------------
   * 0 | left click (or touch)
   * 1 | middle click
   * 2 | right click
   *
   * @since 5.0
   */
  button: MouseButton;
  /**
   * Indicates which buttons are pressed when the event is triggered.
   * See [MouseEvent.buttons](https://developer.mozilla.org/docs/Web/API/MouseEvent/buttons).
   *
   * @since 5.0
   */
  buttons: number;
  /**
   * The horizontal screen coordinate of the click on the view.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The vertical screen coordinate of the click on the view.
   *
   * @since 5.0
   */
  y: number;
  /**
   * The point location of the click on the view in the spatial
   * reference of the map.
   *
   * @since 5.0
   */
  mapPoint: Point;
}

/**
 * Event payload for the view's [View.@hold](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-hold) event.
 *
 * @since 5.0
 */
export interface HoldEvent extends ViewEvent<PointerEvent | MouseEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "hold";
  /**
   * Indicates which mouse button was held down.
   * See [MouseEvent.button](https://developer.mozilla.org/docs/Web/API/MouseEvent/button).
   *
   * Value | Description
   * ------|------------
   * 0 | left mouse button (or touch)
   * 1 | middle mouse button
   * 2 | right mouse button
   *
   * @since 5.0
   */
  button: MouseButton;
  /**
   * Indicates which mouse buttons are pressed when the event is triggered.
   * See [MouseEvent.buttons](https://developer.mozilla.org/docs/Web/API/MouseEvent/buttons).
   *
   * @since 5.0
   */
  buttons: number;
  /**
   * The horizontal screen coordinate of the hold on the view.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The vertical screen coordinate of the hold on the view.
   *
   * @since 5.0
   */
  y: number;
  /**
   * The point location of the click on the view in the spatial
   * reference of the map.
   *
   * @since 5.0
   */
  mapPoint: Point;
}

/**
 * Event payload for the view's [View.@drag](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-drag) event.
 *
 * @since 5.0
 */
export interface DragEvent extends ViewEvent<PointerEvent | MouseEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "drag";
  /**
   * Indicates the state of the drag.
   * The two values `added` and `removed` indicate a change in the number of pointers involved.
   *
   * @since 5.0
   */
  action: "start" | "update" | "added" | "removed" | "end";
  /**
   * Indicates which mouse button was clicked at the start of the drag.
   * See [MouseEvent.button](https://developer.mozilla.org/docs/Web/API/MouseEvent/button).
   *
   * Value | Description
   * ------|------------
   * 0 | left mouse button (or touch)
   * 1 | middle mouse button
   * 2 | right mouse button
   *
   * @since 5.0
   */
  button: MouseButton;
  /**
   * Indicates which mouse buttons are pressed when the event is triggered.
   * See [MouseEvent.buttons](https://developer.mozilla.org/docs/Web/API/MouseEvent/buttons).
   *
   * @since 5.0
   */
  buttons: number;
  /**
   * The horizontal screen coordinate of the pointer on the view.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The vertical screen coordinate of the pointer on the view.
   *
   * @since 5.0
   */
  y: number;
  /**
   * Screen coordinates of the start of the drag.
   *
   * @since 5.0
   */
  origin: DragEventOrigin;
  /**
   * Amount of rotation (in degrees) since the last event of type `start`.
   *
   * @since 5.0
   */
  angle: number;
  /**
   * The radius of a sphere around the multiple pointers involved in this drag. Or 0 while only a single pointer is used.
   *
   * @since 5.0
   */
  radius: number;
}

/**
 * Screen coordinates where a [View.@drag](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-drag) started.
 *
 * @since 5.0
 */
export interface DragEventOrigin {
  /**
   * The horizontal screen coordinate of the pointer on the view.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The vertical screen coordinate of the pointer on the view.
   *
   * @since 5.0
   */
  y: number;
}

/**
 * Event payload for the view's [View.@key-down](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-key-down) event.
 *
 * @since 5.0
 */
export interface KeyDownEvent extends ViewEvent<KeyboardEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "key-down";
  /**
   * Indicates whether this is the first event emitted
   * due to the key press, or a repeat.
   *
   * @since 5.0
   */
  repeat: boolean;
  /**
   * The key value that was pressed, according to the
   * [MDN full list of key values](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/key/Key_Values).
   *
   * @since 5.0
   */
  key: string;
}

/**
 * Event payload for the view's [View.@key-up](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-key-up) event.
 *
 * @since 5.0
 */
export interface KeyUpEvent extends ViewEvent<KeyboardEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "key-up";
  /**
   * The key value that was released, according to the
   * [MDN full list of key values](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/key/Key_Values).
   *
   * @since 5.0
   */
  key: string;
}

/**
 * Base interface for pointer events emitted by the view.
 *
 * @since 5.0
 */
export interface PointerEventCommon extends ViewEvent<PointerEvent> {
  /**
   * Uniquely identifies a pointer between multiple down, move, and up events.
   * Ids might get reused after a pointer-up event.
   *
   * @since 5.0
   */
  pointerId: number;
  /**
   * Indicates the pointer type.
   *
   * @since 5.0
   */
  pointerType: PointerType;
  /**
   * Indicates which mouse button was clicked.
   *
   * @since 5.0
   */
  button: MouseButton;
  /**
   * Indicates which mouse buttons are pressed when the event is triggered.
   * See [MouseEvent.buttons](https://developer.mozilla.org/docs/Web/API/MouseEvent/buttons).
   *
   * @since 5.0
   */
  buttons: number;
  /**
   * The horizontal screen coordinate of the pointer on the view.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The vertical screen coordinate of the pointer on the view.
   *
   * @since 5.0
   */
  y: number;
}

/**
 * Event payload for the view's [View.@pointer-down](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-pointer-down) event.
 *
 * @since 5.0
 */
export interface PointerDownEvent extends PointerEventCommon {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "pointer-down";
}

/**
 * Event payload for the view's [View.@pointer-move](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-pointer-move) event.
 *
 * @since 5.0
 */
export interface PointerMoveEvent extends PointerEventCommon {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "pointer-move";
}

/**
 * Event payload for the view's [View.@pointer-up](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-pointer-up) event.
 *
 * @since 5.0
 */
export interface PointerUpEvent extends PointerEventCommon {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "pointer-up";
}

/**
 * Event payload for the view's [View.@pointer-enter](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-pointer-enter) event.
 *
 * @since 5.0
 */
export interface PointerEnterEvent extends PointerEventCommon {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "pointer-enter";
}

/**
 * Event payload for the view's [View.@pointer-leave](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-pointer-leave) event.
 *
 * @since 5.0
 */
export interface PointerLeaveEvent extends PointerEventCommon {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "pointer-leave";
}

/**
 * Event payload for the view's [View.@mouse-wheel](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-mouse-wheel) event.
 *
 * @since 5.0
 */
export interface ViewMouseWheelEvent extends ViewEvent<WheelEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "mouse-wheel";
  /**
   * The horizontal screen coordinate of the click on the view.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The vertical screen coordinate of the click on the view.
   *
   * @since 5.0
   */
  y: number;
  /**
   * Number representing the vertical scroll amount.
   *
   * @since 5.0
   */
  deltaY: number;
}

/**
 * Event payload for the view's [View.@focus](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-focus) event.
 *
 * @since 5.0
 */
export interface ViewFocusEvent extends ViewEvent<FocusEvent> {}

/**
 * Event payload for the view's [View.@blur](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-blur) event.
 *
 * @since 5.0
 */
export interface ViewBlurEvent extends ViewEvent<FocusEvent> {}

/**
 * Event payload for the view's [View.@resize](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-resize) event.
 *
 * @since 5.0
 */
export interface ViewResizeEvent {
  /**
   * The previous view width in pixels
   *
   * @since 5.0
   */
  oldWidth: number;
  /**
   * The previous view height in pixels
   *
   * @since 5.0
   */
  oldHeight: number;
  /**
   * The new measured view width in pixels
   *
   * @since 5.0
   */
  width: number;
  /**
   * The new measured view height in pixels
   *
   * @since 5.0
   */
  height: number;
}

/**
 * Event payload for the view's [View.@layerview-create](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-layerview-create) event.
 *
 * @since 5.0
 */
export interface LayerViewCreateEvent {
  /**
   * The layer in the map for which the `layerView` was created.
   *
   * @since 5.0
   */
  layer: Layer;
  /**
   * The LayerView rendered
   *                                                in the view representing the layer in `layer`.
   *
   * @since 5.0
   */
  layerView: LayerView;
}

/**
 * Event payload for the view's [View.@layerview-create-error](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-layerview-create-error) event.
 *
 * @since 5.0
 */
export interface LayerViewCreateErrorEvent {
  /**
   * The layer in the map for which the view emitting this event
   *   failed to create a layer view.
   *
   * @since 5.0
   */
  layer: Layer;
  /**
   * An error object describing why the layer view could not be created.
   *
   * @since 5.0
   */
  error: Error;
}

/**
 * Event payload for the view's [View.@layerview-destroy](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-layerview-destroy) event.
 *
 * @since 5.0
 */
export interface LayerViewDestroyEvent {
  /**
   * The layer in the map for which the `layerView` was destroyed.
   *
   * @since 5.0
   */
  layer: Layer;
  /**
   * The LayerView that was destroyed in the view.
   *
   * @since 5.0
   */
  layerView: LayerView;
}

/**
 * Event payload for the view's [View.@double-tap-drag](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-double-tap-drag) event.
 *
 * @since 5.0
 */
export interface DoubleTapDragEvent extends ViewEvent<PointerEvent | MouseEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "double-tap-drag";
  /**
   * Indicates the state of the drag.
   *
   * @since 5.0
   */
  action: "begin" | "update" | "end";
  /**
   * Indicates which mouse button was clicked at the start of the drag.
   * See [MouseEvent.button](https://developer.mozilla.org/docs/Web/API/MouseEvent/button).
   *
   * Value | Description
   * ------|------------
   * 0 | left mouse button (or touch)
   * 1 | middle mouse button
   * 2 | right mouse button
   *
   * @since 5.0
   */
  button: MouseButton;
  /**
   * Indicates which mouse buttons are pressed when the event is triggered.
   * See [MouseEvent.buttons](https://developer.mozilla.org/docs/Web/API/MouseEvent/buttons).
   *
   * @since 5.0
   */
  buttons: number;
  /**
   * The horizontal distance from the drag origin in pixels.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The vertical distance from the drag origin in pixels.
   *
   * @since 5.0
   */
  y: number;
}

/**
 * Event payload for the view's [View.@vertical-two-finger-drag](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-vertical-two-finger-drag) event.
 *
 * @since 5.0
 */
export interface VerticalTwoFingerDragEvent extends ViewEvent<PointerEvent | MouseEvent> {
  /**
   * The event type.
   *
   * @since 5.0
   */
  type: "vertical-two-finger-drag";
  /**
   * Indicates the state of the drag.
   *
   * @since 5.0
   */
  action: "begin" | "update" | "end";
  /**
   * The vertical distance from the drag origin in pixels.
   *
   * @since 5.0
   */
  y: number;
}

/** @since 5.0 */
export interface ViewBaseEventTypes {
  /**
   * Fires when the view's size changes.
   *
   * @since 5.0
   * @see [MapView.size](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#size)
   * @see [MapView.height](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#height)
   * @see [MapView.width](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#width)
   */
  resize: ViewResizeEvent;
  /**
   * Fires after each layer in the map has a corresponding [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/) created
   * and rendered in the view.
   *
   * @since 5.0
   * @see [View.whenLayerView()](https://developers.arcgis.com/javascript/latest/references/core/views/View/#whenLayerView)
   * @example
   * // This function fires each time a layer view is created for a layer in
   * // the map of the view.
   * view.on("layerview-create", function(event) {
   *   // The event contains the layer and its layer view that has just been
   *   // created. Here we check for the creation of a layer view for a layer with
   *   // a specific id, and log the layer view
   *   if (event.layer.id === "satellite") {
   *     // The LayerView for the desired layer
   *     console.log(event.layerView);
   *   }
   * });
   */
  "layerview-create": LayerViewCreateEvent;
  /**
   * Fires when an error occurs during the creation of a [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/)
   * after a layer has been added to the map.
   *
   * @since 5.0
   * @see [View.whenLayerView()](https://developers.arcgis.com/javascript/latest/references/core/views/View/#whenLayerView)
   * @example
   * // This function fires each time an error occurs during the creation of a layerview
   * view.on("layerview-create-error", function(event) {
   *   console.error("LayerView failed to create for layer with the id: ", event.layer.id);
   * });
   */
  "layerview-create-error": LayerViewCreateErrorEvent;
  /**
   * Fires after a [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/) is destroyed and is
   * no longer rendered in the view. This happens for example when a layer is
   * removed from the map of the view.
   *
   * @since 5.0
   */
  "layerview-destroy": LayerViewDestroyEvent;
}

/** @since 5.0 */
export interface ViewEventTypes extends ViewBaseEventTypes {
  /**
   * Fires after a user clicks on the view. This event emits slightly slower than an
   * [View.@immediate-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-immediate-click) event to make sure that a [View.@double-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-double-click)
   * event isn't triggered instead. The [View.@immediate-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-immediate-click) event can be used
   * for responding to a click event without delay.
   *
   * @since 5.0
   * @see [Sample: Access features with hitTest](https://developers.arcgis.com/javascript/latest/sample-code/map-component-hittest/)
   * @example
   * view.on("click", function(event){
   *   // event is the event object returned after the event fires
   *
   *   // Prints the map coordinates of the clicked location
   *   console.log(event.mapPoint);
   * });
   * @example
   * // Set up a click event handler and retrieve the screen point
   * view.on("click", function(event) {
   *  // the hitTest() checks to see if any graphics in the view
   *  // intersect the given screen x, y coordinates
   *  view.hitTest(event)
   *   .then(getGraphics);
   * });
   * @example
   * view.on("click", function(event) {
   *  // you must overwrite default click-for-popup
   *  // behavior to display your own popup
   *  view.popupEnabled = false;
   *
   *  // Get the coordinates of the click on the view
   *  let lat = Math.round(event.mapPoint.latitude * 1000) / 1000;
   *  let lon = Math.round(event.mapPoint.longitude * 1000) / 1000;
   *
   *  view.popup.open({
   *    // Set the popup's title to the coordinates of the location
   *    title: "Reverse geocode: [" + lon + ", " + lat + "]",
   *    location: event.mapPoint // Set the location of the popup to the clicked location
   *    content: "This is a point of interest"  // content displayed in the popup
   *  });
   * });
   */
  click: ClickEvent;
  /**
   * Fires after double-clicking on the view.
   *
   * @since 5.0
   * @example
   * view.on("double-click", function(event) {
   *   // The event object contains the mapPoint and the screen coordinates of the location
   *   // that was clicked.
   *   console.log("screen point", event.x, event.y);
   *   console.log("map point", event.mapPoint);
   * });
   */
  "double-click": DoubleClickEvent;
  /**
   * Fires right after a user clicks on the view. In contrast to the [View.@click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-click) event,
   * the `immediate-click` event is emitted as soon as the user clicks on
   * the view, and is not inhibited by a [View.@double-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-double-click) event. This event
   * is useful for interactive experiences that require feedback without delay.
   *
   * @example
   * // Set up an immediate-click event handler and retrieve the screen point
   * view.on("immediate-click", function(event) {
   *  // the hitTest() checks to see if any graphics in the view
   *  // intersect the given screen x, y coordinates
   *  view.hitTest(event)
   *   .then(getGraphics);
   * });
   */
  "immediate-click": ImmediateClickEvent;
  /**
   * Is emitted after two consecutive [View.@immediate-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-immediate-click) events.
   * In contrast to [View.@double-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-double-click), an `immediate-double-click` cannot
   * be prevented by use of `stopPropagation` on the [View.@immediate-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-immediate-click)
   * event and can therefore be used to react to double-clicking independently of usage of the
   * [View.@immediate-click](https://developers.arcgis.com/javascript/latest/references/core/views/View/#event-immediate-click) event.
   */
  "immediate-double-click": ImmediateDoubleClickEvent;
  /**
   * Fires after holding either a mouse button or a single finger on the view for a short amount of time.
   *
   * @since 5.0
   * @example
   * view.on("hold", function(event) {
   *   // The event object contains the mapPoint and the screen coordinates of the location
   *   // that was clicked.
   *   console.log("hold at screen point", event.x, event.y);
   *   console.log("hold at map point", event.mapPoint);
   * });
   */
  hold: HoldEvent;
  /**
   * Fires during a pointer drag on the view.
   *
   * @since 5.0
   * @example
   * view.on("drag", function(event){
   *  // Print out the current state of the
   *  // drag event.
   *  console.log("drag state", event.action);
   * });
   */
  drag: DragEvent;
  /**
   * Fires after a keyboard key is pressed.
   *
   * @since 5.0
   * @example
   * // Zoom in when user clicks on "a" button
   * // Zoom out when user clicks on "s" button
   * view.on("key-down", function(event){
   *  console.log("key-down", event);
   *
   *  if (event.key === "a"){
   *    let zm = view.zoom + 1;
   *
   *    view.goTo({
   *      target: view.center,
   *      zoom: zm
   *    });
   *  }
   *  else if(event.key == "s"){
   *    let zm = view.zoom - 1;
   *
   *    view.goTo({
   *      target: view.center,
   *      zoom: zm
   *    });
   *  }
   * });
   */
  "key-down": KeyDownEvent;
  /**
   * Fires after a keyboard key is released.
   *
   * @since 5.0
   */
  "key-up": KeyUpEvent;
  /**
   * Fires after a mouse button is pressed, or a finger touches the display.
   *
   * @since 5.0
   */
  "pointer-down": PointerDownEvent;
  /**
   * Fires after the mouse or a finger on the display moves.
   *
   * @since 5.0
   * @example
   * // Fires `pointer-move` event when user clicks on "Shift"
   * // key and moves the pointer on the view.
   * view.on('pointer-move', ["Shift"], function(event){
   *   let point = view.toMap({x: event.x, y: event.y});
   *   bufferPoint(point);
   * });
   */
  "pointer-move": PointerMoveEvent;
  /**
   * Fires after a mouse button is released, or a display touch ends.
   *
   * @since 5.0
   */
  "pointer-up": PointerUpEvent;
  /**
   * Fires after a mouse cursor enters the view, or a display touch begins.
   *
   * @since 5.0
   */
  "pointer-enter": PointerEnterEvent;
  /**
   * Fires after a mouse cursor leaves the view, or a display touch ends.
   *
   * @since 5.0
   */
  "pointer-leave": PointerLeaveEvent;
  /**
   * Fires when a wheel button of a pointing device (typically a mouse) is scrolled on the view.
   *
   * @since 5.0
   * @example
   * view.on("mouse-wheel", function(event){
   *  // deltaY value is positive when wheel is scrolled up
   *  // and it is negative when wheel is scrolled down.
   *  console.log(event.deltaY);
   * });
   */
  "mouse-wheel": ViewMouseWheelEvent;
  /** Fires when browser focus is on the view. */
  focus: ViewFocusEvent;
  /** Fires when browser focus is moved away from the view. */
  blur: ViewBlurEvent;
  /**
   * Fires while the pointer is drag following a double-tap gesture on the view.
   *
   * @since 5.0
   * @example
   * view.on("double-tap-drag", (event) => {
   *   // Display the distance moved from the drag origin.
   *   console.log("x distance:", event.x, "y distance:", event.y);
   * });
   */
  "double-tap-drag": DoubleTapDragEvent;
  /**
   * Fires while the two pointers are dragged on the view.
   *
   * @since 5.0
   * @example
   * view.on("vertical-two-finger-drag", (event) => {
   *   // Display the distance moved vertically from the drag origin.
   *   console.log("y distance:", event.y);
   * });
   */
  "vertical-two-finger-drag": VerticalTwoFingerDragEvent;
}