import type Extent from "../../geometry/Extent.js";
import type SpatialReference from "../../geometry/SpatialReference.js";
import type RasterBandInfo from "./RasterBandInfo.js";
import type RasterSensorInfo from "./RasterSensorInfo.js";
import type FeatureSet from "../../rest/support/FeatureSet.js";
import type { JSONSupport } from "../../core/JSONSupport.js";
import type { PixelSize, RasterBandStatistics, RasterDataType, RasterHistogram, RasterMultidimensionalInfo, RasterPixelType } from "../raster/types.js";
import type { ExtentProperties } from "../../geometry/Extent.js";
import type { SpatialReferenceProperties } from "../../geometry/SpatialReference.js";

export interface RasterInfoProperties extends Partial<Pick<RasterInfo, "attributeTable" | "bandCount" | "colormap" | "height" | "histograms" | "keyProperties" | "multidimensionalInfo" | "noDataValue" | "pixelSize" | "pixelType" | "statistics" | "width">> {
  /** The minimum and maximum X and Y coordinates of a bounding box containing all the raster data. */
  extent?: ExtentProperties;
  /** The spatial reference of the raster. */
  spatialReference?: SpatialReferenceProperties;
}

/**
 * Describes general raster data information exposed by the ArcGIS REST API for
 * [ImageryLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/), [ImageryTileLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryTileLayer/) and [WCSLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/WCSLayer/).
 * RasterInfo contains information such band count, statistics, data type, dimensions and key properties.
 *
 * @since 4.12
 * @see [ImageryLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/)
 * @see [ImageryTileLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryTileLayer/)
 * @see [WCSLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/WCSLayer/)
 * @see [Raster info](https://developers.arcgis.com/rest/services-reference/raster-info.htm)
 */
