"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 IProjectItemData_1 = require("../app/IProjectItemData");
const Database_1 = require("./Database");
const Utilities_1 = require("../core/Utilities");
const AudioDefinition_1 = require("./AudioDefinition");
class SoundDefinitionCatalogDefinition {
    _data;
    _file;
    _isLoaded = false;
    id;
    _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;
    }
    getSoundDefinitionSoundInstanceList() {
        if (!this._data) {
            return undefined;
        }
        const soundList = [];
        if (this._data.sound_definitions) {
            for (const key in this._data.sound_definitions) {
                const soundDefSet = this._data.sound_definitions[key];
                for (const sound of soundDefSet.sounds) {
                    soundList.push(sound);
                }
            }
        }
        else {
            for (const key in this._data) {
                if (key !== "format_version" && key !== "sound_definitions") {
                    const soundDefSet = this._data[key];
                    if (soundDefSet && soundDefSet.sounds && Array.isArray(soundDefSet.sounds)) {
                        for (const sound of soundDefSet.sounds) {
                            soundList.push(sound);
                        }
                    }
                }
            }
        }
        return soundList;
    }
    getCanonincalizedSoundPathList() {
        if (!this._data) {
            return undefined;
        }
        const soundList = [];
        if (this._data.sound_definitions) {
            for (const key in this._data.sound_definitions) {
                const soundDefSet = this._data.sound_definitions[key];
                if (soundDefSet.sounds && Array.isArray(soundDefSet.sounds)) {
                    for (const sound of soundDefSet.sounds) {
                        if (typeof sound === "string") {
                            let path = AudioDefinition_1.default.canonicalizeAudioPath(sound);
                            if (path) {
                                soundList.push(path);
                            }
                        }
                        else if (typeof sound.name === "string") {
                            let path = AudioDefinition_1.default.canonicalizeAudioPath(sound.name);
                            if (path) {
                                soundList.push(path);
                            }
                        }
                    }
                }
            }
        }
        else {
            for (const key in this._data) {
                if (key !== "format_version" && key !== "sound_definitions") {
                    const soundDefSet = this._data[key];
                    if (soundDefSet && soundDefSet.sounds && Array.isArray(soundDefSet.sounds)) {
                        for (const sound of soundDefSet.sounds) {
                            if (typeof sound === "string") {
                                let path = AudioDefinition_1.default.canonicalizeAudioPath(sound);
                                if (path) {
                                    soundList.push(path);
                                }
                            }
                            else if (typeof sound.name === "string") {
                                let path = AudioDefinition_1.default.canonicalizeAudioPath(sound.name);
                                if (path) {
                                    soundList.push(path);
                                }
                            }
                        }
                    }
                }
            }
        }
        return soundList;
    }
    get soundDefinitionPathList() {
        if (!this._data || !this._data.sound_definitions) {
            return undefined;
        }
        const soundDefPathList = [];
        for (const key in this._data.sound_definitions) {
            const soundDefSet = this._data.sound_definitions[key];
            for (const sound of soundDefSet.sounds) {
                if (typeof sound === "string") {
                    soundDefPathList.push(sound);
                }
                else {
                    soundDefPathList.push(sound.name);
                }
            }
        }
        return soundDefPathList;
    }
    getSoundDefinitionSetNameList() {
        if (!this._data || !this._data.sound_definitions) {
            return undefined;
        }
        const soundDefSetNameList = [];
        for (const key in this._data.sound_definitions) {
            soundDefSetNameList.push(key);
        }
        // this seems like a legacy mode?
        for (const key in this._data) {
            if (key !== "sound_definitions" && key !== "format_version") {
                soundDefSetNameList.push(key);
            }
        }
        return soundDefSetNameList;
    }
    static async ensureOnFile(file, loadHandler) {
        let et;
        if (file.manager === undefined) {
            et = new SoundDefinitionCatalogDefinition();
            et.file = file;
            file.manager = et;
        }
        if (file.manager !== undefined && file.manager instanceof SoundDefinitionCatalogDefinition) {
            et = file.manager;
            if (!et.isLoaded) {
                if (loadHandler) {
                    et.onLoaded.subscribe(loadHandler);
                }
                await et.load();
            }
        }
        return et;
    }
    persist() {
        if (this._file === undefined) {
            return;
        }
        if (!this._data) {
            Log_1.default.unexpectedUndefined("SDCDP");
            return;
        }
        const defString = JSON.stringify(this._data, null, 2);
        this._file.setContent(defString);
    }
    async load() {
        if (this._isLoaded) {
            return;
        }
        if (this._file === undefined) {
            Log_1.default.unexpectedUndefined("TTCDF");
            return;
        }
        if (!this._file.isContentLoaded) {
            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._data = data;
        this._isLoaded = true;
        this._onLoaded.dispatch(this, this);
    }
    async deleteLinkToChild(childItem) {
        let packRootFolder = this.getPackRootFolder();
        if (this._data === undefined) {
            await this.load();
        }
        if (childItem.itemType === IProjectItemData_1.ProjectItemType.texture && this._data && this._data.sound_definitions) {
            if (!childItem.isContentLoaded) {
                await childItem.loadContent();
            }
            if (childItem.primaryFile && packRootFolder) {
                let relativePath = this.getRelativePath(childItem.primaryFile, packRootFolder);
                if (relativePath) {
                    for (const key in this._data.sound_definitions) {
                        const soundDef = this._data.sound_definitions[key];
                        for (const sound of soundDef.sounds) {
                            if (typeof sound === "string") {
                                if (sound === relativePath) {
                                    soundDef.sounds = Utilities_1.default.removeItemInArray(sound, soundDef.sounds);
                                }
                            }
                            else if (sound.name === relativePath) {
                                soundDef.sounds = Utilities_1.default.removeItemInArray(sound, soundDef.sounds);
                            }
                        }
                    }
                }
            }
        }
        this.persist();
    }
    getPackRootFolder() {
        let packRootFolder = undefined;
        if (this.file && this.file.parentFolder) {
            let parentFolder = this.file.parentFolder;
            packRootFolder = StorageUtilities_1.default.getParentOfParentFolderNamed("sounds", parentFolder);
        }
        return packRootFolder;
    }
    getRelativePath(file, packRootFolder) {
        let relativePath = file.getFolderRelativePath(packRootFolder);
        if (relativePath) {
            relativePath = StorageUtilities_1.default.ensureNotStartsWithDelimiter(relativePath);
        }
        relativePath = AudioDefinition_1.default.canonicalizeAudioPath(relativePath);
        return relativePath;
    }
    ensureDefintionForFile(project, file) {
        let packRootFolder = this.getPackRootFolder();
        if (!packRootFolder || !this._data) {
            return;
        }
        let relativePath = this.getRelativePath(file, packRootFolder);
        if (!relativePath) {
            return;
        }
        const soundDefName = StorageUtilities_1.default.getBaseFromName(file.name).toLowerCase();
        if (Utilities_1.default.isUsableAsObjectKey(soundDefName)) {
            let soundDef = this._data.sound_definitions[soundDefName];
            if (!soundDef) {
                soundDef = {
                    category: "neutral",
                    sounds: [],
                };
                this._data.sound_definitions[soundDefName] = soundDef;
            }
            if (soundDef && !this.hasSoundByPath(soundDef, relativePath)) {
                soundDef.sounds.push({
                    is3D: false,
                    name: relativePath,
                    volume: 1,
                    weight: 10,
                });
            }
        }
    }
    hasSoundByPath(soundDefSet, path) {
        for (const sound of soundDefSet.sounds) {
            if (typeof sound === "string" && sound === path) {
                return sound;
            }
            else if (typeof sound !== "string" && sound.name === path) {
                return sound;
            }
        }
        return undefined;
    }
    getSoundReferenceMatchesByPath(file) {
        let packRootFolder = this.getPackRootFolder();
        if (!packRootFolder) {
            return;
        }
        let relativePath = this.getRelativePath(file, packRootFolder);
        const retSoundRefs = {};
        if (relativePath && this._data) {
            const keys = this.getSoundDefinitionSetNameList();
            for (const key in keys) {
                if (Utilities_1.default.isUsableAsObjectKey(key)) {
                    let soundDefSet = this._data.sound_definitions[key];
                    if (!soundDefSet) {
                        soundDefSet = this._data[key];
                    }
                    if (soundDefSet && soundDefSet.sounds) {
                        for (const soundInstance of soundDefSet.sounds) {
                            if (typeof soundInstance === "string") {
                                if (StorageUtilities_1.default.isPathEqual(soundInstance, relativePath)) {
                                    if (!retSoundRefs[key]) {
                                        retSoundRefs[key] = [];
                                    }
                                    retSoundRefs[key].push({ name: soundInstance });
                                }
                            }
                            else if (StorageUtilities_1.default.isPathEqual(soundInstance.name, relativePath)) {
                                if (!retSoundRefs[key]) {
                                    retSoundRefs[key] = [];
                                }
                                retSoundRefs[key].push(soundInstance);
                            }
                        }
                    }
                }
            }
        }
        return retSoundRefs;
    }
    getSoundDefinitionMatchesByPath(file) {
        let packRootFolder = this.getPackRootFolder();
        if (!packRootFolder) {
            return;
        }
        let relativePath = this.getRelativePath(file, packRootFolder);
        const retSoundDefs = {};
        if (relativePath && this._data) {
            for (const key in this._data.sound_definitions) {
                const soundDefSet = this._data.sound_definitions[key];
                if (soundDefSet && soundDefSet.sounds) {
                    for (const soundInstance of soundDefSet.sounds) {
                        if (typeof soundInstance === "string") {
                            if (StorageUtilities_1.default.isPathEqual(soundInstance, relativePath)) {
                                retSoundDefs[key] = soundDefSet;
                            }
                        }
                        else if (StorageUtilities_1.default.isPathEqual(soundInstance.name, relativePath)) {
                            retSoundDefs[key] = soundDefSet;
                        }
                    }
                }
            }
        }
        return retSoundDefs;
    }
    async addChildItems(project, item) {
        const itemsCopy = project.getItemsCopy();
        let packRootFolder = this.getPackRootFolder();
        let soundPathList = this.getCanonincalizedSoundPathList();
        for (const candItem of itemsCopy) {
            if (candItem.itemType === IProjectItemData_1.ProjectItemType.audio && packRootFolder && soundPathList) {
                if (!candItem.isContentLoaded) {
                    await candItem.loadContent();
                }
                if (candItem.primaryFile) {
                    let relativePath = this.getRelativePath(candItem.primaryFile, packRootFolder);
                    if (relativePath) {
                        if (soundPathList.includes(relativePath)) {
                            item.addChildItem(candItem);
                            const nextSound = [];
                            for (const sound of soundPathList) {
                                if (sound !== relativePath) {
                                    nextSound.push(sound);
                                }
                            }
                            soundPathList = nextSound;
                        }
                    }
                }
            }
        }
        if (soundPathList) {
            for (const soundDef of soundPathList) {
                const isVanilla = await Database_1.default.isVanillaToken(soundDef);
                item.addUnfulfilledRelationship(soundDef, IProjectItemData_1.ProjectItemType.audio, isVanilla);
            }
        }
    }
}
exports.default = SoundDefinitionCatalogDefinition;

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