import { DataSourceCollection, EntityCollection, ImageryLayerCollection, PrimitiveCollection, Billboard, Cesium3DTileset, GroundPrimitive, Label, PointPrimitive, Polyline, Primitive, DataSource, Entity, ImageryLayer, Color, Viewer, Model, Cesium3DTileFeature, TerrainProvider, TilingScheme, TileAvailability, Credit, Event, Request, TerrainData, Cartesian3, JulianDate, Rectangle } from 'cesium';

/**
 * Represents a path to any nested property in an object, using dot notation.
 *
 * The `(keyof T & string)` portion provides top-level key hints in autocomplete,
 * while `(string & {})` allows any string input to pass through.
 *
 * Actual path validation is delegated to {@link NestedValueOf}, which returns `never`
 * for invalid paths — causing a type error on the corresponding value parameter.
 *
 * @example
 * ```ts
 * function f<Path extends NestedKeyOf<Obj>>(
 *   key: Path,
 *   value: NestedValueOf<Obj, Path> // ← validation happens here
 * ) {}
 *
 * f("a.b.c", 123);       // ✅ valid path, correct value type
 * f("invalid.path", 1);  // ❌ NestedValueOf returns never
 * ```
 */
type NestedKeyOf<T extends object> = (keyof T & string) | (string & {});
/**
 * Extracts the type of a nested property from a property path string.
 *
 * @template ObjectType - The object type to extract the value type from
 * @template Path - The property path string (e.g., "a.b.c")
 *
 * @example
 * type Value = NestedValueOf<{ a: { b: number } }, "a.b">
 * // Result: number
 */
type NestedValueOf<ObjectType, Path extends string> = Path extends `${infer Cur}.${infer Rest}` ? Cur extends keyof ObjectType ? NonNullable<ObjectType[Cur]> extends Function | ((...args: any[]) => any) ? never : NestedValueOf<NonNullable<ObjectType[Cur]>, Rest> : never : Path extends keyof ObjectType ? NonNullable<ObjectType[Path]> extends Function | ((...args: any[]) => any) ? never : ObjectType[Path] : never;

/**
 * @class
 * A wrapper class that enhances Cesium collection objects with tagging functionality.
 * This class provides a consistent API for working with different types of Cesium collections
 * and allows grouping and manipulating collection items by custom tags.
 *
 * @template C - The type of Cesium collection (e.g., EntityCollection, PrimitiveCollection)
 * @template I - The type of items in the collection (e.g., Entity, Primitive)
 *
 * @see [Collection Demo](https://juun.vercel.app/cesium-utils/collection)
 *
 * @example
 * // Example 1: Managing Complex Scene with Multiple Object Types
 * class SceneOrganizer {
 *   private entities: Collection<EntityCollection, Entity>;
 *   private billboards: Collection<BillboardCollection, Billboard>;
 *   private primitives: Collection<PrimitiveCollection, Primitive>;
 *
 *   constructor(viewer: Viewer) {
 *     this.entities = new Collection({ collection: viewer.entities });
 *     this.billboards = new Collection({
 *       collection: viewer.scene.primitives.add(new BillboardCollection())
 *     });
 *     this.primitives = new Collection({
 *       collection: viewer.scene.primitives
 *     });
 *   }
 *
 *   // Unified API across different collection types!
 *   showLayer(layerName: string) {
 *     this.entities.show(layerName);
 *     this.billboards.show(layerName);
 *     this.primitives.show(layerName);
 *   }
 *
 *   hideLayer(layerName: string) {
 *     this.entities.hide(layerName);
 *     this.billboards.hide(layerName);
 *     this.primitives.hide(layerName);
 *   }
 *
 *   removeLayer(layerName: string) {
 *     this.entities.remove(layerName);
 *     this.billboards.remove(layerName);
 *     this.primitives.remove(layerName);
 *   }
 * }
 *
 * // Example 2: Extend the class for Domain-Specific Needs
 * class BuildingCollection extends Collection<EntityCollection, Entity> {
 *   constructor(viewer: Viewer) {
 *     super({ collection: viewer.entities, tag: 'buildings' });
 *   }
 *
 *   addBuilding(options: {
 *     position: Cartesian3;
 *     height: number;
 *     floors: number;
 *     type: 'residential' | 'commercial' | 'industrial';
 *   }): Entity {
 *     const building = new Entity({
 *       position: options.position,
 *       box: {
 *         dimensions: new Cartesian3(50, 50, options.height),
 *         material: this.getMaterialForType(options.type)
 *       }
 *     });
 *
 *     // Tag by type AND by floor count
 *     this.add(building, options.type);
 *     this.add(building, `floors-${options.floors}`);
 *
 *     return building;
 *   }
 *
 *   getByFloorRange(min: number, max: number): Entity[] {
 *     const results: Entity[] = [];
 *     for (let i = min; i <= max; i++) {
 *       results.push(...this.get(`floors-${i}`));
 *     }
 *     return results;
 *   }
 *
 *   private getMaterialForType(type: string): Material {
 *     const colors = {
 *       residential: Color.GREEN,
 *       commercial: Color.BLUE,
 *       industrial: Color.YELLOW
 *     };
 *     return new ColorMaterialProperty(colors[type] || Color.WHITE);
 *   }
 * }
 */
