import type Color from "../../Color.js";
import type ClassBreaksRenderer from "../../renderers/ClassBreaksRenderer.js";
import type SizeStop from "../../renderers/visualVariables/support/SizeStop.js";
import type SmartMappingSliderBase from "./SmartMappingSliderBase.js";
import type BinaryColorSizeSliderViewModel from "./BinaryColorSizeSlider/BinaryColorSizeSliderViewModel.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 { BinaryColorSizeSliderViewModelProperties } from "./BinaryColorSizeSlider/BinaryColorSizeSliderViewModel.js";

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

export interface BinaryColorSizeSliderStyle {
  /**
   * The color of the slider's track
   *   above the middle stop value.
   *   This color should match the color of the symbol in the upper break of the
   *   [ClassBreaksRenderer](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-ClassBreaksRenderer.html) used to define the binary above and below visualization.
   *
   * @default new Color([149, 149, 149])
   */
  trackAboveFillColor?: Color;
  /**
   * The background color of the
   *   slider's track. Generally, this color should be subdued and not interfere with the `trackAboveFillColor` or
   *   `trackBelowFillColor`.
   *
   * @default new Color([224, 224, 224])
   */
  trackBackgroundColor?: Color;
  /**
   * The color of the slider's track
   *   below the middle stop value.
   *   This color should match the color of the symbol in the lower break of the
   *   [ClassBreaksRenderer](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-ClassBreaksRenderer.html) used to define the binary above and below visualization.
   *
   * @default new Color([149, 149, 149])
   */
  trackBelowFillColor?: Color;
}

/**
 * The BinaryColorSizeSlider widget is intended for authoring and exploring diverging data-driven visualizations in any
 * layer that can be rendered with an above and below theme for a [SizeVariable](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-visualVariables-SizeVariable.html).
 * At a minimum you must set the [min](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.html#min), [max](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.html#max), and [stops](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.html#stops) properties
 * of the widget.
 *
 * The [fromRendererResult()](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.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-univariateColorSize.html#createContinuousRenderer)
 * method.
 *
 * ```js
 * const params = {
 *   layer,
 *   view,
 *   valueExpression: "$feature.POP_POVERTY_2020 - $feature.POP_POVERTY_2010",
 *   theme: "above-and-below",
 *   minValue: -50,
 *   maxValue: 50,
 *   colorOptions: {
 *     isContinuous: false
 *   },
 *   symbolOptions: {
 *     symbolStyle: "arrow"
 *   }
 * };
 *
 * const rendererResult = await univariateColorSizeRendererCreator
 *   .createContinuousRenderer(colorParams);
 *
 * layer.renderer = rendererResult.renderer;
 *
 * const histogramResult = await histogram({
 *   layer,
 *   view,
 *   valueExpression: params.valueExpression,
 *   minValue: -50,
 *   maxValue: 50,
 *   numBins: 30
 * });
 *
 * const binarySlider = BinaryColorSizeSlider.fromRendererResult(rendererResult, histogramResult);
 * sizeSlider.container = "slider";
 *
 * // when the user slides the handle(s), update the renderer
 * // with the updated size properties
 *
 * binarySlider.on(["thumb-change", "thumb-drag"], () => {
 *   layer.renderer = binarySlider.updateRenderer( layer.renderer );
 * });
 * ```
 *
 * This slider should be used to update an above and below (diverging) visualization in a layer's renderer.
 * It is the responsibility of the app developer to set up event listeners on that update the size variable of the appropriate renderer.
 *
 * ```js
 * // when the user slides the handle(s), update the renderer
 * // with the updated size stops
 *
 * slider.on(["thumb-change", "thumb-drag"], () => {
 *   layer.renderer = slider.updateRenderer( layer.renderer );
 * });
 * ```
 *
 * @since 4.28
 * @see [BinaryColorSizeSliderViewModel](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider-BinaryColorSizeSliderViewModel.html)
 * @see [univariateColorSizeRendererCreator](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-univariateColorSize.html)
 */
