/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { Point } from "@vertexvis/geometry";
import { getMouseClientPosition } from "../dom";
export class MouseInteraction {
    setPosition(position) {
        this.currentPosition = position;
    }
    getPosition() {
        return this.currentPosition;
    }
    getType() {
        return this.type;
    }
    beginDrag(event, canvasPosition, api, element) {
        // noop
    }
    drag(event, api) {
        // noop
    }
    endDrag(event, api) {
        if (this.currentPosition != null) {
            api.endInteraction();
            this.currentPosition = undefined;
        }
    }
    async zoom(delta, api) {
        // noop
    }
}
export class RotateInteraction extends MouseInteraction {
    constructor() {
        super(...arguments);
        this.type = 'rotate';
    }
    beginDrag(event, canvasPosition, api) {
        if (this.currentPosition == null) {
            this.currentPosition = Point.create(event.screenX, event.screenY);
            api.beginInteraction();
        }
    }
    drag(event, api) {
        if (this.currentPosition != null) {
            const position = Point.create(event.screenX, event.screenY);
            const delta = Point.subtract(position, this.currentPosition);
            api.rotateCamera(delta);
            this.currentPosition = position;
        }
    }
    endDrag(event, api) {
        super.endDrag(event, api);
    }
}
export class RotatePointInteraction extends MouseInteraction {
    constructor() {
        super(...arguments);
        this.type = 'rotate-point';
    }
    beginDrag(event, canvasPosition, api) {
        if (this.currentPosition == null) {
            this.currentPosition = Point.create(event.screenX, event.screenY);
            this.startingPosition = canvasPosition;
            api.beginInteraction();
        }
    }
    drag(event, api) {
        if (this.currentPosition != null && this.startingPosition != null) {
            const position = Point.create(event.screenX, event.screenY);
            const delta = Point.subtract(position, this.currentPosition);
            api.rotateCameraAtPoint(delta, this.startingPosition);
            this.currentPosition = position;
        }
    }
    endDrag(event, api) {
        super.endDrag(event, api);
    }
}
export class ZoomInteraction extends MouseInteraction {
    constructor(interactionConfigProvider) {
        super();
        this.interactionConfigProvider = interactionConfigProvider;
        this.type = 'zoom';
        this.didTransformBegin = false;
    }
    async beginDrag(event, canvasPosition, api, element) {
        if (this.currentPosition == null) {
            this.currentPosition = Point.create(event.clientX, event.clientY);
            const rect = element.getBoundingClientRect();
            const point = getMouseClientPosition(event, rect);
            this.startPt = point;
            await api.beginInteraction();
        }
    }
    async drag(event, api) {
        if (this.currentPosition != null) {
            const position = Point.create(event.clientX, event.clientY);
            const delta = Point.subtract(position, this.currentPosition);
            if (this.startPt != null) {
                await api.zoomCameraToPoint(this.startPt, delta.y);
                this.currentPosition = position;
            }
        }
    }
    endDrag(event, api) {
        super.endDrag(event, api);
        this.stopInteractionTimer();
        this.didTransformBegin = false;
        this.startPt = undefined;
    }
    async zoom(delta, api) {
        await this.operateWithTimer(api, () => api.zoomCamera(this.getDirectionalDelta(delta)));
    }
    async zoomToPoint(pt, delta, api) {
        await this.operateWithTimer(api, () => api.zoomCameraToPoint(pt, this.getDirectionalDelta(delta)));
    }
    async beginInteraction(api) {
        this.didTransformBegin = true;
        await api.beginInteraction();
    }
    async endInteraction(api) {
        this.didTransformBegin = false;
        await api.endInteraction();
    }
    resetInteractionTimer(api) {
        this.stopInteractionTimer();
        this.startInteractionTimer(api);
    }
    getDirectionalDelta(delta) {
        return this.interactionConfigProvider().reverseMouseWheelDirection
            ? -delta
            : delta;
    }
    getInteractionDelay() {
        return this.interactionConfigProvider().mouseWheelInteractionEndDebounce;
    }
    startInteractionTimer(api) {
        this.interactionTimer = window.setTimeout(async () => {
            this.interactionTimer = undefined;
            await this.endInteraction(api);
        }, this.getInteractionDelay());
    }
    stopInteractionTimer() {
        if (this.interactionTimer != null) {
            window.clearTimeout(this.interactionTimer);
            this.interactionTimer = undefined;
        }
    }
    async operateWithTimer(api, f) {
        if (!this.didTransformBegin) {
            await this.beginInteraction(api);
        }
        this.resetInteractionTimer(api);
        f();
    }
}
export class PanInteraction extends MouseInteraction {
    constructor() {
        super(...arguments);
        this.type = 'pan';
    }
    beginDrag(event, canvasPosition, api, element) {
        if (this.currentPosition == null) {
            this.currentPosition = Point.create(event.screenX, event.screenY);
            this.canvasRect = element.getBoundingClientRect();
            api.beginInteraction();
        }
    }
    drag(event, api) {
        if (this.currentPosition != null && this.canvasRect != null) {
            const position = getMouseClientPosition(event, this.canvasRect);
            api.panCameraToScreenPoint(position);
            this.currentPosition = position;
        }
    }
    endDrag(event, api) {
        super.endDrag(event, api);
    }
}
export class TwistInteraction extends MouseInteraction {
    constructor() {
        super(...arguments);
        this.type = 'twist';
    }
    beginDrag(event, canvasPosition, api, element) {
        this.currentPosition = Point.create(event.offsetX, event.offsetY);
        this.canvasRect = element.getBoundingClientRect();
        api.beginInteraction();
    }
    drag(event, api) {
        const position = getMouseClientPosition(event, this.canvasRect);
        this.currentPosition = position;
        api.twistCamera(position);
    }
    endDrag(event, api) {
        super.endDrag(event, api);
    }
}
export class PivotInteraction extends MouseInteraction {
    constructor() {
        super(...arguments);
        this.type = 'pivot';
    }
    beginDrag(event, canvasPosition, api) {
        if (this.currentPosition == null) {
            this.currentPosition = Point.create(event.screenX, event.screenY);
            api.beginInteraction();
        }
    }
    drag(event, api) {
        if (this.currentPosition != null) {
            const position = Point.create(event.screenX, event.screenY);
            const delta = Point.subtract(position, this.currentPosition);
            api.pivotCamera(-0.25 * delta.y, 0.25 * delta.x);
            this.currentPosition = position;
        }
    }
    endDrag(event, api) {
        super.endDrag(event, api);
    }
}
//# sourceMappingURL=mouseInteractions.js.map
