import { LinearSRGBColorSpace, TextureLoader } from "three";
import { EXRLoader } from "three/examples/jsm/loaders/EXRLoader.js";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
import { isDevEnvironment } from "../debug/index.js";
import { getParam, PromiseAllWithErrors, resolveUrl } from "../engine_utils.js";
import { resolveReferences } from "./extension_utils.js";
import { NEEDLE_pmrem } from "./NEEDLE_pmrem.js";
// the lightmap extension is aimed to also export export skyboxes and custom reflection maps
// should we rename it?
// should we split it into multiple extensions?
export const EXTENSION_NAME = "NEEDLE_lightmaps";
const debug = getParam("debuglightmapsextension") || getParam("debuglightmaps");
export var LightmapType;
(function (LightmapType) {
    LightmapType[LightmapType["Lightmap"] = 0] = "Lightmap";
    LightmapType[LightmapType["Skybox"] = 1] = "Skybox";
    LightmapType[LightmapType["Reflection"] = 2] = "Reflection";
})(LightmapType || (LightmapType = {}));
export class NEEDLE_lightmaps {
    get name() {
        return EXTENSION_NAME;
    }
    parser;
    registry;
    source;
    constructor(parser, reg, source) {
        this.parser = parser;
        this.registry = reg;
        this.source = source;
    }
    afterRoot(_result) {
        const extensions = this.parser.json.extensions;
        if (extensions) {
            const ext = extensions[EXTENSION_NAME];
            if (ext) {
                const arr = ext.textures;
                if (!arr?.length) {
                    return null;
                }
                if (debug)
                    console.log(ext);
                return new Promise(async (resolve, _reject) => {
                    const dependencies = [];
                    for (const entry of arr) {
                        if (entry.pointer) {
                            if (debug)
                                console.log(entry);
                            let res = null;
                            // Check if the pointer is a json pointer:
                            if (entry.pointer.startsWith("/textures/") || /** legacy support e.g. SOC */ entry.pointer.startsWith("textures/")) {
                                if (debug)
                                    console.log("Load texture from gltf", entry.pointer);
                                res = resolveReferences(this.parser, entry.pointer).then(res => this.resolveTexture(entry, res));
                            }
                            // The pointer can be a string to a file on disc
                            else if (typeof entry.pointer === "string") {
                                if (debug)
                                    console.log("Load texture from path", entry.pointer);
                                const path = resolveUrl(this.source, entry.pointer);
                                const isPMREM = path.endsWith(".pmrem.ktx2");
                                let loader;
                                if (path.endsWith(".exr"))
                                    loader = new EXRLoader(this.parser.options.manager);
                                else if (path.endsWith(".hdr"))
                                    loader = new RGBELoader(this.parser.options.manager);
                                else if (isPMREM)
                                    loader = this.parser.options.ktx2Loader; // We re-use the KTX2Loader configured on the GLTFLoader, which has GPU support detection built in
                                else
                                    loader = new TextureLoader(this.parser.options.manager);
                                res = loader.loadAsync(path, undefined).then(res => {
                                    if (isPMREM && res) {
                                        NEEDLE_pmrem.postprocess(res);
                                    }
                                    return this.resolveTexture(entry, res);
                                });
                            }
                            else if (entry.pointer === undefined) {
                                // data is missing?
                            }
                            if (res)
                                dependencies.push(res);
                        }
                    }
                    const results = await PromiseAllWithErrors(dependencies);
                    if (results?.anyFailed) {
                        if (isDevEnvironment() || debug)
                            console.error("[NEEDLE_lightmaps]Error during extension loading:", results);
                    }
                    resolve();
                });
            }
        }
        return null;
    }
    resolveTexture(entry, res) {
        const tex = res;
        if (debug)
            console.log("Light Texture loaded:", tex);
        if (tex?.isTexture) {
            if (!this.registry)
                console.log(LightmapType[entry.type], entry.pointer, tex);
            else {
                tex.colorSpace = LinearSRGBColorSpace;
                this.registry.registerTexture(this.source, entry.type, tex, entry.index);
            }
        }
    }
}
//# sourceMappingURL=NEEDLE_lightmaps.js.map