/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { Vector3 } from "@vertexvis/geometry";
import { Viewport } from "../types";
// Scalar that is used in combination with a perspective camera's
// components to determine the relative size of the meshes.
// This attempts to keep the widget approximately the same
// size as zooming occurs.
export const DEFAULT_PERSPECTIVE_MESH_SCALAR = 0.005;
// Scalar that is used in combination with an orthographic camera's
// components to determine the relative size of the meshes.
// This attempts to keep the widget approximately the same
// size as zooming occurs.
export const DEFAULT_ORTHOGRAPHIC_MESH_SCALAR = 0.00625;
// Scalar that is used to increase the relative triangle size
// in viewers with a small area. This attempts to keep the widget
// approximately the same size for all viewing window sizes.
export const TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_NUMERATOR = 1580000;
// Scalar that is used to increase the relative triangle size
// in viewers with a small area. This attempts to keep the widget
// approximately the same size for all viewing window sizes.
export const TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_DENOMINATOR = 520000;
// Scalar that is used to increase the relative triangle size
// in viewers with a small height. This attempts to keep the widget
// approximately the same size for all viewing window sizes.
export const TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_NUMERATOR = 950;
// Scalar that is used to increase the relative triangle size
// in viewers with a small height. This attempts to keep the widget
// approximately the same size for all viewing window sizes.
export const TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_DENOMINATOR = 45;
export class ReglComponent {
    constructor(canvasElement) {
        this.canvasElement = canvasElement;
        this.availableElements = [];
        this.drawableElements = [];
        this.viewport = new Viewport(canvasElement.width, canvasElement.height);
    }
    dispose() {
        var _a;
        (_a = this.reglFrameDisposable) === null || _a === void 0 ? void 0 : _a.cancel();
    }
    updateFrame(frame, redraw = true) {
        this.frame = frame;
        if (redraw) {
            this.updateAndDraw();
        }
    }
    updateDimensions(canvasElement) {
        this.viewport = new Viewport(canvasElement.width, canvasElement.height);
        this.createOrUpdateElements();
    }
    updateAndDraw() {
        if (this.frame != null && this.hasData()) {
            this.createOrUpdateElements();
            this.sortMeshes(this.frame, ...this.availableElements);
            this.draw();
        }
    }
    /**
     * @internal - visible for testing
     */
    getDrawableElements() {
        return this.drawableElements;
    }
    draw() {
        var _a;
        if (this.reglFrameDisposable == null) {
            this.reglFrameDisposable = (_a = this.reglCommand) === null || _a === void 0 ? void 0 : _a.frame(() => {
                this.drawableElements.forEach((el) => el === null || el === void 0 ? void 0 : el.draw({
                    fill: el.fillColor,
                    opacity: !!el.disabled ? 0.2 : 1,
                }));
            });
        }
    }
    clear() {
        var _a;
        (_a = this.reglCommand) === null || _a === void 0 ? void 0 : _a.clear({
            color: [0, 0, 0, 0],
        });
    }
    sortMeshes(frame, ...drawableElements) {
        const compare = (d1, d2) => d1.points.shortestDistanceFrom(frame.scene.camera.position) -
            d2.points.shortestDistanceFrom(frame.scene.camera.position);
        // Reverse sorted elements to draw the closest element last.
        // This causes it to appear above any other element.
        this.drawableElements = drawableElements.filter((el) => el != null)
            .filter((el) => el.points.valid)
            .sort(compare)
            .reverse();
    }
    computeTriangleSize(position, frame) {
        const baseTriangleSize = frame.scene.camera.isOrthographic()
            ? frame.scene.camera.fovHeight * DEFAULT_ORTHOGRAPHIC_MESH_SCALAR
            : Vector3.magnitude(Vector3.subtract(position, frame.scene.camera.position)) * DEFAULT_PERSPECTIVE_MESH_SCALAR;
        // Increase the triangle size for small viewers
        const canvasArea = this.canvasElement.height * this.canvasElement.width;
        const canvasAreaAdjustment = TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_NUMERATOR /
            (canvasArea + TRIANGLE_SIZE_CANVAS_AREA_ADJUSTMENT_DENOMINATOR);
        // Increase the triangle size for viewers with a small height and large width
        const canvasHeightAdjustment = this.canvasElement.height < 650
            ? TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_NUMERATOR /
                (this.canvasElement.height +
                    TRIANGLE_SIZE_CANVAS_HEIGHT_ADJUSTMENT_DENOMINATOR)
            : 1;
        const sizeAdjustment = Math.max(canvasAreaAdjustment, canvasHeightAdjustment, 1);
        return baseTriangleSize * sizeAdjustment;
    }
}
//# sourceMappingURL=regl-component.js.map
