import type { ExtractProps, TextureMap } from '../core/CoreTextureManager.js';
import { EventEmitter } from '../common/EventEmitter.js';
import { Stage, type StageOptions } from '../core/Stage.js';
import { CoreNode } from '../core/CoreNode.js';
import type { INode, INodeProps, ITextNode, ITextNodeProps } from './INode.js';
import type { TextureMemoryManagerSettings } from '../core/TextureMemoryManager.js';
import type { TextRenderer } from '../core/text-rendering/TextRenderer.js';
import type { CanvasRenderer } from '../core/renderers/canvas/CanvasRenderer.js';
import type { WebGlRenderer } from '../core/renderers/webgl/WebGlRenderer.js';
import type { Inspector, InspectorOptions } from './Inspector.js';
import type { CoreShaderNode } from '../core/renderers/CoreShaderNode.js';
import type { ExtractShaderProps, OptionalShaderProps, ShaderMap } from '../core/CoreShaderManager.js';
import { Platform } from '../core/platforms/Platform.js';
/**
 * FPS Update Event Data
 *
 * @category Events
 * @example
 * ```typescript
 * renderer.on('fpsUpdate', (data) => {
 *   console.log(`Current FPS: ${data.fps}`);
 *   if (data.contextSpyData) {
 *     console.log('WebGL calls:', data.contextSpyData);
 *   }
 * });
 * ```
 */
export interface RendererMainFpsUpdateEvent {
    /** Current frames per second */
    fps: number;
    /** Context spy data (if enabled) - contains WebGL call statistics */
    contextSpyData?: unknown;
}
/**
 * Frame Tick Event Data
 *
 * @category Events
 * @example
 * ```typescript
 * renderer.on('frameTick', (data) => {
 *   console.log(`Frame time: ${data.time}ms, delta: ${data.delta}ms`);
 * });
 * ```
 */
export interface RendererMainFrameTickEvent {
    /** Current timestamp */
    time: number;
    /** Time delta since last frame */
    delta: number;
}
/**
 * Quads Update Event Data
 *
 * @category Events
 * @example
 * ```typescript
 * renderer.on('quadsUpdate', (data) => {
 *   console.log(`Rendered quads: ${data.quads}`);
 * });
 * ```
 */
export interface RendererMainQuadsUpdateEvent {
    /** Number of rendered quads */
    quads: number;
}
/**
 * Idle Event Data
 *
 * @category Events
 * @remarks
 * This event is emitted when the renderer has no scene updates to process.
 * The event has no payload - use this for performance optimizations during idle periods.
 *
 * @example
 * ```typescript
 * renderer.on('idle', () => {
 *   // Renderer is idle - perfect time for cleanup, analytics, etc.
 *   console.log('Renderer is idle - no scene changes');
 *
 *   // Example: Perform background tasks
 *   performBackgroundCleanup();
 *   sendAnalytics();
 * });
 * ```
 */
export interface RendererMainIdleEvent {
    /** This event has no payload - listen without parameters */
    readonly __eventHasNoPayload?: never;
}
/**
 * Critical Cleanup Event Data
 *
 * @category Events
 * @example
 * ```typescript
 * renderer.on('criticalCleanup', (data) => {
 *   console.log(`Memory cleanup triggered!`);
 *   console.log(`Memory used: ${data.memUsed} bytes`);
 *   console.log(`Critical threshold: ${data.criticalThreshold} bytes`);
 * });
 * ```
 */
export interface RendererMainCriticalCleanupEvent {
    /** Memory used before cleanup (bytes) */
    memUsed: number;
    /** Critical threshold (bytes) */
    criticalThreshold: number;
}
/**
 * Critical Cleanup Failed Event Data
 *
 * @category Events
 * @example
 * ```typescript
 * renderer.on('criticalCleanupFailed', (data) => {
 *   console.warn(`Memory cleanup failed!`);
 *   console.log(`Memory still used: ${data.memUsed} bytes`);
 *   console.log(`Critical threshold: ${data.criticalThreshold} bytes`);
 *   // Consider reducing texture usage or forcing cleanup
 * });
 * ```
 */
