"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
const IProjectItemData_1 = require("./IProjectItemData");
const Log_1 = require("./../core/Log");
const IProjectItemData_2 = require("./IProjectItemData");
const ste_events_1 = require("ste-events");
const StorageUtilities_1 = require("../storage/StorageUtilities");
const EntityTypeDefinition_1 = require("../minecraft/EntityTypeDefinition");
const IProjectData_1 = require("./IProjectData");
const MCWorld_1 = require("../minecraft/MCWorld");
const ZipStorage_1 = require("../storage/ZipStorage");
const Utilities_1 = require("../core/Utilities");
const IStorage_1 = require("../storage/IStorage");
const ProjectItemUtilities_1 = require("./ProjectItemUtilities");
const ProjectAutogeneration_1 = require("./ProjectAutogeneration");
const ProjectItemRelations_1 = require("./ProjectItemRelations");
class ProjectItem {
    constructor(parent, incomingData) {
        this._onPropertyChanged = new ste_events_1.EventDispatcher();
        this._onFileRetrieved = new ste_events_1.EventDispatcher();
        this._onFolderRetrieved = new ste_events_1.EventDispatcher();
        this._onLoaded = new ste_events_1.EventDispatcher();
        this._pendingLoadRequests = [];
        this._isLoading = false;
        this._isFileContentProcessed = false;
        this._project = parent;
        this._file = null;
        this._folder = null;
        this._isFileContentProcessed = false;
        this._handleMCWorldLoaded = this._handleMCWorldLoaded.bind(this);
        if (incomingData !== undefined && incomingData !== null) {
            this._data = incomingData;
        }
        else {
            this._data = {
                itemType: IProjectItemData_2.ProjectItemType.unknown,
                projectPath: null,
                storageType: IProjectItemData_1.ProjectItemStorageType.singleFile,
                tags: [],
                name: "",
            };
        }
    }
    get parentItemCount() {
        if (this.parentItems === undefined) {
            return 0;
        }
        return this.parentItems.length;
    }
    get childItemCount() {
        if (this.childItems === undefined) {
            return 0;
        }
        return this.childItems.length;
    }
    get unfulfilledRelationshipsCount() {
        if (this.unfulfilledRelationships === undefined) {
            return 0;
        }
        return this.unfulfilledRelationships.length;
    }
    get isInWorld() {
        return this._data.isInWorld;
    }
    set isInWorld(isInWorld) {
        this._data.isInWorld = isInWorld;
    }
    get project() {
        return this._project;
    }
    get onPropertyChanged() {
        return this._onPropertyChanged.asEvent();
    }
    get onLoaded() {
        return this._onLoaded.asEvent();
    }
    get onFileRetrieved() {
        return this._onFileRetrieved.asEvent();
    }
    get onFolderRetrieved() {
        return this._onFolderRetrieved.asEvent();
    }
    get gitHubReference() {
        return this._data.gitHubReference;
    }
    get isInFileContainer() {
        if (!this.projectPath) {
            return false;
        }
        return this.projectPath.indexOf("#") >= 0;
    }
    get isFileContainerStorageItem() {
        return (this.itemType === IProjectItemData_2.ProjectItemType.zip ||
            this.itemType === IProjectItemData_2.ProjectItemType.MCWorld ||
            this.itemType === IProjectItemData_2.ProjectItemType.MCProject ||
            this.itemType === IProjectItemData_2.ProjectItemType.MCAddon ||
            this.itemType === IProjectItemData_2.ProjectItemType.MCPack ||
            this.itemType === IProjectItemData_2.ProjectItemType.MCTemplate);
    }
    get isWorld() {
        return (this.itemType === IProjectItemData_2.ProjectItemType.MCProject ||
            this.itemType === IProjectItemData_2.ProjectItemType.MCWorld ||
            this.itemType === IProjectItemData_2.ProjectItemType.MCTemplate ||
            this.itemType === IProjectItemData_2.ProjectItemType.worldFolder);
    }
    static getGitHubSignature(info) {
        let sig = info.owner + "|" + info.repoName + "|";
        if (info.branch !== undefined) {
            sig += info.branch;
        }
        if (info.folder !== undefined) {
            sig += "|" + info.folder;
        }
        return sig;
    }
    getPack() {
        if (this._pack) {
            return this._pack;
        }
        let thisPath = undefined;
        if (this._file) {
            thisPath = this._file.storageRelativePath;
        }
        else if (this._folder) {
            thisPath = this._folder.storageRelativePath;
        }
        if (thisPath === undefined) {
            return undefined;
        }
        this.project.ensurePacks();
        for (const pack of this.project.packs) {
            if (thisPath.startsWith(pack.folder.storageRelativePath)) {
                this._pack = pack;
                return this._pack;
            }
        }
        return undefined;
    }
    addUnfulfilledRelationship(path, itemType, isVanillaDependent) {
        let pir = {
            parentItem: this,
            path: path,
            itemType: itemType,
            isVanillaDependent: isVanillaDependent === true,
        };
        if (this.unfulfilledRelationships === undefined) {
            this.unfulfilledRelationships = [];
        }
        this.unfulfilledRelationships.push(pir);
    }
    addChildItem(childItem) {
        let pir = {
            parentItem: this,
            childItem: childItem,
        };
        if (this.childItems === undefined) {
            this.childItems = [];
        }
        if (childItem.parentItems === undefined) {
            childItem.parentItems = [];
        }
        this.childItems.push(pir);
        childItem.parentItems.push(pir);
    }
    toString() {
        return this.itemType + ": " + this.projectPath;
    }
    getPackRelativePath() {
        const pack = this.getPack();
        if (!pack) {
            return undefined;
        }
        if (this._file) {
            return this._file.getFolderRelativePath(pack.folder);
        }
        else if (this._folder) {
            return this._folder.getFolderRelativePath(pack.folder);
        }
        return undefined;
    }
    static gitHubReferencesEqual(refA, refB) {
        if (refA === refB) {
            return true;
        }
        if (refA === undefined && refB === undefined) {
            return true;
        }
        if (refA !== undefined &&
            refB !== undefined &&
            refA.owner === refB.owner &&
            refA.repoName === refB.repoName &&
            refA.folder === refB.folder &&
            refA.branch === refB.branch) {
            return true;
        }
        return false;
    }
    set gitHubReference(value) {
        if (ProjectItem.gitHubReferencesEqual(this._data.gitHubReference, value)) {
            return;
        }
        this._data.gitHubReference = value;
        this._project.notifyProjectItemChanged(this);
    }
    get title() {
        return (StorageUtilities_1.default.getContaineredFileLeafPath(this.projectPath) +
            " (" +
            ProjectItemUtilities_1.default.getDescriptionForType(this._data.itemType).toLowerCase() +
            ")");
    }
    get typeTitle() {
        return ProjectItemUtilities_1.default.getDescriptionForType(this._data.itemType);
    }
    getFolderGroupingPath() {
        if (this.projectPath === undefined || this.projectPath === null) {
            return undefined;
        }
        let folderStoragePath = StorageUtilities_1.default.getFolderPath(this.projectPath);
        if (folderStoragePath === undefined) {
            return undefined;
        }
        let folderStoragePathLower = folderStoragePath.toLowerCase();
        const folderTypeRoots = ProjectItemUtilities_1.default.getFolderRootsForType(this.itemType);
        folderTypeRoots.push("zip");
        for (const folderTypeRoot of folderTypeRoots) {
            const start = folderStoragePathLower.indexOf("/" + folderTypeRoot + "/");
            if (start >= 0) {
                folderStoragePath = folderStoragePath.substring(start + 2 + folderTypeRoot.length);
                folderStoragePathLower = folderStoragePath.toLowerCase();
            }
        }
        folderStoragePath = folderStoragePath.replace(/#/gi, " ").trim();
        return folderStoragePath;
    }
    getSchemaPath() {
        switch (this._data.itemType) {
            case IProjectItemData_2.ProjectItemType.behaviorPackManifestJson:
                return "general/manifest.json";
            case IProjectItemData_2.ProjectItemType.behaviorPackListJson:
                return "general/world_x_packs.json";
            case IProjectItemData_2.ProjectItemType.resourcePackListJson:
                return "general/world_x_packs.json";
            case IProjectItemData_2.ProjectItemType.animationControllerBehaviorJson:
                return "behavior/animation_controllers/animation_controller.json";
            case IProjectItemData_2.ProjectItemType.animationBehaviorJson:
                return "behavior/animations/animations.json";
            case IProjectItemData_2.ProjectItemType.blockTypeBehavior:
                return "behavior/blocks/blocks.json";
            case IProjectItemData_2.ProjectItemType.itemTypeBehavior:
                return "behavior/items/items.json";
            case IProjectItemData_2.ProjectItemType.lootTableBehavior:
                return "behavior/loot_tables/loot_tables.json";
            case IProjectItemData_2.ProjectItemType.biomeBehaviorJson:
                return "behavior/blocks/blocks.json";
            case IProjectItemData_2.ProjectItemType.dialogueBehaviorJson:
                return "behavior/dialogue/dialogue.json";
            case IProjectItemData_2.ProjectItemType.entityTypeBehavior:
                return "behavior/entities/entities.json";
            case IProjectItemData_2.ProjectItemType.blocksCatalogResourceJson:
                return "resource/blocks.json";
            case IProjectItemData_2.ProjectItemType.soundCatalog:
                return "resource/sounds.json";
            case IProjectItemData_2.ProjectItemType.animationResourceJson:
                return "resource/animations/actor_animation.json";
            case IProjectItemData_2.ProjectItemType.animationControllerResourceJson:
                return "resource/animation_controllers/animation_controller.json";
            case IProjectItemData_2.ProjectItemType.entityTypeResource:
                return "resource/entity/entity.json";
            case IProjectItemData_2.ProjectItemType.fogResourceJson:
                return "resource/fog/fog.json";
            case IProjectItemData_2.ProjectItemType.modelGeometryJson:
                return "resource/models/entity/model_entity.json";
            case IProjectItemData_2.ProjectItemType.biomeResourceJson:
                return "resource/biomes_client.json";
            case IProjectItemData_2.ProjectItemType.particleJson:
                return "resource/particles/particles.json";
            case IProjectItemData_2.ProjectItemType.renderControllerJson:
                return "resource/render_controllers/render_controllers.json";
            //     case ProjectItemType.uiTextureJson:
            //        return "resource/textures/ui_texture_definition.json";
            case IProjectItemData_2.ProjectItemType.languagesCatalogResourceJson:
                return "language/languages.json";
            case IProjectItemData_2.ProjectItemType.featureBehavior:
                return "behavior/features/features.json";
            case IProjectItemData_2.ProjectItemType.featureRuleBehaviorJson:
                return "behavior/feature_rules/feature_rules.json";
            case IProjectItemData_2.ProjectItemType.functionEventJson:
                return "behavior/functions/tick.json";
            case IProjectItemData_2.ProjectItemType.recipeBehavior:
                return "behavior/recipes/recipes.json";
            case IProjectItemData_2.ProjectItemType.spawnRuleBehavior:
                return "behavior/spawn_rules/spawn_rules.json";
            case IProjectItemData_2.ProjectItemType.tradingBehaviorJson:
                return "behavior/trading/trading.json";
            case IProjectItemData_2.ProjectItemType.attachableResourceJson:
                return "resource/attachables/attachables.json";
            case IProjectItemData_2.ProjectItemType.itemTypeResourceJson:
                return "resource/items/items.json";
            case IProjectItemData_2.ProjectItemType.materialsResourceJson:
                return "resource/materials/materials.json";
            case IProjectItemData_2.ProjectItemType.musicDefinitionJson:
                return "resource/sounds/music_definitions.json";
            case IProjectItemData_2.ProjectItemType.soundDefinitionCatalog:
                return "resource/sounds/sound_definitions.json";
            case IProjectItemData_2.ProjectItemType.blockTypeResourceJson:
                return "resource/blocks.json";
            case IProjectItemData_2.ProjectItemType.uiJson:
                return "resource/ui/ui.json";
            case IProjectItemData_2.ProjectItemType.tickJson:
                return "behavior/functions/tick.json";
            case IProjectItemData_2.ProjectItemType.flipbookTexturesJson:
                return "resource/textures/flipbook_textures.json";
            case IProjectItemData_2.ProjectItemType.itemTextureJson:
                return "resource/textures/item_texture.json";
            case IProjectItemData_2.ProjectItemType.terrainTextureCatalogResourceJson:
                return "resource/textures/terrain_texture.json";
            case IProjectItemData_2.ProjectItemType.globalVariablesJson:
                return "resource/ui/_global_variables.json";
            default:
                return undefined;
        }
    }
    get errorStatus() {
        return this._data.errorStatus;
    }
    set errorStatus(newErrorStatus) {
        this._data.errorStatus = newErrorStatus;
    }
    get source() {
        return this._data.source;
    }
    set source(newSource) {
        this._data.source = newSource;
    }
    get errorMessage() {
        return this._data.errorMessage;
    }
    set errorMessage(newErrorMessage) {
        this._data.errorMessage = newErrorMessage;
    }
    get projectPath() {
        if (this._data.projectPath === undefined && this._data.storagePath) {
            this._data.projectPath = this._data.storagePath;
            return this._data.storagePath;
        }
        return this._data.projectPath;
    }
    set projectPath(newBasePath) {
        this._data.projectPath = newBasePath;
    }
    get effectiveEditPreference() {
        const ep = this.editPreference;
        if (ep === IProjectItemData_1.ProjectItemEditPreference.projectDefault) {
            return this._project.editPreference;
        }
        else if (ep === IProjectItemData_1.ProjectItemEditPreference.forceRaw) {
            return IProjectData_1.ProjectEditPreference.raw;
        }
        else {
            return IProjectData_1.ProjectEditPreference.summarized;
        }
    }
    get editPreference() {
        if (this._data.editPreference === undefined) {
            return IProjectItemData_1.ProjectItemEditPreference.projectDefault;
        }
        return this._data.editPreference;
    }
    set editPreference(newEditPreference) {
        this._data.editPreference = newEditPreference;
    }
    get storageType() {
        if (this._data.storageType === undefined) {
            return IProjectItemData_1.ProjectItemStorageType.singleFile;
        }
        return this._data.storageType;
    }
    set storageType(newStorageType) {
        this._data.storageType = newStorageType;
    }
    get creationType() {
        return this._data.creationType;
    }
    set creationType(newCreationType) {
        this._data.creationType = newCreationType;
    }
    get itemType() {
        return this._data.itemType;
    }
    get file() {
        return this._file;
    }
    get folder() {
        return this._folder;
    }
    set itemType(newItemType) {
        this._data.itemType = newItemType;
        this._onPropertyChanged.dispatch(this, "itemType");
        this._project.notifyProjectItemChanged(this);
    }
    get isLoaded() {
        if (this.storageType === IProjectItemData_1.ProjectItemStorageType.folder) {
            if (!this.folder) {
                return false;
            }
            if (!this.folder.isLoaded) {
                return false;
            }
            if (this.itemType === IProjectItemData_2.ProjectItemType.worldFolder) {
                if (!this.folder.manager || !(this.folder.manager instanceof MCWorld_1.default)) {
                    return false;
                }
                const world = this.folder.manager;
                return world.isLoaded;
            }
            return true;
        }
        else if (this.storageType === IProjectItemData_1.ProjectItemStorageType.singleFile) {
            if (!this.file) {
                return false;
            }
            if (!this.file.isContentLoaded) {
                return false;
            }
            if (this.isWorld) {
                if (!this.file.manager || !(this.file.manager instanceof MCWorld_1.default)) {
                    return false;
                }
                const world = this.file.manager;
                return world.isLoaded;
            }
            return this._isFileContentProcessed;
        }
        Log_1.default.unexpectedContentState();
        return false;
    }
    get tags() {
        return this._data.tags;
    }
    setFile(file) {
        if (file !== this._file) {
            this._file = file;
            this._isFileContentProcessed = false;
        }
    }
    get needsSave() {
        if (this._file === null &&
            this.creationType === IProjectItemData_1.ProjectItemCreationType.generated &&
            this.storageType === IProjectItemData_1.ProjectItemStorageType.singleFile) {
            return true;
        }
        if (this._file === null) {
            return false;
        }
        let val = this._file.needsSave;
        if (!val) {
            if (this.isFileContainerStorageItem &&
                this._file.fileContainerStorage &&
                this._file.fileContainerStorage instanceof ZipStorage_1.default) {
                val = this._file.fileContainerStorage.isContentUpdated;
            }
            if (!val) {
                const jsFile = this.getJavaScriptLibTwin();
                if (jsFile !== undefined) {
                    val = jsFile.needsSave;
                }
            }
        }
        return val;
    }
    updateProjectPath() {
        if (this._project && this._project.projectFolder) {
            if (this._file) {
                this.projectPath = this._file.getFolderRelativePath(this._project.projectFolder);
            }
            else if (this._folder) {
                this.projectPath = this._folder.getFolderRelativePath(this._project.projectFolder);
            }
        }
    }
    async rename(newFileBaseName) {
        await this.load();
        await this._project.ensureProjectFolder();
        if (this._project.projectFolder === undefined || this._project.projectFolder === null) {
            return;
        }
        if (this._file !== null) {
            await this._file.moveTo(this._file.parentFolder.storageRelativePath + newFileBaseName + "." + this._file.type);
            this._data.name = newFileBaseName + "." + this._file.type;
            this.projectPath = this._file.getFolderRelativePath(this._project.projectFolder);
            this.storageType = IProjectItemData_1.ProjectItemStorageType.singleFile;
        }
        else {
            this._data.name = newFileBaseName;
        }
        this._onPropertyChanged.dispatch(this, "name");
        this._project.notifyProjectItemChanged(this);
    }
    async deleteItem() {
        await this.load();
        await ProjectItemRelations_1.default.deleteLinksFromParents(this);
        if (this._file !== null) {
            await this._file.deleteThisFile();
        }
        this._project.removeItem(this);
    }
    get imageUrl() {
        if (this.itemType === IProjectItemData_2.ProjectItemType.worldFolder) {
            if (this.folder) {
                if (this.folder.manager instanceof MCWorld_1.default) {
                    const world = this.folder.manager;
                    if (world.isLoaded) {
                        return "data:image/jpg;base64, " + world.imageBase64;
                    }
                }
            }
        }
        else if (this.isWorld) {
            if (this.file) {
                if (this.file.manager instanceof MCWorld_1.default) {
                    const world = this.file.manager;
                    if (world.isLoaded) {
                        return "data:image/jpg;base64, " + world.imageBase64;
                    }
                }
            }
        }
        else if (ProjectItemUtilities_1.default.isImageType(this.itemType)) {
            if (this._imageUrlBase64Cache) {
                return this._imageUrlBase64Cache;
            }
            if (this._file && this._file.content && this._file.content instanceof Uint8Array) {
                this._imageUrlBase64Cache = "data:image/jpg;base64, " + Utilities_1.default.uint8ArrayToBase64(this._file.content);
                return this._imageUrlBase64Cache;
            }
        }
        return undefined;
    }
    get name() {
        if (this.itemType === IProjectItemData_2.ProjectItemType.worldFolder) {
            if (this.folder) {
                if (this.folder.manager instanceof MCWorld_1.default) {
                    const world = this.folder.manager;
                    if (world.isLoaded) {
                        return world.name;
                    }
                }
            }
        }
        else if (this.itemType === IProjectItemData_2.ProjectItemType.MCWorld || this.itemType === IProjectItemData_2.ProjectItemType.MCTemplate) {
            if (this.file) {
                if (this.file.manager instanceof MCWorld_1.default) {
                    const world = this.file.manager;
                    if (world.isLoaded) {
                        return world.name;
                    }
                }
            }
        }
        // for certain types of project items, the name of the file is critical
        if (this.projectPath &&
            (this.itemType === IProjectItemData_2.ProjectItemType.js ||
                this.itemType === IProjectItemData_2.ProjectItemType.ts ||
                this.itemType === IProjectItemData_2.ProjectItemType.testJs ||
                this.itemType === IProjectItemData_2.ProjectItemType.structure)) {
            return StorageUtilities_1.default.getLeafName(this.projectPath);
        }
        if (this._data.name !== undefined) {
            return this._data.name;
        }
        if (this.projectPath) {
            return StorageUtilities_1.default.getLeafName(this.projectPath);
        }
        return "untitled";
    }
    async ensureFolderStorage() {
        if (this.storageType === IProjectItemData_1.ProjectItemStorageType.folder) {
            if (this._folder === null &&
                this.projectPath !== null &&
                this.projectPath !== undefined &&
                this.projectPath.startsWith("/") &&
                this._project.projectFolder !== null &&
                this._project.projectFolder !== undefined) {
                const prefixPaths = this.projectPath.split("#");
                if (prefixPaths.length > 1) {
                    let folderToLoadFrom = this._project.projectFolder;
                    for (let i = 0; i < prefixPaths.length - 1; i++) {
                        if (folderToLoadFrom) {
                            const zipFile = await folderToLoadFrom.ensureFileFromRelativePath(prefixPaths[i]);
                            await zipFile.loadContent();
                            if (zipFile.content && zipFile.content instanceof Uint8Array) {
                                if (!zipFile.fileContainerStorage) {
                                    const zipStorage = new ZipStorage_1.default();
                                    zipStorage.storagePath = zipFile.storageRelativePath + "#";
                                    await zipStorage.loadFromUint8Array(zipFile.content, zipFile.name);
                                    zipFile.fileContainerStorage = zipStorage;
                                }
                                folderToLoadFrom = zipFile.fileContainerStorage.rootFolder;
                            }
                            else {
                                folderToLoadFrom = undefined;
                            }
                        }
                    }
                    if (folderToLoadFrom) {
                        this._folder = await folderToLoadFrom.ensureFolderFromRelativePath(prefixPaths[prefixPaths.length - 1]);
                    }
                    else {
                        // Log.debugAlert("Unable to parse a containerized file path of '" + this.storagePath + "'");
                        return null;
                    }
                }
                else {
                    this._folder = await this._project.projectFolder.ensureFolderFromRelativePath(this.projectPath);
                }
                await this._folder.load();
                this._onFolderRetrieved.dispatch(this, this._folder);
                if (this.itemType === IProjectItemData_2.ProjectItemType.worldFolder) {
                    const mcworld = await MCWorld_1.default.ensureMCWorldOnFolder(this._folder, this._project, this._handleMCWorldLoaded);
                    if (mcworld) {
                        this.errorMessage = mcworld.storageErrorMessage;
                        if (mcworld.storageErrorStatus === IStorage_1.StorageErrorStatus.unprocessable) {
                            this.errorStatus = IProjectItemData_1.ProjectItemErrorStatus.unprocessable;
                        }
                        else {
                            this.errorStatus = IProjectItemData_1.ProjectItemErrorStatus.none;
                        }
                    }
                }
                else {
                    this._fireLoadedEvent();
                }
            }
            return this._folder;
        }
        return undefined;
    }
    _handleMCWorldLoaded(world, worldA) {
        this._fireLoadedEvent();
    }
    _fireLoadedEvent() {
        if (this._onLoaded && this.isLoaded) {
            this._onLoaded.dispatch(this, this);
        }
    }
    async getManager() {
        await this.load();
        if (this.storageType === IProjectItemData_1.ProjectItemStorageType.singleFile && this._file) {
            return this._file.manager;
        }
        if (this.storageType === IProjectItemData_1.ProjectItemStorageType.folder && this._folder) {
            return this._folder.manager;
        }
        return undefined;
    }
    async ensureStorage() {
        if (this.storageType === IProjectItemData_1.ProjectItemStorageType.folder) {
            await this.ensureFolderStorage();
        }
        else if (this.storageType === IProjectItemData_1.ProjectItemStorageType.singleFile) {
            await this.ensureFileStorage();
        }
    }
    async ensureFileStorage() {
        if (this.storageType === IProjectItemData_1.ProjectItemStorageType.singleFile &&
            this._file === null &&
            this.projectPath !== null &&
            this.projectPath !== undefined &&
            this.projectPath.startsWith("/") &&
            this._project.projectFolder !== null &&
            this._project.projectFolder !== undefined) {
            const prefixPaths = this.projectPath.split("#");
            if (prefixPaths.length > 1) {
                let folderToLoadFrom = this._project.projectFolder;
                for (let i = 0; i < prefixPaths.length - 1; i++) {
                    if (folderToLoadFrom) {
                        const zipFile = await folderToLoadFrom.ensureFileFromRelativePath(prefixPaths[i]);
                        await zipFile.loadContent();
                        if (zipFile.content && zipFile.content instanceof Uint8Array) {
                            if (!zipFile.fileContainerStorage) {
                                const zipStorage = new ZipStorage_1.default();
                                zipStorage.storagePath = zipFile.storageRelativePath + "#";
                                await zipStorage.loadFromUint8Array(zipFile.content, zipFile.name);
                                zipFile.fileContainerStorage = zipStorage;
                            }
                            folderToLoadFrom = zipFile.fileContainerStorage.rootFolder;
                        }
                        else {
                            folderToLoadFrom = undefined;
                        }
                    }
                }
                if (folderToLoadFrom) {
                    this._file = await folderToLoadFrom.ensureFileFromRelativePath(prefixPaths[prefixPaths.length - 1]);
                    this._isFileContentProcessed = false;
                }
                else {
                    Log_1.default.debugAlert("Unable to parse a containerized file path of '" + this.projectPath + "'");
                    return null;
                }
            }
            else {
                this._file = await this._project.projectFolder.ensureFileFromRelativePath(this.projectPath);
                this._isFileContentProcessed = false;
            }
        }
        if (!this._isFileContentProcessed && this._file) {
            if (this._data.creationType === IProjectItemData_1.ProjectItemCreationType.generated) {
                await ProjectAutogeneration_1.default.updateItemAutogeneration(this, true);
            }
            else {
                await this._file.loadContent();
            }
            await ProjectAutogeneration_1.default.updateItemAutogeneratedSideFiles(this);
            this._isFileContentProcessed = true;
            this._onFileRetrieved.dispatch(this, this._file);
            if (this.itemType === IProjectItemData_2.ProjectItemType.MCWorld || this.itemType === IProjectItemData_2.ProjectItemType.MCTemplate) {
                const mcworld = await MCWorld_1.default.ensureOnFile(this._file, this._project, this._handleMCWorldLoaded);
                if (mcworld) {
                    this.errorMessage = mcworld.storageErrorMessage;
                    if (mcworld.storageErrorStatus === IStorage_1.StorageErrorStatus.unprocessable) {
                        this.errorStatus = IProjectItemData_1.ProjectItemErrorStatus.unprocessable;
                    }
                    else {
                        this.errorStatus = IProjectItemData_1.ProjectItemErrorStatus.none;
                    }
                }
            }
            else if (this.itemType === IProjectItemData_2.ProjectItemType.entityTypeBehavior) {
                await EntityTypeDefinition_1.default.ensureOnFile(this._file);
                this._fireLoadedEvent();
            }
            else {
                this._fireLoadedEvent();
            }
        }
        return this._file;
    }
    async getJsonObject() {
        let strContent = await this.getStringContent();
        if (!strContent) {
            return undefined;
        }
        let obj = undefined;
        try {
            strContent = Utilities_1.default.fixJsonContent(strContent);
            obj = JSON.parse(strContent);
        }
        catch (e) {
            Log_1.default.debug("Could not parse content '" + strContent + "': " + e, this.project.name);
        }
        return obj;
    }
    async getStringContent() {
        await this.load();
        if (!this._file) {
            return undefined;
        }
        await this._file.loadContent();
        if (this._file.content instanceof Uint8Array || this._file.content === null) {
            return undefined;
        }
        return this._file.content;
    }
    async load() {
        if (this.isLoaded) {
            return true;
        }
        if (this._isLoading) {
            const pendingLoad = this._pendingLoadRequests;
            const prom = (resolve, reject) => {
                pendingLoad.push(resolve);
            };
            await new Promise(prom);
            return true;
        }
        else {
            this._isLoading = true;
            await this.ensureStorage();
            this._isLoading = false;
            const pendingLoad = this._pendingLoadRequests;
            this._pendingLoadRequests = [];
            for (const prom of pendingLoad) {
                prom(undefined);
            }
            return true;
        }
    }
    async prepareToSave() {
        await this.load();
        await ProjectAutogeneration_1.default.updateItemAutogeneration(this);
        await ProjectAutogeneration_1.default.updateItemAutogeneratedSideFiles(this);
        if (!this.isInFileContainer &&
            this.isFileContainerStorageItem &&
            this.file &&
            this.file.fileContainerStorage &&
            this.file.fileContainerStorage instanceof ZipStorage_1.default) {
            const zs = this.file.fileContainerStorage;
            if (zs.isContentUpdated && (zs.errorStatus === undefined || zs.errorStatus === IStorage_1.StorageErrorStatus.none)) {
                const op = await this._project.carto.notifyOperationStarted("Zipping file '" + this.file.storageRelativePath + "'...");
                const bytes = await zs.generateUint8ArrayAsync();
                await this._project.carto.notifyOperationEnded(op, "Done zipping file '" + this.file.storageRelativePath + "'.");
                this.file.setContent(bytes);
            }
        }
    }
    getJavaScriptLibTwin() {
        if (!this._file) {
            return undefined;
        }
        if (this.itemType === IProjectItemData_2.ProjectItemType.ts) {
            const libScriptsFolder = this.project.getLibScriptsFolder();
            if (!libScriptsFolder) {
                return undefined;
            }
            const jsTwinName = StorageUtilities_1.default.canonicalizeName(StorageUtilities_1.default.getBaseFromName(this._file.name) + ".js");
            return libScriptsFolder.ensureFile(jsTwinName);
        }
        return undefined;
    }
    getFunctionTwin() {
        if (!this._file) {
            return undefined;
        }
        if (this.itemType === IProjectItemData_2.ProjectItemType.actionSet) {
            const functionTwinName = StorageUtilities_1.default.canonicalizeName(StorageUtilities_1.default.getBaseFromName(this._file.name) + ".mcfunction");
            let functionFolder = this._file.parentFolder;
            if (functionFolder.name === "scripts" && functionFolder.parentFolder) {
                functionFolder = functionFolder.parentFolder.ensureFolder("functions");
            }
            return functionFolder.files[functionTwinName];
        }
        return undefined;
    }
    async saveContent() {
        if (this._file) {
            await this._file.saveContent();
            // these next two are associated with action set
            const jsFile = this.getJavaScriptLibTwin();
            if (jsFile !== undefined && jsFile.needsSave) {
                await jsFile.saveContent();
            }
            const functionFile = this.getFunctionTwin();
            if (functionFile !== undefined && functionFile.needsSave) {
                await functionFile.saveContent();
            }
        }
    }
    hasTag(name) {
        return this.tags.includes(name);
    }
    ensureTag(name) {
        if (this.hasTag(name)) {
            return;
        }
        this.tags.push(name);
    }
}
exports.default = ProjectItem;

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