declare class Collection<C extends Collection.Base, I extends Collection.ItemFor<C>> {
    /**
     * Symbol used as a property key to store tags on collection items.
     * Using a Symbol ensures no property naming conflicts with the item's own properties.
     * @readonly
     */
    static readonly symbol: unique symbol;
    /**
     * Default tag used when adding items without specifying a tag.
     * @protected
     */
    protected tag: Collection.Tag;
    /**
     * The underlying Cesium collection being wrapped.
     * @protected
     */
    protected collection: C;
    /**
     * Cache for values array to improve performance
     * @private
     */
    private _valuesCache;
    /**
     * Tag to items map for faster lookups
     * @private
     */
    private _tagMap;
    /**
     * Event listeners
     * @private
     */
    private _eventListeners;
    /**
     * For cleaning up the instances
     * @private
     */
    private _eventCleanupFunctions;
    /**
     * Creates a new Collection instance.
     *
     * @param options - Configuration options
     * @param options.collection - The Cesium collection to wrap
     * @param options.tag - The default tag to use for items (defaults to 'default')
     */
    constructor({ collection, tag }: {
        collection: C;
        tag?: Collection.Tag;
    });
    /**
     * Makes the collection directly iterable, allowing it to be used in `for...of` loops
     * and with spread operators.
     *
     * @returns An iterator for the items in the collection
     *
     * @example
     * // Iterate through all items in the collection
     * for (const entity of collection) {
     *   console.log(entity.id);
     * }
     *
     * // Convert collection to array using spread syntax
     * const entitiesArray = [...collection];
     */
    [Symbol.iterator](): Iterator<I>;
    /**
     * Gets all item instances in the collection.
     * This array should not be modified directly.
     *
     * @returns An array of all items in the collection
     */
    get values(): I[];
    /**
     * Gets the number of items in the collection.
     *
     * @returns The item count
     */
    get length(): number;
    /**
     * Gets all unique tags currently in use in the collection.
     *
     * @returns An array of all unique tags
     *
     * @example
     * // Get all tags
     * const tags = collection.tags;
     * console.log(`Collection has these tags: ${tags.join(', ')}`);
     */
    get tags(): Collection.Tag[];
    /**
     * Registers an event listener for collection events.
     *
     * @param type - The event type to listen for
     * @param handler - The callback function
     * @returns The collection instance for method chaining
     */
    addEventListener(type: Collection.Event, handler: Collection.EventHandler<I>): this;
    /**
     * Removes an event listener.
     *
     * @param type - The event type
     * @param handler - The callback function to remove
     * @returns The collection instance for method chaining
     */
    removeEventListener(type: Collection.Event, handler: Collection.EventHandler<I>): this;
    /**
     * Adds a single item with a tag to the collection.
     *
     * @param item - The item to add to the collection
     * @param tag - Tag to associate with this item (defaults to the collection's default tag)
     * @param index - The index to add the item at (if supported by the collection)
     * @returns The collection instance for method chaining
     *
     * @example
     * const entity = collection.add(new Entity({ ... }), 'landmarks');
     */
    add(item: I, tag?: Collection.Tag, index?: number): this;
    /**
     * Adds multiple items with the same tag to the collection.
     *
     * @param items - The array of items to add to the collection
     * @param tag - Tag to associate with this item (defaults to the collection's default tag)
     * @returns The collection instance for method chaining
     *
     * @example
     * // Add multiple entities with the same tag
     * const entities = [new Entity({ ... }), new Entity({ ... })];
     * const addedEntities = collection.add(entities, 'buildings');
     */
    add(items: I[], tag?: Collection.Tag): this;
    /**
     * Returns true if the provided item is in this collection, false otherwise.
     *
     * @param item - The item instance to check for
     * @returns True if the item is in the collection, false otherwise
     */
    contains(item: I): boolean;
    /**
     * Checks if the collection has any items with the specified tag.
     *
     * @param tag - The tag to check for
     * @returns True if items with the tag exist, false otherwise
     *
     * @example
     * if (collection.contains('temporary')) {
     *   console.log('Temporary items exist');
     * }
     */
    contains(tag: Collection.Tag): boolean;
    /**
     * Removes an item from the collection.
     *
     * @param item - The item to remove
     * @returns The collection instance for method chaining
     */
    remove(item: I): this;
    /**
     * Removes all items with the specified tag from the collection.
     *
     * @param by - The tag identifying which items to remove
     * @returns The collection instance for method chaining
     */
    remove(by: Collection.Tag): this;
    /**
     * Removes all items with the array of tags from the collection.
     *
     * @param by - The tags identifying which items to remove
     * @returns The collection instance for method chaining
     */
    remove(by: Collection.Tag[]): this;
    /**
     * Removes all items from the collection.
     */
    removeAll(): void;
    /**
     * Permanently destroys this Collection instance.
     * Removes all event listeners and clears internal state.
     * The Collection instance should not be used after calling this method.
     */
    destroy(): void;
    /**
     * Gets all items with the specified tag from the collection.
     * Uses an optimized internal map for faster lookups.
     *
     * @param by - The tag to filter by
     * @returns An array of items with the specified tag, or an empty array if none found
     *
     * @example
     * // Get all buildings
     * const buildings = collection.get('buildings');
     */
    get(by: Collection.Tag): I[];
    /**
     * Gets the first item matching the tag. More efficient than `get` when
     * you only need one item, especially for large collections.
     *
     * @param by - The tag to search for
     * @returns The first matching item or undefined if none found
     *
     * @example
     * // Get the first building
     * const firstBuilding = collection.first('buildings');
     */
    first(by: Collection.Tag): I | undefined;
    /**
     * Updates the tag for all items with the specified tag.
     *
     * @param from - The tag to replace
     * @param to - The new tag to assign
     * @returns The number of items updated
     *
     * @example
     * // Rename a tag
     * const count = collection.update('temp', 'temporary');
     * console.log(`Updated ${count} items`);
     */
    update(from: Collection.Tag, to: Collection.Tag): number;
    /**
     * Makes all items with the specified tag visible.
     * Only affects items that have a 'show' property.
     *
     * @param by - The tag identifying which items to show
     * @returns The collection itself.
     *
     * @example
     * // Show all buildings
     * collection.show('buildings');
     */
    show(by: Collection.Tag): this;
    /**
     * Hides all items with the specified tag.
     * Only affects items that have a 'show' property.
     *
     * @param by - The tag identifying which items to hide
     * @returns The collection itself.
     *
     * @example
     * // Hide all buildings
     * collection.hide('buildings');
     */
    hide(by: Collection.Tag): this;
    /**
     * Toggles visibility of all items with the specified tag.
     * Only affects items that have a 'show' property.
     *
     * @param by - The tag identifying which items to toggle
     * @returns The collection itself.
     *
     * @example
     * // Toggle visibility of all buildings
     * collection.toggle('buildings');
     */
    toggle(by: Collection.Tag): this;
    /**
     * Sets a property value on all items with the specified tag.
     * Supports nested property paths using dot notation (e.g., 'billboard.scale').
     *
     * @template Path - A nested property path type
     *
     * @param property - The property name or nested path to set (e.g., 'name' or 'billboard.scale')
     * @param value - The value to set
     * @param by - The tag identifying which items to update
     * @returns The collection itself.
     *
     * @example
     * // Change color of all buildings to red
     * collection.setProperty('color', Color.RED, 'buildings');
     *
     * @example
     * // Change billboard scale using nested path
     * collection.setProperty('billboard.scale', 2.0, 'buildings');
     */
    setProperty<Path extends NestedKeyOf<I>>(property: Path, value: NestedValueOf<I, Path>, by?: Collection.Tag): this;
    /**
     * Filters items in the collection based on a predicate function.
     * Optionally only filters items with a specific tag.
     *
     * @param predicate - Function that tests each item
     * @param by - Optional tag to filter by before applying the predicate
     * @returns Array of items that pass the test
     *
     * @example
     * // Get all buildings taller than 100 meters
     * const tallBuildings = collection.filter(
     *   entity => entity.properties?.height?.getValue() > 100,
     *   'buildings'
     * );
     */
    filter(predicate: (item: I) => boolean, by?: Collection.Tag): I[];
    /**
     * Executes a callback function for each item in the collection.
     * Optionally filters items by tag before execution.
     *
     * @param callback - Function to execute for each item
     * @param by - Optional tag to filter items (if not provided, processes all items)
     *
     * @example
     * // Highlight all buildings
     * collection.forEach((entity) => {
     *   if (entity.polygon) {
     *     entity.polygon.material = new ColorMaterialProperty(Color.YELLOW);
     *   }
     * }, 'buildings');
     */
    forEach(callback: (value: I, index: number) => void, by?: Collection.Tag): void;
    /**
     * Creates a new array with the results of calling a provided function on every element
     * in the collection. Optionally filters by tag before mapping.
     *
     * @param callbackfn - Function that produces an element of the new array
     * @param by - Optional tag to filter items by before mapping
     * @returns A new array with each element being the result of the callback function
     *
     * @example
     * // Get all entity IDs
     * const entityIds = collection.map(entity => entity.id);
     *
     * // Get positions of all buildings
     * const buildingPositions = collection.map(
     *   entity => entity.position.getValue(Cesium.JulianDate.now()),
     *   'buildings'
     * );
     */
    map<R>(callbackfn: (value: I, index: number) => R, by?: Collection.Tag): R[];
    /**
     * Returns the first element in the collection that satisfies the provided testing function.
     * Optionally filters by tag before searching.
     *
     * @param predicate - Function to test each element
     * @param by - Optional tag to filter items by before searching
     * @returns The first element that passes the test, or undefined if no elements pass
     *
     * @example
     * // Find the first entity with a specific name
     * const namedEntity = collection.find(entity => entity.name === 'Target');
     *
     * // Find the first building taller than 100 meters
     * const tallBuilding = collection.find(
     *   entity => entity.properties?.height?.getValue() > 100,
     *   'buildings'
     * );
     */
    find(predicate: (value: I) => boolean, by?: Collection.Tag): I | undefined;
    /**
     * Emits an event to all registered listeners.
     *
     * @private
     * @param type - The event type
     * @param data - Additional event data
     */
    private _emit;
    /**
     * Adds an item to the internal tag map for quick lookups.
     *
     * @private
     * @param item - The item to add
     * @param tag - The tag to associate with the item
     */
    private _addToTagMap;
    /**
     * Removes an item from the internal tag map.
     *
     * @private
     * @param item - The item to remove
     */
    private _removeFromTagMap;
    /**
     * Invalidates the values cache when collection changes.
     *
     * @private
     */
    private _invalidateCache;
    /**
     * Sets up automatic cache invalidation by registering event listeners on the underlying Cesium collection.
     *
     * @private
     * @param collection - The Cesium collection to monitor for changes
     *
     * @see {@link destroy} For cleanup of event listeners
     * @see {@link _invalidateCache} For the actual cache invalidation logic
     */
    private _setupCacheInvalidator;
}
/**
 * @namespace
 */
