import type ColorRamp from "../rest/support/ColorRamp.js";
import type { JSONSupport } from "../core/JSONSupport.js";
import type { RasterBandStatistics } from "../layers/raster/types.js";
import type { RasterStretchType } from "./support/raster/types.js";
import type { ColorRampProperties } from "../rest/support/ColorRamp.js";

export interface RasterStretchRendererProperties extends Partial<Pick<RasterStretchRenderer, "computeGamma" | "customStatistics" | "dynamicRangeAdjustment" | "gamma" | "maxPercent" | "minPercent" | "numberOfStandardDeviations" | "outputMax" | "outputMin" | "sigmoidStrengthLevel" | "stretchType" | "useGamma">> {
  /**
   * The stretched values are mapped to this specified color ramp.
   * The color ramp algorithm must set when using this renderer, otherwise the `cie-lab` [AlgorithmicColorRamp.algorithm](https://developers.arcgis.com/javascript/latest/references/core/rest/support/AlgorithmicColorRamp/#algorithm)
   * used by default.
   *
   * @see [ImageryLayer rendering](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/#rendering)
   */
  colorRamp?: ColorRampProperties | null;
}

/**
 * RasterStretchRenderer defines the symbology with a gradual ramp of colors for each pixel in a [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/) based on the pixel value.
 * The RasterStretchRenderer works well when you have a large range of values to display, such as in imagery,
 * aerial photographs, or elevation models.
 *
 * The stretch renderer allows you to define the range of values to be displayed and apply
 * a [ColorRamp](https://developers.arcgis.com/javascript/latest/references/core/rest/support/ColorRamp/) to those values.
 *
 * @since 4.12
 * @see [Sample - Intro to ImageryTileLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagerytilelayer/)
 * @see [Learn about the contrast stretches to improve the display](https://pro.arcgis.com/en/pro-app/latest/help/analysis/raster-functions/stretch-function.htm)
 * @see [Learn how to use the Stretched renderer](https://desktop.arcgis.com/en/arcmap/latest/manage-data/raster-and-images/drawing-a-continuous-raster-dataset-such-as-an-orthophoto.htm)
 */