export default class BinaryColorSizeSlider extends SmartMappingSliderBase {
  /**
   * A convenience function used to create a BinaryColorSizeSlider widget instance from the
   * [result](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-univariateColorSize.html#RendererResult) of
   * the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-univariateColorSize.html#createContinuousRenderer)
   * method.
   *
   * This method sets the slider [stops](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.html#stops), [min](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.html#min), [max](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.html#max),
   * and [histogramConfig](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.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-BinaryColorSizeSlider.html#container) and any other optional properties.
   *
   * @param rendererResult - The result object from the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-univariateColorSize.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 BinaryColorSizeSlider instance.
   *   This will not render until you assign it a valid [container](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.html#container).
   * @example
   * const params = {
   *   layer,
   *   view,
   *   valueExpression: "$feature.POP_POVERTY_2020 - $feature.POP_POVERTY_2010",
   *   theme: "above-and-below",
   *   minValue: -50,
   *   maxValue: 50,
   *   colorOptions: {
   *     isContinuous: false
   *   },
   *   symbolOptions: {
   *     symbolStyle: "arrow"
   *   }
   * };
   *
   * const rendererResult = await univariateColorSizeRendererCreator
   *   .createContinuousRenderer(colorParams);
   *
   * layer.renderer = rendererResult.renderer;
   *
   * const histogramResult = await histogram({
   *   layer,
   *   view,
   *   valueExpression: params.valueExpression,
   *   minValue: -50,
   *   maxValue: 50,
   *   numBins: 30
   * });
   *
   * const slider = BinaryColorSizeSlider.fromRendererResult(rendererResult, histogramResult);
   * sizeSlider.container = "slider";
   *
   * // when the user slides the handle(s), update the renderer
   * // with the updated size properties
   *
   * slider.on(["thumb-change", "thumb-drag"], () => {
   *   layer.renderer = slider.updateRenderer( layer.renderer );
   * });
   */
  static fromRendererResult(rendererResult: RendererResult, histogramResult?: HistogramResult): BinaryColorSizeSlider;
  /**
   * @example
   * // Typical usage
   * const slider = new BinaryColorSizeSlider({
   *   container: "sliderDiv",
   *   min: 0,
   *   max: 100,
   *   stops: [
   *     { value: 0, size: 4 },
   *     { value: 100, size: 40 }
   *   ]
   * });
   */
  constructor(properties?: BinaryColorSizeSliderProperties);
  /**
   * 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
   * @example
   * // enables the primary handles and syncs it with the others
   * 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`, 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/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.html#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
   * @example slider.persistSizeRangeEnabled = true;
   */
  accessor persistSizeRangeEnabled: boolean;
  /**
   * The size stops from the [SizeVariable](https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-visualVariables-SizeVariable.html)
   * to link to the slider. You must provide either three or five stops. The minimum size
   * should be represented in the size property of the middle stop. The maximum size should
   * be represented in either first or last stops.
   *
   * @example
   * const slider = new BinaryColorSizeSlider({
   *   container: "sliderDiv",
   *   min: 0,
   *   max: 100,
   *   stops: [
   *     { value: -50, size: 20 },
   *     { value: 0, size: 2 }
   *     { value: 100, size: 40 }
   *   ]
   * });
   */
  accessor stops: SizeStop[];
  /**
   * Exposes various properties of the widget
   * that can be styled.
   *
   * @example
   * slider.style = {
   *   trackAboveFillColor: new Color("dodgerblue"),
   *   trackBelowFillColor: new Color("red")
   * };
   */
  accessor style: BinaryColorSizeSliderStyle;
  /**
   * The view model for the BinaryColorSizeSlider widget. This class contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [BinaryColorSizeSliderViewModel](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider-BinaryColorSizeSliderViewModel.html)
   * class to access all properties and methods on the BinaryColorSizeSlider widget.
   */
  get viewModel(): BinaryColorSizeSliderViewModel;
  set viewModel(value: BinaryColorSizeSliderViewModelProperties);
  /**
   * A convenience function used to update the properties of a BinaryColorSizeSlider widget instance from the
   * [result](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-univariateColorSize.html#RendererResult) of
   * the [createContinuousRenderer()](https://developers.arcgis.com/javascript/latest/api-reference/esri-smartMapping-renderers-univariateColorSize.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-univariateColorSize.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.
   * @example
   * const params = {
   *   layer,
   *   view,
   *   valueExpression: "$feature.POP_POVERTY_2020 - $feature.POP_POVERTY_2010",
   *   theme: "above-and-below",
   *   minValue: -50,
   *   maxValue: 50,
   *   colorOptions: {
   *     isContinuous: false
   *   },
   *   symbolOptions: {
   *     symbolStyle: "arrow"
   *   }
   * };
   *
   * const rendererResult = await univariateColorSizeRendererCreator
   *   .createContinuousRenderer(colorParams);
   *
   * layer.renderer = rendererResult.renderer;
   *
   * const histogramResult = await histogram({
   *   layer,
   *   view,
   *   valueExpression: params.valueExpression,
   *   minValue: -50,
   *   maxValue: 50,
   *   numBins: 30
   * });
   *
   * slider.updateFromRendererResult(rendererResult, histogramResult);
   */
  updateFromRendererResult(rendererResult: RendererResult, histogramResult?: HistogramResult): void;
  /**
   * A convenience function used to update the input renderer based on
   * the values of the slider [stops](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-smartMapping-BinaryColorSizeSlider.html#stops).
   *
   * @param renderer - The renderer
   *   to update from the slider values.
   * @returns Returns the updated renderer.
   * @example
   * slider.on(["thumb-change", "thumb-drag"], () => {
   *   layer.renderer = slider.updateRenderer( layer.renderer );
   * });
   */
  updateRenderer(renderer: ClassBreaksRenderer): ClassBreaksRenderer | null | undefined;
}