declare namespace Collection {
    /**
     * The underlying Cesium collection type being wrapped.
     */
    export type Base = DataSourceCollection | EntityCollection | ImageryLayerCollection | PrimitiveCollection;
    /**
     * The item types that can be added to the `PrimitiveCollection` instance.
     */
    type Primitives = Billboard | Cesium3DTileset | GroundPrimitive | Label | PointPrimitive | Polyline | Primitive;
    /**
     * Cesium item type that can be added to the {@link Collection.Base} instance.
     */
    export type Item = DataSource | Entity | ImageryLayer | Primitives;
    /**
     * Gets the item type for a given collection type
     */
    export type ItemFor<C extends Base> = C extends DataSourceCollection ? DataSource : C extends EntityCollection ? Entity : C extends ImageryLayerCollection ? ImageryLayer : C extends PrimitiveCollection ? Primitives : never;
    /**
     * Collection tag type.
     */
    export type Tag = string | number;
    export interface WithTag {
        [key: symbol]: Tag;
    }
    /**
     * Collection event types
     */
    export type Event = "add" | "remove" | "update" | "clear";
    /**
     * Event handler function type
     */
    export type EventHandler<I> = (event: {
        type: Event;
        items?: I[];
        tag?: Collection.Tag;
    }) => void;
    export {  };
}

