import '../../../assert/js/assert.js';
import '../../../tandem/js/PhetioIDUtils.js';
import '../../../globals.js';
import EnabledComponent, { EnabledComponentOptions } from '../../../axon/js/EnabledComponent.js';
import { ObservableArray } from '../../../axon/js/createObservableArray.js';
import WithoutNull from '../../../phet-core/js/types/WithoutNull.js';
import { Display, Node, Pointer, SceneryEvent, TInputListener, Trail } from '../imports.js';
import TProperty from '../../../axon/js/TProperty.js';
import Bounds2 from '../../../dot/js/Bounds2.js';
import TReadOnlyProperty from '../../../axon/js/TReadOnlyProperty.js';
export type SceneryListenerCallback<Listener, DomEventTypes extends Event> = (event: SceneryEvent<DomEventTypes>, listener: Listener) => void;
export type SceneryListenerNullableCallback<Listener, DomEventTypes extends Event> = (event: SceneryEvent<DomEventTypes> | null, listener: Listener) => void;
export type PressListenerDOMEvent = MouseEvent | TouchEvent | PointerEvent | FocusEvent | KeyboardEvent;
export type PressListenerEvent = SceneryEvent<PressListenerDOMEvent>;
export type PressListenerCallback<Listener extends PressListener> = SceneryListenerCallback<Listener, PressListenerDOMEvent>;
export type PressListenerNullableCallback<Listener extends PressListener> = SceneryListenerNullableCallback<Listener, PressListenerDOMEvent>;
export type PressListenerCanStartPressCallback<Listener extends PressListener> = (event: PressListenerEvent | null, listener: Listener) => boolean;
type SelfOptions<Listener extends PressListener> = {
    press?: PressListenerCallback<Listener>;
    release?: PressListenerNullableCallback<Listener>;
    drag?: PressListenerCallback<Listener>;
    targetNode?: Node | null;
    attach?: boolean;
    mouseButton?: number;
    pressCursor?: string | null;
    useInputListenerCursor?: boolean;
    canStartPress?: PressListenerCanStartPressCallback<Listener>;
    a11yLooksPressedInterval?: number;
    collapseDragEvents?: boolean;
    phetioReadOnly?: boolean;
    phetioFeatured?: boolean;
};
export type PressListenerOptions<Listener extends PressListener = PressListener> = SelfOptions<Listener> & EnabledComponentOptions;
export type PressedPressListener = WithoutNull<PressListener, 'pointer' | 'pressedTrail'>;
export default class PressListener extends EnabledComponent implements TInputListener {
    private _id;
    private _mouseButton;
    private _a11yLooksPressedInterval;
    private _pressCursor;
    private _pressListener;
    private _releaseListener;
    private _dragListener;
    private _canStartPress;
    private _targetNode;
    private _attach;
    private _collapseDragEvents;
    readonly overPointers: ObservableArray<Pointer>;
    readonly isPressedProperty: TProperty<boolean>;
    readonly isOverProperty: TProperty<boolean>;
    readonly looksOverProperty: TProperty<boolean>;
    readonly isHoveringProperty: TProperty<boolean>;
    readonly isHighlightedProperty: TProperty<boolean>;
    readonly isFocusedProperty: TProperty<boolean>;
    private readonly cursorProperty;
    pointer: Pointer | null;
    pressedTrail: Trail | null;
    interrupted: boolean;
    private _pendingCollapsedDragEvent;
    private _listeningToPointer;
    private _isHoveringListener;
    private _isHighlightedListener;
    readonly pdomClickingProperty: TProperty<boolean>;
    readonly looksPressedProperty: TReadOnlyProperty<boolean>;
    private _pdomClickingTimeoutListener;
    private _pointerListener;
    private _pressAction;
    private _releaseAction;
    display: Display | null;
    private boundInvalidateOverListener;
    constructor(providedOptions?: PressListenerOptions);
    /**
     * Whether this listener is currently activated with a press.
     */
    get isPressed(): boolean;
    get cursor(): string | null;
    get attach(): boolean;
    get targetNode(): Node | null;
    /**
     * The main node that this listener is responsible for dragging.
     */
    getCurrentTarget(): Node;
    get currentTarget(): Node;
    /**
     * Returns whether a press can be started with a particular event.
     */
    canPress(event: PressListenerEvent): boolean;
    /**
     * Returns whether this PressListener can be clicked from keyboard input. This copies part of canPress, but
     * we didn't want to use canClick in canPress because canClick could be overridden in subtypes.
     */
    canClick(): boolean;
    /**
     * Moves the listener to the 'pressed' state if possible (attaches listeners and initializes press-related
     * properties).
     *
     * This can be overridden (with super-calls) when custom press behavior is needed for a type.
     *
     * This can be called by outside clients in order to try to begin a process (generally on an already-pressed
     * pointer), and is useful if a 'drag' needs to change between listeners. Use canPress( event ) to determine if
     * a press can be started (if needed beforehand).
     *
     * @param event
     * @param [targetNode] - If provided, will take the place of the targetNode for this call. Useful for
     *                              forwarded presses.
     * @param [callback] - to be run at the end of the function, but only on success
     * @returns success - Returns whether the press was actually started
     */
    press(event: PressListenerEvent, targetNode?: Node, callback?: () => void): boolean;
    /**
     * Releases a pressed listener.
     *
     * This can be overridden (with super-calls) when custom release behavior is needed for a type.
     *
     * This can be called from the outside to release the press without the pointer having actually fired any 'up'
     * events. If the cancel/interrupt behavior is more preferable, call interrupt() on this listener instead.
     *
     * @param [event] - scenery event if there was one. We can't guarantee an event, in part to support interrupting.
     * @param [callback] - called at the end of the release
     */
    release(event?: PressListenerEvent, callback?: () => void): void;
    /**
     * Called when move events are fired on the attached pointer listener.
     *
     * This can be overridden (with super-calls) when custom drag behavior is needed for a type.
     *
     * (scenery-internal, effectively protected)
     */
    drag(event: PressListenerEvent): void;
    /**
     * Interrupts the listener, releasing it (canceling behavior).
     *
     * This effectively releases/ends the press, and sets the `interrupted` flag to true while firing these events
     * so that code can determine whether a release/end happened naturally, or was canceled in some way.
     *
     * This can be called manually, but can also be called through node.interruptSubtreeInput().
     */
    interrupt(): void;
    /**
     * This should be called when the listened "Node" is effectively removed from the scene graph AND
     * expected to be placed back in such that it could potentially get multiple "enter" events, see
     * https://github.com/phetsims/scenery/issues/1021
     *
     * This will clear the list of pointers considered "over" the Node, so that when it is placed back in, the state
     * will be correct, and another "enter" event will not be missing an "exit".
     */
    clearOverPointers(): void;
    /**
     * If collapseDragEvents is set to true, this step() should be called every frame so that the collapsed drag
     * can be fired.
     */
    step(): void;
    /**
     * Set the callback that will create a Bounds2 in the global coordinate frame for the AnimatedPanZoomListener to
     * keep in view during a drag operation. During drag input the AnimatedPanZoomListener will pan the screen to
     * try and keep the returned Bounds2 visible. By default, the AnimatedPanZoomListener will try to keep the target of
     * the drag in view but that may not always work if the target is not associated with the translated Node, the target
     * is not defined, or the target has bounds that do not accurately surround the graphic you want to keep in view.
     */
    setCreatePanTargetBounds(createDragPanTargetBounds: (() => Bounds2) | null): void;
    set createPanTargetBounds(createDragPanTargetBounds: (() => Bounds2) | null);
    /**
     * A convenient way to create and set the callback that will return a Bounds2 in the global coordinate frame for the
     * AnimatedPanZoomListener to keep in view during a drag operation. The AnimatedPanZoomListener will try to keep the
     * bounds of the last Node of the provided trail visible by panning the screen during a drag operation. See
     * setCreatePanTargetBounds() for more documentation.
     */
    setCreatePanTargetBoundsFromTrail(trail: Trail): void;
    set createPanTargetBoundsFromTrail(trail: Trail);
    /**
     * If there is a pending collapsed drag waiting, we'll fire that drag (usually before other events or during a step)
     */
    private flushCollapsedDrag;
    /**
     * Recomputes the value for isOverProperty. Separate to reduce anonymous function closures.
     */
    private invalidateOver;
    /**
     * Recomputes the value for isHoveringProperty. Separate to reduce anonymous function closures.
     */
    private invalidateHovering;
    /**
     * Recomputes the value for isHighlightedProperty. Separate to reduce anonymous function closures.
     */
    private invalidateHighlighted;
    /**
     * Fired when the enabledProperty changes
     */
    protected onEnabledPropertyChange(enabled: boolean): void;
    /**
     * Internal code executed as the first step of a press.
     *
     * @param event
     * @param [targetNode] - If provided, will take the place of the targetNode for this call. Useful for
     *                              forwarded presses.
     * @param [callback] - to be run at the end of the function, but only on success
     */
    private onPress;
    /**
     * Internal code executed as the first step of a release.
     *
     * @param event - scenery event if there was one
     * @param [callback] - called at the end of the release
     */
    private onRelease;
    /**
     * Called with 'down' events (part of the listener API). (scenery-internal)
     *
     * NOTE: Do not call directly. See the press method instead.
     */
    down(event: PressListenerEvent): void;
    /**
     * Called with 'up' events (part of the listener API). (scenery-internal)
     *
     * NOTE: Do not call directly.
     */
    up(event: PressListenerEvent): void;
    /**
     * Called with 'enter' events (part of the listener API). (scenery-internal)
     *
     * NOTE: Do not call directly.
     */
    enter(event: PressListenerEvent): void;
    /**
     * Called with `move` events (part of the listener API). It is necessary to check for `over` state changes on move
     * in case a pointer listener gets interrupted and resumes movement over a target. (scenery-internal)
     */
    move(event: PressListenerEvent): void;
    /**
     * Called with 'exit' events (part of the listener API). (scenery-internal)
     *
     * NOTE: Do not call directly.
     */
    exit(event: PressListenerEvent): void;
    /**
     * Called with 'up' events from the pointer (part of the listener API) (scenery-internal)
     *
     * NOTE: Do not call directly.
     */
    pointerUp(event: PressListenerEvent): void;
    /**
     * Called with 'cancel' events from the pointer (part of the listener API) (scenery-internal)
     *
     * NOTE: Do not call directly.
     */
    pointerCancel(event: PressListenerEvent): void;
    /**
     * Called with 'move' events from the pointer (part of the listener API) (scenery-internal)
     *
     * NOTE: Do not call directly.
     */
    pointerMove(event: PressListenerEvent): void;
    /**
     * Called when the pointer needs to interrupt its current listener (usually so another can be added). (scenery-internal)
     *
     * NOTE: Do not call directly.
     */
    pointerInterrupt(): void;
    /**
     * Click listener, called when this is treated as an accessible input listener.
     * In general not needed to be public, but just used in edge cases to get proper click logic for pdom.
     *
     * Handle the click event from DOM for PDOM. Clicks by calling press and release immediately.
     * When assistive technology is used, the browser may not receive 'keydown' or 'keyup' events on input elements, but
     * only a single 'click' event. We need to toggle the pressed state from the single 'click' event.
     *
     * This will fire listeners immediately, but adds a delay for the pdomClickingProperty so that you can make a
     * button look pressed from a single DOM click event. For example usage, see sun/ButtonModel.looksPressedProperty.
     *
     * @param event
     * @param [callback] optionally called immediately after press, but only on successful click
     * @returns success - Returns whether the press was actually started
     */
    click(event: SceneryEvent<MouseEvent> | null, callback?: () => void): boolean;
    /**
     * Focus listener, called when this is treated as an accessible input listener and its target is focused. (scenery-internal)
     * @pdom
     */
    focus(event: SceneryEvent<FocusEvent>): void;
    /**
     * Blur listener, called when this is treated as an accessible input listener.
     * @pdom
     */
    blur(): void;
    /**
     * Disposes the listener, releasing references. It should not be used after this.
     */
    dispose(): void;
    static phetioAPI: {
        pressAction: {
            phetioType: import("../../../tandem.js").IOType<any, any, any>;
        };
        releaseAction: {
            phetioType: import("../../../tandem.js").IOType<any, any, any>;
        };
    };
}
export {};
//# sourceMappingURL=PressListener.d.ts.map