import type Layer from "./layers/Layer.js";
import type Collection from "./core/Collection.js";
import type SpatialReference from "./geometry/SpatialReference.js";
import type PortalItem from "./portal/PortalItem.js";
import type BasemapStyle from "./support/BasemapStyle.js";
import type { ReadonlyArrayOrCollection } from "./core/Collection.js";
import type { JSONSupportMixin } from "./core/JSONSupport.js";
import type { Loadable, LoadableMixinProperties } from "./core/Loadable.js";
import type { BasemapGroundLayer } from "./layers/support/types.js";
import type { PortalItemProperties } from "./portal/PortalItem.js";
import type { SpatialReferenceProperties } from "./geometry/SpatialReference.js";
import type { BasemapStyleProperties } from "./support/BasemapStyle.js";

export interface BasemapProperties extends LoadableMixinProperties, Partial<Pick<Basemap, "groundLayers" | "id" | "thumbnailUrl" | "title">> {
  /** A collection of layers that make up the basemap's features. */
  baseLayers?: ReadonlyArrayOrCollection<Layer>;
  /** The portal item. */
  portalItem?: PortalItemProperties | null;
  /** A collection of reference layers which are displayed over the [base layers](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#baseLayers) and all other layers in the map. They can be used to display labels on top of terrain or streets. */
  referenceLayers?: ReadonlyArrayOrCollection<Layer>;
  /**
   * The spatial reference of the Basemap.
   * For complete listings of supported coordinate systems, see
   * [Using spatial references](https://developers.arcgis.com/rest/services-reference/enterprise/using-spatial-references.htm).
   *
   * When using an [Esri basemap](https://developers.arcgis.com/javascript/latest/references/core/Map/#basemap), the default spatial reference is
   * [Web Mercator Auxiliary Sphere](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#WebMercator).
   *
   * @since 4.14
   */
  spatialReference?: SpatialReferenceProperties;
  /**
   * The style of the basemap from the [basemap styles service (v2)](https://developers.arcgis.com/rest/basemap-styles/).
   * The basemap styles service is a ready-to-use location service that serves vector and image tiles representing geographic features around the world.
   *
   * You can use the service to display:
   * - Streets and navigation styles
   * - Imagery, oceanic, and topographic styles
   * - Creative styles such as nova and blueprint
   * - Localized place labels
   * - Places with styles - _since 4.29_
   * - Worldview boundaries - _since 4.29_
   *
   * > [!CAUTION]
   * >
   * > Use of the basemap style service requires authentication via an [API key](https://developers.arcgis.com/javascript/latest/references/core/config/#Config-apiKey) or [user authentication](https://developers.arcgis.com/javascript/latest/secure-resources/#user-authentication). To learn more about API key authentication,
   * > see the [API key authentication](https://developers.arcgis.com/documentation/security-and-authentication/api-key-authentication/) page in the Esri Developer documentation.
   *
   * @since 4.28
   * @example
   * // creates an arcgis streets basemap with french place labels
   * const basemap = new Basemap({
   *   style: {
   *     id: "arcgis/streets",
   *     language: "fr"
   *   }
   * });
   * @example
   * // creates an arcgis navigation basemap with places
   * const basemap = new Basemap({
   *   style: {
   *     id: "arcgis/navigation",
   *     places: "all"
   *   }
   * });
   */
  style?: BasemapStyleProperties | null;
}