/**
 * @class
 * Lightweight multiton highlight manager for Cesium using flyweight pattern.
 *
 * @example
 * ```
 * // Setup
 * const viewer1 = new Viewer('cesiumContainer1');
 * const viewer2 = new Viewer('cesiumContainer2');
 *
 * const highlighter1 = Highlight.getInstance(viewer1);
 * const highlighter2 = Highlight.getInstance(viewer2);
 *
 * // This highlight only affects viewer1
 * highlighter1.show(someEntity, { color: Color.RED });
 *
 * // This highlight only affects viewer2
 * highlighter2.show(someEntity, { color: Color.BLUE });
 *
 * // When done with viewers
 * Highlight.releaseInstance(viewer1);
 * Highlight.releaseInstance(viewer2);
 * viewer1.destroy();
 * viewer2.destroy();
 * ```
 */
declare class Highlight {
    private static instances;
    private _surface;
    private _silhouette;
    private _color;
    /**
     * Creates a new `Highlight` instance.
     * @private Use {@link getInstance `Highlight.getInstance()`}
     * @param viewer A viewer to create highlight entity in
     */
    private constructor();
    /** Gets the highlight color. */
    get color(): Color;
    /**
     * Sets the highlight color.
     * @param color The new color for highlights
     */
    set color(color: Color);
    /**
     * Gets or creates highlight instance from a viewer.
     * @param viewer The viewer to get or create a new instance from.
     */
    static getInstance(viewer: Viewer): Highlight;
    /**
     * Releases the highlight instance associated with a viewer.
     * @param viewer The viewer whose highlight instance should be released.
     */
    static releaseInstance(viewer: Viewer): void;
    /**
     * Highlights a picked object or a direct instance.
     * @param picked The result of `Scene.pick()` or direct instance to be highlighted.
     * @param options Optional style for the highlight.
     * @see {@link Highlight.Options}
     */
    show(picked: Highlight.Picked, options?: Highlight.Options): void | Entity;
    private _getObject;
    /**
     * Clears the current highlight effects.
     */
    hide(): void;
}
declare namespace Highlight {
    export interface Base {
        show(object: any, options?: Highlight.Options): void;
        hide(): void;
        destroy(): void;
        color: Color;
    }
    export interface Options {
        /** Color of the highlight */
        color?: Color;
        /** To apply outline style for the highlight */
        outline?: boolean;
        /** Outline width */
        width?: number;
    }
    type PickedObject = {
        id?: Entity;
        primitive?: Primitive | GroundPrimitive | Model | Cesium3DTileset;
        tileset?: Cesium3DTileset;
        detail?: {
            model?: Model;
        };
    };
    export type Picked = Entity | Cesium3DTileFeature | GroundPrimitive | PickedObject;
    export {  };
}

/**
 * @class
 * An implementation for highlighting 3D objects in Cesium.
 *
 * **Supported Object Types:**
 * - `Entity` with model graphics. (adjustable outline width)
 * - `Cesium3DTileset` instances. (fixed outline width)
 *
 * Currently supports outline style only.
 *
 * @example
 * ```typescript
 * const viewer = new Viewer("cesiumContainer");
 * const silhouetteHighlight = new SilhouetteHighlight(viewer);
 *
 * // Highlight an object
 * const entity = viewer.entities.add(new Entity({
 *   model: new ModelGraphics(),
 * }));
 * silhouetteHighlight.show(entity);
 * ```
 */
declare class SilhouetteHighlight implements Highlight.Base {
    private _color;
    private _silhouette;
    private _composite;
    private _stages;
    private _entity?;
    private _currentObject;
    private _currentOptions;
    /**
     * Creates a new `Silhouette` instance.
     * @param viewer A viewer to create highlight silhouette in
     */
    constructor(viewer: Viewer);
    /** Gets the highlight color. */
    get color(): Color;
    /** Sets the highlight color. */
    set color(color: Color);
    /** Gets the currently highlighted object */
    get currentObject(): Cesium3DTileFeature | Entity | undefined;
    /**
     * Highlights a picked `Cesium3DTileset` by updating silhouette composite.
     * @param object The object to be highlighted.
     * @param options Optional style for the highlight.
     */
    show(object: Cesium3DTileFeature, options?: Highlight.Options): void;
    /**
     * Highlights a picked `Entity` by updating the model properties.
     * @param object The object to be highlighted.
     * @param options Optional style for the highlight.
     */
    show(object: Entity, options?: Highlight.Options): void;
    /** Clears the current highlight */
    hide(): void;
    /** Clean up the instances */
    destroy(): void;
    /**
     * Compares two Highlight.Options objects for equality
     * @private
     */
    private _optionsEqual;
    /**
     * Clears all current highlights
     * @private
     */
    private _clearHighlights;
}

