(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.RootObject = void 0;
    class RootObject {
        get vsProps() {
            return undefined;
        }
        addEventListener(name, handler) {
            return bridge.addEventHandler(this, name, handler);
        }
        appendChild(e) {
            bridge.appendChild(this, e);
        }
        dispatchEvent(evt) {
            bridge.dispatchEvent(evt);
        }
    }
    exports.RootObject = RootObject;
    class XNode {
        constructor(
        // tslint:disable-next-line: ban-types
        name, attributes, children, isProperty, isTemplate) {
            this.name = name;
            this.attributes = attributes;
            this.children = children;
            this.isProperty = isProperty;
            this.isTemplate = isTemplate;
        }
        static attach(n, tag) {
            return {
                factory: (attributes, ...nodes) => new XNode(n, attributes
                    ? Object.assign(Object.assign({}, attributes), { for: tag }) : { for: tag }, nodes)
            };
        }
        static prepare(n, isProperty, isTemplate) {
            function px(v) {
                return ({
                    [n]: v
                });
            }
            px.factory = (a, ...nodes) => {
                return new XNode(n, a, nodes, isProperty, isTemplate);
            };
            px.toString = () => n;
            return px;
            // return {
            //     factory(a: any, ... nodes: any[]) {
            //         return new XNode(n, a, nodes, isProperty , isTemplate);
            //     },
            //     toString() {
            //         return n;
            //     }
            // } as any;
        }
        // public static property(): NodeFactory {
        //     return {
        //         factory: true
        //     } as any;
        // }
        static getClass(fullTypeName, assemblyName) {
            const n = fullTypeName + ";" + assemblyName;
            const cx = XNode.classes[n] || (XNode.classes[n] =
                bridge.getClass(fullTypeName, assemblyName, RootObject, (name, isProperty, isTemplate) => (a, ...nodes) => new XNode(name, a, nodes, isProperty, isTemplate)));
            return cx;
        }
        /**
         * Declares Root Namespace and Assembly. You can use return function to
         * to declare the type
         * @param ns Root Namespace
         */
        static namespace(ns, assemblyName) {
            return (type, isTemplate) => {
                return (c) => {
                    // static properties !!
                    for (const key in c) {
                        if (c.hasOwnProperty(key)) {
                            const element = c[key];
                            if (element) {
                                const n = ns + "." + type + ":" + key + ";" + assemblyName;
                                const af = (a) => {
                                    const r = {
                                        [n]: a
                                    };
                                    Object.defineProperty(r, "toString", {
                                        value: () => n,
                                        enumerable: false,
                                        configurable: false
                                    });
                                    return r;
                                };
                                af.factory = (a, ...nodes) => new XNode(n, a, nodes, true, element.isTemplate);
                                af.toString = () => n;
                                c[key] = af;
                            }
                        }
                    }
                    const tn = ns + "." + type + ";" + assemblyName;
                    c.factory = (a, ...nodes) => {
                        return new XNode(tn, a, nodes, false, isTemplate);
                    };
                    c.toString = () => tn;
                };
            };
        }
        static create(
        // tslint:disable-next-line: ban-types
        name, attributes, ...children) {
            if (name.factory) {
                return (name.factory)(attributes, ...children);
            }
            if (name.isControl) {
                return new XNode(name, attributes, children);
            }
            switch (typeof name) {
                case "object":
                    name = name.toString();
                    break;
                case "function":
                    return name(attributes || {}, ...children);
            }
            return new XNode(name, attributes, children);
        }
        toString() {
            if (typeof this.name === "string") {
                return `name is of type string and value is ${this.name}`;
            }
            return `name is of type ${typeof this.name}`;
        }
    }
    exports.default = XNode;
    XNode.classes = {};
    // public static template(): NodeFactory {
    //     return {
    //         factory: true,
    //         isTemplate: true,
    //     } as any;
    // }
    XNode.attached = (name) => (n) => ({ [name]: n });
    XNode.factory = (name, isProperty, isTemplate) => (a, ...nodes) => {
        return new XNode(name, a, nodes, isProperty, isTemplate);
    };
    if (typeof bridge !== "undefined") {
        bridge.XNode = XNode;
    }
});
//# sourceMappingURL=XNode.js.map