import type Extent from "../../geometry/Extent.js";
import type Point from "../../geometry/Point.js";
import type Polygon from "../../geometry/Polygon.js";
import type MosaicRule from "../../layers/support/MosaicRule.js";
import type RasterFunction from "../../layers/support/RasterFunction.js";
import type TimeExtent from "../../time/TimeExtent.js";
import type { JSONSupport } from "../../core/JSONSupport.js";
import type { ExtentProperties } from "../../geometry/Extent.js";
import type { PolygonProperties } from "../../geometry/Polygon.js";
import type { PointProperties } from "../../geometry/Point.js";
import type { MosaicRuleProperties } from "../../layers/support/MosaicRule.js";
import type { RasterFunctionProperties } from "../../layers/support/RasterFunction.js";
import type { TimeExtentProperties } from "../../time/TimeExtent.js";

export interface ImageIdentifyParametersProperties extends Partial<Pick<ImageIdentifyParameters, "maxItemCount" | "processAsMultidimensional" | "returnCatalogItems" | "returnGeometry" | "returnPixelValues">> {
  /**
   * Input geometry that defines the location to be identified.
   * The location can be a point, a polygon or extent (requires 10.9.1 or newer server).
   */
  geometry?: (PointProperties & { type: "point" }) | (PolygonProperties & { type: "polygon" }) | (ExtentProperties & { type: "extent" });
  /**
   * Specifies the mosaic rules defining the image sorting order.
   * When a mosaic rule is not specified, `center` is used.
   */
  mosaicRule?: MosaicRuleProperties | null;
  /**
   * Specifies the pixel level being identified on the x and y axis. Defaults to the base resolution of the dataset when not specified.
   * The raster at the specified pixel size in the mosaic dataset will be used for the
   * the [ImageryLayer.identify()](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/#identify) operation on an [ImageryLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/).
   *
   * @example
   * // set the pixel size parameter to match the current
   * // resolution of the view and spatial reference
   * let pixelSize = {
   *   x:view.resolution,
   *   y:view.resolution,
   *   spatialReference: view.spatialReference
   * }
   * // set the identify parameters
   * // data for the current view extent and resolution
   * let params = new ImageIdentifyParameters({
   *   geometry:  view.extent,
   *   pixelSize: pixelSize
   * });
   *
   * // request info for a given location for the specified parameters
   * layer.identify(params).then((result) => {
   *   // results are returned and process it as needed.
   *   console.log("identify result", result);
   * })
   * .catch(function(error){
   *   console.log("error", error)
   * });
   */
  pixelSize?: PointProperties | null;
  /**
   * Specifies the raster function for how the requested image should be processed.
   *
   * @since 4.27
   */
  rasterFunction?: RasterFunctionProperties | null;
  /**
   * An array the [raster functions](https://developers.arcgis.com/javascript/latest/references/core/rest/support/ImageIdentifyParameters/#rasterFunction) to retrieve multiple processed pixel values.
   *
   * @since 4.27
   */
  rasterFunctions?: RasterFunctionProperties[] | null;
  /**
   * A time extent for a temporal data against [time-aware imagery layer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/#timeInfo).
   * For example, it can be used to discover land cover changes by decade.
   */
  timeExtent?: TimeExtentProperties | null;
}

/**
 * Input parameters for [imageService](https://developers.arcgis.com/javascript/latest/references/core/rest/imageService/).
 *
 * @since 4.20
 * @see [imageService](https://developers.arcgis.com/javascript/latest/references/core/rest/imageService/)
 * @see [ImageIdentifyResult](https://developers.arcgis.com/javascript/latest/references/core/rest/support/ImageIdentifyResult/)
 */
export default class ImageIdentifyParameters extends JSONSupport {
  constructor(properties?: ImageIdentifyParametersProperties);
  /**
   * Input geometry that defines the location to be identified.
   * The location can be a point, a polygon or extent (requires 10.9.1 or newer server).
   */
  get geometry(): Point | Polygon | Extent;
  set geometry(value: (PointProperties & { type: "point" }) | (PolygonProperties & { type: "polygon" }) | (ExtentProperties & { type: "extent" }));
  /**
   * Controls the maximum number of returned catalog items, set to 1 to return
   * the top most raster only.
   */
  accessor maxItemCount: number | null | undefined;
  /**
   * Specifies the mosaic rules defining the image sorting order.
   * When a mosaic rule is not specified, `center` is used.
   */
  get mosaicRule(): MosaicRule | null | undefined;
  set mosaicRule(value: MosaicRuleProperties | null | undefined);
  /**
   * Specifies the pixel level being identified on the x and y axis. Defaults to the base resolution of the dataset when not specified.
   * The raster at the specified pixel size in the mosaic dataset will be used for the
   * the [ImageryLayer.identify()](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/#identify) operation on an [ImageryLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/).
   *
   * @example
   * // set the pixel size parameter to match the current
   * // resolution of the view and spatial reference
   * let pixelSize = {
   *   x:view.resolution,
   *   y:view.resolution,
   *   spatialReference: view.spatialReference
   * }
   * // set the identify parameters
   * // data for the current view extent and resolution
   * let params = new ImageIdentifyParameters({
   *   geometry:  view.extent,
   *   pixelSize: pixelSize
   * });
   *
   * // request info for a given location for the specified parameters
   * layer.identify(params).then((result) => {
   *   // results are returned and process it as needed.
   *   console.log("identify result", result);
   * })
   * .catch(function(error){
   *   console.log("error", error)
   * });
   */
  get pixelSize(): Point | null | undefined;
  set pixelSize(value: PointProperties | null | undefined);
  /**
   * When `true`, the request is processed for all variables and dimensions. Pixel values from all slices
   * along with additional properties describing the slices, will be returned.
   * When `false`, the request is processed for the first or selected slices only. It is only applicable when the service is
   * multidimensional. This capability is only available with image services published with ArcGIS Server 10.9 or greater.
   *
   * @default false
   * @since 4.23
   */
  accessor processAsMultidimensional: boolean;
  /**
   * Specifies the raster function for how the requested image should be processed.
   *
   * @since 4.27
   */
  get rasterFunction(): RasterFunction | null | undefined;
  set rasterFunction(value: RasterFunctionProperties | null | undefined);
  /**
   * An array the [raster functions](https://developers.arcgis.com/javascript/latest/references/core/rest/support/ImageIdentifyParameters/#rasterFunction) to retrieve multiple processed pixel values.
   *
   * @since 4.27
   */
  get rasterFunctions(): RasterFunction[] | null | undefined;
  set rasterFunctions(value: RasterFunctionProperties[] | null | undefined);
  /**
   * If `true`, returns both geometry and attributes of the catalog items.
   * Set to `false` when catalog items are not needed to significantly
   * improve identify operation's performance.
   *
   * @default true
   */
  accessor returnCatalogItems: boolean;
  /**
   * When `true`, each feature in the catalog items includes the geometry.
   * When `false`, the features will not display on the map.
   *
   * @default true
   */
  accessor returnGeometry: boolean;
  /**
   * If `true`, the pixel values of all raster catalog items under the requested geometry.
   * Set to `false` when catalog item values are not needed to significantly
   * improve identify operation's performance.
   *
   * @default true
   */
  accessor returnPixelValues: boolean;
  /**
   * A time extent for a temporal data against [time-aware imagery layer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/#timeInfo).
   * For example, it can be used to discover land cover changes by decade.
   */
  get timeExtent(): TimeExtent | null | undefined;
  set timeExtent(value: TimeExtentProperties | null | undefined);
}