/**
 * @class
 * A flyweight implementation for highlighting 2D surface objects in Cesium.
 *
 * This class provides highlighting for ground-clamped geometries (polygons, polylines, rectangles)
 *
 * **Supported Geometry Types:**
 * - `Entity` with polygon, polyline, or rectangle graphics
 * - `GroundPrimitive` instances
 *
 * **Highlighting Modes:**
 * - **Fill mode** (default): Creates a filled geometry using the original shape
 * - **Outline mode**: Creates a polyline outline of the original geometry
 *
 * @example
 * ```typescript
 * // Basic usage
 * const viewer = new Viewer('cesiumContainer');
 * const surfaceHighlight = new SurfaceHighlight(viewer);
 *
 * // Highlight an entity with default red fill
 * const entity = viewer.entities.add(new Entity({
 *   polygon: {
 *     hierarchy: Cartesian3.fromDegreesArray([-75, 35, -74, 35, -74, 36, -75, 36]),
 *     material: Color.BLUE
 *   }
 * }));
 * surfaceHighlight.show(entity);
 * ```
 */
declare class SurfaceHighlight implements Highlight.Base {
    private _color;
    private _entity;
    private _entities;
    private _currentObject;
    private _currentOptions;
    /**
     * Creates a new `SurfaceHighlight` instance.
     * @param viewer A viewer to create highlight entity in
     */
    constructor(viewer: Viewer);
    /** Gets the highlight color. */
    get color(): Color;
    /** Sets the highlight color. */
    set color(color: Color);
    /** Gets the highlight entity */
    get entity(): Entity;
    /** Gets the currently highlighted object */
    get currentObject(): Entity | GroundPrimitive | undefined;
    /**
     * Highlights a picked object by updating the reusable entity
     * @param object The object to be highlighted.
     * @param options Optional style for the highlight.
     * @see {@link Highlight.Options}
     */
    show(object: Entity | GroundPrimitive, options?: Highlight.Options): Entity | undefined;
    /**
     * Clears the current highlight
     */
    hide(): void;
    /** Clean up the instances */
    destroy(): void;
    /**
     * Compares two Highlight.Options objects for equality
     * @private
     */
    private _optionsEqual;
    /**
     * Removes all geometry properties from the highlight entity
     * @private
     */
    private _clearGeometries;
    /**
     * Updates the highlight entity from an Entity object
     * @private
     */
    private _update;
}

/**
 * @class
 * Provides terrain by delegating requests to different terrain providers
 * based on geographic regions and zoom levels. This allows combining
 * multiple terrain sources into a single seamless terrain.
 *
 * @example
 * ``` typescript
 * // Tile-coordinate based for precise control (multiple levels)
 * const customTiles: TerrainTiles = new Map();
 * customTiles.set(15, { x: [55852, 55871], y: [9556, 9575] });
 * customTiles.set(16, { x: [111704, 111742], y: [19112, 19150] });
 *
 * const hybridTerrain = new HybridTerrainProvider({
 *   regions: [
 *     {
 *       provider: customProvider,
 *       tiles: customTiles,
 *     }
 *   ],
 *   defaultProvider: worldTerrain
 * });
 *
 * viewer.terrainProvider = hybridTerrain;
 * ```
 */