/**
 * * [Overview](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#overview)
 * * [Creating a Basemap](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#creating-a-basemap)
 * * [Setting the LOD](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#setting-the-lod)
 * * [Waiting for Load](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#waiting-for-load)
 *
 * <span id="overview"></span>
 * ## Overview
 *
 * A basemap is a collection of layers that provide geographic context to a map or scene with data such as topographic features, road networks, buildings, and labels.
 * These features can be represented with different styles as applicable to your application, such as streets, topographic, or imagery.
 *
 * A basemap can contain both [base layers](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#baseLayers), which comprise one or more layers, and [reference layers](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#referenceLayers).
 * Reference layers are displayed on top of the base layers and all other layers in the map. They can be used to display labels on top of terrain or streets.
 *
 * <span id="creating-a-basemap"></span>
 * ## Creating a Basemap
 *
 * Creates a new basemap object. Basemaps can be created in a variety of ways:
 * 1. From a [PortalItem](https://developers.arcgis.com/javascript/latest/references/core/portal/PortalItem/)
 *     ```js
 *     // in this case the portalItem has to be a webmap
 *     const basemap = new Basemap({
 *       portalItem: {
 *         id: "8dda0e7b5e2d4fafa80132d59122268c" // WGS84 Streets Vector webmap
 *       }
 *     });
 *     ```
 * 2. From a [basemap id](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#fromId)
 *     ```js
 *     // create the basemap from a basemap id
 *     Basemap.fromId("topo-vector");
 *     ```
 * 3. From a [basemap style](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#style)
 *     ```js
 *     // create a basemap from the basemap styles service
 *     const basemap = new Basemap({
 *       style: {
 *         id: "arcgis/outdoor",
 *         language: "es" // displays basemap place labels in spanish
 *       }
 *     });
 *     ```
 * 4. From a custom basemap layer. These basemaps may be created from services you publish to your own server, or from services published by third parties.
 *     ```js
 *     // create from a third party source
 *     const basemap = new Basemap({
 *       baseLayers: [
 *         new WebTileLayer(...)
 *       ],
 *       referenceLayers: [
 *         new WebTileLayer(...)
 *       ]
 *     });
 *     ```
 *
 * <span id="setting-the-lod"></span>
 * ## Setting the LOD
 *
 * The [MapView.constraints.lods](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#constraints) property should be specified when using a dynamic service for a basemap.
 * Do this by either explicitly setting the `lods` within this property, or create the `lods` via the [TileInfo.create()](https://developers.arcgis.com/javascript/latest/references/core/layers/support/TileInfo/#create)
 * method on the [TileInfo](https://developers.arcgis.com/javascript/latest/references/core/layers/support/TileInfo/) class. This method is used to create a new [TileInfo](https://developers.arcgis.com/javascript/latest/references/core/layers/support/TileInfo/) instance
 * with preset properties for [TileInfo.lods](https://developers.arcgis.com/javascript/latest/references/core/layers/support/TileInfo/#lods). See [Zoom and LODs](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#mapview-lods) section in
 * [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/) SDK document for more information.
 *
 * ```js
 * // create a basemap from a dynamic MapServer
 * const basemap = new Basemap({
 *   baseLayers: [
 *     new MapImageLayer({
 *       url: "url to your dynamic MapServer",
 *       title: "Basemap"
 *     })
 *   ],
 *   title: "basemap",
 *   id: "basemap"
 * });
 *
 * const map = new Map({
 *   basemap: basemap
 * });
 *
 * // create a TileInfo instance using the default settings and
 * // pass its resulting LOD's to a MapView's constraints
 * // in this case, lods will match the ArcGIS Online web mercator LODs
 * const view = new MapView({
 *   container: "viewDiv",
 *   map: map,
 *   constraints: {
 *     lods: TileInfo.create().lods
 *   }
 * });
 * ```
 *
 * <span id="waiting-for-load"></span>
 * ## Waiting for Load
 *
 * The [when()](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#when) method on the Basemap instance can be called to execute processes that may only run after the Basemap is [loaded](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#loaded).
 *
 * > [!WARNING]
 * >
 * > **Note:** Basemaps containing 3D layers can only be used in a [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
 *
 * @since 4.0
 * @see [Basemap Layers](https://developers.arcgis.com/documentation/mapping-apis-and-services/maps/basemap-layers/)
 * @see [Basemap Gallery component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-basemap-gallery/)
 * @see [Basemap Toggle component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-basemap-toggle/)
 * @see [Map](https://developers.arcgis.com/javascript/latest/references/core/Map/)
 * @see [Zoom and LODs](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#mapview-lods)
 * @see [Sample - Create a custom basemap](https://developers.arcgis.com/javascript/latest/sample-code/basemap-custom/)
 * @see [Sample - PopupTemplate with promise (basemap from PortalItem)](https://developers.arcgis.com/javascript/latest/sample-code/popuptemplate-promise/)
 */
