/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { BoundingBox, Point, Vector3 } from "@vertexvis/geometry";
import { toProtoDuration } from "@vertexvis/stream-api";
import { updateLookAtRelativeToBoundingBoxCenter } from "../rendering/vectors";
import { FrameCamera } from "../types";
export class FlyToPositionKeyInteraction {
    constructor(stream, configProvider, imageScaleProvider, sceneProvider) {
        this.stream = stream;
        this.configProvider = configProvider;
        this.imageScaleProvider = imageScaleProvider;
        this.sceneProvider = sceneProvider;
    }
    predicate(e) {
        return e.altKey && e.shiftKey;
    }
    async fn(e) {
        var _a, _b;
        const scale = this.imageScaleProvider();
        const hitResult = await this.stream.hitItems({
            point: Point.scale(e.position, (scale === null || scale === void 0 ? void 0 : scale.x) || 1, (scale === null || scale === void 0 ? void 0 : scale.y) || 1),
        }, true);
        if (((_a = hitResult.hitItems) === null || _a === void 0 ? void 0 : _a.hits) != null &&
            hitResult.hitItems.hits.length > 0 &&
            hitResult.hitItems.hits[0].hitPoint != null) {
            const scene = await this.sceneProvider();
            const camera = (await this.sceneProvider()).camera();
            const hit = hitResult.hitItems.hits[0];
            if (hit.hitPoint != null &&
                hit.hitPoint.x != null &&
                hit.hitPoint.y != null &&
                hit.hitPoint.z != null) {
                const hitPoint = Vector3.create(hit.hitPoint.x, hit.hitPoint.y, hit.hitPoint.z);
                const newLookAt = await this.getLookAtPoint(scene, hitPoint, camera.viewVector);
                await this.stream.flyTo({
                    camera: FrameCamera.toProtobuf(camera
                        .update({
                        lookAt: newLookAt,
                        rotationPoint: newLookAt,
                    })
                        .toFrameCamera()),
                    animation: {
                        duration: toProtoDuration(this.configProvider().animation.durationMs),
                    },
                });
            }
            else {
                console.debug(`No hit position found for fly to position [position={x: ${e.position.x}, y: ${e.position.y}}, hit-id={${(_b = hit.itemId) === null || _b === void 0 ? void 0 : _b.hex}}]`);
            }
        }
        else {
            console.debug(`No hit results found for fly to position [position={x: ${e.position.x}, y: ${e.position.y}}]`);
        }
    }
    getLookAtPoint(scene, hitPoint, viewVector) {
        if (scene.isOrthographic()) {
            // Update the lookAt point to take the center of the model into account
            // This change helps ensure that the lookAt point is consistent between
            // the SDK and back-end system such that the calculated depth buffer is correct.
            return updateLookAtRelativeToBoundingBoxCenter(hitPoint, viewVector, BoundingBox.center(scene.boundingBox()));
        }
        else {
            // For perspective, just return the hit point
            return hitPoint;
        }
    }
}
//# sourceMappingURL=flyToPositionKeyInteraction.js.map
