/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { Vector3 } from "@vertexvis/geometry";
import regl from "regl";
import shapeBuilder from "regl-shape";
import { axisPositions } from "../../../lib/transforms/axis-lines";
import { computeArrowNdcValues } from "../../../lib/transforms/axis-translation";
import { AxisLine } from "../../../lib/transforms/line";
import { Mesh, TriangleMesh } from "../../../lib/transforms/mesh";
import { ReglComponent } from "../../../lib/webgl/regl-component";
import { computePlaneNdcValues } from "./plane";
import { computePointNdcValues } from "./point";
// The default amount to scale the computed `triangleSize` by when
// computing the points for the hit position indicator.
export const DEFAULT_POINT_SIZE_SCALAR = 0.4;
// The default amount to scale the computed `triangleSize` by when
// computing the points for the hit plane indicator.
export const DEFAULT_PLANE_SIZE_SCALAR = 5;
export const DEFAULT_PLANE_OPACITY = 0.75;
export class HitIndicator extends ReglComponent {
    constructor(canvasElement, colors = {}, opacities = {}) {
        super(canvasElement);
        this.arrowFillColor = colors.arrow;
        this.planeFillColor = colors.plane;
        this.outlineColor = colors.outline;
        this.planeOpacity = opacities.plane;
    }
    updateTransformAndNormal(transform, normal) {
        var _a;
        this.transform = transform;
        this.normal = normal;
        if (transform != null && normal != null && this.frame != null) {
            this.updateAndDraw();
        }
        else {
            this.clear();
            (_a = this.reglFrameDisposable) === null || _a === void 0 ? void 0 : _a.cancel();
            this.reglFrameDisposable = undefined;
        }
    }
    updateColors(colors) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j;
        this.arrowFillColor = (_a = colors.arrow) !== null && _a !== void 0 ? _a : this.arrowFillColor;
        this.planeFillColor = (_b = colors.plane) !== null && _b !== void 0 ? _b : this.planeFillColor;
        this.outlineColor = (_c = colors.outline) !== null && _c !== void 0 ? _c : this.outlineColor;
        (_d = this.arrow) === null || _d === void 0 ? void 0 : _d.updateFillColor(this.arrowFillColor);
        (_e = this.plane) === null || _e === void 0 ? void 0 : _e.updateFillColor(this.planeFillColor);
        (_f = this.arrow) === null || _f === void 0 ? void 0 : _f.updateOutlineColor(this.outlineColor);
        (_g = this.plane) === null || _g === void 0 ? void 0 : _g.updateOutlineColor(this.outlineColor);
        (_h = this.point) === null || _h === void 0 ? void 0 : _h.updateOutlineColor(this.outlineColor);
        (_j = this.axis) === null || _j === void 0 ? void 0 : _j.updateOutlineColor(this.outlineColor);
    }
    updateOpacities(opacities) {
        this.planeOpacity = opacities.plane;
    }
    hasData() {
        return this.transform != null && this.normal != null;
    }
    createOrUpdateElements() {
        if (this.transform != null && this.normal != null && this.frame != null) {
            if (this.arrow == null) {
                this.createElements(this.transform, this.normal, this.frame);
            }
            else {
                this.updateElements(this.transform, this.normal, this.frame);
            }
        }
    }
    createElements(transform, normal, frame) {
        this.reglCommand = regl({
            canvas: this.canvasElement,
            extensions: 'angle_instanced_arrays',
        });
        const { createShape } = shapeBuilder(this.reglCommand);
        const triangleSize = this.computeTriangleSize(Vector3.fromMatrixPosition(transform), frame);
        this.arrow = new TriangleMesh(createShape, 'hit-normal-arrow', computeArrowNdcValues(transform, frame.scene.camera, normal, triangleSize), this.outlineColor, this.arrowFillColor);
        this.plane = new Mesh(createShape, 'hit-plane', computePlaneNdcValues(transform, frame.scene.camera, normal, triangleSize * DEFAULT_PLANE_SIZE_SCALAR), this.outlineColor, this.planeFillColor, {
            opacity: this.getPlaneOpacity(),
            depth: 0.5,
        });
        this.point = new Mesh(createShape, 'hit-position', computePointNdcValues(transform, frame.scene.camera, normal, triangleSize * DEFAULT_POINT_SIZE_SCALAR), this.outlineColor, this.outlineColor, {
            join: 'round',
            depth: 1,
        });
        this.axis = new AxisLine(createShape, 'hit-normal-axis', axisPositions(transform, frame.scene.camera, this.arrow), this.outlineColor, this.arrowFillColor);
        this.availableElements = [this.arrow, this.point, this.plane, this.axis];
    }
    updateElements(transform, normal, frame) {
        var _a;
        const triangleSize = this.computeTriangleSize(Vector3.fromMatrixPosition(transform), frame);
        if (this.arrow != null) {
            this.arrow.updatePoints(computeArrowNdcValues(transform, frame.scene.camera, normal, triangleSize));
            (_a = this.axis) === null || _a === void 0 ? void 0 : _a.updatePoints(axisPositions(transform, frame.scene.camera, this.arrow));
        }
        if (this.plane != null) {
            this.plane.updatePoints(computePlaneNdcValues(transform, frame.scene.camera, normal, triangleSize * DEFAULT_PLANE_SIZE_SCALAR));
        }
        if (this.point != null) {
            this.point.updatePoints(computePointNdcValues(transform, frame.scene.camera, normal, triangleSize * DEFAULT_POINT_SIZE_SCALAR));
        }
    }
    getPlaneOpacity() {
        if (this.planeOpacity != null) {
            return typeof this.planeOpacity === 'string'
                ? parseFloat(this.planeOpacity)
                : this.planeOpacity;
        }
        return DEFAULT_PLANE_OPACITY;
    }
}
//# sourceMappingURL=indicator.js.map
