import type Font from "./Font.js";
import type Symbol3DLayer from "./Symbol3DLayer.js";
import type OccludedVisibility from "./support/OccludedVisibility.js";
import type Symbol3DHalo from "./support/Symbol3DHalo.js";
import type Symbol3DMaterial from "./support/Symbol3DMaterial.js";
import type Symbol3DTextBackground from "./support/Symbol3DTextBackground.js";
import type { TextVerticalAlignment, TextHorizontalAlignment } from "./types.js";
import type { OccludedVisibilityProperties } from "./support/OccludedVisibility.js";
import type { Symbol3DHaloProperties } from "./support/Symbol3DHalo.js";
import type { Symbol3DMaterialProperties } from "./support/Symbol3DMaterial.js";
import type { Symbol3DTextBackgroundProperties } from "./support/Symbol3DTextBackground.js";
import type { FontProperties } from "./Font.js";
import type { Symbol3DLayerProperties } from "./Symbol3DLayer.js";

export interface TextSymbol3DLayerProperties extends Symbol3DLayerProperties, Partial<Pick<TextSymbol3DLayer, "horizontalAlignment" | "lineHeight" | "text" | "verticalAlignment">> {
  /**
   * The background of the text. The background can be used to define a background color for the
   * text to improve readability by increasing contrast with the background. Setting a background
   * will add additional padding to the text and display using rounded corners.
   *
   * @example symbolLayer.background = { color: [0, 0, 0, 0.75] };
   */
  background?: Symbol3DTextBackgroundProperties | null;
  /** The font of the text label. */
  font?: FontProperties | null;
  /**
   * The halo surrounding the text.
   *
   * @since 4.4
   * @example
   * symbolLayer.halo = {
   *  color: [255, 255, 255, 0.8], // autocasts as Color
   *  size: 2
   * }
   */
  halo?: Symbol3DHaloProperties | null;
  /**
   * The material used to color the text.
   *
   * @example
   * // CSS color string
   * symbolLayer.material = {
   *   color: "dodgerblue"
   * };
   * @example
   * // HEX string
   * symbolLayer.material = {
   *   color: "#33cc33";
   * }
   * @example
   * // array of RGBA values
   * symbolLayer.material = {
   *   color: [51, 204, 51, 0.3];
   * }
   * @example
   * // object with rgba properties
   * symbolLayer.material = {
   *   color: { r: 51, g: 51, b: 204, a: 0.7 }
   * };
   */
  material?: Symbol3DMaterialProperties | null;
  /**
   * Defines the occluded visibility mode of the text.
   *
   * @since 5.0
   */
  occludedVisibility?: OccludedVisibilityProperties | null;
  /**
   * Size of the text label in points. This value may be autocast with a string
   * expressing size in points or pixels (e.g. `12px`). When set, this property
   * overrides the [Font.size](https://developers.arcgis.com/javascript/latest/references/core/symbols/Font/#size) property.
   *
   * @default 9
   * @example
   * // size in points
   * symbolLayer.size = 14;
   * @example
   * // size in pixels
   * symbolLayer.size = "20px"; // autocasts as number
   * @example
   * // size in points
   * symbolLayer.size = "14pt"; // autocasts as number
   */
  size?: number | string;
}

/**
 * TextSymbol3DLayer is used to draw text labels for features of any geometry type. This is typically done
 * by adding it to a [LabelSymbol3D](https://developers.arcgis.com/javascript/latest/references/core/symbols/LabelSymbol3D/) in a 3D [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
 * [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/) does not support 3D symbols.
 *
 * The color of the symbol is set in the [material](https://developers.arcgis.com/javascript/latest/references/core/symbols/TextSymbol3DLayer/#material) property. The size of the text is
 * always defined in points or pixels via the [size](https://developers.arcgis.com/javascript/latest/references/core/symbols/TextSymbol3DLayer/#size) property.
 *
 * A TextSymbol3DLayer may be added to the `symbolLayers` property of any
 * [3D symbol](https://developers.arcgis.com/javascript/latest/references/core/symbols/Symbol3D/). Labeling the features of a
 * [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) is usually done by adding a TextSymbol3DLayer
 * to a [LabelSymbol3D](https://developers.arcgis.com/javascript/latest/references/core/symbols/LabelSymbol3D/), which is then added to a
 * [LabelClass](https://developers.arcgis.com/javascript/latest/references/core/layers/support/LabelClass/) in the
 * [FeatureLayer.labelingInfo](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#labelingInfo) property of the layer.
 * The image below depicts a [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) with labels defined
 * by a [LabelSymbol3D](https://developers.arcgis.com/javascript/latest/references/core/symbols/LabelSymbol3D/) that contains a TextSymbol3DLayer.
 *
 * ![3d-labels](https://developers.arcgis.com/javascript/latest/assets/references/core/symbols/symbols-3d-labels.png)
 *
 * @since 4.0
 * @see [Symbol Builder](https://developers.arcgis.com/javascript/latest/symbol-builder/)
 * @see [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/)
 * @see [LabelClass](https://developers.arcgis.com/javascript/latest/references/core/layers/support/LabelClass/)
 * @see [Sample - Flat vs. volumetric 3D symbol layers](https://developers.arcgis.com/javascript/latest/sample-code/symbols-points-3d/)
 * @see [Sample - Line markers and label placement](https://developers.arcgis.com/javascript/latest/sample-code/visualization-line-markers/)
 * @see [Sample - Query Elevation (points)](https://developers.arcgis.com/javascript/latest/sample-code/elevation-query-points/)
 * @example
 * let labelClass = new LabelClass({
 *   labelExpressionInfo: {
 *     expression: "$feature.COUNTY" // Text for labels comes from COUNTY field
 *   },
 *   symbol: {
 *     type: "label-3d",  // autocasts as new LabelSymbol3D()
 *     symbolLayers: [{
 *       type: "text",  // autocasts as new TextSymbol3DLayer()
 *       material: { color: [ 49,163,84 ] },
 *       size: 12  // points
 *     }]
 *   }
 * });
 * // Add labels to the feature layer
 * featureLayer.labelsVisible = true;
 * featureLayer.labelingInfo = [ labelClass ];
 */