export default class RasterInfo extends JSONSupport {
  constructor(properties: RasterInfoProperties);
  /**
   * The raster attribute table associated with an imagery layer.
   * It returns categorical mapping of pixel values such as
   * class, group, or category, or membership.
   *
   * @see [Sample - Raster attribute table](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagery-attribute-table/)
   * @see [Raster Attribute Table](https://developers.arcgis.com/rest/services-reference/raster-attribute-table.htm)
   * @example
   * layer.when(function() {
   *   // accesses the raster attribute table of the layer
   *   let rasterAttributes = layer.serviceRasterInfo.attributeTable.features;
   * });
   */
  accessor attributeTable: FeatureSet | null | undefined;
  /** Raster band count. */
  accessor bandCount: number;
  /**
   * This property provides additional information for each band in the raster. Raster products will include information
   * such as the color name, wavelength range, the radiance gain, radiance bias, and solar irradiance.
   * All other raster datasets will only contain the band index value.
   *
   * @since 4.27
   */
  get bandInfos(): RasterBandInfo[];
  /**
   * Raster colormap that can be used to display the imagery layer.
   * Each element in the array defines the pixel value and the red, green, and blue color values.
   *
   * @see [Raster colormap](https://developers.arcgis.com/rest/services-reference/colormap.htm)
   */
  accessor colormap: number[][] | null | undefined;
  /**
   * Raster data type controls how the data is rendered by default.
   *
   * Value | Description |
   * ----- | ----------- |
   * generic | Uses the application defaults for resampling and stretching.
   * elevation | Applies bilinear resampling and a [Min-Max stretch](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#stretchType).
   * thematic | Applies nearest neighbor resampling and a [Standard Deviation stretch](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#stretchType).
   * processed | No stretch is applied.
   * scientific | Uses the blue to red color ramp to display the data.
   * vector-uv | Uses the U (magnitude component) and V(direction component) components in the vector field renderer.
   * vector-magdir | Uses the magnitude and direction in the vector field renderer.
   * standard-time | Uses the blue to red color ramp to display the data --- pixel value represents time encoded using OLEDate.
   */
  get dataType(): RasterDataType;
  /** The minimum and maximum X and Y coordinates of a bounding box containing all the raster data. */
  get extent(): Extent;
  set extent(value: ExtentProperties);
  /**
   * Indicates whether the source multidimensional data has been transposed.
   * This only applies to [ImageryTileLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryTileLayer/) that references multidimensional image service.
   *
   * @since 4.25
   */
  get hasMultidimensionalTranspose(): boolean;
  /**
   * Raster height (row count) in pixels.
   *
   * @since 4.15
   */
  accessor height: number;
  /**
   * Raster histograms return basic name-value pairs for number of bins, min and
   * max bounding values, counts of pixels in each bin.
   *
   * @see [Raster histograms](https://developers.arcgis.com/rest/services-reference/histograms.htm)
   */
  accessor histograms: RasterHistogram[] | null | undefined;
  /**
   * Raster key properties.
   *
   * @see [Raster key properties](https://developers.arcgis.com/rest/services-reference/key-properties.htm)
   */
  accessor keyProperties: Record<string, any>;
  /**
   * Returns the multidimensional information associated with the raster service referenced in an imagery layer.
   * If defined, it contains an information on variables and dimensions associated with the service. Multidimensional data is stored as variables where each
   * variable is a multidimensional array represents data captured in multiple dimensions like times and depths/heights.
   *
   * You can filter the multidimensional data with one or multiple dimensional slices by setting the [MosaicRule.multidimensionalDefinition](https://developers.arcgis.com/javascript/latest/references/core/layers/support/MosaicRule/#multidimensionalDefinition)
   * property on an [ImageryLayer.mosaicRule](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/#mosaicRule) or by setting the `multidimensionalDefinition` property on an [ImageryTileLayer.multidimensionalDefinition](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryTileLayer/#multidimensionalDefinition) or
   * a [WCSLayer.multidimensionalDefinition](https://developers.arcgis.com/javascript/latest/references/core/layers/WCSLayer/#multidimensionalDefinition).
   *
   * @see [ImageryLayer - working with multidimensional raster data](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/#multidimensionaldata)
   * @see [ImageryTileLayer - working with multidimensional raster data](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryTileLayer/#multidimensionaldata)
   * @see [Sample - Transposed multidimensional ImageryTileLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-hosted-imagerytilelayer/)
   * @example
   * // update the statistics of the layer's stretch renderer.
   * const renderer = layer.renderer.clone();
   *  const dimensions = layer.rasterInfo.multidimensionalInfo;
   * // get the salinity variable's statistics
   * const salinity = dimensions.variables.find((variable) => variable.name === variableName);
   * renderer.customStatistics = salinity.statistics;
   * layer.renderer = renderer;
   */
  accessor multidimensionalInfo: RasterMultidimensionalInfo | null | undefined;
  /**
   * The pixel value representing no available information.
   * Can be a number (same value for all bands) or array (specific value for each band).
   *
   * @since 4.15
   */
  accessor noDataValue: number | Array<number | null | undefined> | null | undefined;
  /**
   * Raster pixel size. Specifies the pixel size being identified on the x and y axis.
   * Defaults to the base resolution of the dataset when not specified.
   */
  accessor pixelSize: PixelSize;
  /**
   * Pixel type for the raster data source.
   *
   * Value | Range of values that each cell can contain |
   * ----- | ------------------------------------------- |
   * unknown | Pixel type is unknown |
   * s8 | -128 to 127 |
   * s16 | -32768 to 32767 |
   * s32 | -2147483648 to 2147483647 |
   * u8 | 0 to 255 |
   * u16 | 0 to 65535
   * u32 | 0 to 4294967295
   * f32 | -3.402823466e+38 to 3.402823466e+38
   * f64 | 0 to 18446744073709551616
   */
  accessor pixelType: RasterPixelType;
  /**
   * The sensor information associated with an image service referenced by a layer.
   *
   * @since 4.27
   */
  get sensorInfo(): RasterSensorInfo | null | undefined;
  /** The spatial reference of the raster. */
  get spatialReference(): SpatialReference;
  set spatialReference(value: SpatialReferenceProperties);
  /** Raster band statistics. These include the minimum value in the raster, maximum value, mean of all values, and standard deviation. */
  accessor statistics: RasterBandStatistics[] | null | undefined;
  /**
   * Raster width (column count) in pixels.
   *
   * @since 4.15
   */
  accessor width: number;
}