/// <reference path="../../index.d.ts" />
import type Graphic from "@arcgis/core/Graphic.js";
import type ElevationProfileAnalysis from "@arcgis/core/analysis/ElevationProfileAnalysis.js";
import type MapView from "@arcgis/core/views/MapView.js";
import type SceneView from "@arcgis/core/views/SceneView.js";
import type Polyline from "@arcgis/core/geometry/Polyline.js";
import type ElevationInfo from "@arcgis/core/symbols/support/ElevationInfo.js";
import type Collection from "@arcgis/core/core/Collection.js";
import type ElevationProfileGroup from "@arcgis/core/analysis/ElevationProfile/ElevationProfileGroup.js";
import type { PublicLitElement as LitElement } from "@arcgis/lumina";
import type { ArcgisReferenceElement } from "../types.js";
import type { T9nMeta } from "@arcgis/lumina/controllers";
import type { ElevationProfileEffectiveDisplayUnits } from "@arcgis/core/views/analysis/ElevationProfile/types.js";
import type { Icon as Icon } from "@esri/calcite-components/components/calcite-icon";
import type { ElevationInfoMode } from "@arcgis/core/symbols/support/types.js";
import type { ElevationProfileLineUnion } from "@arcgis/core/analysis/ElevationProfile/types.js";
import type { SystemOrLengthUnit } from "@arcgis/core/core/units.js";

/**
 * The Elevation Profile component manages an [ElevationProfileAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/) and displays its elevation profiles.
 *
 * [![elevation profile poster](https://developers.arcgis.com/javascript/latest/assets/references/components/elevation-profile/elevation_profile_poster.avif)](https://developers.arcgis.com/javascript/latest/sample-code/elevation-profile/)
 *
 * The component can visualize multiple profile lines, depending on whether it is used in an [arcgis-map](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-map/) component or an [arcgis-scene](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-scene/) component and on the available elevation source data:
 *
 * * [**ElevationProfileLineGround**](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineGround/): represents a profile line that uses elevation from [arcgis-map.ground](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-map/#ground) of the connected Map or Scene component. The profile recomputes automatically when ground layers are added, removed, or their visibility changes.
 * * [**ElevationProfileLineInput**](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineInput/): represents a profile line that reads elevation from the analysis geometry itself; typically used for polylines with z values. If the line lacks z values but is displayed with a non-draped elevation mode, a profile is still computed. If `elevationInfo` is set to `on-the-ground`, elevation comes from the Ground (when ground layers are present). An elevation offset can be applied. In a Map this requires client-side graphics that already contain z values.
 * * [**ElevationProfileLineQuery**](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineQuery/): represents a profile line that samples elevation from the elevation source set in the [source](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineQuery/#source) property. The elevation source can be an [ElevationLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ElevationLayer/) or an object with a method called `queryElevation` that has the same signature as [queryElevation()](https://developers.arcgis.com/javascript/latest/references/core/layers/ElevationLayer/#queryElevation).
 * * [**ElevationProfileLineScene**](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineScene/): represents a profile line that derives elevation from the `Scene` and all its volumetric objects (e.g. SceneLayer, IntegratedMeshLayer).
 *
 * You can choose to display one or several profile lines in the chart, by setting them in the [profiles](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-elevation-profile/#profiles) property.
 *
 * Hovering over the chart shows an overlaid tooltip with elevation values of all profiles, and displays colored dot markers at the matching positions.
 *
 * Checkboxes in the legend allow hiding individual profiles. Chart units can be set via the settings menu to metric, imperial or a specific unit.
 *
 * Scrolling the chart zooms in to a specific part of the profile chart. When zoomed in, click the minus button to reset the zoom. On touch devices, pinch to zoom in and out.
 *
 * How distance values are computed depends on the map's spatial reference:
 *
 * * In geographic coordinate systems (GCS) and in Web Mercator, distances are computed geodetically.
 * * In projected coordinate systems (PCS), apart from Web Mercator, distances are computed in a Euclidean manner (in their respective PCS).
 *
 * **Known limitations**
 *
 * - [ElevationProfileLineInput](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineInput/) in 2D is only valid when the analysis [geometry](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/#geometry) has z values, `hasZ===true` and no [elevationInfo](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/#elevationInfo) is set.
 * - [ElevationProfileLineScene](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineScene/) is only supported in a 3D [arcgis-scene](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-scene/) component.
 *
 * **See also**
 *
 * - [ElevationProfileAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/)
 * - [Sample - Elevation Profile component](https://developers.arcgis.com/javascript/latest/sample-code/elevation-profile/)
 * - [Sample - Elevation Profile analysis](https://developers.arcgis.com/javascript/latest/sample-code/analysis-elevation-profile/)
 *
 * @slot [settings-start] - Slot for adding custom UI before the built-in settings controls.
 * @slot [settings-end] - Slot for adding custom UI after the built-in settings controls.
 * @since 4.28
 * @example
 * ```html
 * <arcgis-elevation-profile>
 *   <calcite-label slot="settings-end" layout="inline-space-between">
 *     Show all layers
 *     <calcite-checkbox></calcite-checkbox>
 *   </calcite-label>
 * </arcgis-elevation-profile>
 * ```
 */
