import type DimensionAnalysis from "../analysis/DimensionAnalysis.js";
import type DimensionSimpleStyle from "../analysis/DimensionSimpleStyle.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 { DimensionSimpleStyleProperties } from "../analysis/DimensionSimpleStyle.js";
import type { LayerProperties } from "./Layer.js";

export interface DimensionLayerProperties extends LayerProperties, OperationalLayerProperties, Partial<Pick<DimensionLayer, "source">> {
  /**
   * The style defines how the dimension objects of this layer are displayed.
   *
   * This is an alias for the [DimensionAnalysis.style](https://developers.arcgis.com/javascript/latest/references/core/analysis/DimensionAnalysis/#style) of the [source](https://developers.arcgis.com/javascript/latest/references/core/layers/DimensionLayer/#source).
   */
  style?: (DimensionSimpleStyleProperties & { type: "simple" });
  /**
   * The title of the layer used to identify it in places such as the [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.
   *
   * If a layer is loaded as part of a webscene, then the title of the layer as stored in the webscene will be used.
   */
  title?: string | null;
}

/**
 * The dimension layer displays measurement annotations of lengths and distances 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 dimension layer appears in the list. It can be persisted in a [WebScene](https://developers.arcgis.com/javascript/latest/references/core/WebScene/).
 *
 * The dimensions can be created interactively or programmatically into a [DimensionAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/DimensionAnalysis/)
 * object, which then is set as the DimensionLayer's [source](https://developers.arcgis.com/javascript/latest/references/core/layers/DimensionLayer/#source).
 *
 * ```js
 * // create analysis with dimensions
 * const dimensionAnalysis = new DimensionAnalysis({
 *    dimensions: [
 *      new LengthDimension({
 *        startPoint: new Point({ }),
 *        endPoint: new Point({ })
 *      })
 *    ]
 * });
 * // add analysis to the layer and style it
 * const dimensionLayer = new DimensionLayer({
 *    source: dimensionAnalysis,
 *    style: new DimensionSimpleStyle({
 *      color: "white"
 *    }),
 * });
 *
 * // add layer to scene view
 * view.map.add(dimensionLayer);
 * ```
 *
 * Use the [DimensionLayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/DimensionLayerView/) to retrieve the dimensioning results.
 *
 * ```js
 * // retrieve measured results from the layer view
 * const dimensionLayerView = await view.whenLayerView(dimensionLayer);
 * const results = dimensionLayerView.results;
 * ```
 *
 * To start creating or editing length dimensions interactively, use the
 * [DimensionLayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/DimensionLayerView/).
 *
 * ```js
 * // retrieve layer view for the layer
 * const dimensionLayerView = await view.whenLayerView(dimensionLayer);
 *
 * // allow existing length dimensions in the layer to be selected and edited
 * // select a dimensions by hovering and clicking on their offset manipulator
 * dimensionLayerView.interactive = true;
 *
 * const abortController = new AbortController();
 *
 * try {
 *   // start placing a new dimension interactively
 *   await dimensionLayerView.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();
 * ```
 *
 * > [!WARNING]
 * >
 * > **Known Limitations**
 * >
 * > This layer is only supported in a 3D [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
 *
 * @since 4.25
 * @see [DimensionLayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/DimensionLayerView/)
 * @see [DimensionAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/DimensionAnalysis/)
 * @see [LengthDimension](https://developers.arcgis.com/javascript/latest/references/core/analysis/LengthDimension/)
 * @see [DimensionSimpleStyle](https://developers.arcgis.com/javascript/latest/references/core/analysis/DimensionSimpleStyle/)
 * @see [DimensionAnalysisView3D](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/DimensionAnalysisView3D/)
 * @see [Sample - Length dimensioning](https://developers.arcgis.com/javascript/latest/sample-code/layers-dimension/)
 */
export default class DimensionLayer extends DimensionLayerSuperclass {
  /** @example const dimensionLayer = new DimensionLayer(); */
  constructor(properties?: DimensionLayerProperties);
  /**
   * The full extent of the layer which contains all dimensions referenced by the layer.
   *
   * @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 [DimensionAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/DimensionAnalysis/) associated with the layer that stores the dimension shapes.
   * Assigning a null value will create a new empty analysis.
   */
  accessor source: DimensionAnalysis;
  /** The spatial reference of the layer. The spatial reference is derived from the [source](https://developers.arcgis.com/javascript/latest/references/core/layers/DimensionLayer/#source). */
  get spatialReference(): SpatialReference;
  /**
   * The style defines how the dimension objects of this layer are displayed.
   *
   * This is an alias for the [DimensionAnalysis.style](https://developers.arcgis.com/javascript/latest/references/core/analysis/DimensionAnalysis/#style) of the [source](https://developers.arcgis.com/javascript/latest/references/core/layers/DimensionLayer/#source).
   */
  get style(): DimensionSimpleStyle;
  set style(value: (DimensionSimpleStyleProperties & { type: "simple" }));
  /**
   * The title of the layer used to identify it in places such as the [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.
   *
   * If a layer is loaded as part of a webscene, then the title of the layer as stored in the webscene will be used.
   */
  accessor title: string | null | undefined;
  /** The layer type provides a convenient way to check the type of the layer without the need to import specific layer modules. */
  get type(): "dimension";
}
declare const DimensionLayerSuperclass: typeof Layer & typeof MultiOriginJSONSupportMixin & typeof OperationalLayer