import type ClassBreaksRenderer from "../../renderers/ClassBreaksRenderer.js";
import type ColorVariable from "../../renderers/visualVariables/ColorVariable.js";
import type SizeVariable from "../../renderers/visualVariables/SizeVariable.js";
import type ColorSizeStop from "../../renderers/visualVariables/support/ColorSizeStop.js";
import type SmartMappingSliderBase from "./SmartMappingSliderBase.js";
import type ColorSizeSliderViewModel from "./ColorSizeSlider/ColorSizeSliderViewModel.js";
import type { RendererResult } from "../../smartMapping/renderers/univariateColorSize.js";
import type { HistogramResult } from "../../smartMapping/statistics/types.js";
import type { SmartMappingSliderBaseProperties } from "./SmartMappingSliderBase.js";
import type { ColorSizeSliderViewModelProperties } from "./ColorSizeSlider/ColorSizeSliderViewModel.js";

export interface ColorSizeSliderProperties extends SmartMappingSliderBaseProperties, Partial<Pick<ColorSizeSlider, "handlesSyncedToPrimary" | "persistSizeRangeEnabled" | "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/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 ColorSizeSlider widget. This class contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [ColorSizeSliderViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/ColorSizeSliderViewModel/)
   * class to access all properties and methods on the ColorSizeSlider widget.
   */
  viewModel?: ColorSizeSliderViewModelProperties;
}

export type VisualVariable = ColorVariable | SizeVariable;

/**
 * The ColorSizeSlider 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/references/core/renderers/visualVariables/ColorVariable/) and
 * a [SizeVariable](https://developers.arcgis.com/javascript/latest/references/core/renderers/visualVariables/SizeVariable/). Both visual variables should be used
 * to visualize the same data variable.
 *
 * This slider and visualization style is designed specifically for
 * 3D thematic visualizations where both size and color are used to visualize the same data variable in order
 * to minimize confusion because of distortion in perception. For example, a visualization of extruded points
 * may be difficult to understand if two features of similar sizes (and therefore data values) are located
 * far apart from one another; the feature furthest from the [Camera](https://developers.arcgis.com/javascript/latest/references/core/Camera/) will appear smaller than
 * the feature closer to the camera. The color variable can help the user understand that both features have similar values.
 *
 * ![ColorSizeSlider with perspective](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/sliders/colorsizeslider-perspective.avif "ColorSizeSlider with perspective")
 *
 * At a minimum you must set the [min](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#min), [max](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#max), and [stops](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#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.
 *
 * ![ColorSizeSlider with annotations](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/sliders/colorsizeslider-labels.avif "ColorSizeSlider with annotations")
 *
 * The [fromRendererResult()](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#fromRendererResult) method can be used to conveniently create this slider
 * from the result of the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#createContinuousRenderer)
 * method.
 *
 * ```js
 * const params = {
 *   layer: layer,
 *   basemap: map.basemap,
 *   valueExpression: "( $feature.POP_POVERTY / $feature.TOTPOP_CY ) * 100",
 *   view: view
 * };
 *
 * let rendererResult = null;
 *
 * univariateColorSizeRendererCreator
 *   .createContinuousRenderer(params)
 *   .then(function(response) {
 *     rendererResult = response;
 *     layer.renderer = response.renderer;
 *
 *     return histogram({
 *       layer: layer,
 *       valueExpression: colorParams.valueExpression,
 *       view: view,
 *       numBins: 70
 *     });
 *   })
 *    .then(function(histogramResult) {
 *      const slider = ColorSizeSlider.fromRendererResult(rendererResult, histogramResult);
 *      slider.container = "slider";
 *    })
 *    .catch(function(error) {
 *      console.log("there was an error: ", error);
 *    });
 * ```
 *
 * This slider should be used to update the matching [color](https://developers.arcgis.com/javascript/latest/references/core/renderers/visualVariables/ColorVariable/)
 * and [size](https://developers.arcgis.com/javascript/latest/references/core/renderers/visualVariables/SizeVariable/) visual variables in a layer's renderer. It is the responsibility of the app developer
 * to set up event listeners on this slider that update these variables in the appropriate renderer.
 *
 * ```js
 * // when the user slides the handle(s), update the renderer
 * // with the updated color stops
 *
 * slider.on(["thumb-change", "thumb-drag"], function() {
 *   const renderer = layer.renderer.clone();
 *   renderer.visualVariables = slider.updateVisualVariables( renderer.visualVariables );
 *   layer.renderer = renderer;
 * });
 * ```
 *
 * @deprecated since version 5.0. Use the [Slider Color Size](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-slider-color-size-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 [ColorSizeSliderViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/ColorSizeSliderViewModel/)
 * @see [univariateColorSizeRendererCreator](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/)
 */
