import type Color from "../../Color.js";
import type OpacityStop from "../../renderers/visualVariables/support/OpacityStop.js";
import type SmartMappingSliderBase from "./SmartMappingSliderBase.js";
import type OpacitySliderViewModel from "./OpacitySlider/OpacitySliderViewModel.js";
import type { VisualVariableResult } from "../../smartMapping/renderers/opacity.js";
import type { HistogramResult } from "../../smartMapping/statistics/types.js";
import type { SmartMappingSliderBaseProperties } from "./SmartMappingSliderBase.js";
import type { OpacitySliderViewModelProperties } from "./OpacitySlider/OpacitySliderViewModel.js";

export interface OpacitySliderProperties extends SmartMappingSliderBaseProperties, Partial<Pick<OpacitySlider, "stops" | "style">> {
  /**
   * 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/references/core/widgets/Expand/)
   * or [LayerList](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/) widgets.
   *
   * @since 4.11
   */
  label?: string | null;
  /**
   * The view model for the OpacitySlider widget. This class contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [OpacitySliderViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/OpacitySliderViewModel/)
   * class to access all properties and methods on the OpacitySlider widget.
   */
  viewModel?: OpacitySliderViewModelProperties;
}

export interface OpacitySliderStyle {
  /**
   * The color of the slider's track.
   *   For single-color visualizations where
   *   only an Opacity variable is present, you should set this color to match
   *   the color of the symbol in the [SimpleRenderer](https://developers.arcgis.com/javascript/latest/references/core/renderers/SimpleRenderer/).
   *
   * @default new Color([0, 121, 193])
   */
  trackFillColor?: Color;
}

/**
 * The OpacitySlider widget is intended for authoring and exploring data-driven visualizations in any
 * layer that can be rendered with an [OpacityVariable](https://developers.arcgis.com/javascript/latest/references/core/renderers/visualVariables/OpacityVariable/).
 * At a minimum you must set the [min](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/#min), [max](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/#max), and [stops](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/#stops) properties
 * of the widget. The stops are used to render the opacity 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.
 *
 * ![OpacitySlider with annotations](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/sliders/opacityslider-labels.png "OpacitySlider with annotations")
 *
 * The [fromVisualVariableResult()](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/#fromVisualVariableResult) method can be used to conveniently create this slider
 * from the result of the [createVisualVariable()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/opacity/#createVisualVariable)
 * method.
 *
 * ```js
 * const params = {
 *   layer: layer,
 *   basemap: map.basemap,
 *   valueExpression: "( $feature.POP_POVERTY / $feature.TOTPOP_CY ) * 100",
 *   view: view
 * };
 *
 * let variableResult = null;
 *
 * opacityVariableCreator
 *   .createVisualVariable(params)
 *   .then(function(response) {
 *     variableResult = response;
 *     layer.renderer.visualVariables = [ response.visualVariable ];
 *
 *     return histogram({
 *       layer: layer,
 *       valueExpression: params.valueExpression,
 *       view: view,
 *       numBins: 70
 *     });
 *   })
 *    .then(function(histogramResult) {
 *      const slider = OpacitySlider.fromVisualVariableResult(variableResult, histogramResult);
 *      slider.container = "slider";
 *    })
 *    .catch(function(error) {
 *      console.log("there was an error: ", error);
 *    });
 * ```
 *
 * This slider should be used to update an [opacity visual variable](https://developers.arcgis.com/javascript/latest/references/core/renderers/visualVariables/OpacityVariable/)
 * in a layer's renderer. It is the responsibility of the app developer
 * to set up event listeners on this slider to update the opacity variable of the appropriate renderer.
 *
 * ```js
 * // when the user slides the handle(s), update the renderer
 * // with the updated opacity stops
 *
 * slider.on(["thumb-change", "thumb-drag"], function() {
 *   const renderer = layer.renderer.clone();
 *   const opacityVariable = renderer.visualVariables[0].clone();
 *   opacityVariable.stops = slider.stops;
 *   renderer.visualVariables = [ opacityVariable ];
 *   layer.renderer = renderer;
 * });
 * ```
 *
 * @deprecated since version 5.0. Use the [Slider Opacity](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-slider-opacity-legacy/) component instead. For information on widget deprecation, read about [Esri's move to web components](https://developers.arcgis.com/javascript/latest/components-transition-plan/).
 * @since 4.12
 * @see [OpacitySliderViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/OpacitySliderViewModel/)
 * @see [opacityVariableCreator](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/opacity/)
 */
