"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 Log_1 = require("../core/Log");
const IntAttributeComponent_1 = require("./components/IntAttributeComponent");
const FloatAttributeComponent_1 = require("./components/FloatAttributeComponent");
const MinecraftUtilities_1 = require("./MinecraftUtilities");
const ComponentProperty_1 = require("./ComponentProperty");
const ManagedComponent_1 = require("./ManagedComponent");
class ComponentizedBase {
    get onComponentAdded() {
        return this._onComponentAdded.asEvent();
    }
    get onComponentRemoved() {
        return this._onComponentRemoved.asEvent();
    }
    get onComponentChanged() {
        return this._onComponentChanged.asEvent();
    }
    constructor() {
        this._onComponentAdded = new ste_events_1.EventDispatcher();
        this._onComponentRemoved = new ste_events_1.EventDispatcher();
        this._onComponentChanged = new ste_events_1.EventDispatcher();
        this._componentProperties = {};
        this._components = {};
        this._managedComponents = {};
    }
    getComponent(id) {
        if (this._components === undefined) {
            return undefined;
        }
        id = MinecraftUtilities_1.default.canonicalizeFullName(id);
        const component = this._components[id];
        if (component === undefined) {
            return undefined;
        }
        if (!this._managedComponents[id]) {
            this._managedComponents[id] = new ManagedComponent_1.ManagedComponent(id, component);
        }
        return this._managedComponents[id];
    }
    notifyComponentUpdated(id) {
        const component = this.getComponent(id);
        if (component === undefined) {
            Log_1.default.unexpectedUndefined("CBNCU");
        }
        else {
            this._onComponentChanged.dispatch(this, component);
        }
    }
    getComponents() {
        const componentSet = [];
        if (this._components !== undefined) {
            for (const componentName in this._managedComponents) {
                const component = this.getComponent(componentName);
                if (component !== undefined) {
                    componentSet.push(component);
                }
            }
        }
        return componentSet;
    }
    ensureDataComponent(id, component) {
        this._ensureComponentsInitialized();
        id = MinecraftUtilities_1.default.canonicalizeFullName(id);
        if (this._components === undefined || this._managedComponents === undefined) {
            Log_1.default.unexpectedUndefined("CBEDC");
            throw new Error();
        }
        if (this._managedComponents[id] !== undefined) {
            return this._managedComponents[id].getData();
        }
        const mc = this.ensureComponent(id, new ManagedComponent_1.ManagedComponent(id, component));
        if (mc) {
            return mc.getData();
        }
        return undefined;
    }
    ensureComponent(id, component) {
        this._ensureComponentsInitialized();
        id = MinecraftUtilities_1.default.canonicalizeFullName(id);
        if (this._components === undefined || this._managedComponents === undefined) {
            Log_1.default.unexpectedUndefined("CBEC");
            throw new Error();
        }
        if (this._managedComponents[id] !== undefined) {
            return this._managedComponents[id];
        }
        this._managedComponents[id] = component;
        this._components[id] = component.getData();
        this._onComponentAdded.dispatch(this, component);
        return component;
    }
    addComponent(id, component) {
        this._ensureComponentsInitialized();
        id = MinecraftUtilities_1.default.canonicalizeFullName(id);
        component.id = id;
        if (this._managedComponents !== undefined) {
            this._managedComponents[id] = component;
            this._onComponentAdded.dispatch(this, component);
        }
        if (this._components) {
            this._components[id] = component.getData();
        }
    }
    removeComponent(id) {
        if (this._components === undefined) {
            return;
        }
        id = MinecraftUtilities_1.default.canonicalizeFullName(id);
        const newComponents = {};
        const newManagedComponents = {};
        for (const name in this._components) {
            const nameCanon = MinecraftUtilities_1.default.canonicalizeFullName(name);
            if (nameCanon !== id) {
                const component = this._components[name];
                newComponents[name] = component;
            }
        }
        for (const name in this._managedComponents) {
            const nameCanon = MinecraftUtilities_1.default.canonicalizeFullName(name);
            if (nameCanon !== id) {
                const component = this._managedComponents[name];
                newManagedComponents[name] = component;
            }
        }
        this._components = newComponents;
        this._managedComponents = newManagedComponents;
    }
    getComponentProperty(name) {
        return this._componentProperties[name];
    }
    ensureComponentProperty(name) {
        return this.addComponentProperty(name);
    }
    addComponentProperty(name) {
        let property = this._componentProperties[name];
        if (property == null) {
            property = new ComponentProperty_1.default(this, name);
            property.id = name;
            this._componentProperties[name] = property;
            this.notifyComponentPropertyChanged(property);
        }
        return property;
    }
    notifyComponentPropertyChanged(property) { }
    loadAttributeComponentsFromNbtTag(attributesTag) {
        const attributesChildren = attributesTag.getTagChildren();
        for (let i = 0; i < attributesChildren.length; i++) {
            const attributeChild = attributesChildren[i];
            const nameChild = attributeChild.find("Name");
            if (nameChild !== null) {
                const name = nameChild.valueAsString;
                let component = null;
                if (name.endsWith("luck") ||
                    name.endsWith("health") ||
                    name.endsWith("absorption") ||
                    name.endsWith("knockback_resistance") ||
                    name.endsWith("follow_range")) {
                    component = new IntAttributeComponent_1.default();
                }
                else if (name.endsWith("movement") || name.endsWith("jump_strength")) {
                    // movement, underwater_movement, lava_movement, horse.jump_strength
                    component = new FloatAttributeComponent_1.default();
                }
                else {
                    Log_1.default.debugAlert("Unknown component '" + name + "' found");
                    component = new FloatAttributeComponent_1.default();
                }
                const managedComponent = new ManagedComponent_1.ManagedComponent(name, component);
                this.ensureComponent(name, managedComponent);
            }
        }
    }
    _ensureComponentsInitialized() {
        if (this._components === null) {
            this._components = {};
        }
    }
}
exports.default = ComponentizedBase;

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