import { IApplication, IPlugin, Plugin } from 'dill-pixel';
import { Container as PIXIContainer } from 'pixi.js';
import { Actor } from './Actor';
import { Group } from './Group';
import { AABBLike, CrunchPhysicsOptions } from './interfaces';
import { Sensor } from './Sensor';
import { Solid } from './Solid';
import { System } from './System';
import { ActorCollision, Collision, PhysicsEntityConfig, RegisteredCollisionLayer } from './types';
/**
 * Interface for the Crunch physics plugin, providing a simple yet powerful 2D physics system
 * inspired by Towerfall's physics mechanics. Supports dynamic actors, static solids, and trigger sensors.
 *
 * @example
 * ```typescript
 * // Initialize the physics system
 * const physics = this.app.getPlugin('crunch-physics') as ICrunchPhysicsPlugin;
 *
 * const physics = await this.physics.initialize({
 *   gravity: 900,
 *   debug: true,
 *   gridSize: 32
 * });
 *
 * // Create a player character
 * const playerSprite = this.add.sprite({asset:Texture.WHITE, width: 32, height: 64});
 *
 * const player = physics.createActor({
 *   type: 'Player',
 *   position: [100, 100],
 *   size: [32, 64],
 *   view: playerSprite
 * });
 *
 * // Create a platform
 * const platformSprite = this.add.sprite({asset:Texture.WHITE, width: 800, height: 32, tint: 0x00FF00});
 * const platform = physics.createSolid({
 *   type: 'Platform',
 *   position: [0, 500],
 *   size: [800, 32],
 *   view: platformSprite
 * });
 *
 * // Create a coin pickup sensor
 * const coinSprite = this.add.sprite({asset:Texture.WHITE, width: 32, height: 32, tint: 0x00FF00});
 * const coin = physics.createSensor({
 *   type: 'Coin',
 *   position: [400, 400],
 *   size: [32, 32],
 *   view: coinSprite
 * });
 * ```
 */
