/**
 * A module for importing types used in View modules.
 *
 * @since 5.0
 */
import type Camera from "../Camera.js";
import type Graphic from "../Graphic.js";
import type Ground from "../Ground.js";
import type Viewpoint from "../Viewpoint.js";
import type WebDocument2D from "../WebDocument2D.js";
import type WebScene from "../WebScene.js";
import type Analysis from "../analysis/Analysis.js";
import type Collection from "../core/Collection.js";
import type Extent from "../geometry/Extent.js";
import type Point from "../geometry/Point.js";
import type Polygon from "../geometry/Polygon.js";
import type ImageryLayer from "../layers/ImageryLayer.js";
import type ImageryTileLayer from "../layers/ImageryTileLayer.js";
import type Layer from "../layers/Layer.js";
import type MediaLayer from "../layers/MediaLayer.js";
import type RouteLayer from "../layers/RouteLayer.js";
import type BuildingSublayer from "../layers/buildingSublayers/BuildingSublayer.js";
import type SubtypeSublayer from "../layers/support/SubtypeSublayer.js";
import type { ReadonlyArrayOrCollection } from "../core/Collection.js";
import type { AbortOptions } from "../core/promiseUtils.js";
import type { ScreenPoint } from "../core/types.js";
import type { GeometryUnion } from "../geometry/types.js";
import type { MediaElement } from "../layers/media/types.js";
import type { NetworkFeature } from "../rest/support/types.js";
import type { AnalysisViewUnion } from "./analysis/types.js";
import type { EasingName } from "./animation/types.js";
import type { ViewEventTypes } from "./input/types.js";

/**
 * The object ID or the unique identifier string for a [Graphic](https://developers.arcgis.com/javascript/latest/references/core/Graphic/).
 *
 * @see [Graphic.getObjectId](https://developers.arcgis.com/javascript/latest/references/core/Graphic/#getObjectId)
 * @since 5.0
 */
export type ObjectId = number | string;

/**
 * The feature(s) to highlight when calling [highlight()](https://developers.arcgis.com/javascript/latest/references/core/views/layers/FeatureLikeLayerView/#highlight) method on a LayerView instance. When passing a graphic or array of graphics,
 * each feature must have a valid `objectId`.
 *
 * @see [FeatureLikeLayerView.highlight()](https://developers.arcgis.com/javascript/latest/references/core/views/layers/FeatureLikeLayerView/#highlight)
 * @since 5.0
 */
export type HighlightTarget = Graphic | Graphic[] | Collection<Graphic>;

/**
 * The pixels in a single band to highlight when calling [highlight()](https://developers.arcgis.com/javascript/latest/references/core/views/layers/ImageryLayerView/#highlight) method on
 * an [ImageryLayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/ImageryLayerView/) instance.
 *
 * @since 5.0
 */
export interface SingleBandPixelHighlightTarget {
  /**
   * An array of pixel value ranges to highlight. Each range is represented as a two-element array where the first element is the minimum value
   * and the second element is the maximum value of the range.
   */
  pixelRanges: [
      number,
      number
  ][];
  /** The band ID to which the pixel ranges apply. If not specified, the first band (band 0) is used by default. */
  bandId?: number;
}

/**
 * The pixels to highlight based on their values in two bands (an x-band and a y-band) when calling
 * [highlight()](https://developers.arcgis.com/javascript/latest/references/core/views/layers/ImageryLayerView/#highlight) on an [ImageryLayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/ImageryLayerView/) instance.
 *
 * @since 5.0
 */
export interface XYBandPixelHighlightTarget {
  /**
   * The pixel ranges to highlight based on their position in the band space with x-axis and y-axis representing corresponding pixel
   * values for the two selected bands.
   * This can be represented as an [Extent](https://developers.arcgis.com/javascript/latest/references/core/geometry/Extent/) or a [Polygon](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polygon/).
   */
  pixelRanges: Extent | Polygon;
  /** The band ID for the x-coordinate. */
  xBandId: number;
  /** The band ID for the y-coordinate. */
  yBandId: number;
}

/**
 * The pixel value(s) to highlight when calling [highlight()](https://developers.arcgis.com/javascript/latest/references/core/views/layers/ImageryLayerView/#highlight) method on
 * an [ImageryLayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/ImageryLayerView/) instance.
 *
 * @since 5.0
 */
export type PixelHighlightTarget = SingleBandPixelHighlightTarget | XYBandPixelHighlightTarget;

/** @since 5.0 */
export type TargetBase = number[] | GeometryUnion | GeometryUnion[] | Graphic | Graphic[] | Viewpoint;