export interface RendererMainCriticalCleanupFailedEvent {
    /** Memory used after cleanup (bytes) */
    memUsed: number;
    /** Critical threshold (bytes) */
    criticalThreshold: number;
}
/**
 * Settings for the Renderer that can be updated during runtime.
 */
export interface RendererRuntimeSettings {
    /**
     * Authored logical pixel width of the application
     *
     * @defaultValue `1920`
     */
    appWidth: number;
    /**
     * Authored logical pixel height of the application
     *
     * @defaultValue `1080`
     */
    appHeight: number;
    /**
     * Texture Memory Manager Settings
     */
    textureMemory: Partial<TextureMemoryManagerSettings>;
    /**
     * Bounds margin to extend the boundary in which a Node is added as Quad.
     */
    boundsMargin: number | [number, number, number, number];
    /**
     * Factor to convert app-authored logical coorindates to device logical coordinates
     *
     * @remarks
     * This value allows auto-scaling to support larger/small resolutions than the
     * app was authored for.
     *
     * If the app was authored for 1920x1080 and this value is 2, the app's canvas
     * will be rendered at 3840x2160 logical pixels.
     *
     * Likewise, if the app was authored for 1920x1080 and this value is 0.66667,
     * the app's canvas will be rendered at 1280x720 logical pixels.
     *
     * @defaultValue `1`
     */
    deviceLogicalPixelRatio: number;
    /**
     * Factor to convert device logical coordinates to device physical coordinates
     *
     * @remarks
     * This value allows auto-scaling to support devices with different pixel densities.
     *
     * This controls the number of physical pixels that are used to render each logical
     * pixel. For example, if the device has a pixel density of 2, each logical pixel
     * will be rendered using 2x2 physical pixels.
     *
     * By default, it will be set to `window.devicePixelRatio` which is the pixel
     * density of the device the app is running on reported by the browser.
     *
     * @defaultValue `window.devicePixelRatio`
     */
    devicePhysicalPixelRatio: number;
    /**
     * RGBA encoded number of the background to use
     *
     * @defaultValue `0x00000000`
     */
    clearColor: number;
    /**
     * Interval in milliseconds to receive FPS updates
     *
     * @remarks
     * If set to `0`, FPS updates will be disabled.
     *
     * @defaultValue `0` (disabled)
     */
    fpsUpdateInterval: number;
    /**
     * Clears the render buffer on reset
     *
     * @remarks
     * If false, the renderer will not clear the buffer before rendering a new frame.
     * This is useful if you want to preserve the previous frame.
     *
     * @defaultValue `true`
     */
    enableClear: boolean;
    /**
     * DOM Inspector
     *
     * @remarks
     * The inspector will replicate the state of the Nodes created
     * in the renderer and allow inspection of the state of the nodes.
     *
     */
    inspector: typeof Inspector | false;
    /**
     * Inspector Options
     *
     * @remarks
     * Configuration options for the Inspector's performance monitoring features.
     * Only used when inspector is enabled.
     */
    inspectorOptions?: Partial<InspectorOptions>;
    /**
     * Texture Processing Limit (in milliseconds)
     *
     * @remarks
     * The maximum amount of time the renderer is allowed to process textures in a
     * single frame. If the processing time exceeds this limit, the renderer will
     * skip processing the remaining textures and continue rendering the frame.
     *
     * @defaultValue `10`
     */
    textureProcessingTimeLimit: number;
    /**
     * Target FPS for the global render loop
     *
     * @remarks
     * Controls the maximum frame rate of the entire rendering system.
     * When set to 0, no throttling is applied (use display refresh rate).
     * When set to a positive number, the global requestAnimationFrame loop
     * will be throttled to this target FPS, affecting all animations and rendering.
     *
     * This provides global performance control for the entire application,
     * useful for managing performance on lower-end devices.
     *
     * @defaultValue `0` (no throttling, use display refresh rate)
     */
    targetFPS: number;
}
/**
 * Configuration settings for {@link RendererMain}
 */
