/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { Vector3 } from "@vertexvis/geometry";
import { targetIsElement } from "./dom";
import { ViewerWalkModeOperation } from "./model";
export class WalkInteractionHandler {
    constructor(model) {
        this.model = model;
        this.pressed = {};
        this.handleKeyUp = async (event) => {
            const key = event.key.toLocaleLowerCase();
            this.pressed = Object.keys(this.pressed)
                .filter((k) => k !== key)
                .reduce((pressed, k) => ({ ...pressed, [k]: true }), {});
            if (Object.keys(this.pressed).length === 0 && this.interval != null) {
                this.endInteraction();
            }
        };
        this.endInteraction = async () => {
            var _a;
            this.clearInterval();
            await ((_a = this.api) === null || _a === void 0 ? void 0 : _a.endInteraction());
        };
        this.handleKeyDown = this.handleKeyDown.bind(this);
        this.handleKeyUp = this.handleKeyUp.bind(this);
        this.handleEnabledChange = this.handleEnabledChange.bind(this);
        this.restartInteraction = this.restartInteraction.bind(this);
        this.updateCamera = this.updateCamera.bind(this);
        this.handlers = {
            [ViewerWalkModeOperation.MOVE_DOWN]: this.moveDown.bind(this),
            [ViewerWalkModeOperation.MOVE_UP]: this.moveUp.bind(this),
            [ViewerWalkModeOperation.PIVOT_DOWN]: this.pivotDown.bind(this),
            [ViewerWalkModeOperation.PIVOT_LEFT]: this.pivotLeft.bind(this),
            [ViewerWalkModeOperation.PIVOT_RIGHT]: this.pivotRight.bind(this),
            [ViewerWalkModeOperation.PIVOT_UP]: this.pivotUp.bind(this),
            [ViewerWalkModeOperation.WALK_BACKWARD]: this.walkBackward.bind(this),
            [ViewerWalkModeOperation.WALK_FORWARD]: this.walkForward.bind(this),
            [ViewerWalkModeOperation.WALK_LEFT]: this.walkLeft.bind(this),
            [ViewerWalkModeOperation.WALK_RIGHT]: this.walkRight.bind(this),
        };
        this.enabledChangeDisposable = this.model.onEnabledChange(this.handleEnabledChange);
        this.keyBindingsChangeDisposable = this.model.onKeyBindingsChange(this.restartInteraction);
        this.configurationChangeDisposable = this.model.onConfigurationChange(this.restartInteraction);
    }
    dispose() {
        var _a, _b, _c;
        this.disable();
        (_a = this.enabledChangeDisposable) === null || _a === void 0 ? void 0 : _a.dispose();
        (_b = this.keyBindingsChangeDisposable) === null || _b === void 0 ? void 0 : _b.dispose();
        (_c = this.configurationChangeDisposable) === null || _c === void 0 ? void 0 : _c.dispose();
        window.removeEventListener('keydown', this.handleKeyDown);
        window.removeEventListener('keyup', this.handleKeyUp);
    }
    initialize(_, api) {
        this.api = api;
        this.handleEnabledChange(this.model.getEnabled());
    }
    enable() {
        this.disable();
        window.addEventListener('keydown', this.handleKeyDown);
        window.addEventListener('keyup', this.handleKeyUp);
    }
    disable() {
        window.removeEventListener('keydown', this.handleKeyDown);
        window.removeEventListener('keyup', this.handleKeyUp);
    }
    handleKeyDown(event) {
        const key = event.key.toLowerCase();
        const exclude = targetIsElement(event.target) &&
            this.model.isElementExcluded(event.target);
        if (!event.repeat && !exclude) {
            this.pressed = { ...this.pressed, [key]: true };
            this.tryBeginInteraction();
        }
    }
    handleEnabledChange(enabled) {
        if (enabled) {
            this.enable();
        }
        else {
            this.disable();
        }
    }
    restartInteraction() {
        this.clearInterval();
        this.tryBeginInteraction();
    }
    tryBeginInteraction() {
        if (Object.keys(this.pressed).length > 0 && this.someOperationMatches()) {
            this.beginInteraction();
        }
    }
    beginInteraction() {
        var _a, _b;
        if (!((_a = this.api) === null || _a === void 0 ? void 0 : _a.isInteracting())) {
            (_b = this.api) === null || _b === void 0 ? void 0 : _b.beginInteraction();
        }
        if (this.interval == null) {
            this.interval = setInterval(this.updateCamera, this.model.getKeyboardRepeatInterval());
        }
    }
    clearInterval() {
        if (this.interval != null) {
            clearInterval(this.interval);
            this.interval = undefined;
        }
    }
    updateCamera() {
        Object.keys(this.handlers).forEach((key) => {
            const op = key;
            if (this.model.operationMatches(op, this.pressed)) {
                this.handlers[op]();
            }
        });
    }
    someOperationMatches() {
        return Object.keys(this.handlers).some((op) => this.model.operationMatches(op, this.pressed));
    }
    pivotLeft() {
        var _a;
        (_a = this.api) === null || _a === void 0 ? void 0 : _a.pivotCamera(0, this.model.getKeyboardPivotDegrees());
    }
    pivotRight() {
        var _a;
        (_a = this.api) === null || _a === void 0 ? void 0 : _a.pivotCamera(0, -this.model.getKeyboardPivotDegrees());
    }
    pivotUp() {
        var _a;
        (_a = this.api) === null || _a === void 0 ? void 0 : _a.pivotCamera(-this.model.getKeyboardPivotDegrees(), 0);
    }
    pivotDown() {
        var _a;
        (_a = this.api) === null || _a === void 0 ? void 0 : _a.pivotCamera(this.model.getKeyboardPivotDegrees(), 0);
    }
    walkForward() {
        var _a;
        (_a = this.api) === null || _a === void 0 ? void 0 : _a.walk(Vector3.scale(this.relativeWalkSpeed(), Vector3.forward()));
    }
    walkBackward() {
        var _a;
        (_a = this.api) === null || _a === void 0 ? void 0 : _a.walk(Vector3.scale(this.relativeWalkSpeed(), Vector3.back()));
    }
    walkLeft() {
        var _a;
        (_a = this.api) === null || _a === void 0 ? void 0 : _a.walk(Vector3.scale(this.relativeWalkSpeed(), Vector3.left()));
    }
    walkRight() {
        var _a;
        (_a = this.api) === null || _a === void 0 ? void 0 : _a.walk(Vector3.scale(this.relativeWalkSpeed(), Vector3.right()));
    }
    moveUp() {
        var _a;
        (_a = this.api) === null || _a === void 0 ? void 0 : _a.walk(Vector3.scale(this.relativeWalkSpeed(), Vector3.down()));
    }
    moveDown() {
        var _a;
        (_a = this.api) === null || _a === void 0 ? void 0 : _a.walk(Vector3.scale(this.relativeWalkSpeed(), Vector3.up()));
    }
    relativeWalkSpeed() {
        return this.model.getKeyboardWalkSpeed() / 500;
    }
}
//# sourceMappingURL=interactions.js.map
