import type LineOfSightAnalysis from "../analysis/LineOfSightAnalysis.js";
import type LineOfSightAnalysisObserver from "../analysis/LineOfSightAnalysisObserver.js";
import type LineOfSightAnalysisTarget from "../analysis/LineOfSightAnalysisTarget.js";
import type Collection from "../core/Collection.js";
import type Extent from "../geometry/Extent.js";
import type SpatialReference from "../geometry/SpatialReference.js";
import type Layer from "./Layer.js";
import type { MultiOriginJSONSupportMixin } from "../core/MultiOriginJSONSupport.js";
import type { OperationalLayer, OperationalLayerProperties } from "./mixins/OperationalLayer.js";
import type { LineOfSightAnalysisObserverProperties } from "../analysis/LineOfSightAnalysisObserver.js";
import type { LineOfSightAnalysisTargetProperties } from "../analysis/LineOfSightAnalysisTarget.js";
import type { ReadonlyArrayOrCollection } from "../core/Collection.js";
import type { LineOfSightAnalysisProperties } from "../analysis/LineOfSightAnalysis.js";
import type { LayerProperties } from "./Layer.js";

export interface LineOfSightLayerProperties extends LayerProperties, OperationalLayerProperties {
  /**
   * The [LineOfSightAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/LineOfSightAnalysis/) associated with the layer. Assigning a null value
   * will create a new empty analysis.
   */
  analysis?: LineOfSightAnalysisProperties;
  /**
   * The observer defines the point from which the line of sight analysis is performed.
   *
   * The [observer position](https://developers.arcgis.com/javascript/latest/references/core/analysis/LineOfSightAnalysisObserver/#position) must be set
   * before the layer can be saved to a [WebScene](https://developers.arcgis.com/javascript/latest/references/core/WebScene/).
   *
   * This property is an alias to the same property on the [analysis](https://developers.arcgis.com/javascript/latest/references/core/layers/LineOfSightLayer/#analysis)
   * object held by this layer.
   */
  observer?: LineOfSightAnalysisObserverProperties | null;
  /**
   * Target locations. A list of points to look at from the observer.
   *
   * This property is an alias to the same property on the [analysis](https://developers.arcgis.com/javascript/latest/references/core/layers/LineOfSightLayer/#analysis)
   * object held by this layer.
   */
  targets?: ReadonlyArrayOrCollection<LineOfSightAnalysisTargetProperties> | null;
}