/** @since 5.0 */
export type Target2D = TargetBase;

/** @since 5.0 */
export type Target3D = TargetBase | Camera;

/** @since 5.0 */
export interface TargetOptionsBase {
  /**
   * The [MapView.scale](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#scale)/[SceneView.scale](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#scale) to go to.
   *
   * @since 5.0
   */
  scale?: number;
  /**
   * The final [MapView.zoom](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#zoom)/[SceneView.zoom](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#zoom) value to go to.
   *
   * @since 5.0
   */
  zoom?: number;
}

/** @since 5.0 */
export interface TargetOptions2DBase extends TargetOptionsBase {}

/** @since 5.0 */
export interface CenterOptions2D extends TargetOptions2DBase {
  /**
   * The [MapView.center](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#center) to go to.
   *
   * @since 5.0
   */
  center?: number[] | Point;
}

/** @since 5.0 */
export interface TargetOptions2D extends TargetOptions2DBase {
  /**
   * The target of the animation.
   *
   * @since 5.0
   */
  target?: Target2D;
}

/** @since 5.0 */
export interface TargetOptions3DBase extends TargetOptionsBase {}

/** @since 5.0 */
export interface CenterOptions3D extends TargetOptions3DBase {
  /**
   * The [SceneView.center](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#center) to go to.
   *
   * @since 5.0
   */
  center?: number[] | Point;
}

/** @since 5.0 */
export interface TargetOptions3D extends TargetOptions3DBase {
  /**
   * The target of the animation.
   *
   * @since 5.0
   */
  target?: Target3D;
}

/**
 * The target location/viewpoint to animate to in the [MapView.goTo()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#goTo) method.
 * A two-element array of numbers represents the [x,y] coordinates to center the view on.
 * When using an object for the `target`, use the properties
 * in the table below.
 *
 * @since 5.0
 * @see [MapView.goTo()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#goTo)
 */
export type GoToTarget2D = TargetOptions2D | CenterOptions2D | Target2D;

/**
 * The target location/viewpoint to animate to in the [SceneView.goTo()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#goTo) method.
 * A two or three-element array of numbers represents the [x,y,z] coordinates to center the view on.
 * When using an object for the `target`, use the properties
 * in the table below.
 *
 * @since 5.0
 * @see [SceneView.goTo()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#goTo)
 */
export type GoToTarget3D = TargetOptions3D | CenterOptions3D | Target3D;

/**
 * User provided easing function. The function receives a normalized time between 0 and
 * 1 as input and should provide a transformed normalized time between 0 and 1 as output.
 *
 * @param t - The input time (from 0 to 1)
 * @param duration - The total duration (in milliseconds) of the animation. This may
 *   be used for heuristics on deciding what type of easing to perform.
 * @returns a value between 0 and 1
 * @since 5.0
 * @example
 * // Simple quadratic ease in function
 * function easeIn(t) {
 *   return t * t;
 * }
 */
export type EasingFunction = (t: number, duration: number) => number;

/** @since 5.0 */
export type AnimationMode = "always" | "auto";

/** @since 5.0 */
export interface GoToOptionsBase extends AbortOptions {
  /**
   * Indicates whether the transition to the new viewpoint is animated. If set to false, `speedFactor`, `duration`, `maxDuration`, and `easing` properties are ignored.
   * > [!WARNING]
   * >
   * >   Starting at 4.30, the default behavior of `goTo()` follows the user preference for [reduced motion](https://developers.arcgis.com/javascript/latest/accessibility/#reduced-motion).
   * >   By default, `goTo()` will animate, but when the user expresses a preference for reduced motion, `goTo()` will navigate to the specified target without animation.
   * >   It is possible to override the user's preference for reduced motion by configuring [esriConfig.respectPrefersReducedMotion](https://developers.arcgis.com/javascript/latest/references/core/config/#Config-respectPrefersReducedMotion)
   * >   or on a per-call basis by specifying the `animate` property.
   *
   * @default true
   * @since 5.0
   */
  animate?: boolean;
  /**
   * Set the exact duration (in milliseconds) of the animation. Note that by default, animation
   *   duration is calculated based on the time required to reach the target at a constant speed. Setting duration
   *   overrides the speedFactor option. Note that the resulting duration is still limited to the maxDuration.
   *
   * @since 5.0
   */
  duration?: number | null;
  /**
   * The easing function to use for
   *   the animation. This may either be a preset (named) function, or a user specified function. Supported named presets are:
   *     `linear`, `cubic-in`, `cubic-out`, `cubic-in-out`,
   *     `expo-in`, `expo-out`, `expo-in-out`, `quad-in-out-coast`,
   *     `ease-in`, `ease-out`, `ease-in-out`, as well as
   *     `in-cubic`, `out-cubic`, `in-out-cubic`,
   *     `in-expo`, `out-expo`, `in-out-expo`, and `in-out-coast-quad`.
   *   See [easing functions](https://easings.net/) and [CSS easing functions](https://developer.mozilla.org/docs/Web/CSS/easing-function#ease) for graphical representations of these functions.
   *
   * By default, animations that are less than 1000 ms use the `expo-out` easing function; longer animations use the `quad-in-out-coast` easing function.
   *
   * @since 5.0
   */
  easing?: EasingName | EasingFunction;
  /**
   * The maximum allowed duration (in milliseconds) of the animation. The
   *   default maxDuration value takes the specified speedFactor into account. If animationMode is set to "always",
   *   animations will be sped up to fit in this time. Otherwise, animations will not run if they exceed this time.
   *
   * @default isMapView ? 4000 : 8000
   * @since 5.0
   */
  maxDuration?: number;
  /**
   * Increases or decreases the animation speed by the specified factor. A speedFactor
   *   of 2 will make the animation twice as fast, while a speedFactor of 0.5 will make the animation half as fast. Setting
   *   the speed factor will automatically adapt the default maxDuration accordingly.
   *
   * @default 1
   * @since 5.0
   */
  speedFactor?: number;
}

