import { Engine } from '../Engine';
import { DefaultLoader, LoaderConstructor } from './DefaultLoader';
import { Scene, SceneConstructor } from '../Scene';
import { Transition } from './Transition';
import { EventEmitter } from '../EventEmitter';
export interface DirectorNavigationEvent {
    sourceName: string;
    sourceScene: Scene;
    destinationName: string;
    destinationScene: Scene;
}
export type DirectorEvents = {
    navigationstart: DirectorNavigationEvent;
    navigation: DirectorNavigationEvent;
    navigationend: DirectorNavigationEvent;
};
export declare const DirectorEvents: {
    NavigationStart: string;
    Navigation: string;
    NavigationEnd: string;
};
export interface SceneWithOptions {
    /**
     * Scene associated with this route
     *
     * If a constructor is provided it will not be constructed until navigation is requested
     */
    scene: Scene | SceneConstructor;
    /**
     * Specify scene transitions
     */
    transitions?: {
        /**
         * Optionally specify a transition when going "in" to this scene
         */
        in?: Transition;
        /**
         * Optionally specify a transition when going "out" of this scene
         */
        out?: Transition;
    };
    /**
     * Optionally specify a loader for the scene
     */
    loader?: DefaultLoader | LoaderConstructor;
}
export type WithRoot<TScenes> = TScenes | 'root';
export type SceneMap<TKnownScenes extends string = any> = Record<TKnownScenes, Scene | SceneConstructor | SceneWithOptions>;
export interface StartOptions {
    /**
     * Optionally provide first transition from the game start screen
     */
    inTransition?: Transition;
    /**
     * Optionally provide a main loader to run before the game starts
     */
    loader?: DefaultLoader | LoaderConstructor;
}
/**
 * Provide scene activation data and override any existing configured route transitions or loaders
 */
export interface GoToOptions<TActivationData = any> {
    /**
     * Optionally supply scene activation data passed to Scene.onActivate
     */
    sceneActivationData?: TActivationData;
    /**
     * Optionally supply destination scene "in" transition, this will override any previously defined transition
     */
    destinationIn?: Transition;
    /**
     * Optionally supply source scene "out" transition, this will override any previously defined transition
     */
    sourceOut?: Transition;
    /**
     * Optionally supply a different loader for the destination scene, this will override any previously defined loader
     */
    loader?: DefaultLoader;
}
/**
 * The Director is responsible for managing scenes and changing scenes in Excalibur.
 *
 * It deals with transitions, scene loaders, switching scenes
 *
 * This is used internally by Excalibur, generally not mean to
 * be instantiated end users directly.
 */
export declare class Director<TKnownScenes extends string = any> {
    private _engine;
    events: EventEmitter<DirectorEvents>;
    private _logger;
    private _deferredGoto?;
    private _deferredTransition?;
    private _initialized;
    /**
     * Current scene's name
     */
    currentSceneName: string;
    /**
     * Current scene playing in excalibur
     */
    currentScene: Scene;
    /**
     * Current transition if any
     */
    currentTransition?: Transition;
    /**
     * All registered scenes in Excalibur
     */
    readonly scenes: SceneMap<WithRoot<TKnownScenes>>;
    /**
     * Holds all instantiated scenes
     */
    private _sceneToInstance;
    startScene?: string;
    mainLoader?: DefaultLoader;
    /**
     * The default {@apilink Scene} of the game, use {@apilink Engine.goToScene} to transition to different scenes.
     */
    readonly rootScene: Scene;
    private _sceneToLoader;
    private _sceneToTransition;
    /**
     * Used to keep track of scenes that have already been loaded so we don't load multiple times
     */
    private _loadedScenes;
    private _isTransitioning;
    /**
     * Gets whether the director currently transitioning between scenes
     *
     * Useful if you need to block behavior during transition
     */
    get isTransitioning(): boolean;
    constructor(_engine: Engine, scenes: SceneMap<TKnownScenes>);
    /**
     * Initialize the director's internal state
     */
    onInitialize(): Promise<void>;
    get isInitialized(): boolean;
    /**
     * Configures the start scene, and optionally the transition & loader for the director
     *
     * Typically this is called at the beginning of the game to the start scene and transition and never again.
     * @param startScene
     * @param options
     */
    configureStart(startScene: WithRoot<TKnownScenes>, options?: StartOptions): void;
    private _getLoader;
    private _getInTransition;
    private _getOutTransition;
    getDeferredScene(): Scene<unknown> | SceneConstructor;
    /**
     * Returns a scene by name if it exists, might be the constructor and not the instance of a scene
     * @param name
     */
    getSceneDefinition(name?: string): Scene | SceneConstructor | undefined;
    /**
     * Returns the name of the registered scene, null if none can be found
     * @param scene
     */
    getSceneName(scene: Scene): string | null;
    /**
     * Returns the same Director, but asserts a scene DOES exist to the type system
     * @param name
     */
    assertAdded<TScene extends string>(name: TScene): Director<TKnownScenes | TScene>;
    /**
     * Returns the same Director, but asserts a scene DOES NOT exist to the type system
     * @param name
     */
    assertRemoved<TScene extends string>(name: TScene): Director<Exclude<TKnownScenes, TScene>>;
    /**
     * Adds additional Scenes to the game!
     * @param name
     * @param sceneOrRoute
     */
    add<TScene extends string>(name: TScene, sceneOrRoute: Scene | SceneConstructor | SceneWithOptions): Director<TKnownScenes | TScene>;
    remove(scene: Scene): void;
    remove(sceneCtor: SceneConstructor): void;
    remove(name: WithRoot<TKnownScenes>): void;
    /**
     * Go to a specific scene, and optionally override loaders and transitions
     * @param destinationScene
     * @param options
     */
    goToScene(destinationScene: TKnownScenes | string, options?: GoToOptions): Promise<void>;
    /**
     * Retrieves a scene instance by key if it's registered.
     *
     * This will call any constructors that were given as a definition
     * @param scene
     */
    getSceneInstance(scene: string): Scene | undefined;
    /**
     * Triggers scene loading if has not already been loaded
     * @param scene
     * @param hideLoader
     */
    maybeLoadScene(scene: string, hideLoader?: boolean): Promise<void>;
    /**
     * Plays a transition in the current scene and does book keeping for input.
     * @param transition
     */
    playTransition(transition: Transition, targetScene: Scene): Promise<void>;
    /**
     * Swaps the current and destination scene after performing required lifecycle events
     * @param destinationScene
     * @param data
     */
    swapScene<TData = undefined>(destinationScene: string, data?: TData): Promise<void>;
    private _emitEvent;
}
