import { LogicalLevelTechnique } from "./logicalLevelTechnique";
import { PhysicalLevelTechnique } from "./physicalLevelTechnique";
import { decodeVarintInt32 } from "../../decoding/integerDecodingUtils";
import { PhysicalStreamType } from "./physicalStreamType";
import { DictionaryType } from "./dictionaryType";
import { OffsetType } from "./offsetType";
import { LengthType } from "./lengthType";
export function decodeStreamMetadata(tile, offset) {
    const streamMetadata = decodeStreamMetadataInternal(tile, offset);
    if (streamMetadata.logicalLevelTechnique1 === LogicalLevelTechnique.MORTON) {
        return decodePartialMortonEncodedStreamMetadata(streamMetadata, tile, offset);
    }
    if ((LogicalLevelTechnique.RLE === streamMetadata.logicalLevelTechnique1 ||
        LogicalLevelTechnique.RLE === streamMetadata.logicalLevelTechnique2) &&
        PhysicalLevelTechnique.NONE !== streamMetadata.physicalLevelTechnique) {
        return decodePartialRleEncodedStreamMetadata(streamMetadata, tile, offset);
    }
    return streamMetadata;
}
function decodePartialMortonEncodedStreamMetadata(streamMetadata, tile, offset) {
    const mortonInfo = decodeVarintInt32(tile, offset, 2);
    return {
        physicalStreamType: streamMetadata.physicalStreamType,
        logicalStreamType: streamMetadata.logicalStreamType,
        logicalLevelTechnique1: streamMetadata.logicalLevelTechnique1,
        logicalLevelTechnique2: streamMetadata.logicalLevelTechnique2,
        physicalLevelTechnique: streamMetadata.physicalLevelTechnique,
        numValues: streamMetadata.numValues,
        byteLength: streamMetadata.byteLength,
        decompressedCount: streamMetadata.decompressedCount,
        numBits: mortonInfo[0],
        coordinateShift: mortonInfo[1],
    };
}
function decodePartialRleEncodedStreamMetadata(streamMetadata, tile, offset) {
    const rleInfo = decodeVarintInt32(tile, offset, 2);
    return {
        physicalStreamType: streamMetadata.physicalStreamType,
        logicalStreamType: streamMetadata.logicalStreamType,
        logicalLevelTechnique1: streamMetadata.logicalLevelTechnique1,
        logicalLevelTechnique2: streamMetadata.logicalLevelTechnique2,
        physicalLevelTechnique: streamMetadata.physicalLevelTechnique,
        numValues: streamMetadata.numValues,
        byteLength: streamMetadata.byteLength,
        decompressedCount: rleInfo[1],
        runs: rleInfo[0],
        numRleValues: rleInfo[1],
    };
}
function decodeStreamMetadataInternal(tile, offset) {
    const stream_type = tile[offset.get()];
    const physicalStreamType = Object.values(PhysicalStreamType)[stream_type >> 4];
    let logicalStreamType = null;
    switch (physicalStreamType) {
        case PhysicalStreamType.DATA:
            logicalStreamType = {
                dictionaryType: Object.values(DictionaryType)[stream_type & 0xf],
            };
            break;
        case PhysicalStreamType.OFFSET:
            logicalStreamType = {
                offsetType: Object.values(OffsetType)[stream_type & 0xf],
            };
            break;
        case PhysicalStreamType.LENGTH:
            logicalStreamType = {
                lengthType: Object.values(LengthType)[stream_type & 0xf],
            };
            break;
    }
    offset.increment();
    const encodings_header = tile[offset.get()];
    const llt1 = Object.values(LogicalLevelTechnique)[encodings_header >> 5];
    const llt2 = Object.values(LogicalLevelTechnique)[(encodings_header >> 2) & 0x7];
    const plt = Object.values(PhysicalLevelTechnique)[encodings_header & 0x3];
    offset.increment();
    const sizeInfo = decodeVarintInt32(tile, offset, 2);
    const numValues = sizeInfo[0];
    const byteLength = sizeInfo[1];
    return {
        physicalStreamType,
        logicalStreamType,
        logicalLevelTechnique1: llt1,
        logicalLevelTechnique2: llt2,
        physicalLevelTechnique: plt,
        numValues,
        byteLength,
        decompressedCount: numValues,
    };
}
//# sourceMappingURL=streamMetadataDecoder.js.map