export interface ICrunchPhysicsPlugin extends IPlugin<CrunchPhysicsOptions> {
    system: System;
    container: PIXIContainer;
    enabled: boolean;
    /**
     * Initializes the physics system with the specified options.
     */
    initialize(options?: Partial<CrunchPhysicsOptions>, app?: IApplication): Promise<void>;
    /**
     * Sets a custom collision resolver function that will be called when collisions occur.
     *
     * @param resolver - Function to handle collisions
     *
     * @example
     * ```typescript
     * physics.setCollisionResolver((collisions) => {
     *   collisions.forEach(collision => {
     *     if (collision.actor.type === 'Player' && collision.solid.type === 'Spike') {
     *       player.damage(10);
     *     }
     *   });
     * });
     * ```
     */
    setCollisionResolver(resolver: (collisions: Collision[]) => void): void;
    /**
     * Sets a custom resolver for actor-to-actor collisions.
     *
     * @param resolver - Function to handle actor-to-actor collisions
     *
     * @example
     * ```typescript
     * physics.setActorCollisionResolver((collisions) => {
     *   collisions.forEach(collision => {
     *     if (collision.actor1.type === 'Player' && collision.actor2.type === 'Enemy') {
     *       player.takeDamage(10);
     *     }
     *   });
     * });
     * ```
     */
    setActorCollisionResolver(resolver: (collisions: ActorCollision[]) => void): void;
    /**
     * Enables or disables actor-to-actor collision detection.
     *
     * @param enabled - Whether to enable actor-to-actor collisions
     *
     * @example
     * ```typescript
     * // Enable actor-to-actor collisions
     * physics.setActorCollisionsEnabled(true);
     *
     * // Disable actor-to-actor collisions for performance
     * physics.setActorCollisionsEnabled(false);
     * ```
     */
    setActorCollisionsEnabled(enabled: boolean): void;
    /**
     * Creates a generic physics entity based on the provided configuration.
     * Use this when you need to create an entity without knowing its specific type at compile time.
     *
     * @param config - Configuration for the physics entity
     * @returns The created physics entity
     *
     * @example
     * ```typescript
     * const entityConfig = {
     *   type: 'Platform',
     *   position: [100, 100],
     *   size: [200, 32],
     *   view: sprite
     * };
     * const entity = physics.createEntity(entityConfig);
     * ```
     */
    createEntity(config: PhysicsEntityConfig): Actor | Solid | Sensor | Group;
    /**
     * Adds an existing physics entity to the system.
     * Useful when you want to manage entity creation yourself.
     *
     * @param entity - The physics entity to add
     * @returns The added entity
     *
     * @example
     * ```typescript
     * class CustomActor extends Actor {
     *   constructor() {
     *     super({ type: 'Custom', position: [0, 0], size: [32, 32] });
     *   }
     * }
     *
     * const customActor = new CustomActor();
     * physics.addEntity(customActor);
     * ```
     */
    addEntity(entity: Actor | Solid | Sensor | Group): Actor | Solid | Sensor | Group;
    /**
     * Creates a dynamic physics actor that can move and collide with other entities.
     * Actors are typically used for players, enemies, or any moving game objects.
     *
     * @param config - Configuration for the actor
     * @returns The created actor
     *
     * @example
     * ```typescript
     * // Create a player character
     * const player = physics.createActor({
     *   type: 'Player',
     *   position: [100, 100],
     *   size: [32, 64],
     *   view: playerSprite
     * });
     *
     * // Update player in game loop
     * player.velocity.x = 300; // Move right
     * player.velocity.y = -600; // Jump
     * ```
     */
    createActor(config: PhysicsEntityConfig): Actor;
    /**
     * Creates a static solid object that other entities can collide with.
     * Solids are typically used for platforms, walls, and other immovable objects.
     *
     * @param config - Configuration for the solid
     * @returns The created solid
     *
     * @example
     * ```typescript
     * // Create a static platform
     * const platform = physics.createSolid({
     *   type: 'Platform',
     *   position: [0, 500],
     *   size: [800, 32],
     *   view: platformSprite
     * });
     *
     * // Create a moving platform
     * const movingPlatform = physics.createSolid({
     *   type: 'Platform',
     *   position: [100, 300],
     *   size: [200, 32],
     *   view: platformSprite
     * });
     *
     * // Update platform position
     * gsap.to(movingPlatform, {
     *   x: 500,
     *   duration: 2,
     *   yoyo: true,
     *   repeat: -1
     * });
     * ```
     */
    createSolid(config: PhysicsEntityConfig): Solid;
    /**
     * Creates a sensor zone that can detect overlaps with other entities.
     * Sensors are typically used for triggers, collectibles, or detection zones.
     *
     * @param config - Configuration for the sensor
     * @returns The created sensor
     *
     * @example
     * ```typescript
     * // Create a coin pickup
     * const coin = physics.createSensor({
     *   type: 'Coin',
     *   position: [400, 300],
     *   size: [32, 32],
     *   view: coinSprite
     * });
     *
     * // Handle coin collection
     * coin.onActorEnter = (actor) => {
     *   if (actor.type === 'Player') {
     *     increaseScore(10);
     *     physics.removeSensor(coin);
     *   }
     * };
     * ```
     */
    createSensor(config: PhysicsEntityConfig): Sensor;
    createGroup(config: PhysicsEntityConfig): Group;
    addActor(actor: Actor): Actor;
    addSolid(solid: Solid): Solid;
    addSensor(sensor: Sensor): Sensor;
    addGroup(group: Group): Group;
    /**
     * Removes an actor from the physics system.
     *
     * @param actor - The actor to remove
     *
     * @example
     * ```typescript
     * // Remove player when they die
     * function killPlayer(player: Actor) {
     *   playDeathAnimation();
     *   physics.removeActor(player);
     * }
     * ```
     */
    removeActor(actor: Actor): void;
    /**
     * Removes a solid from the physics system.
     *
     * @param solid - The solid to remove
     *
     * @example
     * ```typescript
     * // Remove a platform when it's destroyed
     * function destroyPlatform(platform: Solid) {
     *   playBreakAnimation();
     *   physics.removeSolid(platform);
     * }
     * ```
     */
    removeSolid(solid: Solid): void;
    /**
     * Removes a sensor from the physics system.
     *
     * @param sensor - The sensor to remove
     *
     * @example
     * ```typescript
     * // Remove a coin when it's collected
     * function collectCoin(coin: Sensor) {
     *   playCollectSound();
     *   physics.removeSensor(coin);
     * }
     * ```
     */
    removeSensor(sensor: Sensor): void;
    /**
     * Cleans up the physics system and removes all entities.
     * Call this when transitioning between scenes or shutting down the game.
     *
     * @example
     * ```typescript
     * class GameScene extends Scene {
     *   destroy() {
     *     this.physics.destroy();
     *     super.destroy();
     *   }
     * }
     * ```
     */
    destroy(): void;
    /**
     * Creates a custom collision layer.
     *
     * @param index Index from 0-15 representing which user bit to use (gets shifted to bits 16-31)
     * @returns A unique collision layer value
     *
     * @example
     * ```typescript
     * // Create custom collision layers
     * const WATER_LAYER = physics.createCollisionLayer(0);
     * const LAVA_LAYER = physics.createCollisionLayer(1);
     *
     * // Use in entity creation
     * const waterEntity = physics.createActor({
     *   type: 'Water',
     *   position: [100, 400],
     *   size: [800, 100],
     *   collisionLayer: WATER_LAYER,
     *   collisionMask: CollisionLayer.PLAYER | CollisionLayer.ENEMY
     * });
     * ```
     */
    createCollisionLayer(index: number): number;
    /**
     * Creates a collision mask from multiple layers.
     *
     * @param layers Array of collision layers to combine
     * @returns A combined collision mask
     *
     * @example
     * ```typescript
     * // Create a mask that collides with players, enemies and projectiles
     * const mask = physics.createCollisionMask([
     *   CollisionLayer.PLAYER,
     *   CollisionLayer.ENEMY,
     *   CollisionLayer.PROJECTILE
     * ]);
     * ```
     */
    createCollisionMask(...layers: number[]): number;
    /**
     * Registers a named collision layer for better intellisense support.
     *
     * @param name Name of the collision layer (used for intellisense)
     * @param indexOrDescription Index or description of the layer
     * @param description Optional description of the layer
     * @returns The numeric value of the registered collision layer
     *
     * @example
     * ```typescript
     * // Register named collision layers
     * const WATER = physics.registerCollisionLayer('WATER', 0, 'Water surfaces');
     * const LAVA = physics.registerCollisionLayer('LAVA', 1, 'Lava surfaces that damage players');
     *
     * // Use in entity creation
     * const waterEntity = physics.createActor({
     *   type: 'Water',
     *   position: [100, 400],
     *   size: [800, 100],
     *   collisionLayer: WATER,
     *   collisionMask: CollisionLayer.PLAYER | CollisionLayer.ENEMY
     * });
     * ```
     */
    registerCollisionLayer(name: string, indexOrDescription?: number | string, description?: string): number;
    /**
     * Gets a registered collision layer by name.
     *
     * @param name Name of the collision layer
     * @returns The numeric value of the registered collision layer or undefined if not found
     *
     * @example
     * ```typescript
     * // Get a registered collision layer
     * const waterLayer = physics.getCollisionLayer('WATER');
     * if (waterLayer !== undefined) {
     *   // Use the layer
     *   entity.setCollisionLayer(waterLayer);
     * }
     * ```
     */
    getCollisionLayer(name: string): number | undefined;
    /**
     * Gets all registered collision layers.
     *
     * @returns Array of all registered collision layers
     *
     * @example
     * ```typescript
     * // Get all registered collision layers
     * const layers = physics.getCollisionLayers();
     * console.log(`Registered layers: ${layers.map(l => l.name).join(', ')}`);
     * ```
     */
    getCollisionLayers(): RegisteredCollisionLayer[];
    /**
     * Removes a registered collision layer.
     *
     * @param name Name of the collision layer to remove
     * @returns True if the layer was removed, false if it didn't exist
     *
     * @example
     * ```typescript
     * // Remove a registered collision layer
     * physics.removeCollisionLayer('WATER');
     * ```
     */
    removeCollisionLayer(name: string): boolean;
    /**
     * Clears all registered collision layers.
     *
     * @example
     * ```typescript
     * // Clear all registered collision layers
     * physics.clearCollisionLayers();
     * ```
     */
    clearCollisionLayers(): void;
}
/**
 * Implementation of the Crunch physics plugin.
 * See {@link ICrunchPhysicsPlugin} for detailed API documentation and examples.
 */