export default class OpacitySlider extends SmartMappingSliderBase {
  /**
   * A convenience function used to create an OpacitySlider widget instance from the
   * [result](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/opacity/#VisualVariableResult) of
   * the [createVisualVariable()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/opacity/#createVisualVariable)
   * method.
   *
   * This method sets the slider [stops](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/#stops), [min](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/#min), [max](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/#max),
   * and [histogramConfig](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/#histogramConfig). It is still the developer's responsibility to assign it a proper
   * [container](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/#container) and any other optional properties.
   *
   * @param visualVariableResult - The result object from the [createVisualVariable()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/opacity/#createVisualVariable)
   *   method.
   * @param histogramResult - The result histogram object from the [histogram()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/histogram/#histogram)
   *   method.
   * @returns Returns an OpacitySlider instance. This will not render until you assign
   *   it a valid [container](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/#container).
   * @example
   * const params = {
   *   layer: layer,
   *   basemap: map.basemap,
   *   valueExpression: "( $feature.POP_POVERTY / $feature.TOTPOP_CY ) * 100",
   *   view: view
   * };
   *
   * let vvResult = null;
   *
   * opacityVariableCreator
   *   .createVisualVariable(params)
   *   .then(function(response) {
   *     vvResult = response;
   *     const renderer = layer.renderer.clone();
   *     renderer.visualVariables = [ vvResult.visualVariable ]
   *     layer.renderer = renderer;
   *
   *     return histogram({
   *       layer: layer,
   *       valueExpression: params.valueExpression,
   *       view: view,
   *       numBins: 70
   *     });
   *   })
   *    .then(function(histogramResult) {
   *
   *      const opacitySlider = OpacitySlider.fromVisualVariableResult(vvResult, histogramResult);
   *      opacitySlider.container = "slider";
   *
   *      // when the user slides the handle(s), update the renderer
   *      // with the updated opacity stops
   *
   *      opacitySlider.on(["thumb-change", "thumb-drag"], function() {
   *        const renderer = layer.renderer.clone();
   *        const opacityVariable = renderer.visualVariables[0].clone();
   *        opacityVariable.stops = opacitySlider.stops;
   *        renderer.visualVariables = [ opacityVariable ];
   *        layer.renderer = renderer;
   *      });
   *    })
   *    .catch(function(error) {
   *      console.log("there was an error: ", error);
   *    });
   */
  static fromVisualVariableResult(visualVariableResult: VisualVariableResult, histogramResult?: HistogramResult): OpacitySlider;
  /**
   * @example
   * // Typical usage
   * const slider = new OpacitySlider({
   *   container: "sliderDiv",
   *   statistics: stats,  // object generated from summaryStatistics()
   *   stops: response.visualVariable.stops,  // opacity visual variable generated from the opacityVariableCreator
   * });
   */
  constructor(properties?: OpacitySliderProperties);
  /**
   * 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/references/core/widgets/Expand/)
   * or [LayerList](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/) widgets.
   *
   * @since 4.11
   */
  get label(): string;
  set label(value: string | null | undefined);
  /**
   * The opacity stops from the [OpacityVariable](https://developers.arcgis.com/javascript/latest/references/core/renderers/visualVariables/OpacityVariable/)
   * to link to the slider. The opacity values in these stops will be used
   * to render the gradient on the slider. They should match the opacity
   * rendered in the associated layer's opacity visual variable.
   *
   * @example
   * opacityVariableCreator.createContinuousRenderer({
   *   layer: featureLayer,
   *   field: "fieldName",
   *   basemap: "gray-vector"
   * }).then(function(opacityResponse){
   *   const slider = new OpacitySlider({
   *     stops: opacityResponse.visualVariable.stops,
   *     container: "sliderDiv"
   *   });
   * });
   */
  accessor stops: OpacityStop[];
  /**
   * Exposes various properties of the widget
   * that can be styled.
   *
   * @example slider.style.trackFillColor = new Color("dodgerblue");
   */
  accessor style: OpacitySliderStyle;
  /**
   * The view model for the OpacitySlider widget. This class contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [OpacitySliderViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/OpacitySlider/OpacitySliderViewModel/)
   * class to access all properties and methods on the OpacitySlider widget.
   */
  get viewModel(): OpacitySliderViewModel;
  set viewModel(value: OpacitySliderViewModelProperties);
  /**
   * A convenience function used to update the properties of an OpacitySlider widget instance from the
   * [result](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/opacity/#VisualVariableResult) of
   * the [createVisualVariable()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/opacity/#createVisualVariable)
   * method. This method is useful for cases when the app allows the end user to switch data variables
   * used to render the data.
   *
   * @param visualVariableResult - The result object from the [createVisualVariable()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/opacity/#createVisualVariable)
   *   method.
   * @param histogramResult - The result histogram object from the [histogram()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/histogram/#histogram)
   *   method.
   * @example
   * const params = {
   *   layer: layer,
   *   basemap: map.basemap,
   *   valueExpression: "( $feature.POP_POVERTY / $feature.TOTPOP_CY ) * 100",
   *   view: view
   * };
   *
   * let vvResult = null;
   *
   * opacityVariableCreator
   *   .createVisualVariable(params)
   *   .then(function(response) {
   *     vvResult = response;
   *     const renderer = layer.renderer.clone();
   *     renderer.visualVariables = [ vvResult.visualVariable ]
   *     layer.renderer = renderer;
   *
   *     return histogram({
   *       layer: layer,
   *       valueExpression: params.valueExpression,
   *       view: view,
   *       numBins: 70
   *     });
   *   })
   *    .then(function(histogramResult) {
   *      opacitySlider.updateFromVisualVariableResult(vvResult, histogramResult);
   *    })
   *    .catch(function(error) {
   *      console.log("there was an error: ", error);
   *    });
   */
  updateFromVisualVariableResult(visualVariableResult: VisualVariableResult, histogramResult?: HistogramResult): void;
}