export default class TextSymbol3DLayer extends Symbol3DLayer {
  constructor(properties?: TextSymbol3DLayerProperties);
  /**
   * The background of the text. The background can be used to define a background color for the
   * text to improve readability by increasing contrast with the background. Setting a background
   * will add additional padding to the text and display using rounded corners.
   *
   * @example symbolLayer.background = { color: [0, 0, 0, 0.75] };
   */
  get background(): Symbol3DTextBackground | null | undefined;
  set background(value: Symbol3DTextBackgroundProperties | null | undefined);
  /** The font of the text label. */
  get font(): Font | null | undefined;
  set font(value: FontProperties | null | undefined);
  /**
   * The halo surrounding the text.
   *
   * @since 4.4
   * @example
   * symbolLayer.halo = {
   *  color: [255, 255, 255, 0.8], // autocasts as Color
   *  size: 2
   * }
   */
  get halo(): Symbol3DHalo | null | undefined;
  set halo(value: Symbol3DHaloProperties | null | undefined);
  /**
   * Adjusts the horizontal alignment of the text in multi-lines.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > This property only applies when the symbol layer is not used for labeling purposes. The `horizontalAlignment` for labels
   * > is inferred from the [LabelClass.labelPlacement](https://developers.arcgis.com/javascript/latest/references/core/layers/support/LabelClass/#labelPlacement) value.
   * > If the symbol layer is added to a symbol with a [line callout](https://developers.arcgis.com/javascript/latest/references/core/symbols/callouts/LineCallout3D/)
   * > or [vertical offset](https://developers.arcgis.com/javascript/latest/references/core/symbols/PointSymbol3D/#verticalOffset), then only `center` is supported.
   *
   * @default "center"
   * @since 4.23
   */
  accessor horizontalAlignment: TextHorizontalAlignment;
  /**
   * The height of the space between each line of text. Only applies to multiline text.
   *
   * This property can be considered as a multiplier of the default value of 1.0
   * (e.g. a value of 2.0 will be two times the height of the default height).
   * The range of possible values is: 0.1 - 4.0.
   * If a value of 0 is specified, the default value of 1.0 will be used.
   *
   * @default 1.0
   * @since 4.23
   */
  accessor lineHeight: number;
  /**
   * The material used to color the text.
   *
   * @example
   * // CSS color string
   * symbolLayer.material = {
   *   color: "dodgerblue"
   * };
   * @example
   * // HEX string
   * symbolLayer.material = {
   *   color: "#33cc33";
   * }
   * @example
   * // array of RGBA values
   * symbolLayer.material = {
   *   color: [51, 204, 51, 0.3];
   * }
   * @example
   * // object with rgba properties
   * symbolLayer.material = {
   *   color: { r: 51, g: 51, b: 204, a: 0.7 }
   * };
   */
  get material(): Symbol3DMaterial | null | undefined;
  set material(value: Symbol3DMaterialProperties | null | undefined);
  /**
   * Defines the occluded visibility mode of the text.
   *
   * @since 5.0
   */
  get occludedVisibility(): OccludedVisibility | null | undefined;
  set occludedVisibility(value: OccludedVisibilityProperties | null | undefined);
  /**
   * Size of the text label in points. This value may be autocast with a string
   * expressing size in points or pixels (e.g. `12px`). When set, this property
   * overrides the [Font.size](https://developers.arcgis.com/javascript/latest/references/core/symbols/Font/#size) property.
   *
   * @default 9
   * @example
   * // size in points
   * symbolLayer.size = 14;
   * @example
   * // size in pixels
   * symbolLayer.size = "20px"; // autocasts as number
   * @example
   * // size in points
   * symbolLayer.size = "14pt"; // autocasts as number
   */
  get size(): number;
  set size(value: number | string);
  /**
   * The text to be displayed. To manually create a new line, use the `\n` escape character.
   *
   * @example symbolLayer.text = "You are here";
   * @example symbolLayer.text = "Wish you were \n here";
   */
  accessor text: string | null | undefined;
  /** The symbol type. */
  get type(): "text";
  /**
   * Adjusts the vertical alignment of the text.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > This property only applies when the symbol layer is not used for labeling purposes. The `verticalAlignment` for labels
   * > is inferred from the [LabelClass.labelPlacement](https://developers.arcgis.com/javascript/latest/references/core/layers/support/LabelClass/#labelPlacement) value.
   *
   * @default "baseline"
   * @since 4.23
   */
  accessor verticalAlignment: TextVerticalAlignment;
  /**
   * 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
   * const symbolLayer = graphic.symbol.symbolLayers.at(0).clone();
   */
  clone(): TextSymbol3DLayer;
}