/**
 * Animation options for the [MapView.goTo()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#goTo) method. See properties below for object specifications.
 *
 * @since 5.0
 */
export interface GoToOptions2D extends GoToOptionsBase {
  /**
   * The strategy for deciding whether the transition will animate when `animate` is not `false`, and the user has not expressed a preference for reduced motion.
   *   If set to `"auto"`, the view will automatically decide whether or not to animate, depending on an internal heuristic that considers time, distance, and the `maxDuration` option.
   *   If set to `"always"`, the transition will always animate.
   *
   * @default auto
   * @since 5.0
   */
  animationMode?: AnimationMode;
  /**
   * Indicates if the target geometry is normalized based on the [MapView.center](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#center) of the view.
   * When `true`, if the user pans more than 270 degrees east, the `goTo()` method will navigate the view 90 degrees west when panning to the designated target.
   * This property is only honored if [MapView.spatialReference.isWrappable](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#isWrappable) is `true`.
   *
   * @default true
   * @since 5.0
   */
  pickClosestTarget?: boolean;
}

/**
 * Animation options for the [SceneView.goTo()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#goTo) method. See properties below for parameter specifications.
 *
 * @since 5.0
 */
export interface GoToOptions3D extends GoToOptionsBase {}

/**
 * Options for the [MapView.toScreen()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#toScreen) method. See properties below for object specifications.
 *
 * @since 5.0
 */
export interface ToScreenOptions2D {
  /**
   * Indicates if the point will be normalized based on the [MapView.center](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#center) of the view.
   * When `true`, if the point is not in view, the result of toScreen() will not exceed the pixel equivalent of 180 degrees east or west of the center of the view.
   * This property is only honored if [MapView.spatialReference.isWrappable](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#isWrappable) is `true`.
   *
   * @default true
   * @since 5.0
   */
  pickClosestTarget?: boolean;
}

/**
 * The resulting features returned from the [Popup.fetchFeatures()](https://developers.arcgis.com/javascript/latest/references/core/widgets/Popup/#fetchFeatures) method.
 *
 * @since 5.0
 */
export interface FetchPopupFeaturesResult {
  /**
   * A promise containing [graphics](https://developers.arcgis.com/javascript/latest/references/core/Graphic/) from the selected location. This can be a combination of graphics derived from a [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/), and/or [graphics](https://developers.arcgis.com/javascript/latest/references/core/Graphic/) that reside directly on the view, ie. [View.graphics](https://developers.arcgis.com/javascript/latest/references/core/views/View/#graphics).
   *
   * @since 5.0
   */
  allGraphicsPromise: Promise<Graphic[]>;
  /**
   * An array of promises containing [graphics](https://developers.arcgis.com/javascript/latest/references/core/Graphic/) from the selected location. Each promise resolves to an array of graphics.
   *
   * @since 5.0
   */
  pendingFeatures: Promise<Graphic[]>[];
  /**
   * The resulting location of the [MapView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest) or [SceneView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest)'s' `hitTest`.
   *
   * @since 5.0
   */
  location?: Point | null;
}

/**
 * Object specification for the result returned in [ViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#ViewHitTestResult) of the [MapView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest) method.
 *
 * @since 4.24
 */
