import type Accessor from "../../core/Accessor.js";
import type Extent from "../../geometry/Extent.js";
import type Polygon from "../../geometry/Polygon.js";
import type LOD from "../../layers/support/LOD.js";
import type { PolygonProperties } from "../../geometry/Polygon.js";
import type { ExtentProperties } from "../../geometry/Extent.js";
import type { LODProperties } from "../../layers/support/LOD.js";

export interface MapViewConstraintsProperties extends Partial<Pick<MapViewConstraints, "maxScale" | "maxZoom" | "minScale" | "minZoom" | "rotationEnabled" | "snapToZoom">> {
  /**
   * The area in which the user is allowed to navigate laterally. Only [Extent](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Extent.html) and [Polygon](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polygon.html) geometry types are supported. Z-values are ignored. This property is honored by interactive [MapView navigation](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-2d-MapViewConstraints.html#mapview-navigation) and [MapView#goTo()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#goTo). This property may be [autocast](https://developers.arcgis.com/javascript/latest/autocasting/).
   *
   * @since 4.17
   */
  geometry?: (ExtentProperties & { type: "extent" }) | (PolygonProperties & { type: "polygon" }) | null;
  /**
   * An array of [LODs](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-LOD.html). If not specified, this value is read from the [Map](https://developers.arcgis.com/javascript/latest/api-reference/esri-Map.html). It is possible to generate additional LODs via the
   * [TileInfo#create()](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-TileInfo.html#create) method. This is useful in cases where the default amount of LODs provided are not sufficient. One example of when
   * this is needed is when setting the view scale 1:1. Additionally, this property may be [autocast](https://developers.arcgis.com/javascript/latest/autocasting/).
   */
  lods?: LODProperties[] | null;
}

export default abstract class MapViewConstraints extends Accessor {
  /** A read-only property that specifies the levels of  detail (LODs) read from the [Map](https://developers.arcgis.com/javascript/latest/api-reference/esri-Map.html). */
  get effectiveLODs(): LOD[] | null;
  /** A read-only property that specifies the maximum [scale](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View2D.html#scale) the user is allowed to zoom to within the view. */
  get effectiveMaxScale(): number;
  /** A read-only property that specifies the maximum [zoom](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View2D.html#zoom) level the user is allowed to zoom to within the view. */
  get effectiveMaxZoom(): number;
  /** A read-only property that specifies the minimum [scale](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View2D.html#scale) the user is allowed to zoom to within the view. */
  get effectiveMinScale(): number;
  /** A read-only property that specifies the minimum [zoom](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View2D.html#zoom) level the user is allowed to zoom to within the view. */
  get effectiveMinZoom(): number;
  /**
   * The area in which the user is allowed to navigate laterally. Only [Extent](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Extent.html) and [Polygon](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polygon.html) geometry types are supported. Z-values are ignored. This property is honored by interactive [MapView navigation](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-2d-MapViewConstraints.html#mapview-navigation) and [MapView#goTo()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#goTo). This property may be [autocast](https://developers.arcgis.com/javascript/latest/autocasting/).
   *
   * @since 4.17
   */
  get geometry(): Extent | Polygon | null;
  set geometry(value: (ExtentProperties & { type: "extent" }) | (PolygonProperties & { type: "polygon" }) | null);
  /**
   * An array of [LODs](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-LOD.html). If not specified, this value is read from the [Map](https://developers.arcgis.com/javascript/latest/api-reference/esri-Map.html). It is possible to generate additional LODs via the
   * [TileInfo#create()](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-TileInfo.html#create) method. This is useful in cases where the default amount of LODs provided are not sufficient. One example of when
   * this is needed is when setting the view scale 1:1. Additionally, this property may be [autocast](https://developers.arcgis.com/javascript/latest/autocasting/).
   */
  get lods(): LOD[] | null;
  set lods(value: LODProperties[] | null);
  /**
   * The maximum [scale](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View2D.html#scale) the user is allowed to zoom to within the view. Setting this value to `0` allows the user to overzoom layer tiles.
   *
   * @default 0
   */
  accessor maxScale: number;
  /**
   * The maximum [zoom](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View2D.html#zoom) level the user is allowed to zoom to within the view. Setting this value to `0` allows the user to over-zoom layer tiles.
   *
   * @default -1
   */
  accessor maxZoom: number;
  /**
   * The minimum [scale](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View2D.html#scale) the user is allowed to zoom to within the view.
   *
   * @default 0
   */
  accessor minScale: number;
  /**
   * The minimum [zoom](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View2D.html#zoom) level the user is allowed to zoom to within the view.
   *
   * @default -1
   */
  accessor minZoom: number;
  /**
   * Indicates whether the user can rotate the map.
   *
   * @default true
   */
  accessor rotationEnabled: boolean;
  /**
   * When `true`, the view snaps to the next LOD when zooming in or out. When `false`, the zoom is continuous. This does not apply when zooming in/out using two finger pinch in/out.
   *
   * @default true
   */
  accessor snapToZoom: boolean;
}