export default class ColorSizeSlider extends SmartMappingSliderBase {
  /**
   * A convenience function used to create a ColorSizeSlider widget instance from the
   * [result](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#RendererResult) of
   * the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#createContinuousRenderer)
   * method.
   *
   * This method sets the slider [stops](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#stops), [min](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#min),
   * [max](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#max), and [histogramConfig](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#histogramConfig).
   * It is still the developer's responsibility to assign it a proper
   * [container](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#container) and any other optional properties.
   *
   * @param rendererResult - The result object from the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#createContinuousRenderer)
   *   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 a ColorSizeSlider instance. This will not render until you assign
   *   it a valid [container](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#container).
   * @example
   * let params = {
   *   layer: layer,
   *   basemap: map.basemap,
   *   field: "POP",
   *   view: view,
   *   symbolType: "3d-volumetric",
   *   min: 0,
   *   max: 500000
   * };
   * colorAndSizeRendererCreator
   *   .createContinuousRenderer(params)
   *   .then(function(response) {
   *     // set generated renderer on the layer and add it to the map
   *     rendererResult = response;
   *     layer.renderer = response.renderer;
   *
   *     return histogram({
   *       layer: layer,
   *       field: params.field,
   *       numBins: 70,
   *       maxValue: params.max,
   *       minValue: params.min
   *     });
   *   })
   *   .then(function(histogramResult) {
   *     let slider = ColorSizeSlider.fromRendererResult(rendererResult, histogramResult);
   *     slider.container = "slider";
   *   });
   */
  static fromRendererResult(rendererResult: RendererResult, histogramResult?: HistogramResult): ColorSizeSlider;
  /**
   * @example
   * const slider = new ColorSizeSlider({
   *   min: 0,
   *   max: 100,
   *   stops: [
   *     { value: 25, color: "white", size: 1000 },
   *     { value: 75, color: "dodgerblue", size: 100000 }
   *   ]
   * });
   */
  constructor(properties?: ColorSizeSliderProperties);
  /**
   * Only applicable when three thumbs (i.e. handles) are set on the
   * slider (i.e. when [primaryHandleEnabled](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#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
   * @since 4.18
   * @see [primaryHandleEnabled](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#primaryHandleEnabled)
   * @example
   * // enables the primary handles and syncs it with the others
   * slider.primaryHandleEnabled = true;
   * slider.handlesSyncedToPrimary = true;
   * slider.persistSizeRangeEnabled = 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/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);
  /**
   * Only applicable when three thumbs (i.e. handles) are set on the
   * slider (i.e. when [primaryHandleEnabled](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#primaryHandleEnabled) is `true`).
   * This property is typically used in diverging, or `above-and-below` renderer configurations.
   *
   * When `true`, ensures symbol sizes in the `above` range
   * are consistent with symbol sizes in the `below` range for all slider thumb positions.
   * In other words, the size values in the [stops](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#stops) will adjust
   * proportionally according to the positions of the data values within the
   * constraints of the size range (maxSize - minSize) as the slider thumbs update.
   * When `false`, size values in the stops will remain the same even when slider thumb values
   * change.
   *
   * In most cases, this should be set to `true` to keep sizes in the `above` range consistent with
   * sizes in the `below` range to avoid map misinterpretation.
   *
   * @default false
   * @since 4.19
   * @see [primaryHandleEnabled](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#primaryHandleEnabled)
   * @example
   * slider.primaryHandleEnabled = true;
   * slider.persistSizeRangeEnabled = true;
   */
  accessor persistSizeRangeEnabled: boolean;
  /**
   * 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/references/core/widgets/smartMapping/ColorSizeSlider/#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/references/core/widgets/smartMapping/ColorSizeSlider/#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
   * @since 4.18
   * @see [handlesSyncedToPrimary](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#handlesSyncedToPrimary)
   * @see [persistSizeRangeEnabled](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#persistSizeRangeEnabled)
   * @example
   * // enables the primary handles and syncs it with the others
   * slider.primaryHandleEnabled = true;
   * slider.handlesSyncedToPrimary = true;
   * slider.persistSizeRangeEnabled = true;
   */
  accessor primaryHandleEnabled: boolean;
  /**
   * The colors and sizes corresponding with data values in the
   * [ColorVariable](https://developers.arcgis.com/javascript/latest/references/core/renderers/visualVariables/ColorVariable/) and
   * [SizeVariable](https://developers.arcgis.com/javascript/latest/references/core/renderers/visualVariables/SizeVariable/) of the renderer
   * associated with the slider.
   *
   * Use the [fromRendererResult()](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#fromRendererResult)
   * method to conveniently construct these stops from a renderer generated from
   * the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#createContinuousRenderer)
   * smart mapping module.
   *
   * Use [updateVisualVariables()](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#updateVisualVariables) to update the renderer's
   * visual variables with the values matching the slider thumb positions.
   *
   * @see [fromRendererResult()](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#fromRendererResult)
   * @see [updateVisualVariables()](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/#updateVisualVariables)
   * @example
   * slider.stops = [
   *   { value: 25, color: "white", size: 1000 },
   *   { value: 75, color: "dodgerblue", size: 100000 }
   * ];
   */
  accessor stops: ColorSizeStop[];
  /**
   * The view model for the ColorSizeSlider widget. This class contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [ColorSizeSliderViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/smartMapping/ColorSizeSlider/ColorSizeSliderViewModel/)
   * class to access all properties and methods on the ColorSizeSlider widget.
   */
  get viewModel(): ColorSizeSliderViewModel;
  set viewModel(value: ColorSizeSliderViewModelProperties);
  /**
   * A convenience function used to update the properties of a ColorSizeSlider widget instance from the
   * [result](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#RendererResult) of
   * the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#createContinuousRenderer)
   * method.
   *
   * @param rendererResult - The result object from the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#createContinuousRenderer)
   *   method.
   * @param histogramResult - The result histogram object from the [histogram()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/histogram/#histogram)
   *   method.
   * @example
   * let params = {
   *   layer: layer,
   *   basemap: map.basemap,
   *   field: "POP",
   *   view: view,
   *   symbolType: "3d-volumetric",
   *   minValue: 0,
   *   maxValue: 500000
   * };
   * colorAndSizeRendererCreator
   *   .createContinuousRenderer(params)
   *   .then(function(response) {
   *     // set generated renderer on the layer and add it to the map
   *     rendererResult = response;
   *     layer.renderer = response.renderer;
   *
   *     return histogram({
   *       layer: layer,
   *       field: params.field,
   *       numBins: 70,
   *       maxValue: params.maxValue,
   *       minValue: params.minValue
   *     });
   *   })
   *   .then(function(histogramResult) {
   *     slider.fromRendererResult(rendererResult, histogramResult);
   *   });
   */
  updateFromRendererResult(rendererResult: RendererResult, histogramResult?: HistogramResult): void;
  /**
   * A convenience function used to update a renderer generated with the
   * [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#createContinuousRenderer)
   * method with the values obtained from the slider. This method is useful for cases when the app allows the end user to switch data variables
   * used to render the data.
   *
   * @param renderer - A renderer generated from the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#createContinuousRenderer)
   *   method.
   * @returns Returns the input renderer updated to match the current slider values. This should be set directly
   *   back to the layer where it came from
   * @since 4.18
   * @example
   * slider.on(["thumb-change", "thumb-drag"], function() {
   *   layer.renderer = slider.updateRenderer( layer.renderer );
   * });
   */
  updateRenderer(renderer: ClassBreaksRenderer): ClassBreaksRenderer;
  /**
   * A convenience function used to update the visual variables of a renderer generated with the
   * [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/univariateColorSize/#createContinuousRenderer)
   * method with the values obtained from the slider. This method is useful for cases when the app allows the end user to switch data variables
   * used to render the data.
   *
   * @param variables - The visual variables to update from the renderer associated with the slider. The properties of the
   *   color and size variables will update based on the slider thumb values.
   * @returns Returns the input visual variables updated to match the current slider values. These should be set directly
   *   back to the renderer where they came from.
   * @example
   * slider.on(["thumb-change", "thumb-drag"], function() {
   *   const renderer = layer.renderer.clone();
   *   renderer.visualVariables = slider.updateVisualVariables( renderer.visualVariables );
   *   layer.renderer = renderer;
   * });
   */
  updateVisualVariables(variables: VisualVariable[]): VisualVariable[];
}