import type Camera from "./Camera.js";
import type { JSONSupport } from "./core/JSONSupport.js";
import type { GeometryUnion } from "./geometry/types.js";
import type { MeshProperties } from "./geometry/Mesh.js";
import type { PolylineProperties } from "./geometry/Polyline.js";
import type { PolygonProperties } from "./geometry/Polygon.js";
import type { PointProperties } from "./geometry/Point.js";
import type { MultipointProperties } from "./geometry/Multipoint.js";
import type { ExtentProperties } from "./geometry/Extent.js";
import type { CameraProperties } from "./Camera.js";

export interface ViewpointProperties extends Partial<Pick<Viewpoint, "rotation" | "scale">> {
  /**
   * The viewpoint camera (3D only).
   *
   * > [!WARNING]
   * >
   * > **Z-values** defined in a geographic or metric coordinate system are
   * > expressed in meters. However, in local scenes that use a
   * > projected coordinate system, vertical units are assumed to be the same as the
   * > horizontal units specified by the service.
   */
  camera?: CameraProperties | null;
  /**
   * The target geometry framed by the viewpoint.
   *
   * > [!WARNING]
   * >
   * > **Z-values** defined in a geographic or metric coordinate system are
   * > expressed in meters. However, in local scenes that use a
   * > projected coordinate system, vertical units are assumed to be the same as the
   * > horizontal units specified by the service.
   */
  targetGeometry?: ((ExtentProperties & { type: "extent" }) | (MultipointProperties & { type: "multipoint" }) | (PointProperties & { type: "point" }) | (PolygonProperties & { type: "polygon" }) | (PolylineProperties & { type: "polyline" }) | (MeshProperties & { type: "mesh" })) | null;
}

/**
 * Describes a point of view for a 2D or 3D view. In a 2D view, the viewpoint is
 * determined using a center point and scale value. In a 3D view, it is determined
 * using a [Camera](https://developers.arcgis.com/javascript/latest/references/core/Camera/) position. The Viewpoint can be
 * bookmarked for later use, or used for navigation purposes.
 *
 * @since 4.0
 * @see [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/)
 * @see [Camera](https://developers.arcgis.com/javascript/latest/references/core/Camera/)
 */
export default class Viewpoint extends JSONSupport {
  constructor(properties?: ViewpointProperties);
  /**
   * The viewpoint camera (3D only).
   *
   * > [!WARNING]
   * >
   * > **Z-values** defined in a geographic or metric coordinate system are
   * > expressed in meters. However, in local scenes that use a
   * > projected coordinate system, vertical units are assumed to be the same as the
   * > horizontal units specified by the service.
   */
  get camera(): Camera | null | undefined;
  set camera(value: CameraProperties | null | undefined);
  /**
   * The rotation of due north in relation to the top of the view in degrees.
   *
   * @default 0
   * @see [MapView.rotation](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#rotation)
   * @example
   * // due north is rotated 90 degrees, pointing to the right side of the view
   * viewpoint.rotation = 90;
   * @example
   * // due north is rotated 180 degrees, pointing to the bottom of the view
   * viewpoint.rotation = 180;
   * @example
   * // due north is rotated 270 degrees, pointing to the left side of the view
   * viewpoint.rotation = 270;
   * @example
   * // due north is rotated 0 degrees, pointing to the top of the view (the default)
   * viewpoint.rotation = 0; // 360 or multiple of 360 (e.g. 720) works here as well.
   */
  accessor rotation: number;
  /**
   * The scale of the viewpoint.
   *
   * @default 0
   */
  accessor scale: number;
  /**
   * The target geometry framed by the viewpoint.
   *
   * > [!WARNING]
   * >
   * > **Z-values** defined in a geographic or metric coordinate system are
   * > expressed in meters. However, in local scenes that use a
   * > projected coordinate system, vertical units are assumed to be the same as the
   * > horizontal units specified by the service.
   */
  get targetGeometry(): GeometryUnion | null | undefined;
  set targetGeometry(value: ((ExtentProperties & { type: "extent" }) | (MultipointProperties & { type: "multipoint" }) | (PointProperties & { type: "point" }) | (PolygonProperties & { type: "polygon" }) | (PolylineProperties & { type: "polyline" }) | (MeshProperties & { type: "mesh" })) | null | undefined);
  /**
   * Create a deep clone of the viewpoint.
   *
   * @returns A deep clone of the [Viewpoint](https://developers.arcgis.com/javascript/latest/references/core/Viewpoint/)
   * object that called this method.
   */
  clone(): Viewpoint;
}