import type Layer from "../../layers/Layer.js";
import type CatalogFootprintLayerView from "../layers/CatalogFootprintLayerView.js";
import type CSVLayerView from "../layers/CSVLayerView.js";
import type FeatureLayerView from "../layers/FeatureLayerView.js";
import type GeoJSONLayerView from "../layers/GeoJSONLayerView.js";
import type GeoRSSLayerView from "../layers/GeoRSSLayerView.js";
import type GraphicsLayerView from "../layers/GraphicsLayerView.js";
import type ImageryLayerView from "../layers/ImageryLayerView.js";
import type KMLLayerView from "../layers/KMLLayerView.js";
import type KnowledgeGraphSublayerView from "../layers/KnowledgeGraphSublayerView.js";
import type MediaLayerView from "../layers/MediaLayerView.js";
import type OGCFeatureLayerView from "../layers/OGCFeatureLayerView.js";
import type OrientedImageryLayerView from "../layers/OrientedImageryLayerView.js";
import type ParquetLayerView from "../layers/ParquetLayerView.js";
import type StreamLayerView from "../layers/StreamLayerView.js";
import type WFSLayerView from "../layers/WFSLayerView.js";

/** @since 5.0 */
export interface LayerView2DMap {
  /** @since 5.0 */
  "base-dynamic": never;
  /** @since 5.0 */
  "base-tile": never;
  /** @since 5.0 */
  "bing-maps": never;
  /** @since 5.0 */
  catalog: never;
  /** @since 5.0 */
  "catalog-dynamic-group": never;
  /** @since 5.0 */
  "catalog-footprint": CatalogFootprintLayerView;
  /** @since 5.0 */
  csv: CSVLayerView;
  /** @since 5.0 */
  "geo-rss": GeoRSSLayerView;
  /** @since 5.0 */
  feature: FeatureLayerView;
  /** @since 5.0 */
  geojson: GeoJSONLayerView;
  /** @since 5.0 */
  graphics: GraphicsLayerView;
  /** @since 5.0 */
  group: never;
  /** @since 5.0 */
  imagery: ImageryLayerView;
  /** @since 5.0 */
  "imagery-tile": never;
  /** @since 5.0 */
  kml: KMLLayerView;
  /** @since 5.0 */
  "knowledge-graph": never;
  /** @since 5.0 */
  "link-chart": never;
  /** @since 5.0 */
  "knowledge-graph-sublayer": KnowledgeGraphSublayerView;
  /** @since 5.0 */
  "map-image": never;
  /** @since 5.0 */
  "map-notes": never;
  /** @since 5.0 */
  media: MediaLayerView;
  /** @since 5.0 */
  "ogc-feature": OGCFeatureLayerView;
  /** @since 5.0 */
  "open-street-map": never;
  /** @since 5.0 */
  "oriented-imagery": OrientedImageryLayerView;
  /** @since 5.0 */
  parquet: ParquetLayerView;
  /** @since 5.0 */
  route: never;
  /** @since 5.0 */
  stream: StreamLayerView;
  /** @since 5.0 */
  "subtype-group": never;
  /** @since 5.0 */
  tile: never;
  /** @since 5.0 */
  "vector-tile": never;
  /** @since 5.0 */
  video: never;
  /** @since 5.0 */
  wcs: never;
  /** @since 5.0 */
  "web-tile": never;
  /** @since 5.0 */
  wfs: WFSLayerView;
  /** @since 5.0 */
  wms: never;
  /** @since 5.0 */
  wmts: never;
  /** @since 5.0 */
  "base-elevation": never;
  /** @since 5.0 */
  "building-scene": never;
  /** @since 5.0 */
  dimension: never;
  /** @since 5.0 */
  elevation: never;
  /** @since 5.0 */
  "gaussian-splat": never;
  /** @since 5.0 */
  "integrated-mesh-3dtiles": never;
  /** @since 5.0 */
  "integrated-mesh": never;
  /** @since 5.0 */
  "line-of-sight": never;
  /** @since 5.0 */
  "point-cloud": never;
  /** @since 5.0 */
  scene: never;
  /** @since 5.0 */
  unknown: never;
  /** @since 5.0 */
  unsupported: never;
  /** @since 5.0 */
  viewshed: never;
  /** @since 5.0 */
  voxel: never;
}

/** @since 5.0 */
export type LayerView2DFor<TLayer extends Layer> = LayerView2DMap[TLayer["type"]];