declare class HybridTerrainProvider implements TerrainProvider {
    private _regions;
    private _defaultProvider;
    /** @deprecated This will be removed in 0.5.0. */
    private _fallbackProvider;
    private _tilingScheme;
    private _ready;
    private _availability?;
    private _errorEvent;
    private _removeEventListeners;
    private _hasWaterMask;
    private _hasVertexNormals;
    /**
     * Creates a new `HybridTerrainProvider` instance.
     * @param options {@link HybridTerrainProvider.ConstructorOptions}
     * @returns A new `HybridTerrainProvider` instance.
     */
    constructor(options: HybridTerrainProvider.ConstructorOptions);
    /**
     * Gets a value indicating whether or not the provider is ready for use,
     * or a promise that resolves when the provider becomes ready.
     */
    get ready(): boolean;
    /**
     * Gets the tiling scheme used by this provider.
     */
    get tilingScheme(): TilingScheme;
    /**
     * Gets an object that can be used to determine availability of terrain from this provider.
     */
    get availability(): TileAvailability | undefined;
    /**
     * Gets the list of terrain regions managed by this provider.
     */
    get regions(): readonly HybridTerrainProvider.TerrainRegion[];
    /**
     * Gets the default terrain provider.
     */
    get defaultProvider(): TerrainProvider;
    /**
     * @deprecated
     */
    get fallbackProvider(): TerrainProvider;
    /**
     * Gets all the credits to display from registered providers when
     * this terrain provider is active. Typically this is used to credit
     * the source of the terrain.
     */
    get credit(): Credit;
    /**
     * Gets an event that is raised when the terrain provider encounters an asynchronous error.  By subscribing
     * to the event, you will be notified of the error and can potentially recover from it.  Event listeners
     * are passed an instance of `TileProviderError`.
     */
    get errorEvent(): Event<TerrainProvider.ErrorEvent>;
    /**
     * Gets a value indicating whether or not the provider includes a water mask.  The water mask
     * indicates which areas of the globe are water rather than land, so they can be rendered
     * as a reflective surface with animated waves.
     */
    get hasWaterMask(): boolean;
    /** Gets a value indicating whether or not the requested tiles include vertex normals. */
    get hasVertexNormals(): boolean;
    /**
     * Makes sure we load availability data for a tile
     * @param x - The X coordinate of the tile for which to request geometry.
     * @param y - The Y coordinate of the tile for which to request geometry.
     * @param level - The level of the tile for which to request geometry.
     * @returns Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded
     */
    loadTileDataAvailability(x: number, y: number, level: number): Promise<void> | undefined;
    /**
     * Gets the maximum geometric error allowed in a tile at a given level, taken as the
     * worst case across the default provider and all region providers. Because the hybrid
     * provider's coverage is a composition of multiple sources, the reported error reflects
     * the highest error any source could contribute at this level, ensuring the LOD system
     * refines conservatively enough for all sources.
     * @param level - The tile level for which to get the maximum geometric error.
     * @returns The maximum geometric error across all providers.
     */
    getLevelMaximumGeometricError(level: number): number;
    /**
     * Requests the terrain for a given tile coordinate.
     * @param x The X coordinate of the tile.
     * @param y The Y coordinate of the tile.
     * @param level The zoom level of the tile.
     * @param request The request.
     * @returns A promise for the requested terrain.
     */
    requestTileGeometry(x: number, y: number, level: number, request?: Request): Promise<TerrainData> | undefined;
    /**
     * Determines whether data for a tile is available to be loaded. Checks the specified terrain regions first.
     * @param x - The X coordinate of the tile for which to request geometry.
     * @param y - The Y coordinate of the tile for which to request geometry.
     * @param level - The level of the tile for which to request geometry.
     * @returns Undefined if not supported by the terrain provider, otherwise true or false.
     */
    getTileDataAvailable(x: number, y: number, level: number): boolean | undefined;
    /**
     * Cleans up resources used in the `HybridTerrainProvider`.
     *
     * This method only releases additional resources used to instantiate the `HybridTerrainProvider`.
     */
    destroy(): void;
}
/**
 * @namespace
 * Contains types and factory methods for `HybridTerrainProvider` instance.
 */
declare namespace HybridTerrainProvider {
    /** Initialization options for `HybridTerrainProvider` constructor. */
    interface ConstructorOptions {
        /** An array of terrain regions to include in the hybrid terrain. */
        regions?: TerrainRegion[];
        /** Default provider to use outside of specified terrain regions. */
        defaultProvider: TerrainProvider;
        /**
         * Optional fallback provider when data is not available from default provider.
         *
         * @default EllipsoidTerrainProvider
         * @deprecated
         */
        fallbackProvider?: TerrainProvider;
    }
    /**
     * A factory function which creates a HybridTerrainProvider from tile-coordinate based regions.
     * @param regions Array of regions with tile-coordinate bounds
     * @param defaultProvider Default terrain provider
     * @param fallbackProvider Optional fallback provider
     */
    function fromTileRanges(regions: Array<{
        provider: TerrainProvider;
        tiles: Map<number, {
            x: number | [number, number];
            y: number | [number, number];
        }>;
        levels?: number[];
    }>, defaultProvider: TerrainProvider, fallbackProvider?: TerrainProvider): HybridTerrainProvider;
    /** Represents a terrain region with provider and geographic bounds. */
    interface TerrainRegion {
        /** The terrain provider for this region. */
        provider: TerrainProvider;
        /**
         * Tile-coordinate based bounds (precise control).
         * Map of level to tile coordinate ranges for that level.
         */
        tiles?: Map<number, {
            /** X tile coordinate range [min, max] or single value. */
            x: number | [number, number];
            /** Y tile coordinate range [min, max] or single value. */
            y: number | [number, number];
        }>;
        /** Optional level constraints. If specified, region only applies to these levels. */
        levels?: number[];
    }
    /**
     * Checks if a terrain region contains the specified tile.
     * @param region The terrain region to check
     * @param x The X coordinate of the tile
     * @param y The Y coordinate of the tile
     * @param level The zoom level of the tile
     * @returns True if the region contains the tile, false otherwise
     */
    function regionContainsTile(region: HybridTerrainProvider.TerrainRegion, x: number, y: number, level: number): boolean;
    /**
     * @namespace
     * Utility functions for working with TerrainRegion objects.
     *
     * @deprecated This will be removed in 0.5.0, due to the usage of nested namespace.
     */
    namespace TerrainRegion {
        /**
         * Checks if a terrain region contains the specified tile.
         *
         * @deprecated This will be removed in 0.5.0. Use {@link HybridTerrainProvider.regionContainsTile} instead.
         */
        function contains(region: HybridTerrainProvider.TerrainRegion, x: number, y: number, level: number): boolean;
    }
}

type TerrainTiles = NonNullable<HybridTerrainProvider.TerrainRegion["tiles"]>;
type TerrainRegion = HybridTerrainProvider.TerrainRegion;
type TerrainOptions = HybridTerrainProvider.ConstructorOptions;

