/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Tile
 */
import { assert } from "@itwin/core-bentley";
import { Range3d } from "@itwin/core-geometry";
import { nextPoint3d64FromByteStream, TileFormat, TileHeader } from "./TileIO";
/** Flags describing the geometry contained within a tile in iMdl format.
 * @internal
 */
export var ImdlFlags;
(function (ImdlFlags) {
    /** No special flags */
    ImdlFlags[ImdlFlags["None"] = 0] = "None";
    /** The tile contains some curved geometry */
    ImdlFlags[ImdlFlags["ContainsCurves"] = 1] = "ContainsCurves";
    /** Some geometry within the tile range was omitted based on its size */
    ImdlFlags[ImdlFlags["Incomplete"] = 4] = "Incomplete";
    /** The tile must be refined by sub-division, not magnification. */
    ImdlFlags[ImdlFlags["DisallowMagnification"] = 8] = "DisallowMagnification";
    /** The tile's feature table contains features from multiple models. */
    ImdlFlags[ImdlFlags["MultiModelFeatureTable"] = 16] = "MultiModelFeatureTable";
})(ImdlFlags || (ImdlFlags = {}));
/** Describes the maximum major and minor version of the iMdl tile format supported by this version of this package.
 * @internal
 */
export var CurrentImdlVersion;
(function (CurrentImdlVersion) {
    /** The unsigned 16-bit major version number. If the major version specified in the tile header is greater than this value, then this
     * front-end is not capable of reading the tile content. Otherwise, this front-end can read the tile content even if the header specifies a
     * greater minor version than CurrentVersion.Minor, although some data may be skipped.
     */
    CurrentImdlVersion[CurrentImdlVersion["Major"] = 37] = "Major";
    /** The unsigned 16-bit minor version number. If the major version in the tile header is equal to CurrentVersion.Major, then this package can
     * read the tile content even if the minor version in the tile header is greater than this value, although some data may be skipped.
     */
    CurrentImdlVersion[CurrentImdlVersion["Minor"] = 0] = "Minor";
    /** The unsigned 32-bit version number derived from the 16-bit major and minor version numbers. */
    CurrentImdlVersion[CurrentImdlVersion["Combined"] = 2424832] = "Combined";
})(CurrentImdlVersion || (CurrentImdlVersion = {}));
/** Header embedded at the beginning of binary tile data in iMdl format describing its contents.
 * @internal
 */
export class ImdlHeader extends TileHeader {
    /** The size of this header in bytes. */
    headerLength;
    /** Flags describing the geometry contained within the tile */
    flags;
    /** A bounding box no larger than the tile's range, tightly enclosing the tile's geometry; or a null range if the tile is empty */
    contentRange;
    /** The chord tolerance in meters at which the tile's geometry was faceted */
    tolerance;
    /** The number of elements which contributed at least some geometry to the tile content */
    numElementsIncluded;
    /** The number of elements within the tile range which contributed no geometry to the tile content */
    numElementsExcluded;
    /** The total number of bytes in the binary tile data, including this header */
    tileLength;
    /** A bitfield wherein each set bit indicates an empty sub-volume. */
    emptySubRanges;
    get versionMajor() { return this.version >>> 0x10; }
    get versionMinor() { return (this.version & 0xffff) >>> 0; }
    get isValid() { return TileFormat.IModel === this.format; }
    get isReadableVersion() { return this.versionMajor <= CurrentImdlVersion.Major; }
    /** Deserialize a header from the binary data at the stream's current position.
     * If the binary data does not contain a valid header, the Header will be marked 'invalid'.
     */
    constructor(stream) {
        super(stream);
        this.headerLength = stream.readUint32();
        this.flags = stream.readUint32();
        this.contentRange = new Range3d();
        nextPoint3d64FromByteStream(stream, this.contentRange.low);
        nextPoint3d64FromByteStream(stream, this.contentRange.high);
        this.tolerance = stream.readFloat64();
        this.numElementsIncluded = stream.readUint32();
        this.numElementsExcluded = stream.readUint32();
        this.tileLength = stream.readUint32();
        // empty sub-volume bit field introduced in format v02.00
        this.emptySubRanges = this.versionMajor >= 2 ? stream.readUint32() : 0;
        // Skip any unprocessed bytes in header
        const remainingHeaderBytes = this.headerLength - stream.curPos;
        assert(remainingHeaderBytes >= 0);
        stream.advance(remainingHeaderBytes);
        if (stream.isPastTheEnd)
            this.invalidate();
    }
}
/** Header preceding the feature table embedded in an iMdl tile's content.
 * @internal
 */
export class FeatureTableHeader {
    // The number of bytes the entire table occupies.
    length;
    // The number of subcategories in the table.
    // NOTE: This used to be "max features" which was useless and unused. It is only accurate if ImdlFlags.HasMultiModelFeatureTable is set.
    numSubCategories;
    // The number of features in the table.
    count;
    static readFrom(stream) {
        const length = stream.readUint32();
        const maxFeatures = stream.readUint32();
        const count = stream.readUint32();
        return stream.isPastTheEnd ? undefined : new FeatureTableHeader(length, maxFeatures, count);
    }
    static sizeInBytes = 12;
    constructor(length, numSubCategories, count) {
        this.length = length;
        this.numSubCategories = numSubCategories;
        this.count = count;
    }
}
//# sourceMappingURL=IModelTileIO.js.map