export default class CrunchPhysicsPlugin extends Plugin<CrunchPhysicsOptions> implements ICrunchPhysicsPlugin {
    system: System;
    container: PIXIContainer;
    enabled: boolean;
    private collisionResolver?;
    private overlapResolver?;
    private actorCollisionResolver?;
    constructor();
    private hello;
    initialize(options?: Partial<CrunchPhysicsOptions>, _app: IApplication): Promise<void>;
    setCollisionResolver(resolver: (collisions: Collision[]) => void): void;
    setActorCollisionResolver(resolver: (collisions: ActorCollision[]) => void): void;
    setActorCollisionsEnabled(enabled: boolean): void;
    createEntity(config: PhysicsEntityConfig): Actor | Solid | Sensor | Group;
    addEntity(entity: Actor | Solid | Sensor | Group): Actor | Solid | Sensor | Group;
    createActor(config: PhysicsEntityConfig): Actor;
    createSolid(config: PhysicsEntityConfig): Solid;
    createSensor(config: PhysicsEntityConfig): Sensor;
    createGroup(config: PhysicsEntityConfig): Group;
    addActor(actor: Actor): Actor;
    addSolid(solid: Solid): Solid;
    addSensor(sensor: Sensor): Sensor;
    addGroup(group: Group): Group;
    removeActor(actor: Actor): void;
    removeSolid(solid: Solid): void;
    removeSensor(sensor: Sensor): void;
    removeGroup(group: Group): void;
    destroy(): void;
    private update;
    /**
     * Creates a custom collision layer.
     *
     * @param index Index from 0-15 representing which user bit to use (gets shifted to bits 16-31)
     * @returns A unique collision layer value
     */
    createCollisionLayer(index: number): number;
    /**
     * Creates a collision mask from multiple layers.
     *
     * @param layers Array of collision layers to combine
     * @returns A combined collision mask
     */
    createCollisionMask(...layers: number[]): number;
    /**
     * Registers a named collision layer for better intellisense support.
     *
     * @param name Name of the collision layer (used for intellisense)
     * @param indexOrDescription Index or description of the layer
     * @param description Optional description of the layer
     * @returns The numeric value of the registered collision layer
     */
    registerCollisionLayer(name: string, indexOrDescription?: number | string, description?: string): number;
    /**
     * Gets a registered collision layer by name.
     *
     * @param name Name of the collision layer
     * @returns The numeric value of the registered collision layer or undefined if not found
     */
    getCollisionLayer(name: string): number | undefined;
    /**
     * Gets all registered collision layers.
     *
     * @returns Array of all registered collision layers
     */
    getCollisionLayers(): RegisteredCollisionLayer[];
    /**
     * Removes a registered collision layer.
     *
     * @param name Name of the collision layer to remove
     * @returns True if the layer was removed, false if it didn't exist
     */
    removeCollisionLayer(name: string): boolean;
    /**
     * Clears all registered collision layers.
     */
    clearCollisionLayers(): void;
    /**
     * Checks if two AABB rectangles overlap.
     *
     * @param a - The first AABB rectangle
     * @param b - The second AABB rectangle
     * @returns True if the rectangles overlap, false otherwise
     */
    aabbOverlap(a: AABBLike, b: AABBLike): boolean;
}
//# sourceMappingURL=CrunchPhysicsPlugin.d.ts.map