/*---------------------------------------------------------------------------------------------
* 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
 */
import { BeEvent } from "@itwin/core-bentley";
import { LinePixels } from "@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 BeEvent();
let defaultPatternsInitialized = false;
/** Initialize the maximum line code slots based on System's maxTextureSize.
 * Must be called before initializeDefaultPatterns().
 * @internal
 */
export function initializeLineCodeCapacity(maxTexSize) {
    // Cap at the smaller of maxTextureSize or theoretical maximum (65,536)
    maxLineCodeSlots = Math.min(maxTexSize, 65536);
}
const defaultPatterns = [
    LinePixels.Solid,
    LinePixels.Code1,
    LinePixels.Code2,
    LinePixels.Code3,
    LinePixels.Code4,
    LinePixels.Code5,
    LinePixels.Code6,
    LinePixels.Code7,
    LinePixels.HiddenLine,
    LinePixels.Invisible,
];
function normalizePatternValue(pixels) {
    switch (pixels) {
        case LinePixels.Invalid:
            return normalizePatternValue(LinePixels.Solid);
        case LinePixels.Solid:
        case 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
 */
export 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
 */
export function resetLineCodeState() {
    patternToCode.clear();
    patterns.length = 0;
    defaultPatternsInitialized = false;
}
/** Map a LinePixels value to a texture row index that identifies the corresponding pattern. */
export 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 */
export function onLineCodeAssigned(listener) {
    assignmentEvent.addListener(listener);
    return () => assignmentEvent.removeListener(listener);
}
/** @internal */
export function getLineCodePatterns() {
    return patterns;
}
/** @internal */
export const lineCodeTextureSize = textureSize;
/** Get the current capacity of the line code texture.
 * @internal
 */
export function lineCodeTextureCapacity() {
    return maxLineCodeSlots;
}
//# sourceMappingURL=LineCode.js.map