"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module WebGL
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.lineCodeTextureSize = void 0;
exports.initializeLineCodeCapacity = initializeLineCodeCapacity;
exports.initializeDefaultPatterns = initializeDefaultPatterns;
exports.resetLineCodeState = resetLineCodeState;
exports.lineCodeFromLinePixels = lineCodeFromLinePixels;
exports.onLineCodeAssigned = onLineCodeAssigned;
exports.getLineCodePatterns = getLineCodePatterns;
exports.lineCodeTextureCapacity = lineCodeTextureCapacity;
const core_bentley_1 = require("@itwin/core-bentley");
const core_common_1 = require("@itwin/core-common");
const textureSize = 32;
// Initial capacity - will be updated to System.maxTextureSize in initializeLineCodeCapacity().
// This value is used only for tests that don't initialize the full System.
let maxLineCodeSlots = 16384;
const patternToCode = new Map();
const patterns = [];
const assignmentEvent = new core_bentley_1.BeEvent();
let defaultPatternsInitialized = false;
/** Initialize the maximum line code slots based on System's maxTextureSize.
 * Must be called before initializeDefaultPatterns().
 * @internal
 */
function initializeLineCodeCapacity(maxTexSize) {
    // Cap at the smaller of maxTextureSize or theoretical maximum (65,536)
    maxLineCodeSlots = Math.min(maxTexSize, 65536);
}
const defaultPatterns = [
    core_common_1.LinePixels.Solid,
    core_common_1.LinePixels.Code1,
    core_common_1.LinePixels.Code2,
    core_common_1.LinePixels.Code3,
    core_common_1.LinePixels.Code4,
    core_common_1.LinePixels.Code5,
    core_common_1.LinePixels.Code6,
    core_common_1.LinePixels.Code7,
    core_common_1.LinePixels.HiddenLine,
    core_common_1.LinePixels.Invisible,
];
function normalizePatternValue(pixels) {
    switch (pixels) {
        case core_common_1.LinePixels.Invalid:
            return normalizePatternValue(core_common_1.LinePixels.Solid);
        case core_common_1.LinePixels.Solid:
        case core_common_1.LinePixels.Code0:
            return 0xffffffff;
        default:
            return pixels >>> 0;
    }
}
function assignCodeForPattern(pattern) {
    const normalized = pattern >>> 0;
    const existing = patternToCode.get(normalized);
    if (undefined !== existing)
        return existing;
    if (patterns.length >= maxLineCodeSlots) {
        // Exceeded maximum supported line patterns
        return 0;
    }
    const code = patterns.length;
    patterns.push(normalized);
    patternToCode.set(normalized, code);
    assignmentEvent.raiseEvent({ code, pattern: normalized });
    return code;
}
/** Initialize default line patterns. Called when System is ready.
 * @internal
 */
function initializeDefaultPatterns() {
    if (defaultPatternsInitialized)
        return;
    defaultPatternsInitialized = true;
    for (const pattern of defaultPatterns) {
        const normalized = normalizePatternValue(pattern);
        if (undefined !== normalized)
            assignCodeForPattern(normalized);
    }
}
/** Reset initialization state - used when System reinitializes.
 * @internal
 */
function resetLineCodeState() {
    patternToCode.clear();
    patterns.length = 0;
    defaultPatternsInitialized = false;
}
/** Map a LinePixels value to a texture row index that identifies the corresponding pattern. */
function lineCodeFromLinePixels(pixels) {
    // Ensure default patterns are initialized (for tests that don't call System.onInitialized)
    initializeDefaultPatterns();
    const normalized = normalizePatternValue(pixels);
    if (undefined === normalized)
        return 0;
    return assignCodeForPattern(normalized);
}
/** @internal */
function onLineCodeAssigned(listener) {
    assignmentEvent.addListener(listener);
    return () => assignmentEvent.removeListener(listener);
}
/** @internal */
function getLineCodePatterns() {
    return patterns;
}
/** @internal */
exports.lineCodeTextureSize = textureSize;
/** Get the current capacity of the line code texture.
 * @internal
 */
function lineCodeTextureCapacity() {
    return maxLineCodeSlots;
}
//# sourceMappingURL=LineCode.js.map