/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { Dimensions, Point, Rectangle, Vector3 } from "@vertexvis/geometry";
import { Mapper } from "@vertexvis/utils";
import { encode } from "fast-png";
import { PointToPointHitTester } from "../components/viewer-measurement-distance/hitTest";
import { fromPbFrame } from "../lib/mappers";
import { DepthBuffer, FeatureMap, FramePerspectiveCamera, Orientation, STENCIL_BUFFER_FEATURE_VALUE, StencilBuffer, Viewport, } from "../lib/types";
import { random } from "./random";
const baseDrawFramePayload = {
    sequenceNumber: 1,
    sceneAttributes: {
        visibleBoundingBox: {
            xmin: -100,
            ymin: -100,
            zmin: -100,
            xmax: 100,
            ymax: 100,
            zmax: 100,
        },
        crossSectioning: {
            sectionPlanes: [{ normal: { x: 0, y: 0, z: 0 }, offset: 0 }],
        },
        hasChanged: false,
        displayListSummary: {
            visibleSummary: {
                count: 100,
            },
            selectedVisibleSummary: {
                count: 0,
            },
        },
        modelViewId: { msb: random.integer(), lsb: random.integer() },
    },
    imageAttributes: {
        frameDimensions: { width: 100, height: 50 },
        imageRect: { x: 0, y: 0, width: 100, height: 50 },
        scaleFactor: 1,
    },
    frameCorrelationIds: ['123'],
    image: makeImagePng(100, 50),
    depthBuffer: { value: makeDepthImagePng(100, 50) },
};
export const drawFramePayloadPerspective = {
    ...baseDrawFramePayload,
    sceneAttributes: {
        ...baseDrawFramePayload.sceneAttributes,
        camera: {
            perspective: {
                position: { x: 0, y: 0, z: 100 },
                lookAt: { x: 0, y: 0, z: 0 },
                up: { x: 0, y: 1, z: 0 },
            },
        },
    },
};
export const drawFramePayloadOrthographic = {
    ...baseDrawFramePayload,
    sceneAttributes: {
        ...baseDrawFramePayload.sceneAttributes,
        camera: {
            orthographic: {
                viewVector: { x: 0, y: 0, z: -100 },
                lookAt: { x: 0, y: 0, z: 0 },
                up: { x: 0, y: 1, z: 0 },
                fovHeight: 100,
            },
        },
    },
};
export function copyDrawFramePayloadPerspective(payload, partial) {
    var _a, _b, _c;
    return {
        ...payload,
        ...partial,
        sceneAttributes: {
            ...payload.sceneAttributes,
            ...partial.sceneAttributes,
            camera: {
                ...(_a = partial.sceneAttributes) === null || _a === void 0 ? void 0 : _a.camera,
                perspective: {
                    position: { x: 0, y: 0, z: 100 },
                    lookAt: { x: 0, y: 0, z: 0 },
                    up: { x: 0, y: 1, z: 0 },
                    ...(_c = (_b = partial.sceneAttributes) === null || _b === void 0 ? void 0 : _b.camera) === null || _c === void 0 ? void 0 : _c.perspective,
                },
            },
        },
    };
}
export function makePerspectiveFrame(payload = drawFramePayloadPerspective) {
    return Mapper.ifInvalidThrow(fromPbFrame(Orientation.DEFAULT))(payload);
}
export function makeOrthographicFrame() {
    return Mapper.ifInvalidThrow(fromPbFrame(Orientation.DEFAULT))(drawFramePayloadOrthographic);
}
export function makeImagePng(width, height) {
    const data = new Uint8ClampedArray(width * height * 4);
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const i = y + x;
            data[i + 0] = 255;
            data[i + 1] = 255;
            data[i + 2] = 255;
            data[i + 3] = 255;
        }
    }
    return encode({ width, height, data, depth: 8, channels: 4 });
}
export function makeDepthImagePng(width, height, value = 2 ** 16 - 1) {
    const bytes = makeDepthImageBytes(width, height, value);
    return encode({ width, height, data: bytes, depth: 16, channels: 1 });
}
export function makeDepthImageBytes(width, height, value = 2 ** 16 - 1) {
    const data = new Uint16Array(width * height);
    return data.fill(value);
}
export function makeDepthBuffer(width, height, value = 2 ** 16 - 1, camera) {
    return DepthBuffer.fromPng({ data: makeDepthImageBytes(width, height, value) }, camera !== null && camera !== void 0 ? camera : makePerspectiveFrame().scene.camera, makeImageAttributes(width, height));
}
export function makeStencilImageBytes(width, height, fill) {
    const data = new Uint8Array(width * height * 3);
    for (let i = 0; i < width * height; i++) {
        const x = i % width;
        const y = Math.floor(i / width);
        data[i] = fill(Point.create(x, y));
    }
    return data;
}
export function makeStencilBuffer(width, height, fill, depthBuffer) {
    const data = makeStencilImageBytes(width, height, fill);
    return StencilBuffer.fromPng({ data, channels: 1 }, makeImageAttributes(width, height), data, depthBuffer !== null && depthBuffer !== void 0 ? depthBuffer : makeDepthBuffer(width, height));
}
export function makeFeatureMap(width, height, fill) {
    return FeatureMap.fromPng({
        data: makeFeatureMapBytes(width, height, fill),
        width,
        height,
        channels: 4,
    }, makeImageAttributes(width, height));
}
export function makeFeatureMapBytes(width, height, fill) {
    const data = new Uint8Array(width * height * 4);
    for (let i = 0; i < width * height; i++) {
        const x = i % width;
        const y = Math.floor(i / width);
        const color = fill(Point.create(x, y));
        const offset = i * 4;
        data[offset] = color.r;
        data[offset + 1] = color.g;
        data[offset + 2] = color.b;
        data[offset + 3] = color.a;
    }
    return data;
}
export function makeImageAttributes(width, height) {
    return {
        frameDimensions: Dimensions.create(width, height),
        imageRect: Rectangle.create(0, 0, width, height),
        imageScale: 1,
    };
}
export function makeHitTester({ stencilBuffer, depthBuffer, viewport, camera, } = {}) {
    return new PointToPointHitTester(stencilBuffer !== null && stencilBuffer !== void 0 ? stencilBuffer : makeStencilBuffer(200, 100, () => STENCIL_BUFFER_FEATURE_VALUE), depthBuffer !== null && depthBuffer !== void 0 ? depthBuffer : makeDepthBuffer(200, 100), viewport !== null && viewport !== void 0 ? viewport : new Viewport(200, 100), camera !== null && camera !== void 0 ? camera : new FramePerspectiveCamera(Vector3.forward(), Vector3.origin(), Vector3.up(), 0, 100, 1, 45));
}
export function makeRaycaster() {
    return { hitItems: jest.fn().mockResolvedValue({ hits: [] }) };
}
export function makeHitProvider({ hitTester, raycaster, }) {
    const defaultHitTester = makeHitTester();
    const defaultRaycaster = makeRaycaster();
    return {
        hitTester: () => hitTester !== null && hitTester !== void 0 ? hitTester : defaultHitTester,
        raycaster: async () => raycaster !== null && raycaster !== void 0 ? raycaster : defaultRaycaster,
    };
}
//# sourceMappingURL=fixtures.js.map