export type ViewHit = GraphicHit | MediaHit | RouteHit | LayerHit | RasterHit;

/**
 * Object specification for the graphic hit result returned in [ViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#ViewHitTestResult) of the [MapView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest) method.
 *
 * @since 4.24
 */
export interface GraphicHit {
  /** @since 5.0 */
  type: "graphic";
  /**
   * The point geometry in the spatial reference of the view corresponding with the input screen coordinates.
   *
   * @since 5.0
   */
  mapPoint?: Point | null;
  /**
   * A graphic present in the view that intersects the input screen coordinates. If a label intersects the input screen coordinates (since 4.11), the corresponding graphic is returned. If the graphic comes from a layer with an applied [Renderer](https://developers.arcgis.com/javascript/latest/references/core/renderers/Renderer/), then the [symbol](https://developers.arcgis.com/javascript/latest/references/core/Graphic/#symbol) property will be empty. Other properties may be empty based on the context in which the graphic is fetched.
   *
   * Some layers do not have a [graphic.geometry](https://developers.arcgis.com/javascript/latest/references/core/Graphic/#geometry) (for example: [VoxelLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/VoxelLayer/)). The [graphic.attributes](https://developers.arcgis.com/javascript/latest/references/core/Graphic/#attributes) only includes attributes which are loaded by the client, so it can be a subset of all attributes. [FeatureLayer.outFields](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#outFields) with `["*"]` can be used to force all attributes to be present.
   *
   * The [graphic.symbol](https://developers.arcgis.com/javascript/latest/references/core/Graphic/#symbol) exists only for graphics coming from [GraphicsLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GraphicsLayer/) or [view.graphics](https://developers.arcgis.com/javascript/latest/references/core/views/View/#graphics), but it is possible to compute the displayed symbology with [getDisplayedSymbol](https://developers.arcgis.com/javascript/latest/references/core/symbols/support/symbolUtils/#getDisplayedSymbol).
   *
   * If the result comes from a [VectorTileLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/VectorTileLayer/), result graphics contain attributes of style layers. The graphic's [origin](https://developers.arcgis.com/javascript/latest/references/core/Graphic/#origin) property contains `layerId` and `layerIndex` information, corresponding to the unique id and index of the style layer in the [vector tile style](https://developers.arcgis.com/rest/services-reference/vector-tile-style.htm). Spatial information about the actual feature represented in the style layer is returned only if the style layer is a [symbol layer](https://maplibre.org/maplibre-style-spec/layers/#symbol); otherwise, the graphic's geometry is `null`.
   *
   * @since 5.0
   */
  graphic: Graphic;
  /**
   * The layer that contains the feature/graphic.
   *
   * @since 5.0
   */
  layer: Layer;
}

/**
 * Object specification for the media hit results returned from [MediaLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/MediaLayer/) in [ViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#ViewHitTestResult) of the [MapView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest) method.
 *
 * @since 4.24
 */
export interface MediaHit {
  /** @since 5.0 */
  type: "media";
  /**
   * The point geometry in the spatial reference of the view corresponding with the input screen coordinates.
   *
   * @since 5.0
   */
  mapPoint?: Point | null;
  /**
   * The media layer that contains the element.
   *
   * @since 5.0
   */
  layer: MediaLayer;
  /**
   * An element representing a media element in [MediaLayer.source](https://developers.arcgis.com/javascript/latest/references/core/layers/MediaLayer/#source)
   * that intersects the input screen coordinates.
   *
   * @since 5.0
   */
  element: MediaElement;
  /**
   * An object representing a point on the element. The origin (0, 0) corresponds to the top-left corner of the element.
   *
   * @since 5.0
   */
  sourcePoint?: ScreenPoint | null;
}

/**
 * Object specification for the route hit results returned from [RouteLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/RouteLayer/) in [ViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#ViewHitTestResult) of the [MapView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest) method.
 *
 * @since 4.24
 */
export interface RouteHit {
  /** @since 5.0 */
  type: "route";
  /**
   * The route layer that contains the element.
   *
   * @since 5.0
   */
  layer: RouteLayer;
  /**
   * The point geometry in the spatial reference of the view corresponding with the input screen coordinates.
   *
   * @since 5.0
   */
  mapPoint?: Point | null;
  /**
   * The route hit test will contain all intersecting network elements which, includes one of the following: DirectionLine, DirectionPoint, PointBarrier, PolylineBarrier, PolygonBarrier, Stop, or RouteInfo.
   *
   * @since 5.0
   */
  networkFeature: NetworkFeature;
}

