import type { JSONSupport } from "../../core/JSONSupport.js";
import type { RasterPixelType } from "../raster/types.js";

export interface RasterFunctionProperties extends Partial<Pick<RasterFunction, "functionArguments" | "functionName" | "outputPixelType" | "rasterFunctionDefinition" | "variableName">> {}

/**
 * Raster functions specify processing to be done to the image service. They allow the mosaic image service to deliver a dynamically mosaicked
 * image and they can be used to enhance the mosaicked image product by applying processing operations such as image enhancements, and image algebra.
 * See [raster functions](https://developers.arcgis.com/documentation/common-data-types/raster-function-objects.htm)
 * for a list of functions and their [arguments](https://developers.arcgis.com/javascript/latest/references/core/layers/support/RasterFunction/#functionArguments). The following image shows a landcover ImageryLayer rendered with two chained
 * client-side raster functions used to reclass pixel values (Remap) and assign each pixel a new color (Colormap).
 *
 * [![layers-imagery-rf](https://developers.arcgis.com/javascript/latest/assets/references/core/layers/imagery/layers-imagery-rf.png)](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagery-rasterfunction/)
 *
 * Chaining raster functions is accomplished by setting the Raster argument in the [functionArguments](https://developers.arcgis.com/javascript/latest/references/core/layers/support/RasterFunction/#functionArguments) property to another
 * defined raster function. See example below on chaining a Remap raster function with a Colormap.
 *
 * ```js
 * let remapRF = new RasterFunction();
 * remapRF.functionName = "Remap";
 * remapRF.functionArguments = {
 *   InputRanges: [-3,10,11,37], // remap pixels with values -3 to 10 to now have value of 1
 *   OutputValues: [1,2],        // remap pixel values from 11 to 37 to have a value of 2
 *   Raster: "$$"  // Apply remap to the image service
 * };
 * remapRF.outputPixelType = "u8";
 *
 * let colorRF = new RasterFunction();
 * colorRF.functionName = "Colormap";
 * colorRF.functionArguments = {
 *   Colormap: [
 *     [1, 255, 0, 0],  // Symbolize pixels with value of 1 using red color
 *     [2, 0, 255, 0]   // Symbolize pixels with value of 2 using green color
 *   ],
 *   Raster : remapRF  // Apply Colormap to output raster from the remap rasterFunction
 * };
 *
 * imageLayer.rasterFunction = colorRF;
 * ```
 *
 * The following code snippet shows how convenience methods from the [rasterFunctionUtils](https://developers.arcgis.com/javascript/latest/references/core/layers/support/rasterFunctionUtils/) module can be used
 * when applying a raster function to an imagery or imagery tile layer.
 *
 * ```js
 * // apply NDVI and colormap raster function to an imagery tile layer
 * // use rasterFunctionUtils convenience methods to create raster functions
 * const ndvi = rasterFunctionUtils.bandArithmeticNDVI({
 *   nirBandId: 4,
 *   redBandId: 3,
 *   scientificOutput: false
 * });
 *
 *  const colormap = rasterFunctionUtils.colormap({
 *   colorRampName: "NDVI3",
 *   raster: ndvi
 * });
 * layer.rasterFunction = colormap;
 * ```
 *
 * @since 4.0
 * @see [Sample - Set a server side raster function](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagery-popup/)
 * @see [Sample - ImageryLayer raster function](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagery-rasterfunction/)
 * @see [Sample - Work with pixelFilter in an ImageryLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagery-pixelvalues/)
 * @see [REST API - Raster functions](https://developers.arcgis.com/documentation/common-data-types/raster-function-objects.htm)
 * @see [rasterFunctionUtils](https://developers.arcgis.com/javascript/latest/references/core/layers/support/rasterFunctionUtils/)
 */
export default class RasterFunction extends JSONSupport {
  constructor(properties?: RasterFunctionProperties);
  /**
   * The arguments for the raster function. The structure depends on the function specified.
   * See [raster functions](https://developers.arcgis.com/documentation/common-data-types/raster-function-objects.htm)
   * for a list of functions and their arguments.
   * Also parses the arguments of RFT format.
   *
   * @example
   * rasterFunction.functionArguments = {
   *   "Azimuth":215.0,
   *   "Altitude":75.0,
   *   "ZFactor":0.3
   * };
   */
  accessor functionArguments: Record<string, any>;
  /**
   * The raster function name.
   * See [raster functions](https://developers.arcgis.com/documentation/common-data-types/raster-function-objects.htm)
   * for a list of functions and their arguments. The name in the raster function in RFT JSON format is also parsed to functionName.
   *
   * @example
   * rasterFunction.functionName = "Stretched";
   * rasterFunction.name = "GrayScale";
   */
  accessor functionName: string | null | undefined;
  /**
   * Defines the pixel type of the output image.
   *
   * @default "unknown"
   * @example rasterFunction.outputPixelType = "u8";
   */
  outputPixelType: RasterPixelType;
  /**
   * Property where Raster Function template is passed.
   * RasterFunction template definition created by Raster Function Editor in MapViewer.
   */
  accessor rasterFunctionDefinition: any | null | undefined;
  /**
   * The variable name for the raster function.
   *
   * @example rasterFunction.variableName = "DEM";
   */
  accessor variableName: string | null | undefined;
  /**
   * Creates a deep clone of the raster function.
   *
   * @returns A deep clone of the object that
   * invoked this method.
   * @since 4.29
   * @example
   * // Creates a deep clone of the layer's rasterFunction
   * let rasterFunction = layer.rasterFunction.clone();
   */
  clone(): RasterFunction;
}