/** @packageDocumentation
 * @module Tools
 */
import { Point3d, Transform, Vector3d } from "@itwin/core-geometry";
import { ColorDef } from "@itwin/core-common";
import { HitDetail } from "../HitDetail";
import { IModelConnection } from "../IModelConnection";
import { SelectionSetEvent } from "../SelectionSet";
import { DecorateContext } from "../ViewContext";
import { Viewport } from "../Viewport";
import { BeButtonEvent, BeTouchEvent, EventHandled, InputCollector, Tool } from "./Tool";
import { ManipulatorToolEvent } from "./ToolAdmin";
/** Classes and methods to create on screen control handles for interactive modification of element(s) and pickable decorations.
 * The basic flow is:
 * - Create a sub-class of [[EditManipulator.HandleProvider]] to listen for start of [[SelectTool]] or any other PrimitiveTool that supports handle providers.
 * - Respond to [[ManipulatorToolEvent.Start]] by adding a listener for [[SelectionSet]] change event.
 * - Respond to selection changed event to create control handles as pickable decorations when the desired element(s) or pickable decoration is selected.
 * - Respond to button events on the control handle decoration and run a sub-class of [[EditManipulator.HandleTool]] to modify.
 * @public
 * @extensions
*/
export declare namespace EditManipulator {
    /** Specifies the event for [[EditManipulator.HandleProvider.onManipulatorEvent]] */
    enum EventType {
        /** Control handles should be created, updated, or cleared based on the active selection. */
        Synch = 0,
        /** Control handle modification was cancelled by user. */
        Cancel = 1,
        /** Control handle modification was accepted by user. */
        Accept = 2
    }
    /** Interactive control handle modification is done by installing an [[InputCollector]].
     * Modification typically is started from a click or press and drag while over the handle graphics.
     * The HandleTool base class is set up to define an offset by 2 points. The second point is
     * defined by either another click, or up event when initiated from press and drag.
     * @see [[EditManipulator.HandleProvider]]
     */
    abstract class HandleTool extends InputCollector {
        static toolId: string;
        static hidden: boolean;
        readonly manipulator: HandleProvider;
        constructor(manipulator: HandleProvider);
        /** Establish the initial tool state for handle modification.
         * Default implementation honors the active locks and enables AccuSnap; behavior suitable for a shape vertex handle.
         * @note An InputCollector inherits the tool state of the suspended primitive tool.
         */
        protected init(): void;
        /** Whether to call [[AccuSnap.enableSnap]] for handle modification.
         * @return true to enable snapping to elements.
         */
        protected get wantAccuSnap(): boolean;
        /** Called from reset button up event to allow modification to be cancelled.
         * @return true to cancel modification.
         */
        protected cancel(_ev: BeButtonEvent): boolean;
        /** Called from data button down event to check if enough input has been gathered to complete the modification.
         * @return true to complete modification.
         */
        protected abstract accept(_ev: BeButtonEvent): boolean;
        /** Called following cancel or accept to update the handle provider
         * and return control to suspended PrimitiveTool.
         */
        protected onComplete(_ev: BeButtonEvent, event: EventType): Promise<EventHandled>;
        onDataButtonDown(ev: BeButtonEvent): Promise<EventHandled>;
        onResetButtonUp(ev: BeButtonEvent): Promise<EventHandled>;
        onTouchMove(ev: BeTouchEvent): Promise<void>;
        onTouchComplete(ev: BeTouchEvent): Promise<void>;
        onTouchCancel(ev: BeTouchEvent): Promise<void>;
        onPostInstall(): Promise<void>;
    }
    /** A handle provider maintains a set of controls used to modify element(s) or pickable decorations.
     * The provider works in conjunction with any PrimitiveTool that raises events for [[ToolAdmin.manipulatorToolEvent]].
     * @see [[SelectTool]] The default PrimitiveTool that supports handle providers.
     */
    abstract class HandleProvider {
        iModel: IModelConnection;
        protected _isActive: boolean;
        protected _removeManipulatorToolListener?: () => void;
        protected _removeSelectionListener?: () => void;
        protected _removeDecorationListener?: () => void;
        /** Create a new handle provider to listen for [[ToolAdmin.manipulatorToolEvent]].
         * Usually followed by a call to [[IModelApp.toolAdmin.startDefaultTool]] to immediately raise the [[ManipulatorToolEvent.Start]] event.
         */
        constructor(iModel: IModelConnection);
        /** Call to clear this handle provider. */
        protected stop(): void;
        /** Event raised by a PrimitiveTool that supports handle providers.
         * Add listener for [[IModelConnection.selectionSet.onChanged]] on start event and remove on stop event.
         * Control handles can be created from the active selection set, which may include persistent elements and pickable decorations.
         * @see [[SelectionSet]]
         */
        onManipulatorToolEvent(_tool: Tool, event: ManipulatorToolEvent): void;
        /** Event raised by [[SelectionSet]] when the active selection changes.
         * Calls onManipulatorEvent to let the provider create, update, or clear it's set of controls as appropriate.
         * @see [[SelectionSet]]
         */
        onSelectionChanged(ev: SelectionSetEvent): void;
        /** Register for decorate event to start displaying control handles. */
        protected updateDecorationListener(add: boolean): void;
        /** Sub-classes should override to display the pickable graphics for their controls. */
        decorate(_context: DecorateContext): void;
        /** The provider is responsible for checking if modification by controls is valid.
         * May still wish to present controls for "transient" geometry in non-read/write applications, etc.
         */
        protected abstract createControls(): Promise<boolean>;
        protected clearControls(): void;
        /** A provider can install an [[InputCollector]] to support interactive modification.
         * @return true if a tool was successfully run.
         * @see [[EditManipulator.HandleTool]]
        */
        protected abstract modifyControls(_hit: HitDetail, _ev: BeButtonEvent): Promise<boolean>;
        protected updateControls(): Promise<void>;
        onManipulatorEvent(_eventType: EventType): void;
        /** Sub-classes can override to perform some operation for a double click on a handle. */
        protected onDoubleClick(_hit: HitDetail, _ev: BeButtonEvent): Promise<EventHandled>;
        /** Sub-classes can override to present a menu for a right click on a handle. */
        protected onRightClick(_hit: HitDetail, _ev: BeButtonEvent): Promise<EventHandled>;
        /** Sub-classes can override to respond to a touch tap on a handle. By default, handles are selected by touch drag and taps are ignored. */
        protected onTouchTap(_hit: HitDetail, _ev: BeButtonEvent): Promise<EventHandled>;
        /** Event raised by a PrimitiveTool that supports handle providers to allow a pickable decoration to respond to being located. */
        onDecorationButtonEvent(hit: HitDetail, ev: BeButtonEvent): Promise<EventHandled>;
    }
    /** Utility methods for creating control handles and other decorations. */
    class HandleUtils {
        /** Adjust input color for contrast against view background.
         * @param color The color to adjust.
         * @param vp The viewport to compare.
         * @return color adjusted for view background color or original color if view background color isn't being used.
         */
        static adjustForBackgroundColor(color: ColorDef, vp: Viewport): ColorDef;
        /** Compute a transform that will try to orient a 2d shape (like an arrow) to face the camera.
         * @param vp The viewport to get the rotation from.
         * @param base The world coordinate point to pivot about.
         * @param direction The world coordinate axis to tilt along.
         * @param sizeInches The transform scale specified in screen inches.
         * @returns transform or undefined when input direction is almost perpendicular to viewing direction.
         * @see [[getArrowShape]]
         */
        static getArrowTransform(vp: Viewport, base: Point3d, direction: Vector3d, sizeInches: number): Transform | undefined;
        /** Return array of shape points representing a unit arrow in xy plane pointing in positive x direction. */
        static getArrowShape(baseStart?: number, baseWidth?: number, tipStart?: number, tipEnd?: number, tipWidth?: number, flangeStart?: number, flangeWidth?: number): Point3d[];
    }
}
//# sourceMappingURL=EditManipulator.d.ts.map