/**
 * Copies configuration and state from one Cesium Viewer to another.
 * @param source - The source viewer to copy properties from
 * @param container - DOM element ID or element for the new viewer
 * @param options - Optional override options for the new viewer
 * @returns A new Viewer instance with copied properties
 */
declare function cloneViewer(source: Viewer, container: Element | string, options?: Viewer.ConstructorOptions): Viewer;

/**
 * Copies camera state from source viewer to destination viewer.
 * @param source The source viewer to copy camera states from.
 * @param dest The destination viewer to apply camera properties from the source.
 */
declare function syncCamera(source: Viewer, dest: Viewer): void;

/**
 * Utility for managing deprecation warnings in the cesium-utils library.
 * Provides runtime warnings to help developers identify deprecated API usage.
 */
declare namespace Deprecate {
    /**
     * Configuration options for deprecation warnings.
     */
    interface Options {
        /**
         * Whether to show the warning only once per deprecation message.
         * @default true
         */
        once?: boolean;
        /**
         * Custom prefix for the warning message.
         * @default "[DEPRECATED]"
         */
        prefix?: string;
        /**
         * Whether to include a stack trace in the warning.
         * @default true
         */
        includeStack?: boolean;
        /**
         * Version when the feature will be removed.
         */
        removeInVersion?: string;
    }
    /**
     * Displays a deprecation warning message.
     *
     * @param message - The deprecation message to display
     * @param options - Configuration options for the warning
     *
     * @example
     * ```typescript
     * // Basic usage
     * deprecationWarning("oldFunction() is deprecated. Use newFunction() instead.");
     *
     * // With removal version
     * deprecationWarning("TerrainArea is deprecated.", {
     *   removeInVersion: "v0.3.0"
     * });
     *
     * // Allow multiple warnings
     * deprecationWarning("Repeated warning", { once: false });
     * ```
     */
    function warn(message: string, options?: Options): void;
    /**
     * Creates a deprecation wrapper function that shows a warning when called.
     *
     * @param fn - The function to wrap
     * @param message - The deprecation message
     * @param options - Configuration options for the warning
     * @returns A wrapped function that shows a deprecation warning when called
     *
     * @example
     * ```typescript
     * const oldFunction = deprecate(
     *   () => console.log("old implementation"),
     *   "oldFunction() is deprecated. Use newFunction() instead."
     * );
     *
     * oldFunction(); // Shows warning and executes function
     * ```
     */
    function deprecate<T extends (...args: any[]) => any>(fn: T, message: string, options?: Options): T;
    /**
     * Clears all shown warning messages.
     * Useful for testing or when you want to reset the warning state.
     *
     * @example
     * ```typescript
     * clearDeprecationWarnings();
     * deprecationWarning("This will show again");
     * ```
     */
    function clear(): void;
    /**
     * Gets the count of unique deprecation warnings that have been shown.
     *
     * @returns The number of unique deprecation warnings shown
     */
    function getWarningCount(): number;
    /**
     * Checks if a specific deprecation warning has been shown.
     *
     * @param message - The deprecation message to check
     * @returns True if the warning has been shown, false otherwise
     */
    function hasShown(message: string): boolean;
}

declare const deprecate: typeof Deprecate.deprecate;

/**
 * @since Cesium 1.132.0
 * @experimental
 * Point sunlight analysis utility for shadow calculations.
 *
 * ⚠️ **Warning**: This is an experimental feature that uses Cesium's internal APIs.
 * The API may change or break in future versions of Cesium or cesium-utils.
 *
 * @example
 * ```typescript
 * const sunlight = new Sunlight(viewer);
 * sunlight.analyze(point, JulianDate.now());
 * ```
 */
declare class Sunlight {
    private _uniformState;
    private _viewer;
    private _analyzing;
    private _pointEntityId?;
    private _objectsToExclude;
    private _polylines;
    private _points;
    constructor(viewer: Viewer);
    /** The sun position in 3D world coordinates at the current scene time. */
    get sunPositionWC(): Cartesian3;
    /** A normalized vector to the sun in 3D world coordinates at the current scene time. */
    get sunDirectionWC(): Cartesian3;
    /** Whether sunlight analysis is currently in progress. */
    get isAnalyzing(): boolean;
    /**
     * Gets virtual position and direction of the sun to reduce calculation overhead.
     *
     * @param from target point to start from
     * @param radius virtual distance between target point and the sun. Defaults to 10000 (10km)
     */
    virtualSun(from: Cartesian3, radius?: number): {
        position: Cartesian3;
        direction: Cartesian3;
    };
    /**
     * Analyze the sunlight acceptance from a given point at a given time.
     * @param from target point to analyze
     * @param at time to analyze
     * @param options {@link Sunlight.AnalyzeOptions}
     */
    analyze(from: Cartesian3, at: JulianDate, options?: Sunlight.AnalyzeOptions): Promise<Sunlight.AnalysisResult>;
    /**
     * Analyze the sunlight acceptance from a given point at a given time range.
     * @param from target point to analyze
     * @param range time range to analyze
     * @param options {@link Sunlight.AnalyzeOptions}
     */
    analyze(from: Cartesian3, range: Sunlight.TimeRange, options?: Sunlight.AnalyzeOptions): Promise<Sunlight.AnalysisResult[]>;
    /**
     * Remove all instances created for debug purpose
     */
    clear(): void;
    /**
     * Create an ellipsoid entity for ray collision detection to complement cesium's native click event accuracy
     * @param at where to create the entity
     * @param show whether to show point entity
     * @param errorBoundary size of the point entity for error tolerance
     */
    setTargetPoint(at: Cartesian3, show?: boolean, errorBoundary?: number, color?: Color): Entity;
    private _analyzeSingleTime;
    private _analyzeTimeRange;
    /**
     * @returns A promise tht resolves to an object containing the object and position of the first intersection.
     * @see https://github.com/CesiumGS/cesium/blob/1.136/packages/engine/Source/Scene/Scene.js#L4868
     */
    private _pick;
    private _getExcludedObjects;
}
declare namespace Sunlight {
    const DETECTION_ELLIPSOID_ID = "sunlight-detection-ellipsoid";
    /** for time-range analysis */
    interface TimeRange {
        /** When to start analysis */
        start: JulianDate;
        /** When to end analysis */
        end: JulianDate;
        /** Step interval (seconds) inside the range */
        step: number;
    }
    interface AnalyzeOptions {
        /** List of objects to exclude from ray pick */
        objectsToExclude?: any[];
        /** size of the point entity for error tolerance */
        errorBoundary?: number;
        /** Whether to show sunlight paths */
        debugShowRays?: boolean;
        /** Whether to show points */
        debugShowPoints?: boolean;
    }
    interface AnalysisResult {
        /** ISO time string */
        timestamp: string;
        /** Whether the sunlight has reached */
        result: boolean | any;
    }
}