export default class RasterStretchRenderer extends JSONSupport {
  constructor(properties?: RasterStretchRendererProperties);
  /**
   * The stretched values are mapped to this specified color ramp.
   * The color ramp algorithm must set when using this renderer, otherwise the `cie-lab` [AlgorithmicColorRamp.algorithm](https://developers.arcgis.com/javascript/latest/references/core/rest/support/AlgorithmicColorRamp/#algorithm)
   * used by default.
   *
   * @see [ImageryLayer rendering](https://developers.arcgis.com/javascript/latest/references/core/layers/ImageryLayer/#rendering)
   */
  get colorRamp(): ColorRamp | null | undefined;
  set colorRamp(value: ColorRampProperties | null | undefined);
  /**
   * The computeGamma automatically calculates best gamma value to render exported image based on empirical model.
   * This is applicable to any stretch type when [useGamma](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#useGamma) is `true`.
   *
   * @default false
   */
  accessor computeGamma: boolean;
  /**
   * The input band statistics can be specified through the customStatistics property. If not specified,
   * they will be retrieved from the data. If [dynamicRangeAdjustment](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#dynamicRangeAdjustment) is `true`, these values will be ignored.
   *
   * @since 4.31
   * @see [Learn about calculating statistics](https://pro.arcgis.com/en/pro-app/latest/help/analysis/raster-functions/statistics-function.htm)
   * @example
   * for single band stretch
   * const bandStat = layer.rasterInfo.statistics[0];
   * const renderer = new RasterStretchRenderer();
   * renderer.stretchType = "min-max";
   * renderer.customStatistics = [{
   *   min: valueSlider.values[0],
   *   max: valueSlider.values[1],
   *   avg: bandStat.avg,
   *   stddev: bandStat.stddev
   * }];
   * @example
   * for RGB (e.g. layer.bandIds = [3,2,1])
   * const stats = layer.rasterInfo.statistics;
   * const bandIds = layer.bandIds;
   * const renderer = new RasterStretchRenderer();
   * renderer.stretchType = "min-max";
   * renderer.customStatistics = [{
   *   min: redSlider.values[0],
   *   max: redSlider.values[1],
   *   avg: stats[bandIds[0]].avg,
   *   stddev: stats[bandIds[0]].stddev,
   * }, {
   *   min: greenSlider.values[0],
   *   max: greenSlider.values[1],
   *   avg: stats[bandIds[1]].avg,
   *   stddev: stats[bandIds[1]].stddev,
   * }, {
   *   min: valueSlider.values[0],
   *   max: valueSlider.values[1],
   *   avg: stats[bandIds[2]].avg,
   *   stddev: stats[bandIds[2]].stddev
   * }];
   */
  accessor customStatistics: RasterBandStatistics[] | null | undefined;
  /**
   * When Dynamic Range Adjustment is `true`, the statistics based on the current display extent
   * are calculated as you zoom and pan around the image. This property only applies to images in
   * [2D MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/).
   *
   * @default false
   */
  accessor dynamicRangeAdjustment: boolean;
  /**
   * The gamma values to be used if [useGamma](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#useGamma) is set to `true`.
   * Gamma refers to the degree of contrast between the mid-level gray values of a raster dataset.
   * Gamma does not affect the black or white values in a raster dataset, only the middle values.
   * By applying a gamma correction, you can control the overall brightness of a layer.
   * Gamma stretching is only valid with the `none`, `standard-deviation`, and `min-max` [stretch types](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#stretchType).
   */
  accessor gamma: number[];
  /**
   * Applicable when [stretchType](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#stretchType) is `percent-clip`.
   * Specifies the percentage of the highest values to exclude from the stretch.
   */
  accessor maxPercent: number | null | undefined;
  /**
   * Applicable when [stretchType](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#stretchType) is `percent-clip`.
   * Specifies the percentage of the lowest values to exclude from the stretch.
   */
  accessor minPercent: number | null | undefined;
  /**
   * Applicable when [stretchType](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#stretchType) is `standard-deviation`.
   * Specifies the number of standard deviations to use. The values beyond the number of standard deviations
   * become the [outputMin](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#outputMin) and [outputMax](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#outputMax). The remaining values are linearly stretched
   * between [outputMin](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#outputMin) and [outputMax](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#outputMax).
   */
  accessor numberOfStandardDeviations: number | null | undefined;
  /**
   * The outputMax denotes the output maximum, which is the highest pixel value.
   * The [outputMin](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#outputMin) and [outputMax](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#outputMax) will set the range of values that will then be linearly contrast stretched.
   * The outputMax value ranges from 0-255.
   */
  accessor outputMax: number | null | undefined;
  /**
   * The outputMin denotes the output minimum, which is the lowest pixel value.
   * The [outputMin](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#outputMin) and [outputMax](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#outputMax) will set the range of values that will then be linearly contrast stretched.
   * The outputMin value ranges from 0-255.
   */
  accessor outputMin: number | null | undefined;
  /**
   * The sigmoid strength level determines how much of the sigmoidal function will be used in the stretch.
   * A low value such as 1 will only use the middle portion of the curve,
   * which tends to produce dull and faint colors. A high value such as 6 will use the entire curve,
   * which tends to produce bold and sharp colors.
   */
  accessor sigmoidStrengthLevel: number | null | undefined;
  /**
   * The stretch type defines a histogram stretch that will be applied to the rasters to enhance their appearance.
   * Stretching improves the appearance of the data by spreading the pixel values along a histogram
   * from the minimum and maximum values defined by their bit depth.
   * For example, an 8-bit raster dataset or mosaic dataset will be stretched from 0 to 255.
   * Different stretches will produce different results in the raster display.
   *
   * The possible stretch types are listed below.
   *
   * Value | Description
   * ------|------------
   * none  | No stretch method will be applied, even if statistics exist.
   * standard-deviation | This stretch type applies a linear stretch between the values defined by the standard deviation value.
   * histogram-equalization | The pixel values are stretched to adjust the contrast using the histogram of the data.
   * min-max | This stretch type applies a linear stretch based on the output minimum and output maximum pixel values, which are used as the endpoints for the histogram.
   * percent-clip | This stretch type applies a linear stretch between the defined [minPercent](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#minPercent) and [maxPercent](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#maxPercent) pixel values.
   * sigmoid | The Sigmoid contrast stretch is designed to highlight moderate pixel values in your imagery while maintaining sufficient contrast at the extremes.
   *
   * @default "none"
   */
  accessor stretchType: RasterStretchType;
  /** The type of Renderer. */
  readonly type: "raster-stretch";
  /**
   * Denotes whether the [gamma](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#gamma) value should be used. When `useGamma` is `false`, the gamma is
   * calculated from the statistics and histogram of the data.
   * The [gamma](https://developers.arcgis.com/javascript/latest/references/core/renderers/RasterStretchRenderer/#gamma) property is required if `useGamma` is `true`.
   *
   * @default false
   */
  accessor useGamma: boolean;
  /**
   * Creates a deep clone of the renderer.
   *
   * @returns A deep clone of the object that
   *                                                      invoked this method.
   * @example
   * // Creates a deep clone of the first layer's renderer
   * let renderer = view.map.layers.at(0).renderer.clone();
   */
  clone(): RasterStretchRenderer;
}