import type ElevationProfileAnalysis from "../../../analysis/ElevationProfileAnalysis.js";
import type Point from "../../../geometry/Point.js";
import type AnalysisView2D from "./AnalysisView2D.js";
import type ElevationProfileError from "../../analysis/ElevationProfile/ElevationProfileError.js";
import type ElevationProfileResult from "../../analysis/ElevationProfile/ElevationProfileResult.js";
import type { AbortOptions } from "../../../core/promiseUtils.js";
import type { ElevationProfileStatistics, ElevationProfileEffectiveDisplayUnits, ElevationProfilePickResult, ElevationProfilePlacementResult } from "../../analysis/ElevationProfile/types.js";

/**
 * Represents the analysis view of an [ElevationProfileAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/)
 * after it has been added to [MapView.analyses](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#analyses).
 *
 * The ElevationProfileAnalysisView2D is responsible for rendering an
 * [ElevationProfileAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/) using custom visualizations.
 * The [results](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/#results) property contains the computed elevation profile results.
 *
 * The view for an analysis can be retrieved using [MapView.whenAnalysisView()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#whenAnalysisView)
 * similar to how layer views are retrieved for layers using [MapView.whenLayerView()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#whenLayerView).
 *
 * ```js
 * // Retrieve analysis view for analysis
 * const analysis = new ElevationProfileAnalysis();
 * view.analyses.add(analysis); // Add to the view
 * const analysisView = await view.whenAnalysisView(analysis);
 * ```
 *
 * @since 4.34
 * @see [ElevationProfileAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/)
 * @see [ElevationProfileLineGround](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineGround/)
 * @see [ElevationProfileLineInput](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineInput/)
 * @see [ElevationProfileLineQuery](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLineQuery/)
 * @see [ElevationProfileError](https://developers.arcgis.com/javascript/latest/references/core/views/analysis/ElevationProfile/ElevationProfileError/)
 * @see [ElevationProfileResult](https://developers.arcgis.com/javascript/latest/references/core/views/analysis/ElevationProfile/ElevationProfileResult/)
 * @see [Sample - Elevation Profile analysis](https://developers.arcgis.com/javascript/latest/sample-code/analysis-elevation-profile/)
 * @see [Async cancellation with AbortController](https://developers.arcgis.com/javascript/latest/async-cancellation-with-abortcontroller/)
 */
