import type Extent from "../../geometry/Extent.js";
import type Point from "../../geometry/Point.js";
import type SpatialReference from "../../geometry/SpatialReference.js";
import type DimensionalDefinition from "../support/DimensionalDefinition.js";
import type MultidimensionalSubset from "../support/MultidimensionalSubset.js";
import type RasterInfo from "../support/RasterInfo.js";
import type TimeInfo from "../support/TimeInfo.js";
import type ImageSampleParameters from "../../rest/support/ImageSampleParameters.js";
import type ImageSampleResult from "../../rest/support/ImageSampleResult.js";
import type TimeExtent from "../../time/TimeExtent.js";
import type TimeInterval from "../../time/TimeInterval.js";
import type { FetchRasterOptions, RasterIdentifyOptions } from "../types.js";
import type { RasterInterpolation } from "../support/RasterTypes.js";
import type { RasterIdentifyResult } from "../support/types.js";
import type { RasterRendererUnion } from "../../renderers/support/raster/types.js";
import type { RequestOptions } from "../../request/types.js";
import type { DimensionalDefinitionProperties } from "../support/DimensionalDefinition.js";
import type { MultidimensionalSubsetProperties } from "../support/MultidimensionalSubset.js";
import type { VectorFieldRendererProperties } from "../../renderers/VectorFieldRenderer.js";
import type { UniqueValueRendererProperties } from "../../renderers/UniqueValueRenderer.js";
import type { RasterStretchRendererProperties } from "../../renderers/RasterStretchRenderer.js";
import type { RasterShadedReliefRendererProperties } from "../../renderers/RasterShadedReliefRenderer.js";
import type { RasterColormapRendererProperties } from "../../renderers/RasterColormapRenderer.js";
import type { FlowRendererProperties } from "../../renderers/FlowRenderer.js";
import type { ClassBreaksRendererProperties } from "../../renderers/ClassBreaksRenderer.js";

export interface ImageryTileMixinProperties extends Partial<Pick<ImageryTileMixin, "bandIds" | "copyright" | "interpolation">> {
  /**
   * The multidimensional definitions associated with the layer. Filters the layer by slicing data along defined variables and dimensions such as
   * time, depth, altitude, etc. For example, you can display a particular variable such as temperature or salinity measured at a fixed dimension (e.g. time, depth).
   *
   * @since 4.20
   * @see [ImageryTileLayer - working with multidimensional raster data](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryTileLayer.html#multidimensionaldata)
   * @see [Multidimensional Definition REST API doc](https://developers.arcgis.com/documentation/common-data-types/multidimensional-definition.htm)
   * @see [RasterInfo#multidimensionalInfo](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-RasterInfo.html#multidimensionalInfo)
   * @see [Sample - Multidimensional ImageryTileLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagery-multidimensional/)
   * @example
   * // set the `multidimensionalDefinition` to visualize a sea water
   * // temperature at -5000m on April 7th 2014.
   * const dimension = [
   *   {
   *      variableName: "temperature",
   *      dimensionName: "Std_Time",
   *      values: [1396828800000]
   *   },
   *   {
   *      variableName: "temperature",
   *      dimensionName:"Std_Z",
   *      values:[-5000]
   *   }
   * ];
   * layer.multidimensionalDefinition = dimension;
   * @example
   * // get the layer's multidimensionalDefinition and locate the
   * // Salinity dimension and filter the data by salinity.
   * const multidimensionalDefinition = layer.multidimensionalDefinition;
   * const variableName =  "Salinity";
   * // filter the data by salinity dimension
   * multidimensionalDefinition.forEach((def) => def.variableName = variableName);
   * layer.multidimensionalDefinition = multidimensionalDefinition;
   *
   * // update the statistics of the layer's stretch renderer.
   * const renderer = layer.renderer.clone();
   * const dimensions = layer.serviceRasterInfo.multidimensionalInfo;
   * // get the salinity variable's statistics
   * const salinity = dimensions.variables.find((variable) => variable.name === variableName);
   * renderer.customStatistics = salinity.statistics;
   * layer.renderer = renderer;
   */
  multidimensionalDefinition?: DimensionalDefinitionProperties[] | null;
  /**
   * Represents a multidimensional subset of raster data. This includes subsets of both variables and dimensions. When the multidimensionalSubset is defined on
   * a layer, the [multidimensionalDefinition](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-mixins-ImageryTileMixin.html#multidimensionalDefinition) must be within the defined multidimensionalSubset, otherwise nothing will be
   * displayed.
   *
   * @since 4.25
   * @see [Working with multidimensional data](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryTileLayer.html#multidimensionaldata)
   * @example
   * // set a multidimensionalSubset on the imagery tile layer
   * // so that users can only access wind magnitude and direction data
   * // between Jan 1 - 19, 2011.
   * const multidimensionalSubset = new MultidimensionalSubset({
   *   subsetDefinitions: [
   *     {
   *       variableName: "wind_magdir",
   *       dimensionName: "StdTime",
   *       values: [1293876000000, 1295395200000], // 1/1/11 - 11/19/11
   *       isSlice: false
   *     }
   *   ]
   * });
   * layer.multidimensionalSubset = multidimensionalSubset;
   */
  multidimensionalSubset?: MultidimensionalSubsetProperties | null;
  /**
   * The renderer assigned to the layer. The renderer defines how to visualize pixels in the tile imagery layer.
   * Depending on the renderer type, the pixels may be [stretched](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-RasterStretchRenderer.html)
   * across the color ramp, [classified](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-ClassBreaksRenderer.html),
   * have [different symbols](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-UniqueValueRenderer.html) based on values, or show [shaded reliefs](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-RasterShadedReliefRenderer.html).
   *
   * @see [Sample - Intro to ImageryTileLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagerytilelayer/)
   * @see [Sample - ImageryTileLayer - shaded relief renderer](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagery-renderer/)
   * @see [Sample - Transposed multidimensional ImageryTileLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-hosted-imagerytilelayer/)
   */
  renderer?: ((ClassBreaksRendererProperties & { type: "class-breaks" }) | (FlowRendererProperties & { type: "flow" }) | (RasterColormapRendererProperties & { type: "raster-colormap" }) | (RasterShadedReliefRendererProperties & { type: "raster-shaded-relief" }) | (RasterStretchRendererProperties & { type: "raster-stretch" }) | (UniqueValueRendererProperties & { type: "unique-value" }) | (VectorFieldRendererProperties & { type: "vector-field" })) | null;
}