export abstract class ArcgisElevationProfile extends LitElement {
  /** @internal */
  protected _messages: Partial<{
      cancelButtonLabel: string;
      chartTooltip: string;
      clearProfile: string;
      componentLabel: string;
      "creatingPrompt-2d": string;
      "creatingPrompt-3d": string;
      doneButtonLabel: string;
      errors: {
          noProfile: string;
          tooComplex: string;
          unknown: string;
      };
      hideDetails: string;
      hideProfile: string;
      hideSettings: string;
      profiles: {
          ground: string;
          input: string;
          query: string;
          scene: string;
      };
      readyPrompt: string;
      readyPromptCreateOnly: string;
      readyPromptSelectOnly: string;
      selectButtonLabel: string;
      "selectingPrompt-2d": string;
      "selectingPrompt-3d": string;
      showDetails: string;
      showProfile: string;
      showSettings: string;
      sketchButtonLabel: string;
      statistics: {
          avgElevation: string;
          avgSlope: string;
          gain: string;
          loss: string;
          maxDistance: string;
          maxElevation: string;
          maxSlope: string;
          minElevation: string;
          notAvailable: string;
      };
      uniformChartScalingDisable: string;
      uniformChartScalingEnable: string;
      uniformChartScalingLabel: string;
      unitDistanceSelectLabel: string;
      unitElevationSelectLabel: string;
      zoomOut: string;
  }> & T9nMeta<{
      cancelButtonLabel: string;
      chartTooltip: string;
      clearProfile: string;
      componentLabel: string;
      "creatingPrompt-2d": string;
      "creatingPrompt-3d": string;
      doneButtonLabel: string;
      errors: {
          noProfile: string;
          tooComplex: string;
          unknown: string;
      };
      hideDetails: string;
      hideProfile: string;
      hideSettings: string;
      profiles: {
          ground: string;
          input: string;
          query: string;
          scene: string;
      };
      readyPrompt: string;
      readyPromptCreateOnly: string;
      readyPromptSelectOnly: string;
      selectButtonLabel: string;
      "selectingPrompt-2d": string;
      "selectingPrompt-3d": string;
      showDetails: string;
      showProfile: string;
      showSettings: string;
      sketchButtonLabel: string;
      statistics: {
          avgElevation: string;
          avgSlope: string;
          gain: string;
          loss: string;
          maxDistance: string;
          maxElevation: string;
          maxSlope: string;
          minElevation: string;
          notAvailable: string;
      };
      uniformChartScalingDisable: string;
      uniformChartScalingEnable: string;
      uniformChartScalingLabel: string;
      unitDistanceSelectLabel: string;
      unitElevationSelectLabel: string;
      zoomOut: string;
  }>;
  /**
   * The [ElevationProfileAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/)
   * created or modified by the component.
   *
   * When connecting the Elevation Profile component to the [arcgis-map](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-map/)
   * or [arcgis-scene](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-scene/)
   * components, it automatically creates an empty analysis and adds it to the Map's
   * [arcgis-map.analyses](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-map/#analyses) collection or the Scene's
   * [arcgis-scene.analyses](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-scene/#analyses) collection.
   * You can then wait for the [ElevationProfileAnalysisView2D](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/)
   * or [ElevationProfileAnalysisView3D](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/ElevationProfileAnalysisView3D/)
   * to be created (depending on whether you are using a Map or Scene component) before accessing the analysis results.
   *
   * ```js
   * // Get the Scene component and the Elevation Profile component, and wait until both are ready.
   * const viewElement = document.querySelector("arcgis-scene");
   * await viewElement.viewOnReady();
   * const elevationProfileElement = document.querySelector("arcgis-elevation-profile");
   * await elevationProfileElement.componentOnReady();
   *
   * // Get the ElevationProfileAnalysis created by the Elevation Profile component.
   * const analysis = elevationProfileElement.analysis;
   *
   * // Get the ElevationProfileAnalysisView3D and watch for results.
   * const analysisView = await viewElement.whenAnalysisView(analysis);
   * const handle = reactiveUtils.watch(
   *   () => analysisView?.results,
   *   () => {
   *     console.log("Analysis results:", analysisView.results);
   *   },
   * );
   * ```
   * Whenever the component is destroyed, the analysis is automatically removed from the collection.
   *
   * Alternatively, a programmatically created [ElevationProfileAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/)
   * can be provided to the component.
   * Then, the application itself needs to add it to and later remove it from the analyses collection of the Map or Scene component.
   *
   * ```js
   * // Create the ElevationProfileAnalysis.
   * const analysis = new ElevationProfileAnalysis({
   *   profiles: [{ type: "ground" }, { type: "scene" }]
   * });
   *
   * // Get the Scene component and the Elevation Profile component, and wait until both are ready.
   * const viewElement = document.querySelector("arcgis-scene");
   * await viewElement.viewOnReady();
   * const elevationProfileElement = document.querySelector("arcgis-elevation-profile");
   * await elevationProfileElement.componentOnReady();
   *
   * // Add the analysis to the analyses collection of the Scene component.
   * viewElement.analyses.add(analysis);
   *
   * // Connect the analysis to the elevation profile component.
   * elevationProfileElement.analysis = analysis;
   * ```
   *
   * @since 5.0
   */
  accessor analysis: ElevationProfileAnalysis;
  /**
   * If true, the component will not be destroyed automatically when it is
   * disconnected from the document. This is useful when you want to move the
   * component to a different place on the page, or temporarily hide it. If this
   * is set, make sure to call the [destroy()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-elevation-profile/#destroy) method when you are done to
   * prevent memory leaks.
   *
   * @default false
   */
  accessor autoDestroyDisabled: boolean;
  /**
   * The measurement system (imperial, metric) or specific unit (e.g. feet, kilometers) used to display distance values
   * in the chart, results and legend.
   *
   * @since 5.0
   */
  accessor distanceUnit: SystemOrLengthUnit | undefined;
  /**
   * List of available units unit systems (imperial, metric) and specific units (e.g. feet, kilometers) for displaying
   * the distance values. These are the options displayed in the distance unit dropdown in the settings popover.
   *
   * @since 5.0
   */
  accessor distanceUnitOptions: Array<SystemOrLengthUnit>;
  /**
   * Units which have been selected according to the magnitude of the elevations and distances that are to be displayed
   * in the component, according to the selected elevation and distance units or unit systems.
   *
   * @since 5.0
   */
  get effectiveDisplayUnits(): ElevationProfileEffectiveDisplayUnits | undefined;
  /**
   * Specifies how the geometry Z values are interpreted, for example to compute elevations for an
   * [input](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineInput/)
   * profile line. This property can only be used in a
   * [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
   *
   * [Read more](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/#elevationInfo)
   *
   * @since 5.0
   */
  accessor elevationInfo: ElevationInfo<ElevationInfoMode> | null | undefined;
  /**
   * The measurement system (imperial, metric) or specific unit (e.g. feet, kilometers) used to display elevation values
   * in the chart, results and legend.
   *
   * @since 5.0
   */
  accessor elevationUnit: SystemOrLengthUnit | undefined;
  /**
   * List of available units unit systems (imperial, metric) and specific units (e.g. feet, kilometers) for displaying
   * the elevation values. These are the options displayed in the elevation unit dropdown in the settings popover.
   *
   * @since 5.0
   */
  accessor elevationUnitOptions: Array<SystemOrLengthUnit>;
  /**
   * The feature which is currently selected for display in the elevation profile. The feature is highlighted in the
   * view and its geometry is used as the profile line. When the user starts drawing a new profile line, this feature
   * is cleared.
   *
   * @since 5.0
   */
  accessor feature: Graphic | undefined;
  /**
   * Path along which elevation will be queried in order to generate an elevation profile. It should be a
   * Polyline geometry.
   * [Read more](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/#geometry)
   *
   * @since 5.0
   */
  accessor geometry: Polyline | null | undefined;
  /**
   * If true, the elevation profile chart will be hidden.
   *
   * @default false
   */
  accessor hideChart: boolean;
  /**
   * If true, the clear button will be hidden.
   *
   * @default false
   */
  accessor hideClearButton: boolean;
  /**
   * If true, the distance display unit dropdown will be hidden in the settings popover.
   *
   * @default false
   * @since 5.0
   */
  accessor hideDistanceDisplayUnitSelect: boolean;
  /**
   * If true, the elevation display unit dropdown will be hidden in the settings popover.
   *
   * @default false
   * @since 5.0
   */
  accessor hideElevationDisplayUnitSelect: boolean;
  /**
   * If true, the legend will be hidden.
   *
   * @default false
   */
  accessor hideLegend: boolean;
  /**
   * If true, the button to select features in the view will be hidden.
   *
   * @default false
   */
  accessor hideSelectButton: boolean;
  /**
   * If true, the button which opens the settings popover will be hidden.
   *
   * @default false
   */
  accessor hideSettingsButton: boolean;
  /**
   * If true, the button to start sketching a new profile line will be hidden.
   *
   * @default false
   * @since 5.0
   */
  accessor hideStartButton: boolean;
  /**
   * If true, the uniform chart scaling toggle will be hidden in the settings popover.
   *
   * @default false
   */
  accessor hideUniformChartScalingToggle: boolean;
  /**
   * Indicates whether the component's visualization is hidden in the view.
   *
   * @default false
   * @since 5.0
   */
  accessor hideVisualization: boolean;
  /**
   * If true, the component will not highlight features selected in the view.
   *
   * @default false
   * @since 5.0
   */
  accessor highlightDisabled: boolean;
  /**
   * Icon which represents the component.
   * Typically used when the component is controlled by another component (e.g. by the Expand component).
   *
   * @default "altitude"
   * @see [Calcite Icons](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  accessor icon: Icon["icon"] | undefined;
  /**
   * Relative position along the current elevation profile line, in the range [0, 1].
   * The component updates this value as the user hovers the chart.
   *
   * [Read more](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/ElevationProfileAnalysisView3D/#indicatorRelativePosition)
   *
   * @since 5.0
   */
  get indicatorRelativePosition(): number | undefined;
  /** The component's default label. */
  accessor label: string | undefined;
  /**
   * Replace localized message strings with your own strings.
   *
   * _**Note**: Individual message keys may change between releases._
   *
   * @since 5.0
   */
  accessor messageOverrides: {
      cancelButtonLabel?: string | undefined;
      chartTooltip?: string | undefined;
      clearProfile?: string | undefined;
      componentLabel?: string | undefined;
      "creatingPrompt-2d"?: string | undefined;
      "creatingPrompt-3d"?: string | undefined;
      doneButtonLabel?: string | undefined;
      errors?: {
          noProfile?: string | undefined;
          tooComplex?: string | undefined;
          unknown?: string | undefined;
      } | undefined;
      hideDetails?: string | undefined;
      hideProfile?: string | undefined;
      hideSettings?: string | undefined;
      profiles?: {
          ground?: string | undefined;
          input?: string | undefined;
          query?: string | undefined;
          scene?: string | undefined;
      } | undefined;
      readyPrompt?: string | undefined;
      readyPromptCreateOnly?: string | undefined;
      readyPromptSelectOnly?: string | undefined;
      selectButtonLabel?: string | undefined;
      "selectingPrompt-2d"?: string | undefined;
      "selectingPrompt-3d"?: string | undefined;
      showDetails?: string | undefined;
      showProfile?: string | undefined;
      showSettings?: string | undefined;
      sketchButtonLabel?: string | undefined;
      statistics?: {
          avgElevation?: string | undefined;
          avgSlope?: string | undefined;
          gain?: string | undefined;
          loss?: string | undefined;
          maxDistance?: string | undefined;
          maxElevation?: string | undefined;
          maxSlope?: string | undefined;
          minElevation?: string | undefined;
          notAvailable?: string | undefined;
      } | undefined;
      uniformChartScalingDisable?: string | undefined;
      uniformChartScalingEnable?: string | undefined;
      uniformChartScalingLabel?: string | undefined;
      unitDistanceSelectLabel?: string | undefined;
      unitElevationSelectLabel?: string | undefined;
      zoomOut?: string | undefined;
  };
  /**
   * The collection of profiles to compute and display. Top-level entries can be either individual profile lines or
   * groups that organize multiple lines under a shared title in the legend.
   *
   * [Read more](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/#profiles)
   */
  accessor profiles: Collection<ElevationProfileLineUnion | ElevationProfileGroup>;
  /**
   * The progress, between 0 and 1 of generating all the configured elevation profiles.
   *
   * [Read more](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/ElevationProfileAnalysisView3D/#progress)
   */
  get progress(): number;
  /**
   * By assigning the `id` attribute of the Map or Scene component to this property, you can position a child component anywhere in the DOM while still maintaining a connection to the Map or Scene.
   *
   * @see [Associate components with a Map or Scene component](https://developers.arcgis.com/javascript/latest/programming-patterns/#associate-components-with-a-map-or-scene-component)
   */
  accessor referenceElement: ArcgisReferenceElement | string | undefined;
  /**
   * The component's state. The values mean the following:
   *
   * * `disabled` -  component is being created
   * * `ready` - component is ready; no path configured and no interactive operation ongoing
   * * `creating` - user is creating a new input path
   * * `created` - input path is configured but no interactive operation is ongoing
   * * `selecting` - user is selecting an existing input path
   * * `selected` - user selected an existing input path
   */
  get state(): "disabled" | "ready" | "selected" | "created" | "creating" | "selecting";
  /**
   * Whether the chart should use a uniform scale for the X and Y axes.
   *
   * @default false
   */
  accessor uniformChartScaling: boolean;
  /**
   * The view associated with the component. 
   *   > **Note:** The recommended approach is to fully migrate applications to use map and scene components and avoid using MapView and SceneView directly. However, if you are migrating a large application from widgets to components, you might prefer a more gradual transition. To support this use case, the SDK includes this `view` property which connects a component to a MapView or SceneView. Ultimately, once migration is complete, the arcgis-elevation-profile component will be associated with a map or scene component rather than using the `view` property.
   */
  accessor view: MapView | SceneView | undefined;
  /**
   * Clear the current elevation profile. If an interactive operation is in progress, it will also be stopped.
   *
   * @since 5.0
   */
  clear(): Promise<void>;
  /** Permanently destroy the component. */
  destroy(): Promise<void>;
  /**
   * Start an interactive operation to pick an existing polyline feature in the view to use as the input for the
   * elevation profile. The operation ends when the user presses the <kbd>Escape</kbd> key.
   * To programmatically cancel the operation, call the [stop()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-elevation-profile/#stop) method.
   *
   * @since 5.0
   */
  select(): Promise<void>;
  /**
   * Start an interactive operation that lets the user sketch a new path in the view along which the elevation profile
   * will be generated. The operation completes when the user double-clicks, presses the <kbd>Escape</kbd> key or clicks
   * the Done button in the UI.
   * To programmatically cancel the operation, call the [stop()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-elevation-profile/#stop) method.
   */
  start(): Promise<void>;
  /**
   * Stop any ongoing interactive operation (for example, selecting or sketching a profile line). This can be used to
   * programmatically cancel operations started by [start()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-elevation-profile/#start) or
   * [select()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-elevation-profile/#select).
   */
  stop(): Promise<void>;
  /** Emitted when the value of a property is changed. Use this to listen to changes to properties. */
  readonly arcgisPropertyChange: import("@arcgis/lumina").TargetedEvent<this, { name: "analysis" | "effectiveDisplayUnits" | "elevationInfo" | "feature" | "geometry" | "indicatorRelativePosition" | "progress" | "state"; }>;
  /** Emitted when the component associated with a map or scene view is ready to be interacted with. */
  readonly arcgisReady: import("@arcgis/lumina").TargetedEvent<this, void>;
  readonly "@eventTypes": {
    arcgisPropertyChange: ArcgisElevationProfile["arcgisPropertyChange"]["detail"];
    arcgisReady: ArcgisElevationProfile["arcgisReady"]["detail"];
  };
}