import type FeatureExpressionInfo from "./FeatureExpressionInfo.js";
import type { ClonableMixin, ClonableMixinProperties } from "../../core/Clonable.js";
import type { JSONSupport, JSONSupportMixinProperties } from "../../core/JSONSupport.js";
import type { ElevationUnit } from "../../core/units.js";
import type { ElevationInfoMode } from "./types.js";
import type { FeatureExpressionInfoProperties } from "./FeatureExpressionInfo.js";

export interface ElevationInfoProperties<Modes extends ElevationInfoMode = ElevationInfoMode> extends JSONSupportMixinProperties, ClonableMixinProperties, Partial<Pick<ElevationInfo<Modes>, "offset" | "unit">> {
  /** Defines how to override an element's Z-value based on its attributes. */
  featureExpressionInfo?: FeatureExpressionInfoProperties | null;
  /**
   * Defines how the element is placed with respect to the terrain surface or 3D objects in the scene.
   * If the geometry consists of multiple points (e.g. lines or polygons), the elevation is evaluated
   * separately for each point. See the table below for a list of possible values.
   *
   * ![elevation-info](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/elevation-info.png)
   *
   * Mode | Description
   * ------|------------
   * on-the-ground | Elements are aligned to the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html). If the scene contains an [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html) or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html), then elements are aligned to the [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html) or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html). If elements have z-values, then the z-values are ignored in this mode. Elements with 2D symbols are draped on the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html) or [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html) or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html). This is the default mode for layers without z-values containing [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html), [Polygon](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polygon.html) or [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) rendered with [ObjectSymbol3DLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-ObjectSymbol3DLayer.html).
   * absolute-height | Elements are placed at an absolute elevation (z-value) above sea level. This z-value is determined by the geometry's z-value (if present). If `featureExpressionInfo` is defined, the result of the expression is used instead of the geometry's z-value. This mode doesn't take the elevation of the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html) or any other layers into account. This is the default value of elements with any geometry type where `hasZ = true`.
   * relative-to-ground | Elements are placed at an elevation relative to the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html) or [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html) or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html). The element's elevation is determined by summing up the elevation of the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html) or [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html) or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html) and the geometry's z-value (if present). If `featureExpressionInfo` is defined, the result of the expression is used instead of the geometry's z-value. If the geometries don't have z-values, `relative-to-ground` is the default value for [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) geometries rendered with [IconSymbol3DLayers](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-IconSymbol3DLayer.html).
   * relative-to-scene | Elements are aligned to [extruded polygons](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-ExtrudeSymbol3DLayer.html), [meshes](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-MeshSymbol3D.html), 3D Object [SceneLayers](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-SceneLayer.html) or [BuildingSceneLayers](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-BuildingSceneLayer.html), depending on which one has higher elevation. If the element is not directly above a building or any other element, it is aligned to the elevation of the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html) or the [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html)  or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html). If present, the geometry's z-value is added to the elevation. If `featureExpressionInfo` is defined, the result of the expression is used instead of the geometry's z-value.
   */
  mode?: ElevationInfoMode;
}

/**
 * Specifies how elements like features, observers, targets or flow are placed on the vertical axis (z). This property may only be used
 * in a [SceneView](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-SceneView.html). See the [ElevationInfo sample](https://developers.arcgis.com/javascript/latest/sample-code/scene-elevationinfo/)
 * for an example of how this property may be used.
 *
 * > [!WARNING]
 * >
 * > If the elevation info is not specified, the effective elevation depends on the context and could vary per graphic.
 *
 * @since 4.34
 */
export default class ElevationInfo<Modes extends ElevationInfoMode = ElevationInfoMode> extends ElevationInfoSuperclass {
  constructor(properties?: ElevationInfoProperties);
  /** Defines how to override an element's Z-value based on its attributes. */
  get featureExpressionInfo(): FeatureExpressionInfo | null | undefined;
  set featureExpressionInfo(value: FeatureExpressionInfoProperties | null | undefined);
  /**
   * Defines how the element is placed with respect to the terrain surface or 3D objects in the scene.
   * If the geometry consists of multiple points (e.g. lines or polygons), the elevation is evaluated
   * separately for each point. See the table below for a list of possible values.
   *
   * ![elevation-info](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/elevation-info.png)
   *
   * Mode | Description
   * ------|------------
   * on-the-ground | Elements are aligned to the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html). If the scene contains an [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html) or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html), then elements are aligned to the [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html) or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html). If elements have z-values, then the z-values are ignored in this mode. Elements with 2D symbols are draped on the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html) or [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html) or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html). This is the default mode for layers without z-values containing [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html), [Polygon](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polygon.html) or [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) rendered with [ObjectSymbol3DLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-ObjectSymbol3DLayer.html).
   * absolute-height | Elements are placed at an absolute elevation (z-value) above sea level. This z-value is determined by the geometry's z-value (if present). If `featureExpressionInfo` is defined, the result of the expression is used instead of the geometry's z-value. This mode doesn't take the elevation of the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html) or any other layers into account. This is the default value of elements with any geometry type where `hasZ = true`.
   * relative-to-ground | Elements are placed at an elevation relative to the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html) or [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html) or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html). The element's elevation is determined by summing up the elevation of the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html) or [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html) or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html) and the geometry's z-value (if present). If `featureExpressionInfo` is defined, the result of the expression is used instead of the geometry's z-value. If the geometries don't have z-values, `relative-to-ground` is the default value for [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) geometries rendered with [IconSymbol3DLayers](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-IconSymbol3DLayer.html).
   * relative-to-scene | Elements are aligned to [extruded polygons](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-ExtrudeSymbol3DLayer.html), [meshes](https://developers.arcgis.com/javascript/latest/api-reference/esri-symbols-MeshSymbol3D.html), 3D Object [SceneLayers](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-SceneLayer.html) or [BuildingSceneLayers](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-BuildingSceneLayer.html), depending on which one has higher elevation. If the element is not directly above a building or any other element, it is aligned to the elevation of the [Ground](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html) or the [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMeshLayer.html)  or [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-IntegratedMesh3DTilesLayer.html). If present, the geometry's z-value is added to the elevation. If `featureExpressionInfo` is defined, the result of the expression is used instead of the geometry's z-value.
   */
  get mode(): Modes;
  set mode(value: ElevationInfoMode);
  /**
   * An elevation offset, which is added to the vertical position of the element. If `unit` is not defined, the offset
   * is in `meters`.
   * When `mode = "on-the-ground"`, this property has no effect.
   */
  accessor offset: number | null | undefined;
  /** The unit for `featureExpressionInfo` and `offset` values. */
  accessor unit: ElevationUnit | null | undefined;
}
declare const ElevationInfoSuperclass: typeof JSONSupport & typeof ClonableMixin