export default abstract class ElevationProfileAnalysisView2D extends AnalysisView2D {
  /** The elevation profile analysis associated with the analysis view. */
  get analysis(): ElevationProfileAnalysis;
  /**
   * Units used for all the [results](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/#results) and [statistics](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/#statistics) of the elevation profile analysis.
   *
   * If not specified by user with [ElevationProfileAnalysis.displayUnits](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/#displayUnits),
   * the units are chosen automatically based on the magnitude of the results.
   */
  get effectiveDisplayUnits(): ElevationProfileEffectiveDisplayUnits;
  /**
   * Error encountered while calculating the analysis result. The error has well defined names that can be used
   * to provide specific error feedback to the user. See [ElevationProfileError](https://developers.arcgis.com/javascript/latest/references/core/views/analysis/ElevationProfile/ElevationProfileError/)
   * for the list of possible error names.
   */
  get error(): ElevationProfileError | null | undefined;
  /**
   * Points in the view that are computed from the [indicatorRelativePosition](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/#indicatorRelativePosition)
   * property (in the view's spatial reference).
   * There is one point for each [profile line](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/#profiles).
   * When a [result](https://developers.arcgis.com/javascript/latest/references/core/views/analysis/ElevationProfile/ElevationProfileResult/) of a profile line is not available or
   * no [sample](https://developers.arcgis.com/javascript/latest/references/core/views/analysis/ElevationProfile/ElevationProfileResult/#samples) exists for the specified indicator
   * position, the point is `undefined`.
   *
   * Whenever the [indicatorRelativePosition](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/#indicatorRelativePosition) property has a
   * value, the points are calculated and, by default, rendered in the view. The points in the view can be hidden using
   * the [viewOptions.indicatorPointVisible](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLine/#viewOptions) setting on
   * any of the [profile lines](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/#profiles).
   */
  get indicatorPoints(): Array<Point | null | undefined>;
  /**
   * Relative position along a [result](https://developers.arcgis.com/javascript/latest/references/core/views/analysis/ElevationProfile/ElevationProfileResult/)'s profile line, in
   * [0, 1]. Set this (e.g., when hovering a chart) to compute locations along each configured profile line and expose
   * them via [indicatorPoints](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/#indicatorPoints). The view shows points at these
   * locations unless a line's [viewOptions.indicatorPointVisible](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfile/ElevationProfileLine/#viewOptions)
   * disables them.
   */
  accessor indicatorRelativePosition: number | null | undefined;
  /**
   * Enables interactivity for the [analysis](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/#analysis). When set to `true` the input geometry can be edited
   * interactively.
   *
   * @default false
   */
  accessor interactive: boolean;
  /**
   * Combined progress (0 to 1) of generating all configured profiles.
   *
   * @example
   * reactiveUtils.watch(
   *   () => analysisView.progress,
   *   (progress) => {
   *     // Watch the progress and update the chart or UI when needed
   *   });
   */
  get progress(): number;
  /**
   * Results of the elevation profile analysis. Result objects are created immediately but they are gradually updated as
   * the analysis is computed.
   *
   * Watch [progress](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/#progress) to see the state of the calculation.
   */
  get results(): ElevationProfileResult[];
  /** Combined statistics of all the computed profile lines. */
  get statistics(): ElevationProfileStatistics | null | undefined;
  /** The analysis view type. */
  get type(): "elevation-profile-view-2d";
  /** Whether the analysis is currently being updated. */
  get updating(): boolean;
  /** When `true`, the [analysis](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/#analysis) is visualized in the view. */
  accessor visible: boolean;
  /**
   * Starts an interactive operation to pick a line feature in the view to use as the input for the elevation profile analysis.
   *
   * The operation will finish when the user presses the escape key.
   * To stop the operation programmatically, pass an abort signal as an argument when calling the method.
   *
   * @param options - An object specifying additional options.
   * @returns A promise which resolves when the operation is completed successfully or rejected if it is canceled.
   * @since 4.34
   * @example
   * // Use AbortController to cancel the picking operation at some later point by calling abortController.abort()
   * const abortController = new AbortController();
   *
   * try {
   *   await analysisView.pickFeature({ signal: abortController.signal });
   * } catch (error) {
   *   if (error.name === "AbortError") {
   *     console.log("Picking operation was cancelled.");
   *   }
   * }
   */
  pickFeature(options?: AbortOptions | null | undefined): Promise<ElevationProfilePickResult>;
  /**
   * Starts the interactive placement of a new input line for the elevation profile analysis.
   *
   * If the analysis does not have a [ElevationProfileAnalysis.geometry](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/#geometry) yet, the
   * method allows drawing it interactively in the view. Otherwise, clicking in the view will remove the previous input line
   * and start a new placement operation.
   *
   * The placement operation will finish when the user presses the escape key.
   * To stop the placing programmatically, pass an abort signal as an argument when calling the method.
   *
   * Calling this method sets [interactive](https://developers.arcgis.com/javascript/latest/references/core/views/2d/analysis/ElevationProfileAnalysisView2D/#interactive) to `true`.
   *
   * @param options - An object specifying additional options.
   * @returns A promise which resolves when the operation is completed successfully or rejected if it is canceled.
   * @since 4.34
   * @example
   * // Use AbortController to cancel the placement operation at some later point by calling abortController.abort()
   * const abortController = new AbortController();
   *
   * try {
   *   await analysisView.place({ signal: abortController.signal });
   * } catch (error) {
   *   if (error.name === "AbortError") {
   *     console.log("Placement operation was cancelled.");
   *   }
   * }
   */
  place(options?: AbortOptions | null | undefined): Promise<ElevationProfilePlacementResult>;
}