/** ImageryTileMixin is a mixin that adds common properties and methods to [ImageryTileLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryTileLayer.html) and [WCSLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-WCSLayer.html). */
export abstract class ImageryTileMixin {
  constructor(...args: any[]);
  /** Defines a band combination using 0-based band indexes. */
  accessor bandIds: number[] | null | undefined;
  /** The copyright text as defined by the service. */
  accessor copyright: string | null | undefined;
  /**
   * Defines how to interpolate pixel values. By default, this will be set to the service's resampling method,
   * if it has one. If the service does not have a default resampling method, the `bilinear` resampling will be used in
   * most cases, and `nearest` interpolation type will be used for thematic data source.
   */
  accessor interpolation: RasterInterpolation;
  /**
   * Indicates whether the layer will be included in the legend.
   *
   * @default true
   */
  abstract legendEnabled: boolean;
  /**
   * The multidimensional definitions associated with the layer. Filters the layer by slicing data along defined variables and dimensions such as
   * time, depth, altitude, etc. For example, you can display a particular variable such as temperature or salinity measured at a fixed dimension (e.g. time, depth).
   *
   * @since 4.20
   * @see [ImageryTileLayer - working with multidimensional raster data](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryTileLayer.html#multidimensionaldata)
   * @see [Multidimensional Definition REST API doc](https://developers.arcgis.com/documentation/common-data-types/multidimensional-definition.htm)
   * @see [RasterInfo#multidimensionalInfo](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-RasterInfo.html#multidimensionalInfo)
   * @see [Sample - Multidimensional ImageryTileLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagery-multidimensional/)
   * @example
   * // set the `multidimensionalDefinition` to visualize a sea water
   * // temperature at -5000m on April 7th 2014.
   * const dimension = [
   *   {
   *      variableName: "temperature",
   *      dimensionName: "Std_Time",
   *      values: [1396828800000]
   *   },
   *   {
   *      variableName: "temperature",
   *      dimensionName:"Std_Z",
   *      values:[-5000]
   *   }
   * ];
   * layer.multidimensionalDefinition = dimension;
   * @example
   * // get the layer's multidimensionalDefinition and locate the
   * // Salinity dimension and filter the data by salinity.
   * const multidimensionalDefinition = layer.multidimensionalDefinition;
   * const variableName =  "Salinity";
   * // filter the data by salinity dimension
   * multidimensionalDefinition.forEach((def) => def.variableName = variableName);
   * layer.multidimensionalDefinition = multidimensionalDefinition;
   *
   * // update the statistics of the layer's stretch renderer.
   * const renderer = layer.renderer.clone();
   * const dimensions = layer.serviceRasterInfo.multidimensionalInfo;
   * // get the salinity variable's statistics
   * const salinity = dimensions.variables.find((variable) => variable.name === variableName);
   * renderer.customStatistics = salinity.statistics;
   * layer.renderer = renderer;
   */
  get multidimensionalDefinition(): DimensionalDefinition[] | null | undefined;
  set multidimensionalDefinition(value: DimensionalDefinitionProperties[] | null | undefined);
  /**
   * Represents a multidimensional subset of raster data. This includes subsets of both variables and dimensions. When the multidimensionalSubset is defined on
   * a layer, the [multidimensionalDefinition](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-mixins-ImageryTileMixin.html#multidimensionalDefinition) must be within the defined multidimensionalSubset, otherwise nothing will be
   * displayed.
   *
   * @since 4.25
   * @see [Working with multidimensional data](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryTileLayer.html#multidimensionaldata)
   * @example
   * // set a multidimensionalSubset on the imagery tile layer
   * // so that users can only access wind magnitude and direction data
   * // between Jan 1 - 19, 2011.
   * const multidimensionalSubset = new MultidimensionalSubset({
   *   subsetDefinitions: [
   *     {
   *       variableName: "wind_magdir",
   *       dimensionName: "StdTime",
   *       values: [1293876000000, 1295395200000], // 1/1/11 - 11/19/11
   *       isSlice: false
   *     }
   *   ]
   * });
   * layer.multidimensionalSubset = multidimensionalSubset;
   */
  get multidimensionalSubset(): MultidimensionalSubset | null | undefined;
  set multidimensionalSubset(value: MultidimensionalSubsetProperties | null | undefined);
  /**
   * The renderer assigned to the layer. The renderer defines how to visualize pixels in the tile imagery layer.
   * Depending on the renderer type, the pixels may be [stretched](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-RasterStretchRenderer.html)
   * across the color ramp, [classified](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-ClassBreaksRenderer.html),
   * have [different symbols](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-UniqueValueRenderer.html) based on values, or show [shaded reliefs](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-RasterShadedReliefRenderer.html).
   *
   * @see [Sample - Intro to ImageryTileLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagerytilelayer/)
   * @see [Sample - ImageryTileLayer - shaded relief renderer](https://developers.arcgis.com/javascript/latest/sample-code/layers-imagery-renderer/)
   * @see [Sample - Transposed multidimensional ImageryTileLayer](https://developers.arcgis.com/javascript/latest/sample-code/layers-hosted-imagerytilelayer/)
   */
  get renderer(): RasterRendererUnion | null | undefined;
  set renderer(value: ((ClassBreaksRendererProperties & { type: "class-breaks" }) | (FlowRendererProperties & { type: "flow" }) | (RasterColormapRendererProperties & { type: "raster-colormap" }) | (RasterShadedReliefRendererProperties & { type: "raster-shaded-relief" }) | (RasterStretchRendererProperties & { type: "raster-stretch" }) | (UniqueValueRendererProperties & { type: "unique-value" }) | (VectorFieldRendererProperties & { type: "vector-field" })) | null | undefined);
  /**
   * Raster information retrieved from tiled imagery data source.
   *
   * @since 4.29
   */
  get serviceRasterInfo(): RasterInfo | null | undefined;
  /**
   * The spatial reference of the layer.
   *
   * @since 4.33
   */
  get spatialReference(): SpatialReference;
  /**
   * The layer's time extent. When the layer's [useViewTime](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-mixins-ImageryTileMixin.html#useViewTime) is `false`, the layer
   * instructs the view to show data from the layer based on this time extent.
   * If the `useViewTime` is `true`, and both layer and view time extents are set, then features that fall within
   * the intersection of the view and layer time extents will be displayed.
   * For example, if the layer's time extent is set to display features between 1970 and 1975 and
   * the view has a time extent set to 1972-1980, the effective time on the feature layer will be 1972-1975.
   *
   * @since 4.22
   * @example
   * if (!layer.useViewTime) {
   *   if (layer.timeExtent) {
   *     console.log("Current timeExtent:", layer.timeExtent.start, " - ", layer.timeExtent.end}
   *   } else {
   *     console.log("The layer will display data within the view's timeExtent.");
   *     console.log("Current view.timeExtent:", view.timeExtent.start, " - ", view.timeExtent.end}
   *   }
   * }
   * @example
   * // set the timeExtent on the layer and useViewTime false
   * // In this case, the layer will honor its timeExtent and ignore
   * // the view's timeExtent
   * const layer = new ImageryTileLayer({
   *   url: "https://tiledimageservices.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/NLDAS2011_daily_wind_magdir/ImageServer",
   *   timeExtent: {
   *     start: new Date(2014, 4, 18),
   *     end: new Date(2014, 4, 19)
   *   },
   *   useViewTime: false
   * });
   * @example
   * // timeExtent is set on the layer and the view
   * // In this case, the layer will display features that fall
   * // within the intersection of view and layer time extents
   * // features within Jan 1, 1976 - Jan 1, 1981 will be displayed
   * const view = new MapView({
   *   timeExtent: {
   *     start: new Date(1976, 0, 1),
   *     end: new Date(2002, 0, 1)
   *   }
   * });
   * const layer = new FeatureLayer({
   *   url: myUrl,
   *   timeExtent: {
   *     start: new Date(1974, 0, 1),
   *     end: new Date(1981, 0, 1)
   *   }
   * });
   */
  abstract accessor timeExtent: TimeExtent | null | undefined;
  /**
   * TimeInfo provides information such as date fields that store
   * [start](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-TimeInfo.html#startField)
   * and [end](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-TimeInfo.html#endField) time
   * for each feature and the [TimeInfo#fullTimeExtent](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-TimeInfo.html#fullTimeExtent)
   * for the layer.
   *
   * @since 4.22
   */
  abstract accessor timeInfo: TimeInfo | null | undefined;
  /**
   * A temporary offset of the time data based on a certain [TimeInterval](https://developers.arcgis.com/javascript/latest/api-reference/esri-time-TimeInterval.html). This allows
   * users to overlay features from two or more time-aware layers with different time extents.
   * For example, if a layer has data recorded for the year 1970, an offset value of 2 years would temporarily shift the data to
   * 1972. You can then overlay this data with data recorded in 1972.
   * A time offset can be used for display purposes only. The query and selection are not affected by the offset.
   *
   * @since 4.22
   * @example
   * // Offset a CSV Layer containing hurricanes from 2015 so that they appear in 2019 (+4 years).
   * let layer = new CSVLayer({
   *   url: `hurricanes-and-storms-2015.csv`,
   *   timeOffset: {
   *     value: 4,
   *     unit: "years"
   *   },
   *   timeInfo: {
   *     startField: "ISO_time"
   *   },
   *   renderer: {
   *     type: "simple",
   *     symbol: {
   *       type: "simple-marker",
   *       size: 6,
   *       color: "red",
   *       outline: {
   *         width: 0.5,
   *         color: "black"
   *       }
   *     }
   *   }
   * });
   */
  abstract accessor timeOffset: TimeInterval | null | undefined;
  /**
   * Determines if the layer will update its temporal data based on the view's
   * [View#timeExtent](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View.html#timeExtent). When `false`, the layer will display its temporal
   * data based on the layer's [timeExtent](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-mixins-ImageryTileMixin.html#timeExtent), regardless of changes to the view.
   * If both view and layer time extents are set while this property is `true`, then the features that fall within
   * the intersection of the view and layer time extents will be displayed.
   * For example, if a layer's time extent is set to display features between 1970 and 1975 and
   * the view has a time extent set to 1972-1980, the effective time on the feature layer will be 1972-1975.
   *
   * @default true
   * @since 4.22
   * @example
   * if (featureLayer.useViewTime) {
   *   console.log("Displaying data between:", view.timeExtent.start, " - ", view.timeExtent.end);
   * }
   */
  abstract accessor useViewTime: boolean;
  /**
   * Fetches pixels for a given extent.
   *
   * @param extent - The extent of the image to export.
   * @param width - The width of the image in pixels.
   * @param height - The height of the image in pixels.
   * @param options - The parameter options is an object with the following properties.
   * @returns Resolves to an object containing the parameters of the exported pixels including [PixelBlock](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-PixelBlock.html).
   * The `pixelBlock` contains the value of each pixel in the image.
   * @since 4.19
   */
  fetchPixels(extent: Extent, width: number, height: number, options?: FetchRasterOptions): Promise<any>;
  /**
   * Returns sample point locations, pixel values and corresponding resolutions of the source data for a given geometry. When the input geometry
   * is a [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html), [Extent](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Extent.html), or [Polygon](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polygon.html),
   * the sampling is based on [ImageSampleParameters#sampleCount](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-ImageSampleParameters.html#sampleCount) or
   * [ImageSampleParameters#sampleDistance](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-ImageSampleParameters.html#sampleDistance) parameters. When the geometry is a
   * [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) or [Multipoint](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Multipoint.html), the point or points are used directly.
   *
   * The number of sample locations in the response is based on the `sampleDistance` or `sampleCount` parameter and the maximum is 1000.
   *
   * @param parameters - The parameters used in the getSamples operation.
   * @param requestOptions - Additional [options](https://developers.arcgis.com/javascript/latest/api-reference/esri-request.html#request) to be used for the data request
   * (will override requestOptions defined during construction).
   * @returns When resolved, [ImageSampleResult](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-ImageSampleResult.html) is returned containing an array of [ImageSamples](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-ImageSample.html).
   * @since 4.33
   * @example
   * // get all sample points along a polyline
   * // at the specified sample distance and pixel size
   * const param = {
   *   geometry: polyline
   *   returnFirstValueOnly: false,
   *   interpolation: "nearest",
   *   // unit of the geometry's spatial reference is used
   *   sampleDistance: 30,
   *   outFields: ["*"]
   * };
   * imageryLayer.getSamples(param).then((results) => {
   *   // use the getSamples results as needed.
   *   console.log(results);
   * })
   * .catch(function(error){
   *   console.log(error)
   * })
   */
  getSamples(parameters: ImageSampleParameters, requestOptions?: RequestOptions): Promise<ImageSampleResult>;
  /**
   * Identify pixel values at a given location. This method identifies the content of an image service for the input location and in a specified dimensional definition.
   *
   * Starting at version 4.25, the `identify` method returns pixel values from specific dimensional definitions for a transposed multidimensional service
   * referenced in an [ImageryTileLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryTileLayer.html). Set the `transposedVariableName` parameter along with the `multidimensionalDefinition` to get pixel values
   * from specific dimensional slices. To get pixel values from all dimensional slices, just set the `transposedVariableName`.
   * The ImageryTileLayer's [serviceRasterInfo.hasMultidimensionalTranspose](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-mixins-ImageryTileMixin.html#serviceRasterInfo) property must be `true` when setting the `transposedVariableName` parameter.
   *
   * @param point - Input point that defines the location to be identified.
   * @param options - Optional settings for the identify request.
   * At version 4.25, the `transposedVariableName` was added to get pixel values from specific dimensional definitions if the [ImageryTileLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryTileLayer.html)
   * references a [transposed multidimensional](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-RasterInfo.html#hasMultidimensionalTranspose) image service.
   * Set the `transposedVariableName` and `multidimensionalDefinition` get pixel values for the specified dimensional definitions from a transposed multidimensional service.
   * If `multidimensionalDefinition` is not specified, pixel values will be returned from all the dimensional slices.
   * @returns Returns a promise that resolves to a [RasterIdentifyResult](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-types.html#RasterIdentifyResult) containing a location
   * and pixel values. The identify returns a value for only one slice at a time for [WCSLayer#identify()](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-WCSLayer.html#identify) and for non-transposed multidimensional
   * [ImageryTileLayer#identify()](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryTileLayer.html#identify). If the `transposedVariableName` parameter is set for the transposed multidimensional ImageryTileLayer, the result returns all pixel values
   * from all multidimensional slices.
   * @see [RasterInfo#hasMultidimensionalTranspose](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-RasterInfo.html#hasMultidimensionalTranspose)
   * @see [Working with multidimensional data](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-ImageryTileLayer.html#multidimensionaldata)
   */
  identify(point: Point, options?: RasterIdentifyOptions): Promise<RasterIdentifyResult>;
}