"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", { value: true });
const ste_events_1 = require("ste-events");
const StorageUtilities_1 = require("../storage/StorageUtilities");
const IImageEdits_1 = require("./IImageEdits");
const ImageItem_1 = require("./ImageItem");
const ProjectItemUtilities_1 = require("../app/ProjectItemUtilities");
const IProjectItemData_1 = require("../app/IProjectItemData");
const ProjectItemCreateManager_1 = require("../app/ProjectItemCreateManager");
const BlockTypeDefinition_1 = require("../minecraft/BlockTypeDefinition");
const Utilities_1 = require("../core/Utilities");
class ImageEditsDefinition {
    _file;
    _id;
    _isLoaded = false;
    items = [];
    _backgroundItem;
    data;
    _onLoaded = new ste_events_1.EventDispatcher();
    project = undefined;
    get stackPosition() {
        return this.data?.stackPosition;
    }
    set stackPosition(newStackPosition) {
        if (!this.data) {
            return;
        }
        this.data.stackPosition = newStackPosition;
    }
    get backgroundItem() {
        let backgroundItem = this._backgroundItem;
        if (backgroundItem) {
            return backgroundItem;
        }
        if (!this.data) {
            return undefined;
        }
        backgroundItem = new ImageItem_1.ImageItem({
            origin: { x: 0, y: 0 },
            type: 2,
            coords: [],
        });
        this._backgroundItem = backgroundItem;
        return backgroundItem;
    }
    ensureBackgroundItem(imageData) {
        if (!this._backgroundItem) {
            this._backgroundItem = new ImageItem_1.ImageItem(imageData);
        }
        else {
            this._backgroundItem.data = imageData;
        }
        if (!this.data) {
            this.data = {
                items: [],
            };
        }
        this.data.backgroundItem = this._backgroundItem.data;
        return this._backgroundItem;
    }
    get height() {
        if (!this.data || !this.data.height) {
            return 64;
        }
        return this.data.height;
    }
    set height(height) {
        if (!this.data) {
            return;
        }
        this.data.height = height;
    }
    get width() {
        if (!this.data || !this.data.width) {
            return 64;
        }
        return this.data.width;
    }
    set width(width) {
        if (!this.data) {
            return;
        }
        this.data.width = width;
    }
    get isLoaded() {
        return this._isLoaded;
    }
    get file() {
        return this._file;
    }
    set file(newFile) {
        this._file = newFile;
    }
    get onLoaded() {
        return this._onLoaded.asEvent();
    }
    get id() {
        return this._id;
    }
    set id(newId) {
        this._id = newId;
    }
    get outputs() {
        if (!this.data) {
            return undefined;
        }
        return this.data.outputs;
    }
    ensureData() {
        if (!this.data) {
            this.data = {
                items: [],
            };
        }
        if (!this.data.items) {
            this.data.items = [];
        }
        return this.data;
    }
    async updateOutputs(project) {
        if (!this.data?.outputs) {
            return;
        }
        for (const output of this.data.outputs) {
            await this.updateOutput(project, output);
        }
    }
    async getCorrespondingResourcePackFolder() {
        if (!this.project) {
            return undefined;
        }
        let rpFolder = await this.project?.getDefaultResourcePackFolder();
        return rpFolder;
    }
    async getPaintingOverrideFolder() {
        let rpFolder = await this.getCorrespondingResourcePackFolder();
        if (!rpFolder) {
            return undefined;
        }
        if (!this._file) {
            return undefined;
        }
        rpFolder = await rpFolder.ensureFolderFromRelativePath("/textures/painting/");
        return rpFolder;
    }
    async getCorrespondingBlockTextureFolder() {
        let rpFolder = await this.getCorrespondingResourcePackFolder();
        if (!rpFolder) {
            return undefined;
        }
        if (!this._file) {
            return undefined;
        }
        rpFolder = await rpFolder.ensureFolderFromRelativePath("/textures/blocks/");
        const subPath = StorageUtilities_1.default.getBaseFromName(this._file?.name);
        rpFolder = rpFolder?.ensureFolder(subPath);
        return rpFolder;
    }
    async updateOutput(project, output) {
        if (output.name) {
            if (output.type === IImageEdits_1.ImageOutputType.blockBillboard3x3) {
                await this.updateBlocks(project, output.name, 3, 3);
            }
            else if (output.type === IImageEdits_1.ImageOutputType.blockBillboard4x6) {
                await this.updateBlocks(project, output.name, 6, 4);
            }
            else if (output.type === IImageEdits_1.ImageOutputType.blockBillboard5x8) {
                await this.updateBlocks(project, output.name, 8, 5);
            }
        }
    }
    async setFromCreationData(creationData) {
        if (!this.data) {
            if (creationData.items === undefined) {
                creationData.items = [];
            }
            this.data = creationData;
        }
        if (creationData.outputs) {
            this.data.outputs = creationData.outputs;
        }
        if (creationData.width) {
            this.data.width = creationData.width;
        }
        if (creationData.height) {
            this.data.height = creationData.height;
        }
        await this.persist();
    }
    static getPaintingWidth(paintingSize) {
        switch (paintingSize) {
            case IImageEdits_1.PaintingSize.threeByThree:
            case IImageEdits_1.PaintingSize.threeByFourPortrait:
                return 48;
        }
        return 16;
    }
    static getPaintingHeight(paintingSize) {
        switch (paintingSize) {
            case IImageEdits_1.PaintingSize.oneBlock:
                return 16;
            case IImageEdits_1.PaintingSize.threeByThree:
                return 48;
            case IImageEdits_1.PaintingSize.threeByFourPortrait:
                return 64;
        }
        return 16;
    }
    async updateBlocks(project, name, width, height) {
        const blockTextureFolder = await this.getCorrespondingBlockTextureFolder();
        if (!blockTextureFolder) {
            return;
        }
        for (let i = 0; i < height; i++) {
            for (let j = 0; j < width; j++) {
                const targetName = name + "_r" + String(i + 1) + "c" + String(j + 1);
                let item = ProjectItemUtilities_1.default.getItemByTypeAndName(project, targetName, IProjectItemData_1.ProjectItemType.blockTypeBehavior);
                if (!item) {
                    const galleryItem = await project.carto.getGalleryProjectById("basicDieBlock");
                    if (galleryItem) {
                        await ProjectItemCreateManager_1.default.addFromGallery(project, targetName, galleryItem);
                    }
                    item = ProjectItemUtilities_1.default.getItemByTypeAndName(project, targetName, IProjectItemData_1.ProjectItemType.blockTypeBehavior);
                }
                if (item) {
                    await item.ensureFileStorage();
                    if (item.primaryFile) {
                        const blockType = await BlockTypeDefinition_1.default.ensureOnFile(item.primaryFile);
                        if (blockType && blockTextureFolder.parentFolder) {
                            const imageFile = blockTextureFolder.ensureFile(targetName + ".png");
                            let parentFolder = blockTextureFolder;
                            while (parentFolder.parentFolder !== undefined &&
                                parentFolder.parentFolder !== null &&
                                parentFolder.name.toLowerCase() !== "textures") {
                                parentFolder = parentFolder.parentFolder;
                            }
                            // go one above textures if possible
                            if (parentFolder.parentFolder) {
                                parentFolder = parentFolder.parentFolder;
                            }
                            let frPath = imageFile.getFolderRelativePath(parentFolder);
                            if (frPath) {
                                await blockType.setBlockCatalogTexture(project, "north", targetName);
                                await blockType.setBlockCatalogTexture(project, "east", targetName);
                                await blockType.setBlockCatalogTexture(project, "south", targetName);
                                await blockType.setBlockCatalogTexture(project, "west", targetName);
                                await blockType.setBlockCatalogTexture(project, "up", targetName);
                                await blockType.setBlockCatalogTexture(project, "down", targetName);
                                if (frPath.endsWith(".png")) {
                                    frPath = frPath.substring(0, frPath.length - 4);
                                }
                                frPath = Utilities_1.default.ensureNotStartsWithSlash(frPath);
                                await blockType.setTerrainTexture(project, targetName, {
                                    textures: [{ path: frPath, overlay_color: "#8ab689" }],
                                });
                            }
                        }
                    }
                }
            }
        }
    }
    addNewDrawingItem(item) {
        let data = this.data;
        if (!data) {
            data = this.ensureData();
        }
        if (data.stackPosition !== undefined) {
            this.items = this.items.slice(0, data.stackPosition);
            data.items = data.items.slice(0, data.stackPosition);
            this.stackPosition = undefined;
        }
        data.items.push(item.data);
        this.items.push(item);
    }
    static async ensureAsAccessoryOnImageProjectItem(projectItem) {
        const accessoryFolder = await projectItem.ensureAccessoryFolder();
        const imageFile = accessoryFolder.ensureFile("image_edits.json");
        return await ImageEditsDefinition.ensureOnFile(imageFile, projectItem.project);
    }
    static async ensureOnFile(file, project, loadHandler) {
        let imageEdits;
        if (file.manager === undefined) {
            imageEdits = new ImageEditsDefinition();
            imageEdits.project = project;
            imageEdits.file = file;
            file.manager = imageEdits;
        }
        if (file.manager !== undefined && file.manager instanceof ImageEditsDefinition) {
            imageEdits = file.manager;
            if (!imageEdits.isLoaded && loadHandler) {
                imageEdits.onLoaded.subscribe(loadHandler);
            }
            await imageEdits.load();
            return imageEdits;
        }
        return imageEdits;
    }
    async persist() {
        if (this._file === undefined) {
            return;
        }
        const imageEditorString = JSON.stringify(this.data, null, 2);
        this._file.setContent(imageEditorString);
    }
    async save() {
        if (this._file === undefined) {
            return;
        }
        await this.persist();
        await this._file.saveContent(false);
    }
    _loadFromItems() {
        this.items = [];
        if (this.data?.backgroundItem) {
            this._backgroundItem = new ImageItem_1.ImageItem(this.data.backgroundItem);
        }
        if (this.data?.items) {
            for (const dataItem of this.data?.items) {
                this.items.push(new ImageItem_1.ImageItem(dataItem));
            }
        }
    }
    async load() {
        if (this._file === undefined || this._isLoaded) {
            return;
        }
        await this._file.loadContent();
        if (this._file.content === null || this._file.content instanceof Uint8Array) {
            return;
        }
        this.id = this._file.name;
        this.data = StorageUtilities_1.default.getJsonObject(this._file);
        this._loadFromItems();
        this._isLoaded = true;
    }
}
exports.default = ImageEditsDefinition;

//# sourceMappingURL=../maps/design/ImageEditsDefinition.js.map
