"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeOverlayIntoBase = mergeOverlayIntoBase;
const textures_1 = require("../../textures");
const FACE_NAMES = ['north', 'south', 'east', 'west', 'top', 'bottom'];
const getFaceTexture = (primitive, face) => {
    switch (face) {
        case 'north':
            return primitive.north;
        case 'south':
            return primitive.south;
        case 'east':
            return primitive.east;
        case 'west':
            return primitive.west;
        case 'top':
            return primitive.top;
        case 'bottom':
            return primitive.bottom;
        default:
            return undefined;
    }
};
const setFaceTexture = (primitive, face, textureId) => {
    switch (face) {
        case 'north':
            primitive.north = textureId;
            break;
        case 'south':
            primitive.south = textureId;
            break;
        case 'east':
            primitive.east = textureId;
            break;
        case 'west':
            primitive.west = textureId;
            break;
        case 'top':
            primitive.top = textureId;
            break;
        case 'bottom':
            primitive.bottom = textureId;
            break;
        default:
            break;
    }
};
function mergeOverlayIntoBase(entity, primitive) {
    const textureLookup = new Map(entity.textures.map(entry => [entry.id, entry]));
    const patternLookup = new Map(entity.patterns.map(entry => [entry.id, entry]));
    const materialLookup = new Map(entity.materials.map(entry => [entry.id, entry]));
    FACE_NAMES.forEach(face => {
        const overlayTextureId = (0, textures_1.resolveOverlayFaceTextureId)(primitive, face);
        if (!overlayTextureId) {
            return;
        }
        const baseTextureId = (0, textures_1.resolveFaceTextureId)(primitive, face) ?? getFaceTexture(primitive, face);
        if (!baseTextureId) {
            setFaceTexture(primitive, face, overlayTextureId);
            return;
        }
        const overlayTexture = textureLookup.get(overlayTextureId);
        const overlayPattern = overlayTexture ? patternLookup.get(overlayTexture.pattern) : undefined;
        if (!overlayTexture || !overlayPattern) {
            return;
        }
        const baseTexture = textureLookup.get(baseTextureId);
        const basePattern = baseTexture ? patternLookup.get(baseTexture.pattern) : undefined;
        if (!baseTexture || !basePattern) {
            setFaceTexture(primitive, face, overlayTextureId);
            return;
        }
        const baseData = Array.isArray(basePattern.data) ? basePattern.data.slice() : [];
        const overlayData = Array.isArray(overlayPattern.data) ? overlayPattern.data : [];
        const materialIndexLookup = new Map();
        baseTexture.materials.forEach((materialId, idx) => {
            if (!materialIndexLookup.has(materialId)) {
                materialIndexLookup.set(materialId, idx);
            }
        });
        const ensureMaterialIndex = (materialId) => {
            if (!materialId) {
                return undefined;
            }
            const existing = materialIndexLookup.get(materialId);
            if (existing !== undefined) {
                return existing;
            }
            const nextIndex = baseTexture.materials.length;
            baseTexture.materials.push(materialId);
            materialIndexLookup.set(materialId, nextIndex);
            return nextIndex;
        };
        const opaqueOverlayIndex = (overlayValue) => {
            if (overlayValue === undefined) {
                return undefined;
            }
            const overlayMaterialId = overlayTexture.materials[overlayValue];
            if (!overlayMaterialId) {
                return undefined;
            }
            const overlayMaterial = materialLookup.get(overlayMaterialId);
            if (overlayMaterial && typeof overlayMaterial.opacity === 'number' && overlayMaterial.opacity <= 0) {
                return undefined;
            }
            const mapped = ensureMaterialIndex(overlayMaterialId);
            return mapped;
        };
        const combined = baseData.map((value, index) => {
            const overlayValue = overlayData[index];
            const mappedIndex = opaqueOverlayIndex(overlayValue);
            if (mappedIndex === undefined) {
                return value;
            }
            return mappedIndex;
        });
        basePattern.data = combined;
        basePattern.size = [...overlayPattern.size];
    });
}
//# sourceMappingURL=merge-overlay.js.map