import { AViewerPluginEventMap, AViewerPluginSync, ThreeViewer } from '../../viewer';
import { IObject3D } from '../../core';
import { ComponentJSON, Object3DComponent, TObject3DComponent } from './components';
export type FunctionPropertyNames<T> = {
    [K in keyof T]: T[K] extends (((...args: any[]) => any) | undefined) ? K : never;
}[keyof T] & string;
export interface EntityComponentPluginEventMap extends AViewerPluginEventMap {
    registerComponent: {
        component: Object3DComponent;
        object: IObject3D;
    };
    unregisterComponent: {
        component: Object3DComponent;
        object: IObject3D;
    };
    addComponentType: {
        cls: TObject3DComponent;
    };
    removeComponentType: {
        cls: TObject3DComponent;
    };
}
/**
 * Entity Component Framework plugin for threepipe.
 * Allows attaching reusable components to IObject3D instances.
 * Components can have their own serializable/runtime state, lifecycle methods, and update logic.
 * Components are defined as classes extending Object3DComponent.
 *
 * This system is not documented at the moment.
 */
export declare class EntityComponentPlugin extends AViewerPluginSync<EntityComponentPluginEventMap> {
    static readonly PluginType = "EntityComponentPlugin";
    enabled: boolean;
    protected _running: boolean;
    get running(): boolean;
    start(): void;
    stop(): void;
    componentsDispatch<T extends FunctionPropertyNames<Object3DComponent>>(type: T, ...args: Parameters<NonNullable<Object3DComponent[T]>>): any[][];
    private readonly _components;
    private _typeToComponents;
    readonly componentTypes: Map<string, TObject3DComponent>;
    static readonly ObjectToComponents: WeakMap<IObject3D, Object3DComponent[]>;
    static ObjectDispatch<T extends FunctionPropertyNames<Object3DComponent>>(object: IObject3D, type: T, ...args: Parameters<NonNullable<Object3DComponent[T]>>): any[][];
    static ComponentsDispatch<T extends FunctionPropertyNames<Object3DComponent>>(comps: Object3DComponent[], type: T, args: Parameters<NonNullable<Object3DComponent[T]>>): any[][];
    static UserDataKey: string;
    constructor(running?: boolean);
    addComponentType(type: TObject3DComponent): boolean;
    removeComponentType(type: TObject3DComponent): boolean;
    hasComponentType(type: TObject3DComponent | string): boolean;
    private _onRemove;
    onAdded(viewer: ThreeViewer): void;
    private _preFrame;
    onRemove(viewer: ThreeViewer): void;
    static GetObjectData(obj: IObject3D): Record<string, ComponentJSON> | null;
    /**
     * Add a component to an object
     * @param obj - Target object
     * @param stateOrType - Component state json or type string or component class
     * @param id - Optional component id, if not provided a random uuid will be generated
     * @returns Undo/redo action, added component is in action.component
     */
    addComponent<T extends TObject3DComponent = TObject3DComponent>(obj: IObject3D, stateOrType: ComponentJSON | string | T, id?: string): {
        undo: () => void;
        redo: () => void;
        component: InstanceType<T>;
    };
    /**
     * Remove a component from an object
     * @param obj
     * @param id
     */
    removeComponent(obj: IObject3D, id: string): {
        state: Record<string, any> | null | undefined;
        undo: () => void;
        redo: () => void;
    } | undefined;
    static GetComponentData<T extends TObject3DComponent = TObject3DComponent>(obj: IObject3D, type: string | T): ({
        id: string;
    } & ComponentJSON) | null;
    static GetComponents<T extends TObject3DComponent = TObject3DComponent>(obj: IObject3D, type?: string | T): InstanceType<T>[];
    static GetComponent<T extends TObject3DComponent = TObject3DComponent>(obj: IObject3D, type: string | T): InstanceType<T> | null;
    static GetComponentInParent<T extends TObject3DComponent = TObject3DComponent>(object: IObject3D, type: string | T): InstanceType<T> | null;
    static GetComponentsInParent<T extends TObject3DComponent = TObject3DComponent>(object: IObject3D, type: string | T): InstanceType<T>[];
    /**
     * Get all components of a specific type from the plugin instance
     * @param type - The component type (string or class)
     * @returns Array of components matching the specified type
     */
    getComponentsOfType<T extends TObject3DComponent = TObject3DComponent>(type: string | T): InstanceType<T>[];
    /**
     * Get the first component of a specific type from the plugin instance
     * @param type - The component type (string or class)
     * @returns The first component matching the specified type, or null if not found
     */
    getComponentOfType<T extends TObject3DComponent = TObject3DComponent>(type: string | T): InstanceType<T> | null;
    registerComponent(obj: IObject3D, state: ComponentJSON, id?: string): Object3DComponent | null;
    unregisterComponent(comp: Object3DComponent): Record<string, any> | null | undefined;
    static AddObjectUiConfig: boolean;
    private _objectAdd;
    private _objectRemove;
    private _objectUpdate;
}
export declare const ECS: typeof EntityComponentPlugin;
declare module '../../core/IObject' {
    interface IObject3D {
        /**
         * Get a component attached to this object or in its parent hierarchy, or get a component of the specified type from the global registry.
         * This method is added by EntityComponentPlugin when the object is added to the scene.
         * @param type - The component type (string or class)
         * @param self - If true, only search this object; if false, search parents and global registry
         * @returns The component instance if found, or null
         */
        getComponent?<T extends TObject3DComponent>(type: T | string, self?: boolean): InstanceType<T> | null;
    }
}
//# sourceMappingURL=../../src/plugins/extras/EntityComponentPlugin.d.ts.map