/**
 * A vertex of a tessellated mesh.
 *
 * There are five different tessellation algorithms, one for each supported geometry type. The attributes in a
 * vertex can be used to populate vertex and index buffers that can be rendered using appropriate shaders.
 * See the [SDK sample](https://developers.arcgis.com/javascript/latest/sample-code/custom-gl-tessellation-helpers/) for a possible way of
 * doing this using a single universal shader program that can render any of the supported geometry types.
 *
 * There are four attributes; the first three are 2D points, and the last one is a scalar value. In total
 * a mesh vertex contains 7 numeric values.
 *
 * **Geographic position (x, y)**
 * The geographic point associated to that vertex. For [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)
 * is equivalent to the position of the vertex itself; for [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) and [Multipoint](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Multipoint.html)
 * is the geographic position of the point, and the anchor that will be associated to the corresponding marker symbol;
 * for [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html) it lies on the centerline. The geographic position is usually expressed in map units and a
 * custom vertex shader will generally need to transform it to
 * [normalized device coordinates](https://learnopengl.com/Getting-started/Coordinate-Systems).
 *
 * **Offset vector (xOffset, yOffset)**
 * This is an offset that is generally expressed in units other than the view's ones, and drives the extrusion of the geographic
 * position into lines and quads. For [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)
 * is zero; for [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) and [Multipoint](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Multipoint.html) it goes from the anchor
 * to the four vertices of the quad on screen; for [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html) it goes from the centerline
 * to a vertex on the polyline's edge. The offset vector is usually expressed in some other units than map
 * and will not need to be transformed by the same transform used for the geographic position. A common convention
 * is to express the offset in points or pixels and code the vertex shader accordingly.
 *
 * ![tessellation-helpers-extrusion](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/tessellation-helpers-extrusion.png)
 *
 * **Texture coordinates (uTexcoord, vTexcoord)**
 * The texture coordinates associated to this vertex.
 * For [Extent](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Extent.html) the lower left vertex has coordinates (0, 0) and the upper right (1, 1); for
 * [Polygon](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polygon.html) the coordinates at each vertex match the interpolated coordinates that the
 * smallest enclosing extent for that polygon would have at the same fragment; for [Point](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Point.html) and
 * [Multipoint](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Multipoint.html) each quad has (0, 0) as the lower left texture coordinate and (1, 1) as the
 * upper right one; for [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html) the start cap is made of two vertices with texture
 * coordinates (0, 0) and (0, 1) while the end cap is associated to (1, 0) and (1, 1).
 *
 * ![tessellation-helpers-uv](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/tessellation-helpers-uv.png)
 *
 * **Distance**
 * Valid only for [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html); it is the distance, in map units, from the beginning of the
 * polyline to this vertex.
 *
 * ![tessellation-helpers-distance](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/tessellation-helpers-distance.png)
 *
 * @since 5.0
 */
export interface MeshVertex {
  /**
   * The `x`-coordinate, expressed in the same units as the [MapView](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html).
   *
   * @since 5.0
   */
  x: number;
  /**
   * The `y`-coordinate, expressed in the same units as the [MapView](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html).
   *
   * @since 5.0
   */
  y: number;
  /**
   * The `x`-offset in screen space; this is used to extrude points (into quads), markers and polylines, and is 0 for polygons.
   *
   * @since 5.0
   */
  xOffset: number;
  /**
   * The `y`-offset in screen space; this is used to extrude points (into quads), markers and polylines, and is 0 for polygons.
   *
   * @since 5.0
   */
  yOffset: number;
  /**
   * The `u`-coordinate for texture mapping. It varies between 0 and 1 horizontally for quads and polygons, and along the entire length of a polyline.
   *
   * @since 5.0
   */
  uTexcoord: number;
  /**
   * The `v`-coordinate for texture mapping. It varies between 0 and 1 vertically for quads and polygons, and across the width of a polyline.
   *
   * @since 5.0
   */
  vTexcoord: number;
  /**
   * The distance parameter for this vertex; this only applies when tessellating polylines. It starts
   * from 0 and runs up to the total length of the polyline. It is expressed in map units.
   *
   * @since 5.0
   */
  distance: number;
}

/**
 * The triangle mesh resulting from a tessellation operation.
 *
 * An instance of `Mesh` can be obtained by calling one of the [BaseLayerViewGL2D](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-2d-layers-BaseLayerViewGL2D.html)
 * `tessellate*` methods and passing an instance of [Geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Geometry.html).
 *
 * @since 5.0
 */
export interface TessellatedMesh {
  /**
   * The vertices that make up the mesh.
   * Each element is a [MeshVertex](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-2d-types.html#MeshVertex).
   *
   * @since 5.0
   */
  vertices: MeshVertex[];
  /**
   * The indices of the triangles that connect vertices together;
   * each consecutive triplet of indices denotes a triangle.
   *
   * @since 5.0
   */
  indices: number[];
}

/**
 * Defines which anchor stays still while resizing the browser window. The default, center, ensures the view's center point remains constantly visible as
 * the window size changes. The other options allow the respective portion of the view to remain visible when the window's size is changed.
 *
 * @since 5.0
 */
export type ResizeAlign = "bottom" | "bottom-left" | "bottom-right" | "center" | "left" | "right" | "top" | "top-left" | "top-right";