export type RendererMainSettings = RendererRuntimeSettings & {
    /**
     * Include context call (i.e. WebGL) information in FPS updates
     *
     * @remarks
     * When enabled the number of calls to each context method over the
     * `fpsUpdateInterval` will be included in the FPS update payload's
     * `contextSpyData` property.
     *
     * Enabling the context spy has a serious impact on performance so only use it
     * when you need to extract context call information.
     *
     * @defaultValue `false` (disabled)
     */
    enableContextSpy: boolean;
    /**
     * Number or Image Workers to use
     *
     * @remarks
     * On devices with multiple cores, this can be used to improve image loading
     * as well as reduce the impact of image loading on the main thread.
     * Set to 0 to disable image workers.
     *
     * @defaultValue `2`
     */
    numImageWorkers: number;
    /**
     * Renderer Engine
     *
     * @remarks
     * The renderer engine to use. Spawns a WebGL or Canvas renderer.
     * WebGL is more performant and supports more features. Canvas is
     * supported on most platforms.
     *
     * Note: When using CanvasCoreRenderer you can only use
     * CanvasTextRenderer. The WebGLCoreRenderer supports
     * both CanvasTextRenderer and SdfTextRenderer for Text Rendering.
     *
     */
    renderEngine: typeof CanvasRenderer | typeof WebGlRenderer;
    /**
     * Quad buffer size in bytes
     *
     * @defaultValue 4 * 1024 * 1024
     */
    quadBufferSize: number;
    /**
     * Font Engines
     *
     * @remarks
     * The font engines to use for text rendering. CanvasTextRenderer is supported
     * on all platforms. SdfTextRenderer is a more performant renderer.
     * When using `renderEngine=CanvasCoreRenderer` you can only use `CanvasTextRenderer`.
     * The `renderEngine=WebGLCoreRenderer` supports both `CanvasTextRenderer` and `SdfTextRenderer`.
     *
     * This setting is used to enable tree shaking of unused font engines. Please
     * import your font engine(s) as follows:
     * ```
     * import { CanvasTextRenderer } from '@lightning/renderer/canvas';
     * import { SdfTextRenderer } from '@lightning/renderer/webgl';
     * ```
     *
     * If both CanvasTextRenderer and SdfTextRenderer are provided, the first renderer
     * provided will be asked first if it can render the font. If it cannot render the
     * font, the next renderer will be asked. If no renderer can render the font, the
     * text will not be rendered.
     *
     * **Note** that if you have fonts available in both engines the second font engine
     * will not be used. This is because the first font engine will always be asked first.
     *
     * @defaultValue '[]'
     *
     *
     */
    fontEngines: TextRenderer[];
    /**
     * Force WebGL2
     *
     * @remarks
     * Force the renderer to use WebGL2. This can be used to force the renderer to
     * use WebGL2 even if the browser supports WebGL1.
     *
     * @defaultValue `false`
     */
    forceWebGL2: boolean;
    /**
     * Canvas object to use for rendering
     *
     * @remarks
     * This is used to render the scene graph. If not provided, a new canvas
     * element will be created and appended to the target element.
     */
    canvas: HTMLCanvasElement;
    /**
     * createImageBitmap support for the runtime
     *
     * @remarks
     * This is used to determine if and which version of the createImageBitmap API
     * is supported by the runtime. This is used to determine if the renderer can
     * use createImageBitmap to load images.
     *
     * Options supported
     * - Auto - Automatically determine the supported version
     * - Basic - Supports createImageBitmap(image)
     * - Options - Supports createImageBitmap(image, options)
     * - Full - Supports createImageBitmap(image, sx, sy, sw, sh, options)
     *
     * Note with auto detection, the renderer will attempt to use the most advanced
     * version of the API available. If the API is not available, the renderer will
     * fall back to the next available version.
     *
     * This will affect startup performance as the renderer will need to determine
     * the supported version of the API.
     *
     * @defaultValue `full`
     */
    createImageBitmapSupport: 'auto' | 'basic' | 'options' | 'full';
    /**
     * Provide an alternative platform abstraction layer
     *
     * @remarks
     * By default the Lightning 3 renderer will load a webplatform, assuming it runs
     * inside a web browsr. However for special cases there might be a need to provide
     * an abstracted platform layer to run on non-web or non-standard JS engines
     *
     * @defaultValue `null`
     */
    platform: typeof Platform | null;
    /**
     * Number of times to retry loading a failed texture
     *
     * @remarks
     * When a texture fails to load, Lightning will retry up to this many times
     * before permanently giving up. Each retry will clear the texture ownership
     * and then re-establish it to trigger a new load attempt.
     *
     * Set to null to disable retries. Set to 0 to always try once and never retry.
     * This is typically only used on ImageTexture instances.
     *
     */
    maxRetryCount?: number;
};
/**
 * The Renderer Main API
 *
 * @remarks
 * This is the primary class used to configure and operate the Renderer.
 *
 * It is used to create and destroy Nodes, as well as Texture and Shader
 * references.
 *
 * Example:
 * ```ts
 * import { RendererMain, MainCoreDriver } from '@lightningjs/renderer';
 *
 * // Initialize the Renderer
 * const renderer = new RendererMain(
 *   {
 *     appWidth: 1920,
 *     appHeight: 1080
 *   },
 *   'app',
 *   new MainCoreDriver(),
 * );
 * ```
 *
 * ## Event Handling
 *
 * Listen to events using the standard EventEmitter API:
 * ```typescript
 * renderer.on('fpsUpdate', (data: RendererMainFpsUpdateEvent) => {
 *   console.log(`FPS: ${data.fps}`);
 * });
 *
 * renderer.on('idle', (data: RendererMainIdleEvent) => {
 *   // Renderer is idle - no scene changes
 * });
 * ```
 *
 * @see {@link RendererMainFpsUpdateEvent}
 * @see {@link RendererMainFrameTickEvent}
 * @see {@link RendererMainQuadsUpdateEvent}
 * @see {@link RendererMainIdleEvent}
 * @see {@link RendererMainCriticalCleanupEvent}
 * @see {@link RendererMainCriticalCleanupFailedEvent}
 *
 * @fires RendererMain#fpsUpdate
 * @fires RendererMain#frameTick
 * @fires RendererMain#quadsUpdate
 * @fires RendererMain#idle
 * @fires RendererMain#criticalCleanup
 * @fires RendererMain#criticalCleanupFailed
 */