/**
 * The line of sight layer enables the creation and display of visibility analysis where a line of sight
 * is computed from a single observer position towards
 * a set of targets. The results are visualized in a 3D [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
 *
 * It can be grouped with other layers, and when a [LayerList](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/) widget
 * or [Layer List](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-layer-list/) component is used,
 * the line of sight layer appears in the list. It can be persisted in a [WebScene](https://developers.arcgis.com/javascript/latest/references/core/WebScene/).
 *
 * The line of sight can be created interactively or added programmatically to a [LineOfSightAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/LineOfSightAnalysis/)
 * object, which is then set as the layer's [analysis](https://developers.arcgis.com/javascript/latest/references/core/layers/LineOfSightLayer/#analysis).
 *
 * ```js
 * // create line of sight analysis
 * const lineOfSightAnalysis = new LineOfSightAnalysis({
 *   observer: new LineOfSightAnalysisObserver({ position: new Point({ }) }),
 *   targets:[
 *     new LineOfSightAnalysisTarget({ position: new Point({ }) })
 *   ]
 * });
 *
 * // Create the layer with the analysis.
 * const lineOfSightLayer = new LineOfSightLayer({
 *   analysis: lineOfSightAnalysis
 * });
 *
 * // add to the map
 * view.map.add(lineOfSightLayer);
 * ```
 *
 * Use the [LineOfSightLayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LineOfSightLayerView/) to access analysis results or to edit existing
 * observer and targets interactively.
 *
 * ```js
 * // wait for the view to not be updating to ensure we get the latest results
 * await reactiveUtils.whenOnce(() => !view.updating);
 *
 * // retrieve the results from the layer view
 * const lineOfSightLayerView = await view.whenLayerView(lineOfSightLayer);
 * const results = lineOfSightLayerView.results;
 *
 * // enable editing existing analysis interactively
 * lineOfSightLayerView.interactive = true;
 * ```
 *
 * To create lines of sight interactively, use the
 * [LineOfSightLayerView.place()](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LineOfSightLayerView/#place) method.
 *
 * ```js
 * const abortController = new AbortController();
 *
 * try {
 *   await lineOfSightLayerView.place({ signal: abortController.signal });
 * } catch (error) {
 *   if (error.name === "AbortError") {
 *     console.log("Placement operation was cancelled.");
 *   }
 * }
 *
 * // cancel the placement operation at some later point
 * abortController.abort();
 * ```
 *
 * If the [observer position](https://developers.arcgis.com/javascript/latest/references/core/analysis/LineOfSightAnalysisObserver/#position) or
 * [target position](https://developers.arcgis.com/javascript/latest/references/core/analysis/LineOfSightAnalysisTarget/#position) have [z-values](https://developers.arcgis.com/javascript/latest/references/core/geometry/Point/#hasZ)
 * then these will be treated as absolute values, otherwise the points will be aligned to the ground.
 *
 * > [!WARNING]
 * >
 * > **Known Limitations**
 * >
 * > This layer is only supported in a 3D [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
 * > The results of the tool vary depending on the zoom level, as changes in zoom level affect the level of detail (LOD) of the scene geometry.
 *
 * @since 4.24
 * @see [LineOfSightLayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LineOfSightLayerView/)
 * @see [LineOfSightAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/LineOfSightAnalysis/)
 * @see [LineOfSightAnalysisTarget](https://developers.arcgis.com/javascript/latest/references/core/analysis/LineOfSightAnalysisTarget/)
 * @see [LineOfSightAnalysisObserver](https://developers.arcgis.com/javascript/latest/references/core/analysis/LineOfSightAnalysisObserver/)
 * @see [LineOfSightAnalysisView3D](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/LineOfSightAnalysisView3D/)
 * @see [Line Of Sight component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-line-of-sight/)
 */
export default class LineOfSightLayer extends LineOfSightLayerSuperclass {
  /** @example const lineOfSightLayer = new LineOfSightLayer(); */
  constructor(properties?: LineOfSightLayerProperties);
  /**
   * The [LineOfSightAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/LineOfSightAnalysis/) associated with the layer. Assigning a null value
   * will create a new empty analysis.
   */
  get analysis(): LineOfSightAnalysis;
  set analysis(value: LineOfSightAnalysisProperties);
  /**
   * The full extent of the layer computed from the observer and targets. The returned extent has
   * Z values only if the observer and all targets have absolute Z values.
   *
   * @example
   * // Once the layer loads, set the view's extent to the layer's full extent
   * layer.when(function(){
   *   view.extent = layer.fullExtent;
   * });
   */
  get fullExtent(): Extent | null | undefined;
  /**
   * The observer defines the point from which the line of sight analysis is performed.
   *
   * The [observer position](https://developers.arcgis.com/javascript/latest/references/core/analysis/LineOfSightAnalysisObserver/#position) must be set
   * before the layer can be saved to a [WebScene](https://developers.arcgis.com/javascript/latest/references/core/WebScene/).
   *
   * This property is an alias to the same property on the [analysis](https://developers.arcgis.com/javascript/latest/references/core/layers/LineOfSightLayer/#analysis)
   * object held by this layer.
   */
  get observer(): LineOfSightAnalysisObserver | null | undefined;
  set observer(value: LineOfSightAnalysisObserverProperties | null | undefined);
  /** The spatial reference of the layer. The spatial reference is derived from the observer. */
  get spatialReference(): SpatialReference;
  /**
   * Target locations. A list of points to look at from the observer.
   *
   * This property is an alias to the same property on the [analysis](https://developers.arcgis.com/javascript/latest/references/core/layers/LineOfSightLayer/#analysis)
   * object held by this layer.
   */
  get targets(): Collection<LineOfSightAnalysisTarget> | null | undefined;
  set targets(value: ReadonlyArrayOrCollection<LineOfSightAnalysisTargetProperties> | null);
  /** The layer type provides a convenient way to check the type of the layer without the need to import specific layer modules. */
  get type(): "line-of-sight";
}
declare const LineOfSightLayerSuperclass: typeof Layer & typeof MultiOriginJSONSupportMixin & typeof OperationalLayer