"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
const Project_1 = require("./Project");
const ProjectContent_1 = require("./ProjectContent");
const IProjectData_1 = require("./IProjectData");
const IProjectItemData_1 = require("./IProjectItemData");
const StorageUtilities_1 = require("./../storage/StorageUtilities");
const ZipStorage_1 = require("../storage/ZipStorage");
const ProjectItemUtilities_1 = require("./ProjectItemUtilities");
const ProjectAutogeneration_1 = require("./ProjectAutogeneration");
const Database_1 = require("../minecraft/Database");
const Log_1 = require("../core/Log");
const SoundDefinitionCatalogDefinition_1 = require("../minecraft/SoundDefinitionCatalogDefinition");
const SoundCatalogDefinition_1 = require("../minecraft/SoundCatalogDefinition");
const MinecraftUtilities_1 = require("../minecraft/MinecraftUtilities");
const IGalleryItem_1 = require("./IGalleryItem");
const ProjectUtilities_1 = require("./ProjectUtilities");
const ImageEditsDefinition_1 = require("../design/ImageEditsDefinition");
/// Does create operations for project items.
class ProjectItemCreateManager {
    static async _getDefaultBehaviorPackPath(project) {
        const bpFolder = await project.ensureDefaultBehaviorPackFolder();
        if (project.projectFolder === null) {
            return undefined;
        }
        const defaultPath = bpFolder.getFolderRelativePath(project.projectFolder);
        return defaultPath;
    }
    static async _getDefaultBehaviorPackFolderPath(project, name) {
        const bpFolder = await project.ensureDefaultBehaviorPackFolder();
        if (project.projectFolder === null) {
            return undefined;
        }
        const subfolder = bpFolder.ensureFolder(name);
        await subfolder.ensureExists();
        const defaultPath = subfolder.getFolderRelativePath(project.projectFolder);
        return defaultPath;
    }
    static async _getDefaultDesignPackFolderPath(project, name) {
        const dpFolder = await project.ensureDefaultDesignPackFolder();
        if (project.projectFolder === null) {
            return undefined;
        }
        const subfolder = dpFolder.ensureFolder(name);
        await subfolder.ensureExists();
        const defaultPath = subfolder.getFolderRelativePath(project.projectFolder);
        return defaultPath;
    }
    static async _getDefaultResourcePackPath(project) {
        const rpFolder = await project.ensureDefaultResourcePackFolder();
        if (project.projectFolder === null) {
            return undefined;
        }
        const defaultPath = rpFolder.getFolderRelativePath(project.projectFolder);
        return defaultPath;
    }
    static async _getDefaultResourcePackFolderPath(project, name) {
        const rpFolder = await project.ensureDefaultResourcePackFolder();
        if (project.projectFolder === null) {
            return undefined;
        }
        const subfolder = rpFolder.ensureFolder(name);
        await subfolder.ensureExists();
        const defaultPath = subfolder.getFolderRelativePath(project.projectFolder);
        return defaultPath;
    }
    static async _getDefaultScriptsFolderPath(project) {
        const scriptsFolder = await project.ensureMainScriptsFolder();
        if (project.projectFolder === null) {
            return undefined;
        }
        const defaultPath = scriptsFolder.getFolderRelativePath(project.projectFolder);
        return defaultPath;
    }
    static async createNewItem(project, itemSeed) {
        if (itemSeed.name === "" || itemSeed.name === undefined) {
            itemSeed.name = ProjectItemUtilities_1.default.getNewItemName(itemSeed.itemType);
        }
        let creationData = itemSeed.creationData;
        if (creationData) {
            creationData = ProjectUtilities_1.default.getReplacedCreationDataInObject(project, creationData, itemSeed.name);
        }
        if (itemSeed.itemType) {
            switch (itemSeed.itemType) {
                case IProjectItemData_1.ProjectItemType.js:
                case IProjectItemData_1.ProjectItemType.ts:
                    return ProjectItemCreateManager.createNewScript(project, itemSeed.itemType, itemSeed.name, itemSeed.folder);
                case IProjectItemData_1.ProjectItemType.dataForm:
                    return ProjectItemCreateManager.createNewForm(project, itemSeed.name, itemSeed.folder);
                case IProjectItemData_1.ProjectItemType.audio:
                    return ProjectItemCreateManager.createNewAudio(project, itemSeed.name, itemSeed.folder);
                case IProjectItemData_1.ProjectItemType.texture:
                    return ProjectItemCreateManager.createNewTexture(project, itemSeed.name, itemSeed.folder);
                case IProjectItemData_1.ProjectItemType.designTexture:
                    return ProjectItemCreateManager.createNewDesignTexture(project, itemSeed.name, itemSeed.folder, creationData);
            }
        }
        if (ProjectItemUtilities_1.default.isBehaviorRelated(itemSeed.itemType)) {
            return await ProjectItemCreateManager.createBehaviorPackJsonItem(project, itemSeed);
        }
        else if (ProjectItemUtilities_1.default.isResourceRelated(itemSeed.itemType)) {
            return await ProjectItemCreateManager.createResourcePackJsonItem(project, itemSeed);
        }
        else if (ProjectItemUtilities_1.default.isDesignRelated(itemSeed.itemType)) {
            return await ProjectItemCreateManager.createDesignPackJsonItem(project, itemSeed);
        }
        return undefined;
    }
    static async createNewScript(project, itemType, name, folder) {
        let defaultPath = undefined;
        if (folder && project.projectFolder) {
            defaultPath = folder.getFolderRelativePath(project.projectFolder);
        }
        else {
            defaultPath = await ProjectItemCreateManager._getDefaultScriptsFolderPath(project);
        }
        if (defaultPath === undefined) {
            return;
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, name, itemType === IProjectItemData_1.ProjectItemType.js ? "js" : "ts");
        if (candidateFilePath === undefined) {
            return;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemType === IProjectItemData_1.ProjectItemType.js ? IProjectItemData_1.ProjectItemType.js : IProjectItemData_1.ProjectItemType.ts, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            const baseName = StorageUtilities_1.default.getBaseFromName(file.name);
            if (project.preferredScriptLanguage === IProjectData_1.ProjectScriptLanguage.typeScript) {
                file.setContent(ProjectContent_1.default.getEmptyTypeScript(project.name, baseName));
            }
            else {
                file.setContent(ProjectContent_1.default.getEmptyJavaScript(project.name, baseName));
            }
        }
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
        return pi;
    }
    static async _generateFolderNameForNewItem(project, basePath, baseName) {
        if (project.projectFolder === null) {
            return undefined;
        }
        let index = 0;
        let candidateFolderPath = "";
        let finalPathPrefix = "";
        const projectFolder = project.projectFolder;
        let candidateFolder = null;
        let hash = basePath.indexOf("#");
        let targetFolder = projectFolder;
        while (hash > 0) {
            // dig into container files if needed.
            let containerFilePath = basePath.substring(0, hash);
            basePath = basePath.substring(hash + 1);
            hash = basePath.indexOf("#");
            if (containerFilePath.startsWith(targetFolder.fullPath)) {
                containerFilePath = containerFilePath.substring(targetFolder.fullPath.length);
            }
            finalPathPrefix += containerFilePath + "#";
            const containerFile = await targetFolder.getFileFromRelativePath(containerFilePath);
            if (!containerFile) {
                return undefined;
            }
            const extension = containerFile.type;
            if (extension !== "zip" && extension !== "mcworld" && extension !== "mctemplate") {
                return undefined;
            }
            if (!containerFile.fileContainerStorage) {
                const zipStorage = new ZipStorage_1.default();
                await containerFile.loadContent();
                if (!containerFile.content || !(containerFile.content instanceof Uint8Array)) {
                    return undefined;
                }
                await zipStorage.loadFromUint8Array(containerFile.content, containerFile.name);
                containerFile.fileContainerStorage = zipStorage;
                containerFile.fileContainerStorage.storagePath = containerFilePath + "#";
            }
            targetFolder = containerFile.fileContainerStorage.rootFolder;
        }
        await targetFolder.ensureFolderFromRelativePath(basePath);
        await targetFolder.ensureExists();
        // find a folder name not in use
        do {
            index++;
            candidateFolderPath = basePath + baseName + index;
            candidateFolder = await targetFolder.getFolderFromRelativePath(candidateFolderPath);
        } while (candidateFolder !== null && candidateFolder !== undefined);
        return finalPathPrefix + candidateFolderPath;
    }
    static async _generateFileNameForNewItem(project, basePath, baseName, extension) {
        if (project.projectFolder === null) {
            return undefined;
        }
        let index = 0;
        let candidateFilePath = "";
        let finalPathPrefix = "";
        const projectFolder = project.projectFolder;
        let candidateFile = null;
        let hash = basePath.indexOf("#");
        let targetFolder = projectFolder;
        while (hash > 0) {
            // dig into container files if needed.
            let containerFilePath = basePath.substring(0, hash);
            basePath = basePath.substring(hash + 1);
            hash = basePath.indexOf("#");
            if (containerFilePath.startsWith(targetFolder.fullPath)) {
                containerFilePath = containerFilePath.substring(targetFolder.fullPath.length);
            }
            finalPathPrefix += containerFilePath + "#";
            const containerFile = await targetFolder.getFileFromRelativePath(containerFilePath);
            if (!containerFile) {
                return undefined;
            }
            const extension = containerFile.type;
            if (extension !== "zip" && extension !== "mcworld" && extension !== "mctemplate") {
                return undefined;
            }
            if (!containerFile.fileContainerStorage) {
                const zipStorage = new ZipStorage_1.default();
                await containerFile.loadContent();
                if (!containerFile.content || !(containerFile.content instanceof Uint8Array)) {
                    return undefined;
                }
                await zipStorage.loadFromUint8Array(containerFile.content);
                containerFile.fileContainerStorage = zipStorage;
                containerFile.fileContainerStorage.storagePath = containerFilePath + "#";
            }
            targetFolder = containerFile.fileContainerStorage.rootFolder;
        }
        await targetFolder.ensureFolderFromRelativePath(basePath);
        await targetFolder.ensureExists();
        candidateFilePath = basePath + baseName + "." + extension;
        candidateFile = await targetFolder.getFileFromRelativePath(candidateFilePath);
        if (candidateFile) {
            // find a filename not in use
            do {
                index++;
                candidateFilePath = basePath + baseName + index + "." + extension;
                candidateFile = await targetFolder.getFileFromRelativePath(candidateFilePath);
            } while (candidateFile !== null && candidateFile !== undefined);
        }
        return finalPathPrefix + candidateFilePath;
    }
    static async createNewGameTestScript(project) {
        const defaultPath = await ProjectItemCreateManager._getDefaultBehaviorPackFolderPath(project, "scripts");
        if (defaultPath === undefined) {
            return;
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, "test", "js");
        if (candidateFilePath === undefined) {
            return;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.testJs, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            const baseName = StorageUtilities_1.default.getBaseFromName(file.name);
            if (project.preferredScriptLanguage === IProjectData_1.ProjectScriptLanguage.typeScript) {
                const tsFile = file.parentFolder.ensureFile(baseName + ".ts");
                if (tsFile !== null) {
                    const content = ProjectContent_1.default.getEmptyTestTypeScript(project.name, baseName);
                    tsFile.setContent(content);
                }
            }
            const content = ProjectContent_1.default.getEmptyTestJavaScript(project.name, baseName);
            file.setContent(content);
        }
        await project.save();
    }
    static async createNewFunction(project) {
        const defaultPath = await this._getDefaultBehaviorPackFolderPath(project, "functions");
        if (defaultPath === undefined) {
            return;
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, "action", "mcfunction");
        if (candidateFilePath === undefined) {
            return;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.MCFunction, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            const content = "say hello";
            file.setContent(content);
        }
        await project.save();
    }
    static async createNewStructure(project) {
        const defaultPath = await ProjectItemCreateManager._getDefaultBehaviorPackFolderPath(project, "structures");
        if (defaultPath === undefined) {
            return;
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, "structure", "mcstructure");
        if (candidateFilePath === undefined) {
            return;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.structure, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            const structureBytes = ProjectContent_1.default.generateDefaultStructure();
            if (structureBytes !== undefined) {
                file.setContent(structureBytes);
            }
        }
        await project.save();
    }
    static async createNewActionSet(project) {
        const defaultPath = await this._getDefaultBehaviorPackFolderPath(project, "actions");
        if (defaultPath === undefined) {
            return;
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, defaultPath, "actionset", "json");
        if (candidateFilePath === undefined) {
            return;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.actionSet, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            const baseName = StorageUtilities_1.default.getBaseFromName(file.name);
            const content = ProjectContent_1.default.getEmptyActionSet(project.name, baseName);
            file.setContent(content);
        }
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
    }
    static async createNewDocumentedType(project) {
        const defaultPath = await this._getDefaultBehaviorPackFolderPath(project, "docs");
        if (defaultPath === undefined) {
            return;
        }
        const candidateFolderPath = await ProjectItemCreateManager._generateFolderNameForNewItem(project, defaultPath, "type");
        if (candidateFolderPath === undefined) {
            return;
        }
        const pi = project.ensureItemByProjectPath(candidateFolderPath, IProjectItemData_1.ProjectItemStorageType.folder, candidateFolderPath, IProjectItemData_1.ProjectItemType.documentedTypeFolder, Project_1.FolderContext.metaData, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        await pi.ensureFolderStorage();
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
    }
    static getExistingPath(project, itemType) {
        if (!project.projectFolder) {
            return undefined;
        }
        for (const item of project.items) {
            if (item.itemType === itemType && item.primaryFile) {
                return item.primaryFile.parentFolder.getFolderRelativePath(project.projectFolder);
            }
        }
        return undefined;
    }
    static async createNewForm(project, name, folder) {
        let path = undefined;
        if (!project.projectFolder) {
            return undefined;
        }
        if (folder) {
            path = folder.getFolderRelativePath(project.projectFolder);
        }
        else {
            path = ProjectItemCreateManager.getExistingPath(project, IProjectItemData_1.ProjectItemType.dataForm);
            if (path === undefined) {
                path = await this._getDefaultBehaviorPackFolderPath(project, "forms");
                if (path === undefined) {
                    return undefined;
                }
            }
        }
        if (!path) {
            return undefined;
        }
        if (!name) {
            name = "form";
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, "form.json");
        if (candidateFilePath === undefined) {
            return undefined;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.dataForm, Project_1.FolderContext.metaData, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            const content = "{}";
            file.setContent(content);
        }
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
        return pi;
    }
    static async ensureSoundDefinitionCatalogDefinition(project) {
        const items = project.getItemsByType(IProjectItemData_1.ProjectItemType.soundDefinitionCatalog);
        if (items.length > 0) {
            await items[0].ensureStorage();
            const itemFile = items[0].primaryFile;
            if (itemFile) {
                await itemFile.loadContent();
                if (!itemFile.content) {
                    this.setFileToDefaultContent(itemFile);
                }
                return await SoundDefinitionCatalogDefinition_1.default.ensureOnFile(itemFile);
            }
        }
        let path = undefined;
        if (!project.projectFolder) {
            return undefined;
        }
        path = await this._getDefaultResourcePackFolderPath(project, "sounds");
        if (path === undefined) {
            return undefined;
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, "sound_definitions", "json");
        if (candidateFilePath === undefined) {
            return undefined;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.soundDefinitionCatalog, Project_1.FolderContext.resourcePack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file === null) {
            return undefined;
        }
        this.setFileToDefaultContent(file);
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
        return await SoundDefinitionCatalogDefinition_1.default.ensureOnFile(file);
    }
    static setFileToDefaultContent(file) {
        const content = '{\r\n   "format_version" : "1.20.20",\r\n   "sound_definitions" : {}\r\n}';
        file.setContent(content);
        file.saveContent();
    }
    static async addFromGallery(project, newName, galleryItem) {
        if (galleryItem.type === IGalleryItem_1.GalleryItemType.entityType) {
            await ProjectUtilities_1.default.addEntityTypeFromGallery(project, galleryItem, newName, ProjectUtilities_1.NewEntityTypeAddMode.baseId, async (message) => {
                Log_1.default.message(message);
            });
        }
        else if (galleryItem.type === IGalleryItem_1.GalleryItemType.itemType) {
            await ProjectUtilities_1.default.addItemTypeFromGallery(project, galleryItem, newName);
        }
        else if (galleryItem.type === IGalleryItem_1.GalleryItemType.blockType) {
            await ProjectUtilities_1.default.addBlockTypeFromGallery(project, galleryItem, newName);
        }
        else if (galleryItem.type >= IGalleryItem_1.GalleryItemType.spawnLootRecipes && galleryItem.targetType) {
            await ProjectItemCreateManager.createNewItem(project, {
                itemType: galleryItem.targetType,
                contentTemplateName: galleryItem.id,
                name: newName,
                folder: undefined,
            });
        }
    }
    static async ensureSoundCatalogDefinition(project) {
        const items = project.getItemsByType(IProjectItemData_1.ProjectItemType.soundCatalog);
        if (items.length > 0) {
            await items[0].ensureStorage();
            if (items[0].primaryFile) {
                return await SoundCatalogDefinition_1.default.ensureOnFile(items[0].primaryFile);
            }
        }
        let path = undefined;
        if (!project.projectFolder) {
            return undefined;
        }
        path = await this._getDefaultResourcePackFolderPath(project, "sounds");
        if (path === undefined) {
            return undefined;
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, "sounds", "json");
        if (candidateFilePath === undefined) {
            return undefined;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.soundCatalog, Project_1.FolderContext.resourcePack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file === null) {
            return undefined;
        }
        const content = "{\r\n}";
        file.setContent(content);
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
        return await SoundCatalogDefinition_1.default.ensureOnFile(file);
    }
    static async createDesignPackJsonItem(project, itemSeed) {
        let path = undefined;
        if (!project.projectFolder) {
            return undefined;
        }
        const folderRootsForType = ProjectItemUtilities_1.default.getFolderRootsForType(itemSeed.itemType);
        Log_1.default.assert(folderRootsForType.length > 0, "No folder roots for item type: " + itemSeed.itemType);
        if (itemSeed.folder) {
            path = itemSeed.folder.getFolderRelativePath(project.projectFolder);
        }
        else {
            path = ProjectItemCreateManager.getExistingPath(project, itemSeed.itemType);
            if (path === undefined) {
                path = await this._getDefaultDesignPackFolderPath(project, folderRootsForType[0]);
                if (path === undefined) {
                    return undefined;
                }
            }
        }
        if (!path) {
            return undefined;
        }
        let namespacedId = itemSeed.name;
        let name = namespacedId;
        if (!namespacedId || !name) {
            name = ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
            namespacedId = name;
        }
        name = MinecraftUtilities_1.default.getNamespacedIdName(name);
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, "json");
        if (candidateFilePath === undefined) {
            return undefined;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemSeed.itemType, Project_1.FolderContext.designPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            let content = "{}";
            await Database_1.default.loadContent();
            if (Database_1.default.contentFolder !== null) {
                const contentTemplate = itemSeed.contentTemplateName
                    ? itemSeed.contentTemplateName
                    : ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
                const sourceFile = await Database_1.default.contentFolder.getFileFromRelativePath("/newitemjson/" + contentTemplate + ".json");
                if (sourceFile) {
                    await sourceFile.loadContent();
                    if (sourceFile.content) {
                        content = sourceFile.content.toString();
                    }
                }
            }
            content = content.replace(/examplens:examplename/g, namespacedId);
            file.setContent(content);
        }
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
        return pi;
    }
    static async createBehaviorPackJsonItem(project, itemSeed) {
        let path = undefined;
        if (!project.projectFolder) {
            return undefined;
        }
        const folderRootsForType = ProjectItemUtilities_1.default.getFolderRootsForType(itemSeed.itemType);
        Log_1.default.assert(folderRootsForType.length > 0, "No folder roots for item type: " + itemSeed.itemType);
        if (itemSeed.folder) {
            path = itemSeed.folder.getFolderRelativePath(project.projectFolder);
        }
        else {
            path = ProjectItemCreateManager.getExistingPath(project, itemSeed.itemType);
            if (path === undefined) {
                path = await this._getDefaultBehaviorPackFolderPath(project, folderRootsForType[0]);
                if (path === undefined) {
                    return undefined;
                }
            }
        }
        if (!path) {
            return undefined;
        }
        let namespacedId = itemSeed.name;
        let name = namespacedId;
        if (!namespacedId || !name) {
            name = ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
            namespacedId = name;
        }
        name = MinecraftUtilities_1.default.getNamespacedIdName(name);
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, "json");
        if (candidateFilePath === undefined) {
            return undefined;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemSeed.itemType, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            let content = "{}";
            await Database_1.default.loadContent();
            if (Database_1.default.contentFolder !== null) {
                const contentTemplate = itemSeed.contentTemplateName
                    ? itemSeed.contentTemplateName
                    : ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
                const sourceFile = await Database_1.default.contentFolder.getFileFromRelativePath("/newitemjson/" + contentTemplate + ".json");
                if (sourceFile) {
                    await sourceFile.loadContent();
                    if (sourceFile.content) {
                        content = sourceFile.content.toString();
                    }
                }
            }
            content = content.replace(/examplens:examplename/g, namespacedId);
            file.setContent(content);
        }
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
        return pi;
    }
    static async createResourcePackJsonItem(project, itemSeed) {
        let path = undefined;
        if (!project.projectFolder) {
            return undefined;
        }
        const folderRootsForType = ProjectItemUtilities_1.default.getFolderRootsForType(itemSeed.itemType);
        Log_1.default.assert(folderRootsForType.length > 0, "No folder roots for item type: " + itemSeed.itemType);
        if (itemSeed.folder) {
            path = itemSeed.folder.getFolderRelativePath(project.projectFolder);
        }
        else {
            path = ProjectItemCreateManager.getExistingPath(project, itemSeed.itemType);
            if (path === undefined) {
                path = await this._getDefaultResourcePackFolderPath(project, folderRootsForType[0]);
                if (path === undefined) {
                    return undefined;
                }
            }
        }
        if (!path) {
            return undefined;
        }
        let namespacedId = itemSeed.name;
        let name = namespacedId;
        if (!namespacedId || !name) {
            name = ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
            namespacedId = name;
        }
        name = MinecraftUtilities_1.default.getNamespacedIdName(name);
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, "json");
        if (candidateFilePath === undefined) {
            return undefined;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemSeed.itemType, Project_1.FolderContext.resourcePack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            let content = "{}";
            await Database_1.default.loadContent();
            if (Database_1.default.contentFolder !== null) {
                const contentTemplate = itemSeed.contentTemplateName
                    ? itemSeed.contentTemplateName
                    : ProjectItemUtilities_1.default.getNewItemTechnicalName(itemSeed.itemType);
                const sourceFile = await Database_1.default.contentFolder.getFileFromRelativePath("/newitemjson/" + contentTemplate + ".json");
                if (sourceFile) {
                    await sourceFile.loadContent();
                    if (sourceFile.content) {
                        content = sourceFile.content.toString();
                    }
                }
            }
            content = content.replace(/examplens:examplename/g, namespacedId);
            file.setContent(content);
        }
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
        return pi;
    }
    static async createNewResourcePackBinaryItem(project, sourceFileName, extension, defaultFolderPath, exampleName, itemType, name, folder) {
        let path = undefined;
        if (!project.projectFolder) {
            return undefined;
        }
        await Database_1.default.loadContent();
        if (Database_1.default.contentFolder === null) {
            Log_1.default.unexpectedContentState();
            return undefined;
        }
        const sourceFile = Database_1.default.contentFolder.ensureFile(sourceFileName);
        await sourceFile.loadContent();
        if (!(sourceFile.content instanceof Uint8Array)) {
            Log_1.default.error("Could not find source " + extension + " file content.");
            return;
        }
        if (folder) {
            path = folder.getFolderRelativePath(project.projectFolder);
        }
        else {
            path = ProjectItemCreateManager.getExistingPath(project, itemType);
            if (path === undefined) {
                path = await this._getDefaultResourcePackFolderPath(project, defaultFolderPath);
                if (path === undefined) {
                    return undefined;
                }
            }
        }
        if (!path) {
            return undefined;
        }
        if (!name) {
            name = exampleName;
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, extension);
        if (candidateFilePath === undefined) {
            return undefined;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemType, Project_1.FolderContext.resourcePack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            file.setContent(sourceFile.content);
        }
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
        return pi;
    }
    static async createNewDesignPackBinaryItem(project, sourceFileName, extension, defaultFolderPath, exampleName, itemType, name, folder) {
        let path = undefined;
        if (!project.projectFolder) {
            return undefined;
        }
        await Database_1.default.loadContent();
        if (Database_1.default.contentFolder === null) {
            Log_1.default.unexpectedContentState();
            return undefined;
        }
        const sourceFile = Database_1.default.contentFolder.ensureFile(sourceFileName);
        await sourceFile.loadContent();
        if (!(sourceFile.content instanceof Uint8Array)) {
            Log_1.default.error("Could not find source " + extension + " file content.");
            return;
        }
        if (folder) {
            path = folder.getFolderRelativePath(project.projectFolder);
        }
        else {
            path = ProjectItemCreateManager.getExistingPath(project, itemType);
            if (path === undefined) {
                path = await this._getDefaultDesignPackFolderPath(project, defaultFolderPath);
                if (path === undefined) {
                    return undefined;
                }
            }
        }
        if (!path) {
            return undefined;
        }
        if (!name) {
            name = exampleName;
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path, name, extension);
        if (candidateFilePath === undefined) {
            return undefined;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), itemType, Project_1.FolderContext.designPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            file.setContent(sourceFile.content);
        }
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
        return pi;
    }
    static async createNewDesignTexture(project, name, folder, creationData) {
        const projectItem = await this.createNewDesignPackBinaryItem(project, "blank64.png", "png", "design_textures", "design_texture", IProjectItemData_1.ProjectItemType.designTexture, name, folder);
        if (projectItem && creationData) {
            const imageEdits = await ImageEditsDefinition_1.default.ensureAsAccessoryOnImageProjectItem(projectItem);
            if (imageEdits) {
                await imageEdits.setFromCreationData(creationData);
            }
        }
        return projectItem;
    }
    static async createNewTexture(project, name, folder) {
        return await this.createNewResourcePackBinaryItem(project, "blank64.png", "png", "textures", "texture", IProjectItemData_1.ProjectItemType.texture, name, folder);
    }
    static async createNewAudio(project, name, folder) {
        return await this.createNewResourcePackBinaryItem(project, "blank.ogg", "ogg", "sounds", "sound", IProjectItemData_1.ProjectItemType.audio, name, folder);
    }
    static async createNewWorldTest(project, name, folder) {
        let path = undefined;
        if (!project.projectFolder) {
            return;
        }
        if (folder) {
            path = folder.getFolderRelativePath(project.projectFolder);
        }
        else {
            path = ProjectItemCreateManager.getExistingPath(project, IProjectItemData_1.ProjectItemType.dataForm);
            if (path === undefined) {
                path = await this._getDefaultBehaviorPackFolderPath(project, "forms");
                if (path === undefined) {
                    return;
                }
            }
        }
        if (!path) {
            return;
        }
        if (!name) {
            name = "form";
        }
        const candidateFilePath = await ProjectItemCreateManager._generateFileNameForNewItem(project, path + "tests/", "worldtest", "json");
        if (candidateFilePath === undefined) {
            return;
        }
        const pi = project.ensureItemByProjectPath(candidateFilePath, IProjectItemData_1.ProjectItemStorageType.singleFile, StorageUtilities_1.default.getLeafName(candidateFilePath), IProjectItemData_1.ProjectItemType.worldTest, Project_1.FolderContext.behaviorPack, undefined, IProjectItemData_1.ProjectItemCreationType.normal);
        const file = await pi.ensureFileStorage();
        if (file !== null) {
            const baseName = StorageUtilities_1.default.getBaseFromName(file.name);
            const content = ProjectContent_1.default.getEmptyWorldTest(project.name, baseName);
            file.setContent(content);
        }
        await ProjectAutogeneration_1.default.updateProjectAutogeneration(project);
        await project.save();
    }
}
exports.default = ProjectItemCreateManager;

//# sourceMappingURL=../maps/app/ProjectItemCreateManager.js.map
