"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.VibrantVisualsFileExtensionVariants = void 0;
const Log_1 = require("../core/Log");
const ste_events_1 = require("ste-events");
const StorageUtilities_1 = require("../storage/StorageUtilities");
const IProjectItemData_1 = require("../app/IProjectItemData");
const exifr_1 = require("exifr");
const tga_codec_1 = require("@lunapaint/tga-codec");
exports.VibrantVisualsFileExtensionVariants = [
    "_mer.png",
    "_mer.tga",
    "_mers.png",
    "_mers.tga",
    // "_normal.png", <-- too many false positives
    // "_normal.tga",
    ".texture_set.json",
];
class TextureDefinition {
    _file;
    _isLoaded = false;
    _isContentProcessed = false;
    _width;
    _height;
    _errorMessage;
    _errorProcessing;
    _imageData;
    _onLoaded = new ste_events_1.EventDispatcher();
    id;
    get width() {
        return this._width;
    }
    get height() {
        return this._height;
    }
    get errorMessage() {
        return this._errorMessage;
    }
    get errorProcessing() {
        return this._errorProcessing;
    }
    get imageData() {
        return this._imageData;
    }
    get data() {
        if (!this._file || !this._file.content || typeof this._file.content === "string") {
            return undefined;
        }
        return this._file.content;
    }
    get isLoaded() {
        return this._isLoaded;
    }
    get file() {
        return this._file;
    }
    get onLoaded() {
        return this._onLoaded.asEvent();
    }
    set file(newFile) {
        this._file = newFile;
    }
    getPixel(x, y) {
        if (!this._imageData) {
            throw new Error("Image data is not available.");
        }
        const width = this._width ?? 0;
        const height = this._height ?? 0;
        if (x < 0 || x >= width || y < 0 || y >= height) {
            throw new Error("Invalid pixel coordinates.");
        }
        const index = (y * width + x) * 4;
        return {
            r: this._imageData[index],
            g: this._imageData[index + 1],
            b: this._imageData[index + 2],
            a: this._imageData[index + 3],
        };
    }
    get isContentProcessed() {
        return this._isContentProcessed;
    }
    async processContent() {
        if (this._isContentProcessed) {
            return;
        }
        if (!this._file) {
            return;
        }
        if (!this._file.isContentLoaded) {
            await this._file.loadContent();
        }
        if (!this._file.content || !(this._file.content instanceof Uint8Array)) {
            return;
        }
        if (this._file.type !== "tga") {
            const exifr = new exifr_1.Exifr({});
            try {
                await exifr.read(this._file.content);
                const results = await exifr.parse();
                if (!results) {
                    this._errorProcessing = true;
                    this._errorMessage = "No results returned.";
                }
                else {
                    this._width = results.ImageWidth;
                    this._height = results.ImageHeight;
                }
            }
            catch (e) {
                this._errorProcessing = true;
                this._errorMessage = e.message ? e.message : e.toString();
            }
        }
        else {
            try {
                const tga = await (0, tga_codec_1.decodeTga)(this._file.content);
                this._width = tga.image.width;
                this._height = tga.image.height;
            }
            catch (e) {
                this._errorProcessing = true;
                this._errorMessage = e.message ? e.message : e.toString();
            }
        }
        /*
        this usage of pngjs didn't seem to work for a significant portion of PNGs
        same with the upnp library
        if (this._file.type === "png" && this._file.content && this._file.content instanceof Uint8Array) {
          try {
            const pngm = PNG.sync.read(Buffer.from(this._file.content.buffer));
    
            if (pngm.width !== this._width || pngm.height !== this._height) {
              throw new Error("Mismatch in parsed image dimensions.");
            }
    
            this._imageData = new Uint8Array(pngm.data);
          } catch (e: any) {
            console.log("Could not get PNG data for " + this._file.extendedPath);
          }
        }*/
        this._isContentProcessed = true;
    }
    unloadContent() {
        this._isContentProcessed = false;
        this._imageData = undefined;
    }
    static async ensureOnFile(file, loadHandler) {
        let texd;
        if (file.manager === undefined) {
            texd = new TextureDefinition();
            texd.file = file;
            file.manager = texd;
        }
        if (file.manager !== undefined && file.manager instanceof TextureDefinition) {
            texd = file.manager;
            if (!texd.isLoaded) {
                if (loadHandler) {
                    texd.onLoaded.subscribe(loadHandler);
                }
                await texd.load();
            }
        }
        return texd;
    }
    getReferencePath() {
        if (!this._file) {
            return undefined;
        }
        let projectPath = this._file.storageRelativePath;
        return TextureDefinition.getTexturePath(projectPath);
    }
    static canonicalizeTexturePath(projectPath) {
        if (projectPath === undefined) {
            return undefined;
        }
        projectPath = projectPath.toLowerCase();
        const lastPeriod = projectPath.lastIndexOf(".");
        if (lastPeriod >= 0) {
            const removedPart = projectPath.substring(lastPeriod + 1);
            if (StorageUtilities_1.AllowedExtensionsSet.has(removedPart)) {
                projectPath = projectPath.substring(0, lastPeriod);
            }
        }
        return projectPath;
    }
    static getTexturePath(projectPath) {
        const lastPeriod = projectPath.lastIndexOf(".");
        if (lastPeriod >= 0) {
            projectPath = projectPath.substring(0, lastPeriod);
        }
        const ppLower = projectPath.toLowerCase();
        const texturesIndex = ppLower.indexOf("/textures/");
        if (texturesIndex < 0) {
            return undefined;
        }
        return projectPath.substring(texturesIndex + 1);
    }
    persist() { }
    async load() {
        if (this._isLoaded) {
            return;
        }
        if (this._file === undefined) {
            Log_1.default.unexpectedUndefined("TSCDF");
            return;
        }
        await this._file.loadContent();
        if (!this._file.content || typeof this._file.content === "string") {
            return;
        }
        this._isLoaded = true;
        this._onLoaded.dispatch(this, this);
    }
    async addChildItems(project, item) {
        const itemsCopy = project.getItemsByType(IProjectItemData_1.ProjectItemType.texture);
        for (const candItem of itemsCopy) {
            let pf = candItem.primaryFile;
            if (!pf) {
                await candItem.ensureStorage();
                pf = candItem.primaryFile;
            }
            if (pf) {
                const parentFolder = pf.parentFolder;
                if (!parentFolder) {
                    continue;
                }
                if (!parentFolder.isLoaded) {
                    await parentFolder.load();
                }
                let baseName = StorageUtilities_1.default.getBaseFromName(pf.name);
                const parentFiles = parentFolder.files;
                for (const ext of exports.VibrantVisualsFileExtensionVariants) {
                    const vvSidecarFile = parentFiles[baseName + ext];
                    if (vvSidecarFile !== undefined && vvSidecarFile.extendedPath) {
                        const sidecarItem = project.getItemByExtendedOrProjectPath(vvSidecarFile.extendedPath);
                        if (sidecarItem && sidecarItem !== candItem) {
                            candItem.addChildItem(sidecarItem);
                        }
                    }
                }
            }
        }
    }
}
exports.default = TextureDefinition;

//# sourceMappingURL=../maps/minecraft/TextureDefinition.js.map