/**
 * Object specification for the layer hit results returned in [ViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#ViewHitTestResult) by [SceneView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest) when a [GaussianSplatLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GaussianSplatLayer/) is hit.
 *
 * @since 5.1
 */
export interface LayerHit {
  /** @since 5.1 */
  type: "layer";
  /**
   * The layer that intersects the input screen coordinates.
   *
   * @since 5.1
   */
  layer: Layer;
  /**
   * The point in the spatial reference of the view corresponding to the input screen coordinates.
   *
   * @since 5.1
   */
  mapPoint: Point;
}

/**
 * Object specification for the raster hit results returned from [ImageryLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/) or [ImageryTileLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryTileLayer/) in [ViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#ViewHitTestResult) of the [MapView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest) method.
 *
 * @since 5.1
 */
export interface RasterHit {
  /** @since 5.1 */
  type: "raster";
  /**
   * The raster layer that contains the element.
   *
   * @since 5.1
   */
  layer: ImageryTileLayer | ImageryLayer;
  /**
   * The point geometry in the spatial reference of the view corresponding with the input screen coordinates.
   *
   * @since 5.1
   */
  mapPoint: Point;
  /**
   * The pixel values at the hit location.
   *
   * @since 5.1
   */
  pixelValue: number[];
  /**
   * The band IDs corresponding to the pixel values.
   *
   * @since 5.1
   */
  bandIds: number[];
  /**
   * Indicates whether the pixel values represent magnitude and direction.
   *
   * @since 5.1
   */
  isMagnitudeAndDirection: boolean;
}

/**
 * Object specification for the result of the [MapView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest) method.
 *
 * @since 4.24
 */
export interface ViewHitTestResult {
  /**
   * The screen coordinates (or native mouse event) of the click on the view.
   *
   * @since 5.0
   */
  screenPoint?: ScreenPoint | null;
  /**
   * An array of result objects returned from the [MapView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest).
   * Results are returned when the location of the input screen coordinates intersects a [Graphic](https://developers.arcgis.com/javascript/latest/references/core/Graphic/),
   * [media element](https://developers.arcgis.com/javascript/latest/references/core/layers/support/ImageElement/), or [RouteLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/RouteLayer/) in the view.
   *
   * @since 5.0
   */
  results: ViewHit[];
}

/**
 * Object returned when [MapView.takeScreenshot()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#takeScreenshot) or [SceneView.takeScreenshot()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#takeScreenshot) promise resolves:
 *
 * @since 4.9
 */
export interface Screenshot {
  /**
   * A data url representing the screenshot.
   *
   * @since 5.0
   */
  dataUrl: string;
  /**
   * The raw RGBA image data.
   *
   * @since 5.0
   */
  data: ImageData;
}

/**
 * Encoding settings used when calling [MapView.takeScreenshot()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#takeScreenshot) or [SceneView.takeScreenshot()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#takeScreenshot) methods.
 *
 * @since 5.0
 */
export interface EncodingSettings {
  /**
   * The format of the encoded image data. Defaults to png.
   *
   * @default png
   * @since 5.0
   */
  format: "png" | "jpeg" | "jpg";
  /**
   * The quality (between 0 and 100) of the jpg encoded image data. Defaults to 90.
   *
   * @default 98
   * @since 5.0
   */
  quality: number;
}

/**
 * Common settings used when calling [MapView.takeScreenshot()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#takeScreenshot) or [SceneView.takeScreenshot()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#takeScreenshot) methods.
 *
 * @since 5.0
 */
export interface SettingsCommon extends EncodingSettings {
  /**
   * Indicates whether to ignore the background
   *   color set in the [initial view properties](https://developers.arcgis.com/javascript/latest/references/core/WebMap/#initialViewProperties) of the web map.
   *
   * @default false
   * @since 5.0
   */
  ignoreBackground?: boolean;
}

/**
 * Specifies whether to take a screenshot of a specific area of the view.
 *
 * @see [UserSettings](https://developers.arcgis.com/javascript/latest/references/core/views/types/#UserSettings)
 * @since 5.0
 */
export interface Rect {
  /**
   * The x coordinate of the area.
   *
   * @since 5.0
   */
  x: number;
  /**
   * The y coordinate of the area.
   *
   * @since 5.0
   */
  y: number;
  /**
   * The width of the area.
   *
   * @since 5.0
   */
  width: number;
  /**
   * The height of the area.
   *
   * @since 5.0
   */
  height: number;
}

/**
 * Param settings used to capture screenshots an area by calling [MapView.takeScreenshot()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#takeScreenshot) or [SceneView.takeScreenshot()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#takeScreenshot) methods.
 * Width and height indicate the target image's width and height.
 *
 * @since 5.0
 */
