import type Color from "../Color.js";
import type Symbol3DLayer from "./Symbol3DLayer.js";
import type { WaterBodySize, WaveStrength } from "./types.js";
import type { ColorLike } from "../Color.js";
import type { Symbol3DLayerProperties } from "./Symbol3DLayer.js";

export interface WaterSymbol3DLayerProperties extends Symbol3DLayerProperties, Partial<Pick<WaterSymbol3DLayer, "waterbodySize" | "waveDirection" | "waveStrength">> {
  /**
   * The dominant color used to shade the water. The water has different shades of the dominant color based
   * on the reflection of the light. The image below shows how different types of water can be represented with
   * different colors. For example for deep water the dominant color could be navy blue.
   *
   * ![symbol3D-water](https://developers.arcgis.com/javascript/latest/assets/references/core/symbols/symbol3d-water-colors.png)
   *
   * The color can be autocast with an array of rgb(a) values, named string, hex string or an hsl(a) string,
   * an object with `r`, `g`, `b`, and `a` properties, or a [Color](https://developers.arcgis.com/javascript/latest/references/core/Color/) object.
   *
   * @default "#0077be"
   * @example
   * // a new color by a HEX string
   * symbolLayer.color = "#005b66";
   */
  color?: ColorLike;
}

/**
 * WaterSymbol3DLayer is used to render [Polygon](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polygon/) geometries as realistic, animated water surfaces,
 * therefore it can only be used inside a [PolygonSymbol3D](https://developers.arcgis.com/javascript/latest/references/core/symbols/PolygonSymbol3D/).
 *
 * ![symbol3D-water](https://developers.arcgis.com/javascript/latest/assets/references/core/symbols/symbol3d-water.png)
 *
 * Various properties can be set to enhance the realistic effect of this symbol layer. The [waveStrength](https://developers.arcgis.com/javascript/latest/references/core/symbols/WaterSymbol3DLayer/#waveStrength)
 * can be set to show the magnitude of the waves and [waveDirection](https://developers.arcgis.com/javascript/latest/references/core/symbols/WaterSymbol3DLayer/#waveDirection) indicates
 * the direction in which the waves travel. The [waterbodySize](https://developers.arcgis.com/javascript/latest/references/core/symbols/WaterSymbol3DLayer/#waterbodySize) can be set to specify how large the waterbody is.
 * The dominant [color](https://developers.arcgis.com/javascript/latest/references/core/symbols/WaterSymbol3DLayer/#color) of the water can be used to change the appearance of the water.
 *
 * This symbol layer is not supported in a [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/).
 *
 * @since 4.12
 * @see [Realistic water visualization in 3D](https://developers.arcgis.com/javascript/latest/sample-code/visualization-realistic-water/)
 * @example
 * const waterLayer = new FeatureLayer({
 *   ...,
 *   renderer: {
 *     type: "simple",
 *     symbol: {
 *       type: "polygon-3d",
 *       symbolLayers: [{
 *         type: "water",
 *         waveDirection: 180,
 *         color: "#5975a3",
 *         waveStrength: "moderate",
 *         waterbodySize: "small"
 *       }]
 *     }
 *   }
 * });
 */
export default class WaterSymbol3DLayer extends Symbol3DLayer {
  constructor(properties?: WaterSymbol3DLayerProperties);
  /**
   * The dominant color used to shade the water. The water has different shades of the dominant color based
   * on the reflection of the light. The image below shows how different types of water can be represented with
   * different colors. For example for deep water the dominant color could be navy blue.
   *
   * ![symbol3D-water](https://developers.arcgis.com/javascript/latest/assets/references/core/symbols/symbol3d-water-colors.png)
   *
   * The color can be autocast with an array of rgb(a) values, named string, hex string or an hsl(a) string,
   * an object with `r`, `g`, `b`, and `a` properties, or a [Color](https://developers.arcgis.com/javascript/latest/references/core/Color/) object.
   *
   * @default "#0077be"
   * @example
   * // a new color by a HEX string
   * symbolLayer.color = "#005b66";
   */
  get color(): Color;
  set color(value: ColorLike);
  /** The symbol type. */
  get type(): "water";
  /**
   * Indicates the size of the waterbody which is represented by the
   * symbol layer. `small` can be set for small lakes,
   * rivers or swimming pools, `medium` can be set for large lakes,
   * whereas `large` is recommended for ocean and sea waterbodies.
   *
   * @default "medium"
   * @example
   * // sets the waterBodySize for an ocean like waterbody.
   * symbolLayer.waterbodySize = "large";
   */
  accessor waterbodySize: WaterBodySize;
  /**
   * Indicates the direction in which the waves travel. This value represents the geographic rotation in degrees and it ranges from
   * 0 to 360 degrees.
   * A value of 0 degrees corresponds to geographic north, which means that the wave travels from south to north.
   *
   * The default is set to `null`, which will display the waves without a distinct direction.
   *
   * @example
   * // sets the wave direction to 215 degrees
   * symbolLayer.waveDirection = 215;
   */
  accessor waveDirection: number | null | undefined;
  /**
   * Indicates the shape and intensity of the waves. Currently only calm to moderate waterbodies can be represented.
   * A `calm` wave strength represents water without waves, acting almost like a mirror. A water with `rippled` wave strength
   * has very small and short waves. `slight` wave strength displays the waves with a more pronounced form, but they are still quite short.
   * Choosing `moderate` will display waves with a longer form and a slightly increased intensity.
   *
   * @default "moderate"
   * @example
   * // sets the wave strength to small waves
   * symbolLayer.waveStrength = "slight";
   */
  accessor waveStrength: WaveStrength;
  /**
   * Creates a deep clone of the symbol layer.
   *
   * @returns A deep clone of the object that
   *                                                      invoked this method.
   * @example
   * // Creates a deep clone of the graphic's first symbol layer
   * let symLyr = graphic.symbol.symbolLayers.at(0).clone();
   */
  clone(): WaterSymbol3DLayer;
}