import '../../../assert/js/assert.js';
import '../../../tandem/js/PhetioIDUtils.js';
import '../../../globals.js';
/**
 * A persistent display of a specific Node and its descendants, which is updated at discrete points in time.
 *
 * Use display.getDOMElement or display.domElement to retrieve the Display's DOM representation.
 * Use display.updateDisplay() to trigger the visual update in the Display's DOM element.
 *
 * A standard way of using a Display with Scenery is to:
 * 1. Create a Node that will be the root
 * 2. Create a Display, referencing that node
 * 3. Make changes to the scene graph
 * 4. Call display.updateDisplay() to draw the scene graph into the Display
 * 5. Go to (3)
 *
 * Common ways to simplify the change/update loop would be to:
 * - Use Node-based events. Initialize it with Display.initializeEvents(), then
 *   add input listeners to parts of the scene graph (see Node.addInputListener).
 * - Execute code (and update the display afterwards) by using Display.updateOnRequestAnimationFrame.
 *
 * Internal documentation:
 *
 * Lifecycle information:
 *   Instance (create,dispose)
 *     - out of update:            Stateless stub is created synchronously when a Node's children are added where we
 *                                 have no relevant Instance.
 *     - start of update:          Creates first (root) instance if it doesn't exist (stateless stub).
 *     - synctree:                 Create descendant instances under stubs, fills in state, and marks removed subtree
 *                                 roots for disposal.
 *     - update instance disposal: Disposes root instances that were marked. This also disposes all descendant
 *                                 instances, and for every instance,
 *                                 it disposes the currently-attached drawables.
 *   Drawable (create,dispose)
 *     - synctree:                 Creates all drawables where necessary. If it replaces a self/group/shared drawable on
 *                                 the instance,
 *                                 that old drawable is marked for disposal.
 *     - update instance disposal: Any drawables attached to disposed instances are disposed themselves (see Instance
 *                                 lifecycle).
 *     - update drawable disposal: Any marked drawables that were replaced or removed from an instance (it didn't
 *                                 maintain a reference) are disposed.
 *
 *   add/remove drawables from blocks:
 *     - stitching changes pending "parents", marks for block update
 *     - backbones marked for disposal (e.g. instance is still there, just changed to not have a backbone) will mark
 *         drawables for block updates
 *     - add/remove drawables phase updates drawables that were marked
 *     - disposed backbone instances will only remove drawables if they weren't marked for removal previously (e.g. in
 *         case we are from a removed instance)
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import Emitter from '../../../axon/js/Emitter.js';
import TProperty from '../../../axon/js/TProperty.js';
import Bounds2 from '../../../dot/js/Bounds2.js';
import Dimension2 from '../../../dot/js/Dimension2.js';
import Vector2 from '../../../dot/js/Vector2.js';
import PhetioObject, { PhetioObjectOptions } from '../../../tandem/js/PhetioObject.js';
import UtteranceQueue from '../../../utterance-queue/js/UtteranceQueue.js';
import { BackboneDrawable, ChangeInterval, Color, Drawable, FocusManager, Input, InputOptions, Instance, Node, PDOMInstance, Pointer, SceneryEvent, TInputListener, TOverlay, Trail } from '../imports.js';
import TEmitter from '../../../axon/js/TEmitter.js';
type SelfOptions = {
    width?: number;
    height?: number;
    allowCSSHacks?: boolean;
    allowSafariRedrawWorkaround?: boolean;
    allowSceneOverflow?: boolean;
    allowLayerFitting?: boolean;
    defaultCursor?: string;
    forceSVGRefresh?: boolean;
    backgroundColor?: Color | string | null;
    preserveDrawingBuffer?: boolean;
    allowWebGL?: boolean;
    accessibility?: boolean;
    supportsInteractiveHighlights?: boolean;
    interactive?: boolean;
    listenToOnlyElement?: boolean;
    batchDOMEvents?: boolean;
    assumeFullWindow?: boolean;
    aggressiveContextRecreation?: boolean;
    passiveEvents?: boolean | null;
    allowBackingScaleAntialiasing?: boolean;
    container?: HTMLElement;
};
type ParentOptions = Pick<PhetioObjectOptions, 'tandem'>;
export type DisplayOptions = SelfOptions & ParentOptions;
export default class Display {
    readonly id: number;
    readonly sizeProperty: TProperty<Dimension2>;
    descriptionUtteranceQueue: UtteranceQueue;
    focusManager: FocusManager;
    _input: Input | null;
    readonly _accessible: boolean;
    readonly _preserveDrawingBuffer: boolean;
    _sharedCanvasInstances: Record<number, Instance>;
    _frameId: number;
    _aggressiveContextRecreation: boolean;
    _allowBackingScaleAntialiasing: boolean;
    _allowLayerFitting: boolean;
    _forceSVGRefresh: boolean;
    private readonly _allowWebGL;
    private readonly _allowCSSHacks;
    private readonly _allowSceneOverflow;
    private readonly _defaultCursor;
    private readonly _rootNode;
    private _rootBackbone;
    private readonly _domElement;
    private _baseInstance;
    private _currentSize;
    private _dirtyTransformRoots;
    private _dirtyTransformRootsWithoutPass;
    private _instanceRootsToDispose;
    private _reduceReferencesNeeded;
    private _drawablesToDispose;
    private _drawablesToChangeBlock;
    private _drawablesToUpdateLinks;
    private _changeIntervalsToDispose;
    private _lastCursor;
    private _currentBackgroundCSS;
    private _backgroundColor;
    private _requestAnimationFrameID;
    private _inputListeners;
    private _interactive;
    private _listenToOnlyElement;
    private _batchDOMEvents;
    private _assumeFullWindow;
    private _passiveEvents;
    private _overlays;
    private _pointerOverlay;
    private _pointerAreaOverlay;
    private _hitAreaOverlay;
    private _canvasAreaBoundsOverlay;
    private _fittedBlockBoundsOverlay;
    private _isPainting?;
    _isDisposing?: boolean;
    _isDisposed?: boolean;
    private _focusRootNode?;
    private _focusOverlay?;
    _rootPDOMInstance?: PDOMInstance;
    private _boundHandleFullScreenNavigation?;
    private perfSyncTreeCount?;
    private perfStitchCount?;
    private perfIntervalCount?;
    private perfDrawableBlockChangeCount?;
    private perfDrawableOldIntervalCount?;
    private perfDrawableNewIntervalCount?;
    readonly _refreshSVGEmitter: Emitter<[]>;
    private _refreshSVGPending;
    /**
     * Constructs a Display that will show the rootNode and its subtree in a visual state. Default options provided below
     *
     * @param rootNode - Displays this node and all of its descendants
     * @param [providedOptions]
     */
    constructor(rootNode: Node, providedOptions?: DisplayOptions);
    getDOMElement(): HTMLElement;
    get domElement(): HTMLElement;
    /**
     * Updates the display's DOM element with the current visual state of the attached root node and its descendants
     */
    updateDisplay(): void;
    getPhetioElementAt(point: Vector2): PhetioObject | null;
    private updateSize;
    /**
     * Whether WebGL is allowed to be used in drawables for this Display
     */
    isWebGLAllowed(): boolean;
    get webglAllowed(): boolean;
    getRootNode(): Node;
    get rootNode(): Node;
    getRootBackbone(): BackboneDrawable;
    get rootBackbone(): BackboneDrawable;
    /**
     * The dimensions of the Display's DOM element
     */
    getSize(): Dimension2;
    get size(): Dimension2;
    getBounds(): Bounds2;
    get bounds(): Bounds2;
    /**
     * Changes the size that the Display's DOM element will be after the next updateDisplay()
     */
    setSize(size: Dimension2): void;
    /**
     * Changes the size that the Display's DOM element will be after the next updateDisplay()
     */
    setWidthHeight(width: number, height: number): void;
    /**
     * The width of the Display's DOM element
     */
    getWidth(): number;
    get width(): number;
    set width(value: number);
    /**
     * Sets the width that the Display's DOM element will be after the next updateDisplay(). Should be an integral value.
     */
    setWidth(width: number): this;
    /**
     * The height of the Display's DOM element
     */
    getHeight(): number;
    get height(): number;
    set height(value: number);
    /**
     * Sets the height that the Display's DOM element will be after the next updateDisplay(). Should be an integral value.
     */
    setHeight(height: number): this;
    /**
     * Will be applied to the root DOM element on updateDisplay(), and no sooner.
     */
    setBackgroundColor(color: Color | string | null): this;
    set backgroundColor(value: Color | string | null);
    get backgroundColor(): Color | string | null;
    getBackgroundColor(): Color | string | null;
    get interactive(): boolean;
    set interactive(value: boolean);
    /**
     * Adds an overlay to the Display. Each overlay should have a .domElement (the DOM element that will be used for
     * display) and an .update() method.
     */
    addOverlay(overlay: TOverlay): void;
    /**
     * Removes an overlay from the display.
     */
    removeOverlay(overlay: TOverlay): void;
    /**
     * Get the root accessible DOM element which represents this display and provides semantics for assistive
     * technology. If this Display is not accessible, returns null.
     */
    getPDOMRootElement(): HTMLElement | null;
    get pdomRootElement(): HTMLElement | null;
    /**
     * Has this Display enabled accessibility features like PDOM creation and support.
     */
    isAccessible(): boolean;
    /**
     * Returns true if the element is in the PDOM. That is only possible if the display is accessible.
     * @param element
     * @param allowRoot - If true, the root of the PDOM is also considered to be "under" the PDOM.
     */
    isElementUnderPDOM(element: Element, allowRoot: boolean): boolean;
    /**
     * Implements a workaround that prevents DOM focus from leaving the Display in FullScreen mode. There is
     * a bug in some browsers where DOM focus can be permanently lost if tabbing out of the FullScreen element,
     * see https://github.com/phetsims/scenery/issues/883.
     */
    private handleFullScreenNavigation;
    /**
     * Returns the bitmask union of all renderers (canvas/svg/dom/webgl) that are used for display, excluding
     * BackboneDrawables (which would be DOM).
     */
    getUsedRenderersBitmask(): number;
    /**
     * Called from Instances that will need a transform update (for listeners and precomputation). (scenery-internal)
     *
     * @param instance
     * @param passTransform - Whether we should pass the first transform root when validating transforms (should
     * be true if the instance is transformed)
     */
    markTransformRootDirty(instance: Instance, passTransform: boolean): void;
    private updateDirtyTransformRoots;
    /**
     * (scenery-internal)
     */
    markDrawableChangedBlock(drawable: Drawable): void;
    /**
     * Marks an item for later reduceReferences() calls at the end of Display.update().
     * (scenery-internal)
     */
    markForReducedReferences(item: {
        reduceReferences: () => void;
    }): void;
    /**
     * (scenery-internal)
     */
    markInstanceRootForDisposal(instance: Instance): void;
    /**
     * (scenery-internal)
     */
    markDrawableForDisposal(drawable: Drawable): void;
    /**
     * (scenery-internal)
     */
    markDrawableForLinksUpdate(drawable: Drawable): void;
    /**
     * Add a {ChangeInterval} for the "remove change interval info" phase (we don't want to leak memory/references)
     * (scenery-internal)
     */
    markChangeIntervalToDispose(changeInterval: ChangeInterval): void;
    private updateBackgroundColor;
    private updateCursor;
    /**
     * Sets the cursor to be displayed when over the Display.
     */
    private setElementCursor;
    private setSceneCursor;
    private applyCSSHacks;
    canvasDataURL(callback: (str: string) => void): void;
    /**
     * Renders what it can into a Canvas (so far, Canvas and SVG layers work fine)
     */
    canvasSnapshot(callback: (canvas: HTMLCanvasElement, imageData: ImageData) => void): void;
    /**
     * TODO: reduce code duplication for handling overlays https://github.com/phetsims/scenery/issues/1581
     */
    setPointerDisplayVisible(visibility: boolean): void;
    /**
     * TODO: reduce code duplication for handling overlays https://github.com/phetsims/scenery/issues/1581
     */
    setPointerAreaDisplayVisible(visibility: boolean): void;
    /**
     * TODO: reduce code duplication for handling overlays https://github.com/phetsims/scenery/issues/1581
     */
    setHitAreaDisplayVisible(visibility: boolean): void;
    /**
     * TODO: reduce code duplication for handling overlays https://github.com/phetsims/scenery/issues/1581
     */
    setCanvasNodeBoundsVisible(visibility: boolean): void;
    /**
     * TODO: reduce code duplication for handling overlays https://github.com/phetsims/scenery/issues/1581
     */
    setFittedBlockBoundsVisible(visibility: boolean): void;
    /**
     * Sets up the Display to resize to whatever the window inner dimensions will be.
     */
    resizeOnWindowResize(): void;
    /**
     * Updates on every request animation frame. If stepCallback is passed in, it is called before updateDisplay() with
     * stepCallback( timeElapsedInSeconds )
     */
    updateOnRequestAnimationFrame(stepCallback?: (dt: number) => void): void;
    cancelUpdateOnRequestAnimationFrame(): void;
    /**
     * Initializes event handling, and connects the browser's input event handlers to notify this Display of events.
     *
     * NOTE: This can be reversed with detachEvents().
     */
    initializeEvents(options?: InputOptions): void;
    /**
     * Detach already-attached input event handling (from initializeEvents()).
     */
    detachEvents(): void;
    /**
     * Adds an input listener.
     */
    addInputListener(listener: TInputListener): this;
    /**
     * Removes an input listener that was previously added with addInputListener.
     */
    removeInputListener(listener: TInputListener): this;
    /**
     * Returns whether this input listener is currently listening to this Display.
     *
     * More efficient than checking display.inputListeners, as that includes a defensive copy.
     */
    hasInputListener(listener: TInputListener): boolean;
    /**
     * Returns a copy of all of our input listeners.
     */
    getInputListeners(): TInputListener[];
    get inputListeners(): TInputListener[];
    /**
     * Interrupts all input listeners that are attached to this Display.
     */
    interruptInput(): this;
    /**
     * Interrupts all pointers associated with this Display, see https://github.com/phetsims/scenery/issues/1582.
     */
    interruptPointers(): this;
    /**
     * Interrupts all pointers associated with this Display that are NOT currently having events executed.
     * see https://github.com/phetsims/scenery/issues/1582.
     *
     * If excludePointer is provided and is non-null, it's used as the "current" pointer that should be excluded from
     * interruption.
     */
    interruptOtherPointers(excludePointer?: Pointer | null): this;
    static readonly INTERRUPT_OTHER_POINTERS: (event: SceneryEvent) => void;
    /**
     * (scenery-internal)
     */
    ensureNotPainting(): void;
    /**
     * Triggers a loss of context for all WebGL blocks.
     *
     * NOTE: Should generally only be used for debugging.
     */
    loseWebGLContexts(): void;
    /**
     * Makes this Display available for inspection.
     */
    inspect(): void;
    /**
     * Returns an HTML fragment that includes a large amount of debugging information, including a view of the
     * instance tree and drawable tree.
     */
    getDebugHTML(): string;
    /**
     * Returns the getDebugHTML() information, but wrapped into a full HTML page included in a data URI.
     */
    getDebugURI(): string;
    /**
     * Attempts to open a popup with the getDebugHTML() information.
     */
    popupDebug(): void;
    /**
     * Attempts to open an iframe popup with the getDebugHTML() information in the same window. This is similar to
     * popupDebug(), but should work in browsers that block popups, or prevent that type of data URI being opened.
     */
    iframeDebug(): void;
    getPDOMDebugHTML(): string;
    /**
     * Will attempt to call callback( {string} dataURI ) with the rasterization of the entire Display's DOM structure,
     * used for internal testing. Will call-back null if there was an error
     *
     * Only tested on recent Chrome and Firefox, not recommended for general use. Guaranteed not to work for IE <= 10.
     *
     * See https://github.com/phetsims/scenery/issues/394 for some details.
     */
    foreignObjectRasterization(callback: (url: string | null) => void): void;
    popupRasterization(): void;
    /**
     * Will return null if the string of indices isn't part of the PDOMInstance tree
     */
    getTrailFromPDOMIndicesString(indicesString: string): Trail | null;
    /**
     * Forces SVG elements to have their visual contents refreshed, by changing state in a non-visually-apparent way.
     * It should trick browsers into re-rendering the SVG elements.
     *
     * See https://github.com/phetsims/scenery/issues/1507
     */
    refreshSVG(): void;
    /**
     * Similar to refreshSVG (see docs above), but will do so on the next frame.
     */
    refreshSVGOnNextFrame(): void;
    /**
     * Releases references.
     *
     * TODO: this dispose function is not complete. https://github.com/phetsims/scenery/issues/1581
     */
    dispose(): void;
    /**
     * Takes a given DOM element, and asynchronously renders it to a string that is a data URL representing an SVG
     * file.
     *
     * @param domElement
     * @param width - The width of the output SVG
     * @param height - The height of the output SVG
     * @param callback - Called as callback( url: {string} ), where the URL will be the encoded SVG file.
     */
    static elementToSVGDataURL(domElement: HTMLElement, width: number, height: number, callback: (url: string | null) => void): void;
    /**
     * Returns true when NO nodes in the subtree are disposed.
     */
    private static assertSubtreeDisposed;
    /**
     * Adds an input listener to be fired for ANY Display
     */
    static addInputListener(listener: TInputListener): void;
    /**
     * Removes an input listener that was previously added with Display.addInputListener.
     */
    static removeInputListener(listener: TInputListener): void;
    /**
     * Interrupts all input listeners that are attached to all Displays.
     */
    static interruptInput(): void;
    static userGestureEmitter: TEmitter;
    static inputListeners: TInputListener[];
}
export {};
//# sourceMappingURL=Display.d.ts.map