export interface UserSettings extends SettingsCommon {
  /**
   * The width of the screenshot (defaults to the area width). The
   *   height will be derived automatically if left unspecified, according to the aspect ratio of the
   *   of the screenshot area.
   *
   * @since 5.0
   */
  width: number;
  /**
   * The height of the screenshot (defaults to the area height). The
   *   width will be derived automatically if left unspecified, according to the aspect ratio of the
   *   screenshot area.
   *
   * @since 5.0
   */
  height: number;
  /**
   * Specifies whether to take a screenshot of a specific
   *   area of the view. The area coordinates are relative to the origin of the padded view (see
   *   [MapView.padding](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#padding)/[SceneView.padding](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#padding)) and will be clipped to the
   *   view size. Defaults to the whole view (padding excluded).
   *
   * @since 5.0
   */
  area: Rect;
  /**
   * An optional list of layers to be included in the screenshot.
   *
   * @since 5.0
   */
  layers?: ReadonlyArrayOrCollection<Layer>;
  /**
   * Indicates whether view padding should be ignored.
   *   Set this property to `true` to allow padded areas to be included in the screenshot.
   *
   * @default false
   * @since 5.0
   */
  ignorePadding: boolean;
}

/**
 * Type extension that adds `distance` property to hit test results.
 *
 * @since 5.0
 */
export type HitExtension<T> = T
  & {
  /**
   * The distance from the camera position to the point geometry hit on this graphic. In global scenes the distance will be in meters while in local scenes
   * the distance will be in the unit of the spatial reference of the view.
   *
   * @since 5.0
   */
  distance: number;
};

/**
 * Object specification for the result returned in [SceneViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#SceneViewHitTestResult) of the [SceneView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest) method.
 *
 * @since 4.24
 */
export type SceneViewHit = SceneViewGraphicHit | SceneViewMediaHit | SceneViewRouteHit | SceneViewLayerHit;

/**
 * Object specification for the graphic hit result returned in [SceneViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#SceneViewHitTestResult) of the [SceneView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest) method.
 *
 * @since 4.24
 */
export type SceneViewGraphicHit = HitExtension<GraphicHit>;

/**
 * Object specification for the media hit results returned from [MediaLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/MediaLayer/) in [SceneViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#SceneViewHitTestResult) of the [SceneView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest) method.
 *
 * @since 4.24
 */
export type SceneViewMediaHit = HitExtension<MediaHit>;

/**
 * Object specification for the route hit results returned from [RouteLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/RouteLayer/) in [SceneViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#SceneViewHitTestResult) of the [SceneView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest) method.
 *
 * @since 4.24
 */
export type SceneViewRouteHit = HitExtension<RouteHit>;

/**
 * Object specification for the layer hit results returned in [SceneViewHitTestResult](https://developers.arcgis.com/javascript/latest/references/core/views/types/#SceneViewHitTestResult) of the [SceneView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest) method.
 *
 * Currently this hit type is returned from [GaussianSplatLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GaussianSplatLayer/).
 *
 * @since 5.1
 */
export type SceneViewLayerHit = HitExtension<LayerHit>;

/**
 * Object specification for the result of the [SceneView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest) method.
 *
 * @since 4.24
 */
export interface SceneViewHitTestResult extends ViewHitTestResult {
  /**
   * An array of result objects returned from the [SceneView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest)
   * when the location of the input screen coordinates intersect features in the view.
   *
   * @since 5.0
   */
  results: SceneViewHit[];
  /**
   * Ground intersection result. The ground hit result will always be returned, even if the ground was excluded from the [SceneView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest).
   *
   * @since 5.0
   */
  ground: SceneViewHitTestResultGround;
}

/** @since 5.0 */
export interface SceneViewHitTestResultGround {
  /**
   * The point at which the ground was hit while performing the
   *   hitTest. This may be `null` when the ground was not hit at all (for example by clicking on the sky).
   *
   * @since 5.0
   */
  mapPoint: Point;
  /**
   * The distance from camera position to the ground hit. The distance will be `0` if the ground was not hit at all. In global scenes the distance will be in meters while in local scenes the distance will be in the unit of the spatial reference of the view.
   *
   * @since 5.0
   */
  distance: number;
}

/**
 * A layer, graphic, or collection of layers or graphics to be used in the MapView's [hitTest](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest) filter options.
 *
 * @since 5.0
 * @see [MapView.hitTest()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest)
 */
export type HitTestItem = Layer | SubtypeSublayer | Graphic;

