/** @packageDocumentation
 * @module Tools
 */
import { BeEvent } from "@itwin/core-bentley";
import { Point2d, Point3d, XAndY } from "@itwin/core-geometry";
import { GeometryStreamProps } from "@itwin/core-common";
import { DialogItemValue, DialogPropertyItem, DialogPropertySyncItem } from "@itwin/appui-abstract";
import { HitDetail } from "../HitDetail";
import { DecorateContext } from "../ViewContext";
import { ScreenViewport, Viewport } from "../Viewport";
import { PrimitiveTool } from "./PrimitiveTool";
import { BeButton, BeButtonEvent, BeButtonState, BeModifierKeys, BeTouchEvent, BeWheelEvent, CoordinateLockOverrides, EventHandled, InputCollector, InputSource, InteractiveTool, Tool } from "./Tool";
import { ViewTool } from "./ViewTool";
/**
 * @public
 * @extensions
 */
export declare enum StartOrResume {
    Start = 1,
    Resume = 2
}
/**
 * @public
 * @extensions
 */
export declare enum ManipulatorToolEvent {
    Start = 1,
    Stop = 2,
    Suspend = 3,
    Unsuspend = 4
}
/** Maintains the state of tool settings properties for the current session.
 * @see [[ToolAdmin.toolSettingsState]] to access the state for the current session.
 * @public
 */
export declare class ToolSettingsState {
    /** Retrieve saved tool settings DialogItemValue by property name. */
    getInitialToolSettingValue(toolId: string, propertyName: string): DialogItemValue | undefined;
    /** Retrieve an array of DialogPropertyItem with the values latest values that were used in the session. */
    getInitialToolSettingValues(toolId: string, propertyNames: string[]): DialogPropertyItem[] | undefined;
    /** Save single tool settings value to session storage. */
    saveToolSettingProperty(toolId: string, item: DialogPropertyItem): void;
    /** Save an array of tool settings values to session storage */
    saveToolSettingProperties(toolId: string, tsProps: DialogPropertyItem[]): void;
}
/** @internal */
export declare class ToolState {
    coordLockOvr: CoordinateLockOverrides;
    locateCircleOn: boolean;
    setFrom(other: ToolState): void;
    clone(): ToolState;
}
/** @internal */
export declare class SuspendedToolState {
    private readonly _toolState;
    private readonly _accuSnapState;
    private readonly _locateOptions;
    private readonly _viewCursor?;
    private _inDynamics;
    private _shuttingDown;
    constructor();
    stop(): void;
}
/** @internal */
export declare class CurrentInputState {
    private readonly _rawPoint;
    private readonly _point;
    private readonly _viewPoint;
    qualifiers: BeModifierKeys;
    viewport?: ScreenViewport;
    button: BeButtonState[];
    lastButton: BeButton;
    inputSource: InputSource;
    lastMotion: Point2d;
    lastWheelEvent?: BeWheelEvent;
    lastTouchStart?: BeTouchEvent;
    touchTapTimer?: number;
    touchTapCount?: number;
    get rawPoint(): Point3d;
    set rawPoint(pt: Point3d);
    get point(): Point3d;
    set point(pt: Point3d);
    get viewPoint(): Point3d;
    set viewPoint(pt: Point3d);
    get isShiftDown(): boolean;
    get isControlDown(): boolean;
    get isAltDown(): boolean;
    isDragging(button: BeButton): boolean;
    onStartDrag(button: BeButton): void;
    onInstallTool(): void;
    clearKeyQualifiers(): void;
    clearViewport(vp: Viewport): void;
    private isAnyDragging;
    private setKeyQualifier;
    setKeyQualifiers(ev: MouseEvent | KeyboardEvent | TouchEvent): void;
    onMotion(pt2d: XAndY): void;
    changeButtonToDownPoint(ev: BeButtonEvent): void;
    updateDownPoint(ev: BeButtonEvent): void;
    onButtonDown(button: BeButton): void;
    onButtonUp(button: BeButton): void;
    toEvent(ev: BeButtonEvent, useSnap: boolean): void;
    adjustLastDataPoint(ev: BeButtonEvent): void;
    toEventFromLastDataPoint(ev: BeButtonEvent): void;
    fromPoint(vp: ScreenViewport, pt: XAndY, source: InputSource): void;
    fromButton(vp: ScreenViewport, pt: XAndY, source: InputSource, applyLocks: boolean): void;
    isStartDrag(button: BeButton): boolean;
}
/** Supplied by EditTools.initialize to make sure the current edit command finishes before starting a new primitive tool in the event that
 * the current edit tool that did not do so in it's onCleanup.
 * @internal
 */
