/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Tools
 */
import { IModelApp } from "../IModelApp";
import { BeButton, EventHandled, InteractiveTool } from "./Tool";
import { DefaultViewTouchTool, FitViewTool, ViewHandleType, ViewManip } from "./ViewTool";
/**
 * The default "idle" tool. If no tool is active, or the active tool does not respond to a given
 * event, input events are forwarded to the idle tool. The default idle tool converts middle mouse button events
 * and touch gestures into view navigation operations like pan, zoom, rotate, and fit.
 *
 * Controls are as follows:
 * - Mouse/keyboard:
 *   - mmb: pan
 *   - shift-mmb: rotate
 *   - wheel: zoom in/out
 *   - double-mmb: fit view
 * - Touch:
 *   - single-finger drag: rotate
 *   - two-finger drag: pan
 *   - pinch: zoom in/out
 *   - double-tap: fit view
 *
 * Touch inputs can be combined e.g. drag two fingers while moving them closer together => pan + zoom in
 * @public
 */
export class IdleTool extends InteractiveTool {
    static toolId = "Idle";
    static hidden = true;
    async onMouseStartDrag(ev) {
        if (!ev.viewport)
            return EventHandled.No;
        let toolId;
        let handleId;
        switch (ev.button) {
            case BeButton.Middle:
                if (ev.isControlKey) {
                    toolId = ev.viewport.view.allow3dManipulations() ? "View.Look" : "View.Scroll";
                    handleId = ev.viewport.view.allow3dManipulations() ? ViewHandleType.Look : ViewHandleType.Scroll;
                }
                else if (ev.isShiftKey) {
                    toolId = "View.Rotate";
                    handleId = ViewHandleType.Rotate;
                }
                else {
                    toolId = "View.Pan";
                    handleId = ViewHandleType.Pan;
                }
                break;
            case BeButton.Data:
                // When no active tool is present install rotate view tool on drag of data button
                if (undefined !== IModelApp.toolAdmin.activeTool)
                    return EventHandled.No;
                toolId = "View.Rotate";
                handleId = ViewHandleType.Rotate;
                break;
            default:
                // When no active tool is present install pan view tool on drag of reset button
                if (undefined !== IModelApp.toolAdmin.activeTool)
                    return EventHandled.No;
                toolId = "View.Pan";
                handleId = ViewHandleType.Pan;
                break;
        }
        const currTool = IModelApp.toolAdmin.viewTool;
        if (currTool) {
            if (currTool instanceof ViewManip)
                return currTool.startHandleDrag(ev, handleId); // See if current view tool can drag using this handle, leave it active regardless...
            return EventHandled.No;
        }
        const viewTool = IModelApp.tools.create(toolId, ev.viewport, true, true);
        if (viewTool && await viewTool.run())
            return viewTool.startHandleDrag(ev);
        return EventHandled.Yes;
    }
    async onMiddleButtonUp(ev) {
        if (!ev.viewport)
            return EventHandled.No;
        if (ev.isDoubleClick) {
            const viewTool = new FitViewTool(ev.viewport, true);
            return await viewTool.run() ? EventHandled.Yes : EventHandled.No;
        }
        if (ev.isControlKey || ev.isShiftKey)
            return EventHandled.No;
        IModelApp.tentativePoint.process(ev);
        return EventHandled.Yes;
    }
    async onMouseWheel(ev) { return IModelApp.toolAdmin.processWheelEvent(ev, true); }
    async onTouchMoveStart(ev, startEv) {
        const tool = new DefaultViewTouchTool(startEv, ev);
        return await tool.run() ? EventHandled.Yes : EventHandled.No;
    }
    async onTouchTap(ev) {
        if (ev.isSingleTap) {
            // Send data down/up for single finger tap.
            await IModelApp.toolAdmin.convertTouchTapToButtonDownAndUp(ev, BeButton.Data);
            return EventHandled.Yes;
        }
        else if (ev.isTwoFingerTap) {
            // Send reset down/up for two finger tap.
            await IModelApp.toolAdmin.convertTouchTapToButtonDownAndUp(ev, BeButton.Reset);
            return EventHandled.Yes;
        }
        else if (ev.isDoubleTap) {
            const vp = ev.viewport;
            if (undefined === vp)
                return EventHandled.No;
            // Fit view on single finger double tap.
            const tool = new FitViewTool(vp, true);
            return await tool.run() ? EventHandled.Yes : EventHandled.No;
        }
        return EventHandled.No;
    }
    async exitTool() { }
    async run() { return true; }
}
//# sourceMappingURL=IdleTool.js.map