"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
const Log_1 = require("../core/Log");
const ste_events_1 = require("ste-events");
const StorageUtilities_1 = require("../storage/StorageUtilities");
const Project_1 = require("../app/Project");
const ContentIndex_1 = require("../core/ContentIndex");
const Database_1 = require("./Database");
const IProjectItemData_1 = require("../app/IProjectItemData");
const BlockTypeDefinition_1 = require("./BlockTypeDefinition");
const Utilities_1 = require("../core/Utilities");
class BlocksCatalogDefinition {
    blocksCatalog;
    _file;
    _isLoaded = false;
    _onLoaded = new ste_events_1.EventDispatcher();
    get isLoaded() {
        return this._isLoaded;
    }
    get file() {
        return this._file;
    }
    get onLoaded() {
        return this._onLoaded.asEvent();
    }
    set file(newFile) {
        this._file = newFile;
    }
    static async ensureOnFile(file, loadHandler) {
        let et;
        if (file.manager === undefined) {
            et = new BlocksCatalogDefinition();
            et.file = file;
            file.manager = et;
        }
        if (file.manager !== undefined && file.manager instanceof BlocksCatalogDefinition) {
            et = file.manager;
            if (!et.isLoaded && loadHandler) {
                et.onLoaded.subscribe(loadHandler);
            }
            await et.load();
        }
        return et;
    }
    getBlockDefinition(id) {
        if (!this.blocksCatalog) {
            return undefined;
        }
        if (this.blocksCatalog[id]) {
            return this.blocksCatalog[id];
        }
        const colon = id.indexOf(":");
        if (colon >= 0) {
            id = id.substring(colon + 1);
        }
        return this.blocksCatalog[id];
    }
    ensureBlockDefinition(id) {
        if (!this.blocksCatalog) {
            this.blocksCatalog = {};
        }
        if (this.blocksCatalog[id]) {
            return this.blocksCatalog[id];
        }
        const colon = id.indexOf(":");
        if (colon >= 0) {
            let noColonId = id.substring(colon + 1);
            if (this.blocksCatalog[noColonId]) {
                return this.blocksCatalog[noColonId];
            }
        }
        this.blocksCatalog[id] = {};
        return this.blocksCatalog[id];
    }
    setBlockDefinition(id, catalogResource) {
        if (!this.blocksCatalog) {
            this.blocksCatalog = {};
        }
        if (this.blocksCatalog[id]) {
            return this.blocksCatalog[id];
        }
        const colon = id.indexOf(":");
        if (colon >= 0) {
            let noColonId = id.substring(colon + 1);
            if (this.blocksCatalog[noColonId]) {
                return this.blocksCatalog[noColonId];
            }
        }
        this.blocksCatalog[id] = catalogResource;
        this.persist();
        return this.blocksCatalog[id];
    }
    static async getBlockCatalog(project) {
        const blockCatalogItems = project.getItemsByType(IProjectItemData_1.ProjectItemType.blocksCatalogResourceJson);
        if (blockCatalogItems && blockCatalogItems.length > 0) {
            await blockCatalogItems[0].ensureStorage();
            if (blockCatalogItems[0].primaryFile) {
                return await BlocksCatalogDefinition.ensureOnFile(blockCatalogItems[0].primaryFile);
            }
        }
        return undefined;
    }
    static async ensureBlockCatalog(project) {
        let blockCatalog = await this.getBlockCatalog(project);
        if (blockCatalog) {
            return blockCatalog;
        }
        const defaultRp = await project.getDefaultResourcePackFolder();
        if (defaultRp) {
            const blockCatalogFile = defaultRp.ensureFile("blocks.json");
            blockCatalogFile.setContent('{"format_version": "1.21.40"}');
            project.ensureItemFromFile(blockCatalogFile, IProjectItemData_1.ProjectItemType.blocksCatalogResourceJson, Project_1.FolderContext.resourcePack);
            return await BlocksCatalogDefinition.ensureOnFile(blockCatalogFile);
        }
        return undefined;
    }
    getDefaultTextureId(id) {
        const ref = this.getBlockDefinition(id);
        if (ref && ref.textures) {
            if (typeof ref.textures === "string") {
                return ref.textures;
            }
            if (ref.textures["side"]) {
                return ref.textures["side"];
            }
            else if (ref.textures["up"]) {
                return ref.textures["up"];
            }
            else {
                for (const key in ref.textures) {
                    return ref.textures[key];
                }
            }
        }
        return undefined;
    }
    getTextureReferences() {
        const textureRefs = [];
        if (this.blocksCatalog) {
            for (const resourceId in this.blocksCatalog) {
                const resource = this.blocksCatalog[resourceId];
                if (resource && resource.textures) {
                    if (!textureRefs.includes(resourceId)) {
                        textureRefs.push(resourceId);
                    }
                }
            }
        }
        return textureRefs;
    }
    async getDependenciesList(project) {
        const dependencies = {
            unused: [],
            vanillaOverride: [],
        };
        if (this.blocksCatalog) {
            const myBlockIds = {};
            let projectItemsCopy = project.getItemsCopy();
            for (const item of projectItemsCopy) {
                if (item.itemType === IProjectItemData_1.ProjectItemType.blockTypeBehavior) {
                    await item.ensureFileStorage();
                    if (item.primaryFile) {
                        const blockTypeDef = await BlockTypeDefinition_1.default.ensureOnFile(item.primaryFile);
                        if (blockTypeDef && blockTypeDef.id && Utilities_1.default.isUsableAsObjectKey(blockTypeDef.id)) {
                            myBlockIds[blockTypeDef.id] = true;
                            const colon = blockTypeDef.id.indexOf(":");
                            if (colon >= 0) {
                                const noColonId = blockTypeDef.id.substring(colon + 1);
                                myBlockIds[noColonId] = true;
                            }
                        }
                    }
                }
            }
            for (const resourceId in this.blocksCatalog) {
                if (resourceId !== "format_version") {
                    const resource = this.blocksCatalog[resourceId];
                    if (resource && (resource.textures || resource.sound || resource.carried_textures)) {
                        if (!dependencies.unused.includes(resourceId) && !dependencies.vanillaOverride.includes(resourceId)) {
                            let foundMatch = myBlockIds[resourceId] === true;
                            if (!foundMatch) {
                                let resourceColon = resourceId.indexOf(":");
                                if (resourceColon < 0) {
                                    const vanillaTermMatches = await Database_1.default.getVanillaMatches("minecraft:" + resourceId, true, [
                                        ContentIndex_1.AnnotationCategory.blockTypeSource,
                                    ]);
                                    if (vanillaTermMatches && vanillaTermMatches.length > 0) {
                                        dependencies.vanillaOverride.push(resourceId);
                                        foundMatch = true;
                                    }
                                }
                                else if (resourceId.startsWith("minecraft:")) {
                                    const vanillaTermMatches = await Database_1.default.getVanillaMatches(resourceId, true, [
                                        ContentIndex_1.AnnotationCategory.blockTypeSource,
                                    ]);
                                    if (vanillaTermMatches && vanillaTermMatches.length > 0) {
                                        dependencies.vanillaOverride.push(resourceId);
                                        foundMatch = true;
                                    }
                                }
                            }
                            if (!foundMatch) {
                                dependencies.unused.push(resourceId);
                            }
                        }
                    }
                }
            }
        }
        return dependencies;
    }
    removeId(id) {
        if (this.blocksCatalog) {
            this.blocksCatalog[id] = undefined;
        }
    }
    persist() {
        if (this._file === undefined) {
            return;
        }
        const defString = JSON.stringify(this.blocksCatalog, null, 2);
        this._file.setContent(defString);
    }
    async load() {
        if (this._isLoaded) {
            return;
        }
        if (this._file === undefined) {
            Log_1.default.unexpectedUndefined("BCRDF");
            return;
        }
        await this._file.loadContent();
        if (!this._file.content || this._file.content instanceof Uint8Array) {
            return;
        }
        let data = {};
        let result = StorageUtilities_1.default.getJsonObject(this._file);
        if (result) {
            data = result;
        }
        this.blocksCatalog = data;
        this._isLoaded = true;
        this._onLoaded.dispatch(this, this);
    }
}
exports.default = BlocksCatalogDefinition;

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