export default class Basemap extends BasemapSuperclass {
  /**
   * Creates a new basemap instance from a [basemap id](https://developers.arcgis.com/javascript/latest/references/core/Map/#basemap-id).
   * See [basemap id](https://developers.arcgis.com/javascript/latest/references/core/Map/#basemap-id) for a list of possible values.
   *
   * @param id - The basemap id.
   * @returns A new Basemap instance.
   * @example const streetsBasemap = Basemap.fromId("streets-vector");
   * @example const nightBasemap = Basemap.fromId("streets-night-vector");
   */
  static fromId(id: string): Basemap | null | undefined;
  constructor(properties?: BasemapProperties);
  /** A collection of layers that make up the basemap's features. */
  get baseLayers(): Collection<Layer>;
  set baseLayers(value: ReadonlyArrayOrCollection<Layer>);
  /**
   * A collection of 3D Tiles IM layers (currently at most one supported)
   * If any layer is added here that has global coverage, it will override both ground.layers and basemap.baselayers
   */
  accessor groundLayers: Collection<BasemapGroundLayer>;
  /**
   * An identifier used to refer to the basemap when referencing it elsewhere.
   *
   * @example
   * const customBasemap = new Basemap({
   *   baseLayers: [layers],
   *   title: "Custom Basemap",
   *   id: "myBasemap"
   * });
   */
  accessor id: string | null | undefined;
  /**
   * Indicates whether the basemap instance has loaded. When `true`,
   * all the properties of the object can be accessed.
   *
   * @default false
   */
  get loaded(): boolean;
  /** The portal item. */
  get portalItem(): PortalItem | null | undefined;
  set portalItem(value: PortalItemProperties | null | undefined);
  /** A collection of reference layers which are displayed over the [base layers](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#baseLayers) and all other layers in the map. They can be used to display labels on top of terrain or streets. */
  get referenceLayers(): Collection<Layer>;
  set referenceLayers(value: ReadonlyArrayOrCollection<Layer>);
  /**
   * The spatial reference of the Basemap.
   * For complete listings of supported coordinate systems, see
   * [Using spatial references](https://developers.arcgis.com/rest/services-reference/enterprise/using-spatial-references.htm).
   *
   * When using an [Esri basemap](https://developers.arcgis.com/javascript/latest/references/core/Map/#basemap), the default spatial reference is
   * [Web Mercator Auxiliary Sphere](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#WebMercator).
   *
   * @since 4.14
   */
  get spatialReference(): SpatialReference;
  set spatialReference(value: SpatialReferenceProperties);
  /**
   * The style of the basemap from the [basemap styles service (v2)](https://developers.arcgis.com/rest/basemap-styles/).
   * The basemap styles service is a ready-to-use location service that serves vector and image tiles representing geographic features around the world.
   *
   * You can use the service to display:
   * - Streets and navigation styles
   * - Imagery, oceanic, and topographic styles
   * - Creative styles such as nova and blueprint
   * - Localized place labels
   * - Places with styles - _since 4.29_
   * - Worldview boundaries - _since 4.29_
   *
   * > [!CAUTION]
   * >
   * > Use of the basemap style service requires authentication via an [API key](https://developers.arcgis.com/javascript/latest/references/core/config/#Config-apiKey) or [user authentication](https://developers.arcgis.com/javascript/latest/secure-resources/#user-authentication). To learn more about API key authentication,
   * > see the [API key authentication](https://developers.arcgis.com/documentation/security-and-authentication/api-key-authentication/) page in the Esri Developer documentation.
   *
   * @since 4.28
   * @example
   * // creates an arcgis streets basemap with french place labels
   * const basemap = new Basemap({
   *   style: {
   *     id: "arcgis/streets",
   *     language: "fr"
   *   }
   * });
   * @example
   * // creates an arcgis navigation basemap with places
   * const basemap = new Basemap({
   *   style: {
   *     id: "arcgis/navigation",
   *     places: "all"
   *   }
   * });
   */
  get style(): BasemapStyle | null | undefined;
  set style(value: BasemapStyleProperties | null | undefined);
  /**
   * The URL pointing to an image that represents the basemap. When using a custom
   * basemap in the [Basemap Toggle](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-basemap-toggle/) component, the image
   * specified here will display in the component. When the user clicks the image,
   * the map's basemap will update to the basemap associated with the image.
   *
   * @see [Sample - Custom basemap](https://developers.arcgis.com/javascript/latest/sample-code/basemap-custom/)
   */
  accessor thumbnailUrl: string | null | undefined;
  /**
   * The title of the basemap.
   *
   * @default "Basemap"
   */
  accessor title: string;
  /**
   * Creates a deep clone of this object.
   *
   * @returns A deep clone of the [Basemap](https://developers.arcgis.com/javascript/latest/references/core/Basemap/) instance that
   * invoked this method.
   */
  clone(): Basemap;
  /**
   * Destroys the basemap, and any associated resources, including its [baseLayers](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#baseLayers) and [portalItem](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#portalItem).
   * These can no longer be used once the basemap has been destroyed. To prevent these objects from being destroyed,
   * remove them from the basemap before calling `destroy()`.
   *
   * ```
   * // prevent the layers from being destroyed by removing them from the basemap
   * const baseLayers = basemap.baseLayers.removeAll();
   * const referenceLayers = basemap.referenceLayers.removeAll();
   *
   * // unset portalItem from the basemap so that it is not destroyed
   * const portalItem = basemap.portalItem;
   * basemap.portalItem = null;
   *
   * // destroy the basemap and any remaining associated resources
   * basemap.destroy();
   * ```
   *
   * @since 4.17
   * @see [Map.destroy()](https://developers.arcgis.com/javascript/latest/references/core/Map/#destroy)
   * @see [WebMap.destroy()](https://developers.arcgis.com/javascript/latest/references/core/WebMap/#destroy)
   * @see [WebScene.destroy()](https://developers.arcgis.com/javascript/latest/references/core/WebScene/#destroy)
   * @see [Ground.destroy()](https://developers.arcgis.com/javascript/latest/references/core/Ground/#destroy)
   * @see [Layer.destroy()](https://developers.arcgis.com/javascript/latest/references/core/layers/Layer/#destroy)
   * @see [PortalItem.destroy()](https://developers.arcgis.com/javascript/latest/references/core/portal/PortalItem/#destroy)
   */
  destroy(): void;
  /**
   * Loads all the externally loadable resources associated with the basemap.
   * For the basemap this will load all the base layers and reference layers.
   *
   * @returns Resolves when all the loadable resources have been loaded.
   *   Rejects if at least one of the loadable resources failed to load.
   * @since 4.9
   * @see [load()](https://developers.arcgis.com/javascript/latest/references/core/Basemap/#load)
   * @example
   * // Load all resources but ignore if one or more of them failed to load
   * basemap.loadAll()
   *   .catch(function(error) {
   *     // Ignore any failed resources
   *   })
   *   .then(function() {
   *     console.log("All loaded");
   *   });
   */
  loadAll(): Promise<this>;
}
declare const BasemapSuperclass: typeof Loadable & typeof JSONSupportMixin