/**
 * Tilemap plugin for ECSpresso.
 *
 * Two ingestion paths share a common `LoadedTilemap` shape:
 * - `registerAsset` — load a Tiled `.tmj` file via the asset manager
 * - `registerRuntime` — pass a pre-built tile-id array (procedural)
 *
 * Query methods (`isSolid`, `isOpaque`, `isWalkable`) read from `tileMetadata`
 * regardless of source.
 */
import { type BasePluginOptions } from 'ecspresso';
import type { ComponentsConfig, ResourcesConfig } from '../../type-utils';
import { type NavGrid } from '../ai/pathfinding';
import type { Vector2D } from '../../utils/math';
export declare const TILE_FLIP_HORIZONTAL = 2147483648;
export declare const TILE_FLIP_VERTICAL = 1073741824;
export declare const TILE_FLIP_DIAGONAL = 536870912;
export declare const TILE_GID_MASK = 536870911;
export interface DecodedGid {
    id: number;
    flipH: boolean;
    flipV: boolean;
    flipD: boolean;
}
export declare function decodeGid(gid: number): DecodedGid;
/** The three tile flag keys the query API understands. Custom keys flow through unchanged. */
export type TileFlag = 'solid' | 'blocksSight' | 'walkable';
/** Tile metadata. Known flag keys drive query methods; arbitrary custom keys are preserved. */
export interface TileMetadata {
    solid?: boolean;
    blocksSight?: boolean;
    walkable?: boolean;
    [key: string]: unknown;
}
export interface ObjectDef {
    name: string;
    type: string;
    x: number;
    y: number;
    width: number;
    height: number;
    rotation: number;
    properties: Record<string, string | number | boolean>;
}
export interface RuntimeTileset {
    textureKey: string;
    columns: number;
    tileWidth: number;
    tileHeight: number;
    firstgid?: number;
}
export interface RuntimeLayer {
    name: string;
    tiles: Uint32Array | Uint8Array | readonly number[];
    parallax?: Vector2D;
    opacity?: number;
    visible?: boolean;
}
export interface TilemapRuntimeData {
    width: number;
    height: number;
    tileSize: number;
    layers: readonly RuntimeLayer[];
    tilesets: readonly RuntimeTileset[];
    tileMetadata?: Record<number, TileMetadata>;
    objectLayers?: readonly {
        name: string;
        objects: readonly ObjectDef[];
    }[];
}
export interface LoadedLayer {
    name: string;
    tiles: Uint32Array;
    parallax: Vector2D;
    opacity: number;
    visible: boolean;
}
export interface LoadedTileset {
    textureKey: string;
    columns: number;
    tileWidth: number;
    tileHeight: number;
    firstgid: number;
}
export interface LoadedObjectLayer {
    name: string;
    objects: readonly ObjectDef[];
}
export interface LoadedTilemap {
    readonly width: number;
    readonly height: number;
    readonly tileWidth: number;
    readonly tileHeight: number;
    readonly layers: readonly LoadedLayer[];
    readonly tilesets: readonly LoadedTileset[];
    readonly tileMetadata: ReadonlyMap<number, TileMetadata>;
    readonly objectLayers: readonly LoadedObjectLayer[];
    tileToWorld(tx: number, ty: number): Vector2D;
    worldToTile(wx: number, wy: number): {
        tx: number;
        ty: number;
    };
    getTile(layerIndex: number, tx: number, ty: number): number;
    isSolid(tx: number, ty: number): boolean;
    isOpaque(tx: number, ty: number): boolean;
    isWalkable(tx: number, ty: number): boolean;
    buildNavGrid(layerIndex: number, costFn?: (tileId: number) => number): NavGrid;
    getObjectLayer(name: string): readonly ObjectDef[];
    getObjects(type: string): readonly ObjectDef[];
}
/** Subset of a Tiled `.tmj` (JSON) document we consume in v1. */
export interface TiledMap {
    width: number;
    height: number;
    tilewidth: number;
    tileheight: number;
    tilesets: readonly TiledTileset[];
    layers: readonly TiledLayer[];
}
export interface TiledTileset {
    firstgid: number;
    columns: number;
    tilewidth: number;
    tileheight: number;
    image: string;
    imagewidth: number;
    imageheight: number;
    tiles?: readonly TiledTileDef[];
}
export interface TiledTileDef {
    id: number;
    properties?: readonly TiledProperty[];
    animation?: readonly {
        tileid: number;
        duration: number;
    }[];
}
export interface TiledProperty {
    name: string;
    type: 'bool' | 'int' | 'float' | 'string' | 'color' | 'file' | 'object';
    value: string | number | boolean;
}
export type TiledLayer = TiledTileLayer | TiledObjectLayer;
export interface TiledTileLayer {
    type: 'tilelayer';
    name: string;
    width: number;
    height: number;
    data: readonly number[];
    opacity: number;
    visible: boolean;
    parallaxx?: number;
    parallaxy?: number;
}
export interface TiledObjectLayer {
    type: 'objectgroup';
    name: string;
    objects: readonly TiledObject[];
}
export interface TiledObject {
    id: number;
    name?: string;
    type?: string;
    x: number;
    y: number;
    width?: number;
    height?: number;
    rotation?: number;
    properties?: readonly TiledProperty[];
}
export interface ParseTiledOptions {
    tilesetTextures: Record<string, string>;
}
export type TilemapCullingMode = 'viewport' | 'none';
export interface TilemapLayerComponent {
    dataKey: string;
    tilesetKey?: string;
    layerIndex: number;
    opacity: number;
    parallax: Vector2D;
    cullingMode: TilemapCullingMode;
    cameraRef?: number;
    tintFn?: (tx: number, ty: number) => number | null;
}
export interface TilemapColliderTag {
    dataKey: string;
}
export interface TilemapComponentTypes {
    tilemap: TilemapLayerComponent;
    tilemapCollider: TilemapColliderTag;
}
export interface TilemapRegistry {
    registerRuntime(dataKey: string, data: TilemapRuntimeData): LoadedTilemap;
    registerAsset(dataKey: string, assetKey: string, options?: ParseTiledOptions): Promise<LoadedTilemap>;
    get(dataKey: string): LoadedTilemap | undefined;
    has(dataKey: string): boolean;
    readonly entries: ReadonlyMap<string, LoadedTilemap>;
}
export interface TilemapResourceTypes {
    tilemaps: TilemapRegistry;
}
export type TilemapWorldConfig = ComponentsConfig<TilemapComponentTypes> & ResourcesConfig<TilemapResourceTypes>;
export interface TilemapPluginOptions<G extends string = 'rendering'> extends BasePluginOptions<G> {
    /** Optional collision layer name. When set, solid tiles auto-spawn `aabbCollider` strips. */
    collisionLayer?: string;
    /** Layers the auto-generated tile bodies collide with. */
    collidesWith?: readonly string[];
}
export declare function createLoadedTilemap(data: TilemapRuntimeData): LoadedTilemap;
export declare function parseTiledJSON(map: TiledMap, options: ParseTiledOptions): LoadedTilemap;
export declare function createTilemapPlugin<G extends string = 'rendering'>(options?: TilemapPluginOptions<G>): import("ecspresso").Plugin<import("ecspresso").WithResources<import("ecspresso").WithComponents<import("ecspresso").EmptyConfig, TilemapComponentTypes>, TilemapResourceTypes>, import("ecspresso").EmptyConfig, never, G, never, never>;
/**
 * Create a `tilemap` layer component for spreading into `spawn()`.
 *
 * @example
 * ```typescript
 * ecs.spawn({
 *   ...createTilemapLayer('dungeon', 0),
 *   ...createLocalTransform(0, 0),
 * });
 * ```
 */
export declare function createTilemapLayer(dataKey: string, layerIndex: number, options?: {
    tilesetKey?: string;
    opacity?: number;
    parallax?: Vector2D;
    cullingMode?: TilemapCullingMode;
    cameraRef?: number;
    tintFn?: (tx: number, ty: number) => number | null;
}): Pick<TilemapComponentTypes, 'tilemap'>;
