/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { Dimensions, Vector3 } from "@vertexvis/geometry";
import { protoToDate } from "@vertexvis/stream-api";
import { Mapper as M } from "@vertexvis/utils";
import { Token } from "../token";
import { CrossSectioning, Frame, FrameCameraBase, FrameImage, FrameScene, Orientation, SceneViewSummary, } from "../types";
import { fromPbJsUuid, fromPbJsUuid2l } from "./corePbJs";
import { fromPbBoundingBox3f, fromPbDim, fromPbRect, fromPbVector3f, } from "./geometry";
import { fromPbRGBi } from "./material";
import { fromPbBytesValue } from "./scalar";
export const fromPbPerspectiveCamera = M.defineMapper(M.read(M.mapProp('position', M.compose(M.required('position'), fromPbVector3f)), M.mapProp('lookAt', M.compose(M.required('lookAt'), fromPbVector3f)), M.mapProp('up', M.compose(M.required('up'), fromPbVector3f)), M.getProp('fovY')), ([position, lookAt, up, fovY]) => {
    return {
        position,
        lookAt,
        up,
        fovY: (fovY === null || fovY === void 0 ? void 0 : fovY.value) != null ? fovY.value : 45,
    };
});
export const fromPbOrthographicCamera = M.defineMapper(M.read(M.mapProp('viewVector', M.compose(M.required('viewVector'), fromPbVector3f)), M.mapProp('lookAt', M.compose(M.required('lookAt'), fromPbVector3f)), M.mapProp('up', M.compose(M.required('up'), fromPbVector3f)), M.mapProp('fovHeight', M.required('fovHeight'))), ([viewVector, lookAt, up, fovHeight]) => ({
    viewVector,
    lookAt,
    up,
    fovHeight,
}));
export const fromPbCamera = M.defineMapper(M.read(M.mapProp('position', M.ifDefined(fromPbVector3f)), M.mapProp('lookAt', M.ifDefined(fromPbVector3f)), M.mapProp('up', M.ifDefined(fromPbVector3f)), M.mapProp('perspective', M.ifDefined(fromPbPerspectiveCamera)), M.mapProp('orthographic', M.ifDefined(fromPbOrthographicCamera))), ([position, lookAt, up, perspective, orthographic]) => {
    var _a;
    return ((_a = perspective !== null && perspective !== void 0 ? perspective : orthographic) !== null && _a !== void 0 ? _a : {
        position: position !== null && position !== void 0 ? position : Vector3.back(),
        lookAt: lookAt !== null && lookAt !== void 0 ? lookAt : Vector3.origin(),
        up: up !== null && up !== void 0 ? up : Vector3.up(),
        fovY: 45,
    });
});
export const fromPbSectionPlane = M.defineMapper(M.read(M.mapProp('normal', M.compose(M.required('normal'), fromPbVector3f)), M.requiredProp('offset')), ([normal, offset]) => ({ normal, offset }));
const fromPbImageAttributes = M.defineMapper(M.read(M.mapProp('frameDimensions', M.compose(M.required('frameDimensions'), fromPbDim)), M.mapProp('imageRect', M.compose(M.required('imageRect'), fromPbRect)), M.mapProp('scaleFactor', M.required('scaleFactor'))), ([frameDimensions, imageRect, imageScale]) => ({
    frameDimensions,
    imageRect,
    imageScale,
}));
export const fromPbCrossSectioning = M.defineMapper(M.read(M.mapProp('sectionPlanes', M.compose(M.required('sectionPlanes'), M.mapArray(fromPbSectionPlane))), M.mapProp('highlightColor', M.ifDefined(fromPbRGBi))), ([sectionPlanes, highlightColor]) => CrossSectioning.create({
    sectionPlanes,
    highlightColor: highlightColor || undefined,
}));
const fromPbItemSetSummary = M.defineMapper(M.read(M.requiredProp('count'), M.mapProp('boundingBox', M.ifDefined(fromPbBoundingBox3f))), ([count, boundingBox]) => ({
    count,
    boundingBox: boundingBox !== null && boundingBox !== void 0 ? boundingBox : undefined,
}));
const fromPbDisplayListSummary = M.defineMapper(M.read(M.mapProp('visibleSummary', M.ifDefined(fromPbItemSetSummary)), M.mapProp('selectedVisibleSummary', M.ifDefined(fromPbItemSetSummary))), ([visibleSummary, selectedVisibleSummary]) => SceneViewSummary.create({
    visibleSummary: visibleSummary !== null && visibleSummary !== void 0 ? visibleSummary : undefined,
    selectedVisibleSummary: selectedVisibleSummary !== null && selectedVisibleSummary !== void 0 ? selectedVisibleSummary : undefined,
}));
const fromPbFrameImageAttributes = M.defineMapper(M.read(M.mapProp('imageAttributes', M.compose(M.required('imageAttributes'), fromPbImageAttributes))), ([imageAttr]) => imageAttr);
const fromPbFrameImage = M.defineMapper(M.read(fromPbFrameImageAttributes, M.mapProp('image', M.required('image'))), ([imageAttr, image]) => new FrameImage(imageAttr, image));
const fromPbSceneAttributes = M.defineMapper(M.read(M.mapRequiredProp('camera', fromPbCamera), M.mapRequiredProp('visibleBoundingBox', fromPbBoundingBox3f), M.mapRequiredProp('crossSectioning', fromPbCrossSectioning), M.requiredProp('hasChanged'), M.mapRequiredProp('displayListSummary', fromPbDisplayListSummary), M.mapProp('modelViewId', M.ifDefined(fromPbJsUuid2l))), ([camera, boundingBox, crossSectioning, hasChanged, displayListSummary, modelViewId,]) => ({
    camera,
    boundingBox,
    crossSectioning,
    hasChanged,
    displayListSummary,
    modelViewId: modelViewId != null ? modelViewId : undefined,
}));
const fromPbFrameSceneAttributes = M.defineMapper(M.read(M.mapProp('sceneAttributes', M.compose(M.required('sceneAttributes'), fromPbSceneAttributes))), ([sceneAttr]) => sceneAttr);
const fromPbFrameCamera = M.defineMapper(M.read(fromPbFrameSceneAttributes, fromPbFrameImageAttributes), ([sceneAttr, imageAttr]) => FrameCameraBase.fromBoundingBox(sceneAttr.camera, sceneAttr.boundingBox, Dimensions.aspectRatio(imageAttr.frameDimensions)));
function fromPbFrameScene(worldOrientation) {
    return M.defineMapper(M.read(fromPbFrameSceneAttributes, fromPbFrameCamera), ([sceneAttr, camera]) => new FrameScene(camera, sceneAttr.boundingBox, sceneAttr.crossSectioning, worldOrientation, sceneAttr.hasChanged, sceneAttr.displayListSummary, sceneAttr.modelViewId));
}
export function fromPbFrame(worldOrientation) {
    return M.defineMapper(M.read(M.mapProp('frameCorrelationIds', (ids) => (ids != null ? ids : [])), M.requiredProp('sequenceNumber'), M.compose(fromPbFrameImageAttributes, M.getProp('frameDimensions')), fromPbFrameScene(worldOrientation), fromPbFrameImage, M.mapProp('depthBuffer', fromPbBytesValue), M.mapProp('featureMap', fromPbBytesValue), M.mapProp('temporalRefinementCorrelationId', (id) => id != null ? fromPbJsUuid(id) : null)), ([cIds, seq, fd, s, i, db, fm, trci]) => new Frame(cIds, trci || '', seq, fd, i, s, db, fm));
}
export function fromPbFrameOrThrow(worldOrientation) {
    return M.ifInvalidThrow(fromPbFrame(worldOrientation));
}
export const fromPbWorldOrientation = M.defineMapper(M.compose(M.required('orientation'), M.read(M.mapProp('up', M.compose(M.required('up'), fromPbVector3f)), M.mapProp('front', M.compose(M.required('front'), fromPbVector3f)))), ([up, front]) => new Orientation(up, front));
export const fromPbWorldOrientationOrThrow = M.ifInvalidThrow(fromPbWorldOrientation);
const fromPbStencilBufferResult = M.defineMapper(M.read(M.mapRequiredProp('imageAttributes', fromPbImageAttributes), M.requiredProp('stencilBuffer'), M.mapRequiredProp('depthBuffer', M.compose(fromPbBytesValue, M.required('depthBuffer')))), ([imageAttributes, stencilBuffer, depthBuffer]) => ({
    imageAttributes,
    stencilBuffer,
    depthBuffer,
}));
export const fromPbStencilBuffer = fromPbStreamResponse('stencilBuffer', fromPbStencilBufferResult);
export const fromPbStencilBufferOrThrow = M.ifInvalidThrow(fromPbStencilBuffer);
function fromPbStreamResponse(prop, mapper) {
    return M.mapRequiredProp(prop, mapper);
}
export const fromPbToken = M.defineMapper(M.read(M.requiredProp('token'), M.requiredProp('expiresIn')), ([token, expiresIn]) => Token.create(token, expiresIn));
export const fromPbStartStreamResponse = M.defineMapper(M.read(M.compose(M.requiredProp('startStream'), M.mapRequiredProp('streamId', fromPbJsUuid)), M.compose(M.requiredProp('startStream'), M.mapRequiredProp('sceneId', fromPbJsUuid)), M.compose(M.requiredProp('startStream'), M.mapRequiredProp('sceneViewId', fromPbJsUuid)), M.compose(M.requiredProp('startStream'), M.mapRequiredProp('sessionId', fromPbJsUuid)), M.compose(M.requiredProp('startStream'), M.mapRequiredProp('worldOrientation', fromPbWorldOrientation)), M.compose(M.requiredProp('startStream'), M.mapRequiredProp('token', fromPbToken))), ([streamId, sceneId, sceneViewId, sessionId, worldOrientation, token]) => ({
    streamId,
    sceneId,
    sceneViewId,
    sessionId: sessionId,
    worldOrientation,
    token,
}));
export const fromPbStartStreamResponseOrThrow = M.ifInvalidThrow(fromPbStartStreamResponse);
export const fromPbReconnectResponse = M.defineMapper(M.read(M.compose(M.requiredProp('reconnect'), M.mapRequiredProp('token', fromPbToken))), ([token]) => ({ token }));
export const fromPbReconnectResponseOrThrow = M.ifInvalidThrow(fromPbReconnectResponse);
export const fromPbRefreshTokenResponse = M.defineMapper(M.compose(M.requiredProp('refreshToken'), M.requiredProp('token'), fromPbToken), (token) => token);
export const fromPbRefreshTokenResponseOrThrow = M.ifInvalidThrow(fromPbRefreshTokenResponse);
export const fromPbSyncTimeResponse = M.defineMapper(M.compose(M.requiredProp('syncTime'), M.requiredProp('replyTime'), M.read(M.requiredProp('seconds'), M.requiredProp('nanos'))), ([seconds, nanos]) => protoToDate({ seconds, nanos }));
export const fromPbSyncTimeResponseOrThrow = M.ifInvalidThrow(fromPbSyncTimeResponse);
//# sourceMappingURL=frameStreaming.js.map