export interface EditCommandHandler {
    finishCommand(): Promise<string>;
}
/** Controls the operation of [[Tool]]s, administering the current [[ViewTool]], [[PrimitiveTool]], and [[IdleTool]] and forwarding events to the appropriate tool.
 * @see [[IModelApp.toolAdmin]] to access the session's `ToolAdmin`.
 * @public
 * @extensions
 */
export declare class ToolAdmin {
    markupView?: ScreenViewport;
    /** @internal */
    readonly currentInputState: CurrentInputState;
    /** @internal */
    readonly toolState: ToolState;
    /** Maintains the state of tool settings properties for the current session. */
    readonly toolSettingsState: ToolSettingsState;
    private _canvasDecoration?;
    private _suspendedByViewTool?;
    private _suspendedByInputCollector?;
    private _viewTool?;
    private _primitiveTool?;
    private _idleTool?;
    private _inputCollector?;
    private _saveCursor?;
    private _saveLocateCircle;
    private _defaultToolId;
    private _defaultToolArgs?;
    private _lastHandledMotionTime?;
    private _mouseMoveOverTimeout?;
    private _editCommandHandler?;
    /** The name of the [[PrimitiveTool]] to use as the default tool.
     * Defaults to "Select", referring to [[SelectionTool]].
     * @note An empty string signifies no default tool allowing more events to be handled by [[idleTool]].
     * @see [[startDefaultTool]] to activate the default tool.
     * @see [[defaultToolArgs]] to supply arguments when starting the tool.
     */
    get defaultToolId(): string;
    set defaultToolId(toolId: string);
    /** The arguments supplied to the default [[Tool]]'s [[Tool.run]] method from [[startDefaultTool]].
     * @see [[defaultToolId]] to configure the default tool.
     */
    get defaultToolArgs(): any[] | undefined;
    set defaultToolArgs(args: any[] | undefined);
    /** Apply operations such as transform, copy or delete to all members of an assembly. */
    assemblyLock: boolean;
    /** If Grid Lock is on, project data points to grid. */
    gridLock: boolean;
    /** If ACS Snap Lock is on, project snap points to the ACS plane. */
    acsPlaneSnapLock: boolean;
    /** If ACS Plane Lock is on, standard view rotations are relative to the ACS instead of global. */
    acsContextLock: boolean;
    /** Options for how uncaught exceptions should be handled by [[ToolAdmin.exceptionHandler]]. */
    static exceptionOptions: {
        /** Log exception to Logger. */
        log: boolean;
        /** Show an alert box explaining that a problem happened. */
        alertBox: boolean;
        /** Include the "gory details" (e.g. stack trace) in the alert box. */
        details: boolean;
        /** break into debugger (only works if debugger is already opened) */
        launchDebugger: boolean;
    };
    /** A function that catches otherwise-uncaught exceptions occurring inside ToolAdmin.eventLoop.
     * To customize the behavior of this function, modify [[ToolAdmin.exceptionOptions]].
     * To replace it within your own handler, simply assign to it, e.g.:
     * ```ts
     * ToolAdmin.exceptionHandler = (exception: any): Promise<any> => {
     *  ... your implementation here
     * }
     * ```
     */
    static exceptionHandler(exception: any): Promise<any>;
    private static readonly _removals;
    /** The registered handler method that will update the UI with any property value changes.
     *  @internal
     */
    private _toolSettingsChangeHandler;
    /** Returns the handler registered by the UI layer that allows it to display property changes made by the active Tool. */
    get toolSettingsChangeHandler(): ((toolId: string, syncProperties: DialogPropertySyncItem[]) => void) | undefined;
    set toolSettingsChangeHandler(handler: ((toolId: string, syncProperties: DialogPropertySyncItem[]) => void) | undefined);
    /** The registered handler method that will inform the UI to reload tool setting with properties from active tool.
   *  @internal
   */
    private _reloadToolSettingsHandler;
    /** Returns the handler registered by the UI layer that allows it to display property changes made by the active Tool. */
    get reloadToolSettingsHandler(): (() => void) | undefined;
    set reloadToolSettingsHandler(handler: (() => void) | undefined);
    /** The registered handler method that will trigger UI Sync processing.
     *  @internal
     */
    private _toolSyncUiEventDispatcher;
    /** Returns the handler registered by the UI layer that will trigger UiSyncEvent processing that informs UI component to refresh their state. */
    get toolSyncUiEventDispatcher(): ((syncEventId: string, useImmediateDispatch?: boolean) => void) | undefined;
    set toolSyncUiEventDispatcher(handler: ((syncEventId: string, useImmediateDispatch?: boolean) => void) | undefined);
    /** Handler for keyboard events. */
    private static _keyEventHandler;
    /** @internal */
    onInitialized(): void;
    /** @internal */
    onShutDown(): void;
    /** Get the ScreenViewport where the cursor is currently, if any. */
    get cursorView(): ScreenViewport | undefined;
    /** Called from ViewManager.dropViewport to prevent tools from continuing to operate on the dropped viewport.
     * @internal
     */
    forgetViewport(vp: ScreenViewport): void;
    private getMousePosition;
    private getMouseMovement;
    private getMouseButton;
    private onMouseButton;
    private onWheel;
    private sendTapEvent;
    private doubleTapTimeout;
    private onTouch;
    /** A first-in-first-out queue of ToolEvents. */
    private static _toolEvents;
    private static tryReplace;
    /** @internal */
    private static getNextEvent;
    /** Called from HTML event listeners. Events are processed in the order they're received in ToolAdmin.eventLoop
     * @internal
     */
    static addEvent(ev: Event, vp?: ScreenViewport): void;
    /** Process the next event in the event queue, if any. */
    private processNextEvent;
    private _processingEvent;
    /**
     * Process a single event, plus timer events. Don't start work on new events if the previous one has not finished.
     * @internal
     */
    processEvent(): Promise<void>;
    /** The idleTool handles events that are not otherwise processed. */
    get idleTool(): InteractiveTool;
    set idleTool(idleTool: InteractiveTool);
    /** Return true to filter (ignore) events to the given viewport */
    protected filterViewport(vp: ScreenViewport): boolean;
    /** @internal */
    onInstallTool(tool: InteractiveTool): Promise<boolean>;
    /** @internal */
    onPostInstallTool(tool: InteractiveTool): Promise<void>;
    get viewTool(): ViewTool | undefined;
    get primitiveTool(): PrimitiveTool | undefined;
    /** The currently active InteractiveTool. May be ViewTool, InputCollector, PrimitiveTool, undefined - in that priority order. */
    get activeTool(): InteractiveTool | undefined;
    /** The current tool. May be ViewTool, InputCollector, PrimitiveTool, or IdleTool - in that priority order. */
    get currentTool(): InteractiveTool;
    /** Allow applications to inhibit specific tooltips, such as for maps. */
    wantToolTip(_hit: HitDetail): boolean;
    /** Ask the current tool to provide tooltip contents for the supplied HitDetail. */
    getToolTip(hit: HitDetail): Promise<HTMLElement | string>;
    /**
     * Event raised whenever the active tool changes. This includes PrimitiveTool, ViewTool, and InputCollector.
     * @param newTool The newly activated tool
     */
    readonly activeToolChanged: BeEvent<(tool: Tool, start: StartOrResume) => void>;
    /**
     * Event raised by tools that support edit manipulators like the SelectTool.
     * @param tool The current tool
     */
    readonly manipulatorToolEvent: BeEvent<(tool: Tool, event: ManipulatorToolEvent) => void>;
    private onMouseEnter;
    /** @internal */
    onMouseLeave(vp: ScreenViewport): void;
    /** @internal */
    updateDynamics(ev?: BeButtonEvent, useLastData?: boolean, adjustPoint?: boolean): void;
    sendEndDragEvent(ev: BeButtonEvent): Promise<any>;
    private setCanvasDecoration;
    private pickCanvasDecoration;
    /** Current request for locate/snap */
    private _snapMotionPromise?;
    /** Current request for active tool motion event */
    private _toolMotionPromise?;
    private clearMotionPromises;
    private forceOnMotionSnap;
    private onMotionSnap;
    private onMotionSnapOrSkip;
    private shouldSkipOnMotionSnap;
    private onStartDrag;
    private onMotion;
    private onMotionEnd;
    private onMouseMove;
    adjustPointToACS(pointActive: Point3d, vp: Viewport, perpendicular: boolean): void;
    adjustPointToGrid(pointActive: Point3d, vp: Viewport): void;
    adjustPoint(pointActive: Point3d, vp: ScreenViewport, projectToACS?: boolean, applyLocks?: boolean): void;
    adjustSnapPoint(perpendicular?: boolean): void;
    /** @internal */
    sendButtonEvent(ev: BeButtonEvent): Promise<any>;
    private onButtonDown;
    private onButtonUp;
    /** Called when any *modifier* (Shift, Alt, or Control) key is pressed or released. */
    private onModifierKeyTransition;
    private static getModifierKey;
    /** Process key down events while the Ctrl key is pressed */
    onCtrlKeyPressed(keyEvent: KeyboardEvent): Promise<{
        handled: boolean;
        result: boolean;
    }>;
    /** Process shortcut key events */
    processShortcutKey(_keyEvent: KeyboardEvent, _wentDown: boolean): Promise<boolean>;
    /** Event for every key down and up transition. */
    private onKeyTransition;
    /** Called to undo previous data button for primitive tools or undo last write operation. */
    doUndoOperation(): Promise<boolean>;
    /** Called to redo previous data button for primitive tools or undo last write operation. */
    doRedoOperation(): Promise<boolean>;
    private onActiveToolChanged;
    private onUnsuspendTool;
    /** @internal */
    setInputCollector(newTool?: InputCollector): Promise<void>;
    /** @internal */
    exitInputCollector(): Promise<void>;
    /** @internal */
    startInputCollector(newTool: InputCollector): Promise<void>;
    /** @internal */
    setViewTool(newTool?: ViewTool): Promise<void>;
    /** @internal */
    exitViewTool(): Promise<void>;
    /** @internal */
    startViewTool(newTool: ViewTool): Promise<void>;
    /** @internal */
    setEditCommandHandler(handler?: EditCommandHandler): void;
    /** @internal */
    setPrimitiveTool(newTool?: PrimitiveTool): Promise<void>;
    /** @internal */
    startPrimitiveTool(newTool?: PrimitiveTool): Promise<void>;
    /** Method used by interactive tools to send updated values to UI components, typically showing tool settings.
     * @beta
     */
    syncToolSettingsProperties(toolId: string, syncProperties: DialogPropertySyncItem[]): void;
    /** Method used by interactive tools to send request to reload UI from properties returned via method supplyToolSettingsProperties.
     * @beta
     */
    reloadToolSettingsProperties(): void;
    /** Method used to "bump" the value of a tool setting for the current tool.
     * To "bump" a setting means to toggle a boolean value or cycle through enum values.
     * If no `settingIndex` param is specified, the first setting is bumped.
     * Returns true if the setting was successfully bumped.
     */
    bumpToolSetting(settingIndex?: number): Promise<boolean>;
    /** Method used by interactive tools to inform one or more UI components to refresh. This is typically used to update labels or icons associated with a specific tool.
     * This method should be used when the caller wants the UI layer to process the sync event immediately. Use dispatchUiSyncEvent when the event may be triggered while other
     * more important user interaction processing is required.
     * @param specificSyncEventId Optional sync event id. If not specified then "tool-admin-refresh-ui" is used.
     * @param toolId Optional, will be used if specificSyncEventId is not specified. If used, the resulting sync event Id will be created using `tool-admin-refresh-ui-${toolId}`.toLowerCase()
     */
    dispatchImmediateUiSyncEvent(specificSyncEventId?: string, toolId?: string): void;
    /** Method used by interactive tools to inform one or more UI components to refresh. This is typically used to update labels or icons associated with a specific tool.
     * This method should be used when the caller wants the UI layer to process the sync event on a timer, waiting a few 100 ms, allowing other events that may require a UI refresh
     * to be processed together.
     * @param specificSyncEventId Optional sync event id. If not specified then "tool-admin-refresh-ui" is used.
     * @param toolId Optional, will be used if specificSyncEventId is not specified. If used, the resulting sync event Id will be created using `tool-admin-refresh-ui-${toolId}`.toLowerCase()
     */
    dispatchUiSyncEvent(specificSyncEventId?: string, toolId?: string): void;
    /**
     * Starts the default [[PrimitiveTool]], if any. Generally invoked automatically when other tools exit, so shouldn't be called directly.
     * @note The default tool, when specified, must be a subclass of [[PrimitiveTool]]. A call to startDefaultTool is required to terminate
     * an active [[ViewTool]] or [[InputCollector]] and replace or clear the current [[PrimitiveTool]]. The default tool can not be
     * a subclass of [[ViewTool]] as view tools replace each other and aren't suspended. This means [[ViewTool.exitTool]] would
     * result in the active tool being undefined instead of making the default tool active.
     * The tool's [[Tool.run]] method is invoked with arguments specified by [[defaultToolArgs]].
     * @see [[defaultToolId]] to configure the default tool.
     */
    startDefaultTool(): Promise<void>;
    /**
     * Call from external events or immediate tools that may have invalidated the current primitive tool's state.
     * Examples are undo, which may invalidate any references to elements, or an immediate tool that uses an edit command to write to the iModel,
     * since immediate tools do not replace the active tool.
     * The current primitive tool is expected to call installTool with a new instance, or exitTool to start the default tool.
     * @note Should be called even if the primitive tool is currently suspended by a view tool or input collector.
     */
    restartPrimitiveTool(): Promise<void>;
    setCursor(cursor: string | undefined): void;
    /** @internal */
    testDecorationHit(id: string): boolean;
    /** @internal */
    getDecorationGeometry(hit: HitDetail): GeometryStreamProps | undefined;
    /** @internal */
    decorate(context: DecorateContext): void;
    get isLocateCircleOn(): boolean;
    /** @internal */
    beginDynamics(): void;
    /** @internal */
    endDynamics(): void;
    /** Fill the supplied button event from the current cursor location. */
    fillEventFromCursorLocation(ev: BeButtonEvent, useSnap?: boolean): void;
    /** Fill the supplied button event from the last data button location. */
    fillEventFromLastDataButton(ev: BeButtonEvent): void;
    /** @internal */
    setAdjustedDataPoint(ev: BeButtonEvent): void;
    /** Can be called by tools that wish to emulate mouse button down/up events for onTouchTap. */
    convertTouchTapToButtonDownAndUp(ev: BeTouchEvent, button?: BeButton): Promise<void>;
    /** Can be called by tools that wish to emulate moving the mouse with a button depressed for onTouchMoveStart.
     * @note Calls the tool's onMouseStartDrag method from onMotion.
     */
    convertTouchMoveStartToButtonDownAndMotion(startEv: BeTouchEvent, ev: BeTouchEvent, button?: BeButton): Promise<void>;
    /** Can be called by tools that wish to emulate pressing the mouse button for onTouchStart or onTouchMoveStart. */
    convertTouchStartToButtonDown(ev: BeTouchEvent, button?: BeButton): Promise<void>;
    /** Can be called by tools that wish to emulate releasing the mouse button for onTouchEnd or onTouchComplete.
     * @note Calls the tool's onMouseEndDrag method if convertTouchMoveStartToButtonDownAndMotion was called for onTouchMoveStart.
     */
    convertTouchEndToButtonUp(ev: BeTouchEvent, button?: BeButton): Promise<void>;
    /** Can be called by tools that wish to emulate a mouse motion event for onTouchMove. */
    convertTouchMoveToMotion(ev: BeTouchEvent): Promise<void>;
    /** Can be called by tools to invoke their [[InteractiveTool.onDynamicFrame]] method without requiring a motion event. */
    simulateMotionEvent(): void;
    /** @internal */
    setIncompatibleViewportCursor(restore: boolean): void;
    /** Performs default handling of mouse wheel event (zoom in/out) */
    processWheelEvent(ev: BeWheelEvent, doUpdate: boolean): Promise<EventHandled>;
    /** @internal */
    onSelectedViewportChanged(previous: ScreenViewport | undefined, current: ScreenViewport | undefined): Promise<void>;
    setLocateCircleOn(locateOn: boolean): void;
    setLocateCursor(enableLocate: boolean): void;
    /** Controls how the button event location is adjusted for the active tool */
    get coordinateLockOverrides(): CoordinateLockOverrides;
    set coordinateLockOverrides(coordLockOvr: CoordinateLockOverrides);
    /** @internal */
    callOnCleanup(): Promise<void>;
}
/**
 * Default processor to handle wheel events.
 * @internal
 */
export declare class WheelEventProcessor {
    static process(ev: BeWheelEvent, doUpdate: boolean): Promise<void>;
    private static doZoom;
}
//# sourceMappingURL=ToolAdmin.d.ts.map