/**
 * A layer, graphic, or collection of layers or graphics to be used in the MapView's [hitTest](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest) filter options.
 *
 * @since 5.0
 */
export type HitTestOptionsItem = HitTestItem | Iterable<HitTestItem | Iterable<HitTestItem>>;

/**
 * Options for specifying which [HitTestItem](https://developers.arcgis.com/javascript/latest/references/core/views/types/#HitTestItem) are included or excluded when calling the MapView’s [hitTest](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#hitTest) method.
 *
 * @since 5.0
 */
export interface HitTestOptions {
  /**
   * A list of layers and graphics to include in the hitTest. All layers and graphics will be
   *   included if include is not specified.
   *
   * @since 5.0
   */
  include?: HitTestOptionsItem | null;
  /**
   * A list of layers and graphics to exclude from the hitTest. No layers or graphics will be
   *   excluded if exclude is not specified.
   *
   * @since 5.0
   */
  exclude?: HitTestOptionsItem | null;
}

/**
 * Intersection test options. By default the [Map.ground](https://developers.arcgis.com/javascript/latest/references/core/Map/#ground) is excluded if its opacity is smaller than one.
 *
 * @since 5.0
 */
export type HitTestItem3D = HitTestItem | Ground | BuildingSublayer;

/**
 * A layer, graphic, or collection of layers or graphics to be used in the SceneView's [hitTest](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest) filter options.
 *
 * @since 5.0
 */
export type HitTestOptions3DItem = HitTestItem3D | Iterable<HitTestItem3D | Iterable<HitTestItem3D>>;

/**
 * Options for specifying which [HitTestItem3D](https://developers.arcgis.com/javascript/latest/references/core/views/types/#HitTestItem3D) are included or excluded when calling the SceneView's [hitTest](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#hitTest) method.
 *
 * @since 5.0
 */
export interface HitTestOptions3D {
  /**
   * A list of layers and graphics to include for intersection testing. All layers and graphics
   *   will be included if include is not specified.
   *
   * @since 5.0
   */
  include?: HitTestOptions3DItem | null;
  /**
   * A list of layers and graphics to exclude for intersection testing. No layers or graphics
   *   will be excluded if exclude is not specified.
   *
   * @since 5.0
   */
  exclude?: HitTestOptions3DItem | null;
}

/**
 * A convenience property used for defining the breakpoints on the [height](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#height)
 * and [width](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#width) of the view. The sizes specified here determine the values of
 * the [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) and [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint)
 * properties depending on the view's size.
 *
 *  Setting up breakpoints can aid in responsive app design. It does this
 *  by watching width and height breakpoints. This is helpful as it removes
 *  the need for multiple [`@media` calls](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries).
 *  Instead of listening for the view's size and/or resizes property,
 *  you can set up a watch handler for either the  [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) or
 *  [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint) properties of the view.
 *
 * > [!WARNING]
 * >
 * > Please refer to the [styling guide](https://developers.arcgis.com/javascript/latest/styling/#view-size-css-classes) for additional
 * > information on working with this.
 *
 * @since 5.0
 * @see [BreakpointsOwner.breakpoints](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#breakpoints)
 */
export interface Breakpoints {
  /**
   * Sets the `xsmall` breakpoint in pixels used by
   * [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) and [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint). If the
   * view's [height](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#height) or [width](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#width) is smaller than this value, then the value of
   * [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) or [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint) will
   * be `xsmall`.
   *
   * @default 544
   * @since 5.0
   */
  xsmall: number;
  /**
   * Sets the `small` breakpoint in pixels used by
   * [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) and [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint). If the
   * view's [height](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#height) or [width](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#width) is between this value and the value
   * of the `xsmall` property, then the value of
   * [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) or [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint) will
   * be `small`.
   *
   * @default 768
   * @since 5.0
   */
  small: number;
  /**
   * Sets the `medium` breakpoint in pixels used by
   * [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) and [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint). If the
   * view's [height](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#height) or [width](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#width) is between this value and the value
   * of the `small` property, then the value of
   * [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) or [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint) will
   * be `medium`.
   *
   * @default 992
   * @since 5.0
   */
  medium: number;
  /**
   * Sets the `large` breakpoint in pixels used by
   * [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) and [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint). If the
   * view's [height](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#height) or [width](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#width) is between this value and the value
   * of the `medium` property, then the value of
   * [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) or [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint) will
   * be `large`.
   * [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) and [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint). If the
   * view's [height](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#height) or [width](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#width) is greater than the value
   * of the `large` property, then the value of
   * [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint) or [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint) will
   * be `xlarge`.
   *
   * @default 1200
   * @since 5.0
   */
  large: number;
}

