import type ColorStop from "../../renderers/visualVariables/support/ColorStop.js";
import type SmartMappingSliderBase from "./SmartMappingSliderBase.js";
import type ColorSliderViewModel from "./ColorSlider/ColorSliderViewModel.js";
import type { ContinuousRendererResult } from "../../smartMapping/renderers/color.js";
import type { HistogramResult } from "../../smartMapping/statistics/types.js";
import type { SmartMappingSliderBaseProperties } from "./SmartMappingSliderBase.js";
import type { ColorSliderViewModelProperties } from "./ColorSlider/ColorSliderViewModel.js";

export interface ColorSliderProperties extends SmartMappingSliderBaseProperties, Partial<Pick<ColorSlider, "handlesSyncedToPrimary" | "primaryHandleEnabled" | "stops">> {
  /**
   * The widget's default label. This label displays when it is
   * used within another widget, such as the [Expand](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Expand.html)
   * or [LayerList](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-LayerList.html) widgets.
   *
   * @since 4.11
   */
  label?: string | null;
  /**
   * The view model for the ColorSlider widget. This class contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [ColorSliderViewModel](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider-ColorSliderViewModel.html)
   * class to access all properties and methods on the ColorSlider widget.
   */
  viewModel?: ColorSliderViewModelProperties;
}

/**
 * The ColorSlider widget is intended for authoring and exploring data-driven visualizations in any
 * layer that can be rendered with a [ColorVariable](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-visualVariables-ColorVariable.html).
 * At a minimum you must set the [min](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#min), [max](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#max), and [stops](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#stops) properties
 * of the widget. The stops are used to render a color gradient on the track of the slider.
 *
 * <span id="image-annotations"></span>
 * See the image below for a summary of the configurable options available on this slider.
 *
 * ![ColorSlider with annotations](https://developers.arcgis.com/javascript/latest/assets/img/apiref/widgets/sliders/colorslider-2-labels.png "ColorSlider with annotations")
 *
 * The [fromRendererResult()](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#fromRendererResult) method can be used to conveniently create this slider
 * from the result of the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-color.html#createContinuousRenderer)
 * method.
 *
 * ```js
 * const colorParams = {
 *   layer: layer,
 *   basemap: map.basemap,
 *   valueExpression: "( $feature.POP_POVERTY / $feature.TOTPOP_CY ) * 100",
 *   view: view,
 *   theme: "above-and-below"
 * };
 *
 * let rendererResult = null;
 *
 * colorRendererCreator
 *   .createContinuousRenderer(colorParams)
 *   .then(function(response) {
 *     rendererResult = response;
 *     layer.renderer = response.renderer;
 *
 *     return histogram({
 *       layer: layer,
 *       valueExpression: colorParams.valueExpression,
 *       view: view,
 *       numBins: 70
 *     });
 *   })
 *    .then(function(histogramResult) {
 *      const colorSlider = ColorSlider.fromRendererResult(rendererResult, histogramResult);
 *      colorSlider.container = "slider";
 *      colorSlider.primaryHandleEnabled = true;
 *    })
 *    .catch(function(error) {
 *      console.log("there was an error: ", error);
 *    });
 * ```
 *
 * This slider should be used to update a [color visual variable](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-visualVariables-ColorVariable.html)
 * in a layer's renderer. It is the responsibility of the app developer
 * to set up event listeners on this slider that update the color variable of the appropriate renderer.
 *
 * ```js
 * // when the user slides the handle(s), update the renderer
 * // with the updated color stops
 *
 * colorSlider.on(["thumb-change", "thumb-drag"], function() {
 *   const renderer = layer.renderer.clone();
 *   const colorVariable = renderer.visualVariables[0].clone();
 *   colorVariable.stops = colorSlider.stops;
 *   renderer.visualVariables = [ colorVariable ];
 *   layer.renderer = renderer;
 * });
 * ```
 *
 * @since 4.12
 * @see [ColorSliderViewModel](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider-ColorSliderViewModel.html)
 * @see [colorRendererCreator](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-color.html)
 */
