"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.componentClassFromSpec = componentClassFromSpec;
const clone_1 = require("../util/clone");
const weakMerge_1 = require("../weakMerge");
const component_1 = require("./component");
const componentClassFromSpecId_1 = require("./componentClassFromSpecId");
const parentElement_1 = require("./platform/web/parentElement");
function componentClassFromSpec(spec, specs, sub_component_map = {}, memory) {
    const { id, name, units = {}, component = { defaultWidth: 120, defaultHeight: 120 }, } = (0, clone_1.clone)(spec);
    const { children = [], subComponents = {}, slots = [] } = component;
    class Parent extends component_1.Component {
        constructor($props, $system) {
            super($props, $system);
            for (const unitId in subComponents) {
                const unitSpec = units[unitId];
                const { id } = unitSpec;
                let childComponent = sub_component_map[unitId];
                if (!childComponent) {
                    const specs_ = (0, weakMerge_1.weakMerge)($system.specs, specs);
                    const Class = (0, componentClassFromSpecId_1.componentClassFromSpecId)($system.components, specs_, id, memory?.memory?.unit?.[unitId] ?? unitSpec.memory);
                    childComponent = new Class({}, $system);
                }
                this.setSubComponent(unitId, childComponent);
            }
            const fillParentRoot = (unitId) => {
                const component = this.$subComponent[unitId];
                const subComponentSpec = subComponents[unitId] || {};
                const { children = [], childSlot = {} } = subComponentSpec;
                for (const childUnitId of children) {
                    fillParentRoot(childUnitId);
                    const slotName = childSlot[childUnitId] || 'default';
                    const childRoot = this.$subComponent[childUnitId];
                    component.registerParentRoot(childRoot, slotName);
                }
            };
            const $element = (0, parentElement_1.parentElement)($system);
            this.$element = $element;
            this.$primitive = false;
            let i = 0;
            for (const _slot of slots) {
                const [slot, slotSlot] = _slot;
                const subComponent = this.$subComponent[slot];
                const slotName = i === 0 ? 'default' : `${i}`;
                this.$slot[slotName] = subComponent.$slot[slotSlot];
                this.$slotId[slotName] = slot;
                this.$slotTarget[slotName] = slotSlot;
                i++;
            }
            for (let child_id of children) {
                const rootComponent = this.$subComponent[child_id];
                fillParentRoot(child_id);
                this.registerRoot(rootComponent);
            }
        }
        onDestroy() {
            super.onDestroy();
            for (const unitId in this.$subComponent) {
                const component = this.$subComponent[unitId];
                component.destroy();
            }
        }
    }
    Parent.id = id;
    Object.defineProperty(Parent, 'name', {
        value: name,
    });
    return Parent;
}
//# sourceMappingURL=componentClassFromSpec.js.map