"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_STYLE = void 0;
const componentClassFromSpecId_1 = require("../../../../client/componentClassFromSpecId");
const component_1 = require("../../../../client/component_");
const createParent_1 = require("../../../../client/createParent");
const element_1 = require("../../../../client/element");
const parentElement_1 = require("../../../../client/platform/web/parentElement");
const array_1 = require("../../../../util/array");
exports.DEFAULT_STYLE = {};
class Wrap extends element_1.Element {
    constructor(props, $system) {
        super(props, $system);
        this.$_ = ['W'];
        this._Container = (0, createParent_1.parentClass)();
        this._child_container = [];
        this._parent_container = [];
        this._parent_child_container = [];
        this._rewrap = () => {
            for (let at = 0; at < this._child_container.length; at++) {
                this.rewrapChild(at);
            }
            for (let at = 0; at < this._parent_container.length; at++) {
                this.rewrapParentRoot(at);
            }
            for (let at = 0; at < this._parent_child_container.length; at++) {
                this.rewrapParentChild(at);
            }
        };
        this._connected_container = (at, method) => {
            const container = new this._Container({}, this.$system);
            const _ = (0, component_1.getComponentInterface)(container);
            const containerUnit = this.$unit[`${method}`]({ at, _ });
            container.connect(containerUnit);
            return container;
        };
        const $element = (0, parentElement_1.default)($system);
        $element.className = 'wrap';
        this.$element = $element;
        this.$slot = {
            default: this,
        };
    }
    rewrapParentChild(at) {
        const _at = at;
        const container = this._parent_child_container[at];
        container.disconnect();
        const child = this.$parentRoot[at];
        const childSlot = this.$parentRootSlotName[at];
        const new_container = this._connected_parent_root_container(at);
        this._parent_child_container[at] = new_container;
        super.domRemoveParentChildAt(container, childSlot, at, _at);
        super.memRemoveParentChildAt(container, childSlot, at, _at);
        container.removeChild(child);
        new_container.appendChild(child);
        super.domAppendParentChildAt(new_container, childSlot, at, _at);
        super.memAppendParentChild(new_container, childSlot, at, _at);
    }
    rewrapParentRoot(at) {
        const container = this._parent_container[at];
        container.disconnect();
        const child = this.$parentRoot[at];
        const childSlot = this.$parentRootSlotName[at];
        const new_container = this._connected_parent_root_container(at);
        this._parent_container[at] = new_container;
        if (this.$mountParentRoot.includes(child)) {
            super.domRemoveParentRootAt(container, childSlot, at, at);
            super.postRemoveParentRootAt(container, childSlot, at, at);
            container.removeChild(child);
            new_container.appendChild(child);
            super.domAppendParentRoot(new_container, childSlot, at);
            super.postAppendParentRoot(new_container, childSlot, at);
        }
    }
    rewrapChild(at) {
        const container = this._child_container[at];
        container.disconnect();
        const child = this.$children[at];
        const childSlot = this.$childSlotName[at];
        super.domRemoveChild(container, childSlot, at);
        super.postRemoveChild(container, at);
        container.removeChild(child);
        const new_container = this._connected_child_container(at);
        new_container.appendChild(child);
        this._child_container[at] = new_container;
        super.domAppendChild(new_container, childSlot, at);
        super.postAppendChild(new_container, childSlot, at);
    }
    _connected_child_container(at) {
        return this._connected_container(at, '$refChildContainer');
    }
    _connected_parent_root_container(at) {
        return this._connected_container(at, '$refParentRootContainer');
    }
    _connected_parent_child_container(at) {
        return this._connected_container(at, '$refParentChildContainer');
    }
    memAppendChild(child, slotName, at) {
        const container = this._connected_child_container(at);
        this._child_container.push(container);
        container.memAppendChild(child, 'default', at);
        super.memAppendChild(child, slotName, at);
    }
    memAppendParentChild(component, slotName, at, _at) {
        // console.log(
        //   'Wrap',
        //   'memAppendParentChild',
        //   component.constructor.name,
        //   component.$globalId,
        //   slotName,
        //   at,
        //   _at
        // )
        const container = this._connected_parent_child_container(at);
        (0, array_1.push)(this._parent_child_container, container);
        container.memAppendChild(component, 'default', at);
        super.memAppendParentChild(component, slotName, at, _at);
    }
    domAppendParentChildAt(component, slotName, _at) {
        // console.log(
        //   'Wrap',
        //   'domAppendParentChildAt',
        //   component.constructor.name,
        //   component.$globalId,
        //   slotName,
        //   at,
        //   _at
        // )
        const container = this._parent_child_container[_at];
        container.domAppendChild(component, 'default', _at);
        super.domAppendParentChildAt(container, slotName, _at, _at);
    }
    memInsertParentChildAt(component, slotName, _at) {
        // console.log(
        //   'Wrap',
        //   'memInsertParentChildAt',
        //   component.constructor.name,
        //   component.$globalId,
        //   slotName,
        //   _at
        // )
        const container = this._connected_parent_child_container(_at);
        (0, array_1.insert)(this._parent_child_container, container, _at);
        container.memAppendChild(component, 'default', _at);
        super.memInsertParentChildAt(component, slotName, _at);
    }
    domInsertParentChildAt(component, slotName, _at) {
        // console.log(
        //   'Wrap',
        //   'domInsertParentChildAt',
        //   component.constructor.name,
        //   component.$globalId,
        //   slotName,
        //   at,
        //   _at
        // )
        const container = this._parent_child_container[_at];
        container.domInsertParentChildAt(component, 'default', _at);
        super.domInsertParentChildAt(container, slotName, _at);
    }
    memRemoveParentChildAt(component, slotName, at, _at) {
        // console.log(
        //   'Wrap',
        //   'memRemoveParentChildAt',
        //   component.constructor.name,
        //   component.$globalId,
        //   at,
        //   _at
        // )
        this._parent_child_container.splice(_at, 1);
        super.memRemoveParentChildAt(component, slotName, at, _at);
    }
    domRemoveParentChildAt(component, slotName, at, _at) {
        // console.log(
        //   'Wrap',
        //   'domRemoveParentChildAt',
        //   component.constructor.name,
        //   component.$globalId,
        //   at,
        //   _at
        // )
        const container = this._parent_child_container[_at];
        container.domRemoveChild(component, 'default', at);
        super.domRemoveParentChildAt(container, slotName, at, _at);
    }
    domAppendChild(child, slotName, at) {
        const container = this._child_container[at];
        container.domAppendChild(child, 'default', at);
        super.domAppendChild(container, slotName, at);
    }
    postAppendChild(child, slotName, at) {
        const container = this._child_container[at];
        child.$parent = this;
        container.mount(this.$context);
    }
    postAppendParentChild(child, slotName, at) {
        const container = this._parent_child_container[at];
        container.mount(this.$context);
    }
    domRemoveChild(child, slotName, at) {
        const container = this._child_container[at];
        container.domRemoveChild(child, 'default', at);
        super.domRemoveChild(container, slotName, at);
    }
    postRemoveChild(child, at) {
        const container = this._child_container[at];
        container.unmount();
        super.postRemoveChild(child, at);
    }
    insertParentRoot(component, at, slotName) {
        // console.log('Graph', 'insertParentRoot', component, at, slotName)
        const container = this._connected_parent_root_container(at);
        (0, array_1.insert)(this._parent_container, container, at);
        super.insertParentRoot(component, at, slotName);
    }
    unshiftParentRoot(component, slotName) {
        // console.log('Graph', 'unshiftParentRoot', component)
        const container = this._connected_parent_root_container(0);
        (0, array_1.unshift)(this._parent_container, container);
        super.unshiftParentRoot(component, slotName);
    }
    pullParentRoot(component) {
        // console.log('Graph', 'pullParentRoot', component)
        const at = this.$parentRoot.indexOf(component);
        (0, array_1.removeAt)(this._parent_container, at);
        super.pullParentRoot(component);
    }
    memAppendParentRoot(component, slotName, at) {
        const container = this._connected_parent_root_container(at);
        this._parent_container.push(container);
        container.memAppendChild(component, 'default', at);
        super.memAppendParentRoot(component, slotName, at);
    }
    domAppendParentRoot(component, slotName, at) {
        // console.log('Graph', 'domAppendParentRoot', component, slotName, at)
        const container = this._parent_container[at];
        container.appendChild(component);
        super.domAppendParentRoot(container, slotName, at);
    }
    postAppendParentRoot(component, slotName, at) {
        // console.log('Graph', 'postAppendParentRoot', component, slotName, at)
        const container = this._parent_container[at];
        super.postAppendParentRoot(container, slotName, at);
    }
    domRemoveParentRootAt(component, slotName, at, _at) {
        // console.log('Wrap', 'domRemoveParentRootAt', component, at)
        const container = this._parent_container[_at];
        container.domRemoveChild(component, 'default', at);
        super.domRemoveParentRootAt(container, slotName, at, _at);
    }
    postRemoveParentRootAt(component, slotName, at, _at) {
        // console.log('Wrap', 'postRemoveParentRootAt', component, at)
        super.postRemoveParentRootAt(component, slotName, at, _at);
    }
    domInsertParentRootAt(component, at, slotName) {
        const container = this._parent_container[at];
        container.domAppendChild(component, 'default', at);
        super.domInsertParentRootAt(container, at, slotName);
    }
    postInsertParentRootAt(component, at, slotName) {
        const container = this._parent_container[at];
        super.postInsertParentRootAt(container, at, slotName);
    }
    onPropChanged(name, current) {
        if (name === 'component') {
            let componentClass;
            if (current) {
                const Class = current;
                const { __bundle } = Class;
                const { id, input } = __bundle.unit;
                componentClass = (0, componentClassFromSpecId_1.componentClassFromSpecId)(this.$system.components, this.$system.specs, this.$system.classes, id, input);
            }
            else {
                componentClass = (0, createParent_1.parentClass)();
            }
            this._Container = componentClass;
            this._rewrap();
        }
    }
    getContainer() {
        return this._Container;
    }
    getChildContainer(at) {
        return this._child_container[at];
    }
    getParentChildContainer(at) {
        return this._parent_child_container[at];
    }
    getParentRootContainer(at) {
        return this._parent_container[at];
    }
}
exports.default = Wrap;
//# sourceMappingURL=Component.js.map