export default class ColorSlider extends SmartMappingSliderBase {
  /**
   * A convenience function used to create a ColorSlider widget instance from the
   * [result](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-color.html#ContinuousRendererResult) of
   * the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-color.html#createContinuousRenderer)
   * method.
   *
   * This method sets the slider [stops](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#stops), [min](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#min), [max](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#max),
   * and [histogramConfig](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#histogramConfig). It is still the developer's responsibility to assign it a proper
   * [container](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#container) and any other optional properties, such as [primaryHandleEnabled](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#primaryHandleEnabled).
   *
   * @param rendererResult - The result object from the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-color.html#createContinuousRenderer)
   *   method.
   * @param histogramResult - The result histogram object from the [histogram()](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-statistics-histogram.html#histogram)
   *   method.
   * @returns Returns a ColorSlider instance. This will not render until you assign
   *   it a valid [container](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#container).
   * @example
   * const colorParams = {
   *   layer: layer,
   *   basemap: map.basemap,
   *   valueExpression: "( $feature.POP_POVERTY / $feature.TOTPOP_CY ) * 100",
   *   view: view,
   *   theme: "above-and-below"
   * };
   *
   * let rendererResult = null;
   *
   * colorRendererCreator
   *   .createContinuousRenderer(colorParams)
   *   .then(function(response) {
   *     rendererResult = response;
   *     layer.renderer = response.renderer;
   *
   *     return histogram({
   *       layer: layer,
   *       valueExpression: colorParams.valueExpression,
   *       view: view,
   *       numBins: 70
   *     });
   *   })
   *    .then(function(histogramResult) {
   *
   *      const colorSlider = ColorSlider.fromRendererResult(rendererResult, histogramResult);
   *      colorSlider.container = "slider";
   *      colorSlider.primaryHandleEnabled = true;
   *
   *      // when the user slides the handle(s), update the renderer
   *      // with the updated color stops
   *
   *      colorSlider.on(["thumb-change", "thumb-drag"], function() {
   *        const renderer = layer.renderer.clone();
   *        const colorVariable = renderer.visualVariables[0].clone();
   *        colorVariable.stops = colorSlider.stops;
   *        renderer.visualVariables = [ colorVariable ];
   *        layer.renderer = renderer;
   *      });
   *    })
   *    .catch(function(error) {
   *      console.log("there was an error: ", error);
   *    });
   */
  static fromRendererResult(rendererResult: ContinuousRendererResult, histogramResult?: HistogramResult): ColorSlider;
  /**
   * @example
   * // Typical usage
   * // rendererResponse is result of color.createContinuousRenderer()
   * const slider = new ColorSlider({
   *   container: "sliderDiv",
   *   min: rendererResponse.statistics.min,
   *   max: rendererResponse.statistics.max,
   *   stops: rendererResponse.visualVariable.stops
   * });
   */
  constructor(properties?: ColorSliderProperties);
  /**
   * Only applicable when three thumbs (i.e. handles) are set on the
   * slider (i.e. when [primaryHandleEnabled](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#primaryHandleEnabled) is `true`). This property
   * indicates whether the position of the outside handles are synced with the middle, or primary,
   * handle. When enabled, if the primary handle is moved then the outside handle positions are updated
   * while maintaining a fixed distance from the primary handle.
   *
   * @default true
   * @see [primaryHandleEnabled](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#primaryHandleEnabled)
   * @example
   * // enables the primary handles and syncs it with the others
   * slider.primaryHandleEnabled = true;
   * slider.handlesSyncedToPrimary = true;
   */
  accessor handlesSyncedToPrimary: boolean;
  /**
   * The widget's default label. This label displays when it is
   * used within another widget, such as the [Expand](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Expand.html)
   * or [LayerList](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-LayerList.html) widgets.
   *
   * @since 4.11
   */
  get label(): string;
  set label(value: string | null | undefined);
  /**
   * When `true`, the slider will render a third handle between the
   * two handles already provided by default. This is the primary handle.
   * Three or five [stops](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#stops) must be defined for the primary handle to render.
   * The primary handle represents the middle stop.
   *
   * When [handlesSyncedToPrimary](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#handlesSyncedToPrimary) is `true`, then
   * this handle will control the position of the others when moved.
   *
   * This is typically used in diverging, or `above-and-below` renderer configurations.
   *
   * @default false
   * @see [handlesSyncedToPrimary](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#handlesSyncedToPrimary)
   * @example
   * // enables the primary handles and syncs it with the others
   * slider.primaryHandleEnabled = true;
   * slider.handlesSyncedToPrimary = true;
   */
  accessor primaryHandleEnabled: boolean;
  /**
   * The color stops from the [ColorVariable](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-visualVariables-ColorVariable.html)
   * to link to the slider. The colors in these stops will be used
   * to render the color gradient on the slider's track. They should match the colors
   * rendered in the associated layer's renderer.
   *
   * @example
   * colorRendererCreator.createContinuousRenderer({
   *   layer: featureLayer,
   *   field: "fieldName",
   *   basemap: "gray-vector"
   * }).then(function(colorResponse){
   *   let slider = new ColorSlider({
   *     stops: colorResponse.visualVariable.stops,
   *     min: colorResponse.statistics.min,
   *     max: colorResponse.statistics.max,
   *     container: "sliderDiv"
   *   });
   * });
   */
  accessor stops: ColorStop[];
  /**
   * The view model for the ColorSlider widget. This class contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [ColorSliderViewModel](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider-ColorSliderViewModel.html)
   * class to access all properties and methods on the ColorSlider widget.
   */
  get viewModel(): ColorSliderViewModel;
  set viewModel(value: ColorSliderViewModelProperties);
  /**
   * A convenience function used to update the properties of a ColorSlider widget instance from the
   * [result](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-color.html#ContinuousRendererResult) of
   * the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-color.html#createContinuousRenderer)
   * method. This method is useful for cases when the app allows the end user to switch data variables
   * used to render the data.
   *
   * @param rendererResult - The result object from the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-color.html#createContinuousRenderer)
   *   method.
   * @param histogramResult - The result histogram object from the [histogram()](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-statistics-histogram.html#histogram)
   *   method.
   * @see [fromRendererResult()](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-ColorSlider.html#fromRendererResult)
   * @example
   * const colorParams = {
   *   layer: layer,
   *   basemap: map.basemap,
   *   valueExpression: "( $feature.POP_POVERTY / $feature.TOTPOP_CY ) * 100",
   *   view: view,
   *   theme: "above-and-below"
   * };
   *
   * let rendererResult = null;
   *
   * colorRendererCreator
   *   .createContinuousRenderer(colorParams)
   *   .then(function(response) {
   *     rendererResult = response;
   *     layer.renderer = response.renderer;
   *
   *     return histogram({
   *       layer: layer,
   *       valueExpression: colorParams.valueExpression,
   *       view: view,
   *       numBins: 70
   *     });
   *   })
   *    .then(function(histogramResult) {
   *      colorSlider.updateFromRendererResult(rendererResult, histogramResult);
   *    })
   *    .catch(function(error) {
   *      console.log("there was an error: ", error);
   *    });
   */
  updateFromRendererResult(rendererResult: ContinuousRendererResult, histogramResult?: HistogramResult): void;
}