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";

/** @since 5.0 */
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/references/core/geometry/Extent/) and [Polygon](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polygon/) geometry types are supported. Z-values are ignored. This property is honored by interactive [MapView navigation](https://developers.arcgis.com/javascript/latest/references/core/views/2d/MapViewConstraints/#mapview-navigation) and [MapView.goTo()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#goTo). This property may be [autocast](https://developers.arcgis.com/javascript/latest/autocasting/). */
  geometry?: (ExtentProperties & { type: "extent" }) | (PolygonProperties & { type: "polygon" }) | null;
  /**
   * An array of [LODs](https://developers.arcgis.com/javascript/latest/references/core/layers/support/LOD/). If not specified, this value is read from the [Map](https://developers.arcgis.com/javascript/latest/references/core/Map/). It is possible to generate additional LODs via the
   * [TileInfo.create()](https://developers.arcgis.com/javascript/latest/references/core/layers/support/TileInfo/#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/).
   *
   * @since 5.0
   */
  lods?: LODProperties[] | null;
}

/**
 * Specifies constraints to [scale](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#scale), [zoom](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#zoom), and [rotation](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#rotation) that may be applied to the MapView.
 *  The `constraints.lods` should be set in the MapView constructor, if the map does not have a [basemap](https://developers.arcgis.com/javascript/latest/references/core/Map/#basemap) or when the basemap does not have [TileInfo](https://developers.arcgis.com/javascript/latest/references/core/layers/support/TileInfo/).
 * 
 *
 * @see [View2D.constraints](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#constraints)
 * @since 5.0
 * @example
 * view.constraints = {
 *  geometry: { // Constrain lateral movement to Lower Manhattan
 *    type: "extent",
 *    xmin: -74.020,
 *    ymin:  40.700,
 *    xmax: -73.971,
 *    ymax:  40.73
 *  },
 *  minScale: 500000, // User cannot zoom out beyond a scale of 1:500,000
 *  maxScale: 0, // User can overzoom tiles
 *  rotationEnabled: false // Disables map rotation
 * @example
 * // This snippet shows how to set the MapView scale 1:1 while generating additional LODs for the MapView.constraints.
 *  const spatialReference = new SpatialReference({
 *    wkid: 2154
 *  });
 *  const center = new Point({
 *    x: 0,
 *    y: 0,
 *    spatialReference
 *  });
 *
 *  // Create LODs from level 0 to 31
 *  const tileInfo = TileInfo.create({
 *    spatialReference,
 *    numLODs: 32
 *  });
 *  const lods = tileInfo.lods;
 *
 *  let view = new MapView({
 *    container: "viewDiv",
 *    map,
 *    scale: 1,
 *    center,
 *    spatialReference,
 *    constraints: {
 *      lods: lods,
 *      snapToZoom: false
 *    }
 *  });
 * @see [Zoom and LODs](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#mapview-lods)
 * @see [TileInfo.create()](https://developers.arcgis.com/javascript/latest/references/core/layers/support/TileInfo/#create)
 */
export default class MapViewConstraints extends Accessor {
  constructor(properties?: MapViewConstraintsProperties);
  /**
   * A read-only property that specifies the levels of  detail (LODs) read from the [Map](https://developers.arcgis.com/javascript/latest/references/core/Map/).
   *
   * @since 5.0
   */
  get effectiveLODs(): LOD[] | null;
  /**
   * A read-only property that specifies the maximum [scale](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#scale) the user is allowed to zoom to within the view.
   *
   * @since 5.0
   */
  get effectiveMaxScale(): number;
  /**
   * A read-only property that specifies the maximum [zoom](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#zoom) level the user is allowed to zoom to within the view.
   *
   * @since 5.0
   */
  get effectiveMaxZoom(): number;
  /**
   * A read-only property that specifies the minimum [scale](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#scale) the user is allowed to zoom to within the view.
   *
   * @since 5.0
   */
  get effectiveMinScale(): number;
  /**
   * A read-only property that specifies the minimum [zoom](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#zoom) level the user is allowed to zoom to within the view.
   *
   * @since 5.0
   */
  get effectiveMinZoom(): number;
  /** The area in which the user is allowed to navigate laterally. Only [Extent](https://developers.arcgis.com/javascript/latest/references/core/geometry/Extent/) and [Polygon](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polygon/) geometry types are supported. Z-values are ignored. This property is honored by interactive [MapView navigation](https://developers.arcgis.com/javascript/latest/references/core/views/2d/MapViewConstraints/#mapview-navigation) and [MapView.goTo()](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#goTo). This property may be [autocast](https://developers.arcgis.com/javascript/latest/autocasting/). */
  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/references/core/layers/support/LOD/). If not specified, this value is read from the [Map](https://developers.arcgis.com/javascript/latest/references/core/Map/). It is possible to generate additional LODs via the
   * [TileInfo.create()](https://developers.arcgis.com/javascript/latest/references/core/layers/support/TileInfo/#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/).
   *
   * @since 5.0
   */
  get lods(): LOD[] | null;
  set lods(value: LODProperties[] | null);
  /**
   * The maximum [scale](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#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
   * @since 5.0
   */
  accessor maxScale: number;
  /**
   * The maximum [zoom](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#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
   * @since 5.0
   */
  accessor maxZoom: number;
  /**
   * The minimum [scale](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#scale) the user is allowed to zoom to within the view.
   *
   * @default 0
   * @since 5.0
   */
  accessor minScale: number;
  /**
   * The minimum [zoom](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#zoom) level the user is allowed to zoom to within the view.
   *
   * @default -1
   * @since 5.0
   */
  accessor minZoom: number;
  /**
   * Indicates whether the user can rotate the map.
   *
   * @default true
   * @since 5.0
   */
  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
   * @since 5.0
   */
  accessor snapToZoom: boolean;
}