/**
 * A convenience property indicating the view's orientation. See the table below for a list of possible values.
 *
 * > [!WARNING]
 * >
 * > Please refer to the [styling guide](https://developers.arcgis.com/javascript/latest/styling/#view-size-css-classes) for additional
 * > information on working with this.
 *
 * Possible Value | Description
 * ---------------|------------
 * landscape | The [width](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#width) of the view is greater than its [height](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#height).
 * portrait | The [width](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#width) of the view is equal to or smaller than its [height](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#height).
 *
 * @since 5.0
 */
export type BreakpointOrientation = "landscape" | "portrait";

/**
 * Indicates the general size of the view's width or height. This value is
 * determined based on where the view's [width](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#width) or [height](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#height) falls in the ranges defined
 * in the [breakpoints](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#breakpoints) property. See the table below
 * for a list of possible values. Use the [breakpoints](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#breakpoints) property to
 * override the default thresholds.
 *
 * Possible Value | Description | Default thresholds (pixels)
 * ---------------|-------------|-------------------
 * xsmall | The width or height of the view is smaller than the value set in the `xsmall` [breakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#breakpoints). | < 545
 * small | The width or height of the view is between the values set in the `xsmall` and `small` [breakpoints](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#breakpoints). | 545 - 768
 * medium | The width or height of the view is between the values set in the `small` and `medium` [breakpoints](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#breakpoints). | 769 - 992
 * large | The width or height of the view is between the values set in the `medium` and `large` [breakpoints](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#breakpoints). | 993 - 1200
 * xlarge | The width or height of the view is larger than the value set in the `large` [breakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#breakpoints). | > 1200
 *
 * @since 5.0
 * @see [widthBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#widthBreakpoint)
 * @see [heightBreakpoint](https://developers.arcgis.com/javascript/latest/references/core/views/BreakpointsOwner/#heightBreakpoint)
 */
export type BreakpointSize = "xsmall" | "small" | "medium" | "large" | "xlarge";

/** @since 5.0 */
export interface AnalysisViewCreateEvent {
  /**
   * The analysis for which the `analysisView` was created.
   *
   * @since 5.0
   */
  analysis: Analysis;
  /**
   * The analysis view that was created.
   *
   * @since 5.0
   */
  analysisView: AnalysisViewUnion;
}

/** @since 5.0 */
export interface AnalysisViewCreateErrorEvent {
  /**
   * The analysis for which the `analysisView` was created.
   *
   * @since 5.0
   */
  analysis: Analysis;
  /**
   * An error object describing why the analysis view could not be created.
   *
   * @since 5.0
   */
  error: Error;
}

/** @since 5.0 */
export interface AnalysisViewDestroyEvent {
  /**
   * The analysis whose analysis view was destroyed.
   *
   * @since 5.0
   */
  analysis: Analysis;
  /**
   * The analysis view that was destroyed.
   *
   * @since 5.0
   */
  analysisView: AnalysisViewUnion;
}

/** @since 5.0 */
export interface AnalysisViewEvents {
  /**
   * Fires when the view for an [Analysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/Analysis/) is created.
   *
   * @since 5.0
   * @see [MapView.whenAnalysisView()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#whenAnalysisView)
   * @see [SceneView.whenAnalysisView()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#whenAnalysisView)
   */
  "analysis-view-create": AnalysisViewCreateEvent;
  /**
   * Fires when an error occurs during the creation of an [Analysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/Analysis/) after an analysis
   * is added to the view.
   *
   * @since 5.0
   * @see [MapView.whenAnalysisView()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#whenAnalysisView)
   * @see [SceneView.whenAnalysisView()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#whenAnalysisView)
   */
  "analysis-view-create-error": AnalysisViewCreateErrorEvent;
  /**
   * Fires after an [analysis view](https://developers.arcgis.com/javascript/latest/references/core/unionTypes/#AnalysisViewUnion) is destroyed.
   *
   * @since 5.0
   */
  "analysis-view-destroy": AnalysisViewDestroyEvent;
}

/** @since 5.0 */
export type SceneViewEventTypes = ViewEventTypes
  & AnalysisViewEvents;

/** @internal */
export interface PersistableComponent {
  /**
   * Updates the web document (either a [WebDocument2D](https://developers.arcgis.com/javascript/latest/references/core/WebDocument2D/) or [WebScene](https://developers.arcgis.com/javascript/latest/references/core/WebScene/)) with the state of this component
   * so that it can be persisted as part of the web document.
   *
   * @param document - The web document to update with the state of this component.
   * @internal
   */
  updateWebDocument(document: WebDocument2D | WebScene): void;
}