export declare class RendererMain extends EventEmitter {
    readonly root: INode;
    readonly canvas: HTMLCanvasElement;
    readonly stage: Stage;
    private inspector;
    /**
     * Constructs a new Renderer instance
     *
     * @param settings Renderer settings
     * @param target Element ID or HTMLElement to insert the canvas into
     * @param driver Core Driver to use
     */
    constructor(settings: Partial<RendererMainSettings>, target?: string | HTMLElement);
    /**
     * Resolves the Texture Memory Manager values
     *
     * @param props
     * @returns
     */
    private resolveTxSettings;
    /**
     * Create a new scene graph node
     *
     * @remarks
     * A node is the main graphical building block of the Renderer scene graph. It
     * can be a container for other nodes, or it can be a leaf node that renders a
     * solid color, gradient, image, or specific texture, using a specific shader.
     *
     * To create a text node, see {@link createTextNode}.
     *
     * See {@link CoreNode} for more details.
     *
     * @param props
     * @returns
     */
    createNode<ShNode extends CoreShaderNode<any>>(props: Partial<INodeProps<ShNode>>): INode<ShNode>;
    /**
     * Create a new scene graph text node
     *
     * @remarks
     * A text node is the second graphical building block of the Renderer scene
     * graph. It renders text using a specific text renderer that is automatically
     * chosen based on the font requested and what type of fonts are installed
     * into an app.
     *
     * See {@link ITextNode} for more details.
     *
     * @param props
     * @returns
     */
    createTextNode(props: Partial<ITextNodeProps>): ITextNode;
    /**
     * Destroy a node
     *
     * @remarks
     * This method destroys a node
     *
     * @param node
     * @returns
     */
    destroyNode(node: INode): void;
    /**
     * Create a new texture reference
     *
     * @remarks
     * This method creates a new reference to a texture. The texture is not
     * loaded until it is used on a node.
     *
     * It can be assigned to a node's `texture` property, or it can be used
     * when creating a SubTexture.
     *
     * @param textureType
     * @param props
     * @param options
     * @returns
     */
    createTexture<TxType extends keyof TextureMap>(textureType: TxType, props: ExtractProps<TextureMap[TxType]>): InstanceType<TextureMap[TxType]>;
    /**
     * Create a new shader controller for a shader type
     *
     * @remarks
     * This method creates a new Shader Controller for a specific shader type.
     *
     * If the shader has not been loaded yet, it will be loaded. Otherwise, the
     * existing shader will be reused.
     *
     * It can be assigned to a Node's `shader` property.
     *
     * @param shaderType
     * @param props
     * @returns
     */
    createShader<ShType extends keyof ShaderMap>(shType: ShType, props?: OptionalShaderProps<ShType>): CoreShaderNode<NonNullable<ExtractShaderProps<ShType>>>;
    /**
     * Get a Node by its ID
     *
     * @param id
     * @returns
     */
    getNodeById(id: number): CoreNode | null;
    toggleFreeze(): void;
    advanceFrame(): void;
    getBufferInfo(): import("../core/renderers/CoreRenderer.js").BufferInfo | null;
    /**
     * Re-render the current frame without advancing any running animations.
     *
     * @remarks
     * Any state changes will be reflected in the re-rendered frame. Useful for
     * debugging.
     *
     * May not do anything if the render loop is running on a separate worker.
     */
    rerender(): void;
    /**
     * Cleanup textures that are not being used
     *
     * @param aggressive - If true, will cleanup all textures, regardless of render status
     *
     * @remarks
     * This can be used to free up GFX memory used by textures that are no longer
     * being displayed.
     *
     * This routine is also called automatically when the memory used by textures
     * exceeds the critical threshold on frame generation **OR** when the renderer
     * is idle and the memory used by textures exceeds the target threshold.
     *
     * **NOTE**: This is a heavy operation and should be used sparingly.
     * **NOTE2**: This will not cleanup textures that are currently being displayed.
     * **NOTE3**: This will not cleanup textures that are marked as `preventCleanup`.
     * **NOTE4**: This has nothing to do with the garbage collection of JavaScript.
     */
    cleanup(): void;
    /**
     * Sets the clear color for the stage.
     *
     * @param color - The color to set as the clear color.
     */
    setClearColor(color: number): void;
    /**
     * Set options for the renderer
     *
     * @param options
     */
    setOptions(options: Partial<RendererRuntimeSettings>): void;
    private updateAppDimensions;
    get settings(): Readonly<StageOptions>;
    /**
     * Gets the target FPS for the global render loop
     *
     * @returns The current target FPS (0 means no throttling)
     *
     * @remarks
     * This controls the maximum frame rate of the entire rendering system.
     * When 0, the system runs at display refresh rate.
     */
    get targetFPS(): number;
    /**
     * Sets the target FPS for the global render loop
     *
     * @param fps - The target FPS to set for the global render loop.
     *              Set to 0 or a negative value to disable throttling.
     *
     * @remarks
     * This setting affects the entire rendering system immediately.
     * All animations, rendering, and frame updates will be throttled
     * to this target FPS. Provides global performance control.
     *
     * @example
     * ```typescript
     * // Set global target to 30fps for better performance
     * renderer.targetFPS = 30;
     *
     * // Disable global throttling (use display refresh rate)
     * renderer.targetFPS = 0;
     * ```
     */
    set targetFPS(fps: number);
    private windowDevicePixelRatio;
    /**
     * Close and destroy the renderer, releasing all resources.
     *
     * @remarks
     * This method performs a full teardown of the renderer:
     * - Stops the platform render loop
     * - Destroys all scene nodes (including text node font resources)
     * - Releases all texture memory and GPU resources
     * - Terminates image worker threads
     * - Removes the canvas element from the target div
     * - Destroys the inspector if active
     */
    close(): void;
}
