"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Element_ = void 0;
const method_1 = require("../../component/method");
const MethodNotImplementedError_1 = require("../../exception/MethodNotImplementedError");
const array_1 = require("../../util/array");
const Stateful_1 = require("../Stateful");
class Element_ extends Stateful_1.Stateful {
    constructor({ i = [], o = [] }, opt = {}, system, id) {
        super({
            i,
            o,
        }, opt, system, id);
        this.__ = ['U', 'C', 'J', 'V', 'EE'];
        this._children = [];
        this._root = [];
        this._parent_root = [];
        this._parent_children = [];
        this._slot = {};
        this._state = {};
        this._animations = [];
        this._stopPropagation = {};
        this._stopImmediatePropagation = {};
        this._preventDefault = {};
        this.addListener('play', this._play);
        this.addListener('pause', this._pause);
        this.addListener('set', (name, data) => {
            var _a, _b, _c, _d;
            if (!this._forwarding) {
                if (data === undefined) {
                    this._forwarding_empty = true;
                    // @ts-ignore
                    (_b = (_a = this._output) === null || _a === void 0 ? void 0 : _a[name]) === null || _b === void 0 ? void 0 : _b.pull();
                    this._forwarding_empty = false;
                }
                else {
                    this._forwarding = true;
                    // @ts-ignore
                    (_d = (_c = this._output) === null || _c === void 0 ? void 0 : _c[name]) === null || _d === void 0 ? void 0 : _d.push(data);
                    this._forwarding = false;
                }
            }
            if (!this._set_from_input &&
                !this._backwarding &&
                !this._forwarding &&
                data !== undefined) {
                this._backwarding = true;
                // TODO add to end of event queue
                setTimeout(() => {
                    var _a, _b;
                    (_b = (_a = this._input) === null || _a === void 0 ? void 0 : _a[name]) === null || _b === void 0 ? void 0 : _b.pull();
                    this._backwarding = false;
                }, 0);
            }
        });
        this._slot = {
            default: this,
        };
    }
    isElement() {
        return true;
    }
    detach() {
        throw new MethodNotImplementedError_1.MethodNotImplementedError();
    }
    registerRoot(component) {
        return (0, method_1.registerRoot)(this, this._root, component);
    }
    unregisterRoot(component) {
        return (0, method_1.unregisterRoot)(this, this._root, component);
    }
    reorderRoot(component, to) {
        return (0, method_1.reorderRoot)(this, this._root, component, to);
    }
    registerParentRoot(component, slotName) {
        return (0, method_1.registerParentRoot)(this, this._parent_root, component, slotName);
    }
    unregisterParentRoot(component) {
        return (0, method_1.unregisterParentRoot)(this, this._parent_root, component);
    }
    reorderParentRoot(component, to) {
        return (0, method_1.reorderParentRoot)(this, this._parent_root, component, to);
    }
    appendParentChild(component, slotName) {
        return (0, method_1.appendParentChild)(this, this._parent_children, component, slotName);
    }
    removeParentChild(component) {
        return (0, method_1.removeParentChild)(this, this._parent_children, component);
    }
    appendChild(bundle) {
        return (0, method_1.appendChild)(this, this._children, bundle);
    }
    insertChild(Bundle, at) {
        throw new MethodNotImplementedError_1.MethodNotImplementedError();
    }
    pushChild(Bundle) {
        return (0, method_1.pushChild)(this, this._children, Bundle);
    }
    hasChild(at) {
        return (0, method_1.hasChild)(this, this._children, at);
    }
    removeChild(at) {
        return (0, method_1.removeChild)(this, this._children, at);
    }
    pullChild(at) {
        throw (0, method_1.pullChild)(this, this._children, at);
    }
    refChild(at) {
        return (0, method_1.refChild)(this, this._children, at);
    }
    refChildren() {
        return (0, method_1.refChildren)(this, this._children);
    }
    refSlot(slotName) {
        const slot = this._slot[slotName];
        if (slot) {
            return slot;
        }
        throw new MethodNotImplementedError_1.MethodNotImplementedError();
    }
    getAnimations() {
        return this._animations;
    }
    animate(keyframes, opt) {
        return (0, method_1.animate)(this, this._animations, keyframes, opt);
    }
    cancelAnimation(id) {
        return (0, method_1.cancelAnimation)(this, this._animations, id);
    }
    stopPropagation(name) {
        return (0, method_1.stopPropagation)(this, this._stopPropagation, name);
    }
    getSetup() {
        const setup = {
            animations: this._animations,
            events: this.eventNames(),
            stopPropagation: Object.keys(this._stopPropagation),
            stopImmediatePropagation: Object.keys(this._stopImmediatePropagation),
            preventDefault: Object.keys(this._preventDefault),
        };
        return setup;
    }
    _play() {
        (0, array_1.forEach)(this._children, (u) => u.play());
    }
    _pause() {
        (0, array_1.forEach)(this._children, (u) => u.pause());
    }
}
exports.Element_ = Element_;
//# sourceMappingURL=index.js.map