/**
 * @class
 * Utility class for visualizing terrain provider boundaries and debugging terrain loading.
 */
declare class TerrainVisualizer {
    private _viewer;
    private _terrainProvider;
    private _visible;
    private _tileCoordinatesLayer;
    private _hybridImageryLayer;
    private _colors;
    /**
     * Creates a new `TerrainVisualizer`.
     * @param viewer The Cesium viewer instance
     * @param options {@link TerrainVisualizer.ConstructorOptions}
     */
    constructor(viewer: Viewer, options: TerrainVisualizer.ConstructorOptions);
    /**
     * Sets the terrain provider to visualize.
     * @param terrainProvider The terrain provider to visualize.
     */
    setTerrainProvider(terrainProvider: HybridTerrainProvider): void;
    /**
     * Updates all active visualizations.
     */
    update(): void;
    /**
     * Clears all visualizations.
     */
    clear(): void;
    /**
     * Shows terrain visualization using HybridImageryProvider.
     * Optionally adds tile coordinate grid overlay.
     * @param options Visualization options
     */
    show(options?: {
        /** Show tile coordinate labels. Default: true */
        showTileCoordinates?: boolean;
        /** Transparency level (0-1). Default: 0.5 */
        alpha?: number;
    }): void;
    private _ensureTileCoordinatesLayer;
    /**
     * Hides the terrain visualization.
     */
    hide(): void;
    /**
     * Sets the colors used for visualization.
     * @param colors Map of role names to colors
     */
    setColors(colors: Record<string, Color>): void;
    /**
     * Shows terrain regions using HybridImageryProvider (performant, global coverage).
     * This replaces the entity-based approach with an imagery layer.
     * @param alpha Transparency level (0-1), default 0.5
     */
    showImageryOverlay(alpha?: number): void;
    /**
     * Hides the imagery overlay.
     */
    hideImageryOverlay(): void;
    /**
     * Shows tile coordinate grid overlay.
     */
    showTileCoordinates(): void;
    /**
     * Hides tile coordinate grid overlay.
     */
    hideTileCoordinates(): void;
    /**
     * Sets the transparency of the imagery overlay.
     * @param alpha Transparency level (0-1), where 0 is fully transparent and 1 is fully opaque
     */
    setAlpha(alpha: number): void;
    /**
     * Flies the camera to focus on a rectangle.
     * @param rectangle The rectangle to focus on.
     * @param options {@link Viewer.flyTo}
     */
    flyTo(rectangle: Rectangle, options?: {
        duration?: number;
    }): void;
    /** Whether tile coordinates are currently visible. */
    get tileCoordinatesVisible(): boolean;
    /** Whether the grid is currently visible. */
    get visible(): boolean;
    /** The viewer used in the visualizer */
    get viewer(): Viewer;
    /** The colors used in the visualizer */
    get colors(): Map<string, Color>;
    /** The hybrid terrain instance used in the visualizer */
    get terrainProvider(): HybridTerrainProvider;
}
/**
 * @namespace
 * Contains types, utility functions, and constants for terrain visualization.
 */
declare namespace TerrainVisualizer {
    /** Initialization options for `TerrainVisualizer` constructor. */
    interface ConstructorOptions {
        /** Colors to use for different visualization elements */
        colors?: Record<string, Color>;
        /** Whether to show tile grid initially. */
        tile?: boolean;
        /** Initial zoom level to use for visualizations. */
        activeLevel?: number;
        /** Terrain provider to visualize. */
        terrainProvider: HybridTerrainProvider;
    }
    /** Options for {@link TerrainVisualizer.visualize} */
    interface Options {
        color?: Color;
        show?: boolean;
        maxTilesToShow?: number;
        levels?: number[];
        tag?: string;
        alpha?: number;
        tileAlpha?: number;
    }
}

export { Collection, Deprecate, Highlight, HybridTerrainProvider, SilhouetteHighlight, Sunlight, SurfaceHighlight, type TerrainOptions, TerrainRegion, type TerrainTiles, TerrainVisualizer, cloneViewer, deprecate, syncCamera };
