import { DOMError } from './errors/DOMError';
var Node = /** @class */ (function () {
    function Node(nodeName) {
        this.nodeType = -1;
        this.childNodes = [];
        this.nodeName = nodeName;
    }
    Node.prototype.appendChild = function (child) {
        if (child.contains(this))
            throw new DOMError("Failed to execute 'appendChild' on 'Node': The new child element contains the parent.");
        // Remove the node first before appending it.
        if (child.parentNode) {
            child.parentNode.removeChild(child);
        }
        // Append the node
        child.parentNode = this;
        this.childNodes.push(child);
        return child;
    };
    Node.prototype.insertBefore = function (child, referenceNode) {
        var index = this.childNodes.indexOf(referenceNode);
        if (index === -1)
            throw new DOMError("Failed to execute 'insertBefore' on 'Node': The reference node is not a child of this node.");
        if (child.contains(this))
            throw new DOMError("Failed to execute 'appendChild' on 'Node': The new child element contains the parent.");
        // Remove the node first before appending it.
        if (child.parentNode) {
            child.parentNode.removeChild(child);
        }
        this.childNodes.splice(index, 0, child);
        child.parentNode = this;
        return child;
    };
    Node.prototype.removeChild = function (child) {
        var index = this.childNodes.indexOf(child);
        if (index === -1)
            throw new DOMError("Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.");
        this.childNodes.splice(index, 1);
        child.parentNode = undefined;
        return child;
    };
    Node.prototype.replaceChild = function (newChild, oldChild) {
        if (newChild === oldChild)
            throw new DOMError("Failed to execute 'replaceChild' on 'Node': The new child element contains the old element.");
        if (newChild.contains(this))
            throw new DOMError("Failed to execute 'replaceChild' on 'Node': The new child element contains the parent.");
        // Remove the node first before appending it.
        if (newChild.parentNode) {
            newChild.parentNode.removeChild(newChild);
        }
        var index = this.childNodes.indexOf(oldChild);
        if (index === -1)
            throw new DOMError("Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.");
        this.childNodes.splice(index, 1, newChild);
        oldChild.parentNode = undefined;
        newChild.parentNode = this;
        return oldChild;
    };
    Node.prototype.contains = function (child) {
        if (child === this)
            return false;
        for (var i = 0; i < this.childNodes.length; i++) {
            if (this.childNodes[i] === child) {
                return true;
            }
            else if (this.childNodes[i].contains(child)) {
                return true;
            }
        }
        return false;
    };
    Object.defineProperty(Node.prototype, "firstChild", {
        get: function () {
            if (this.childNodes.length > 0) {
                return this.childNodes[0];
            }
            return undefined;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Node.prototype, "lastChild", {
        get: function () {
            if (this.childNodes.length > 0) {
                return this.childNodes[this.childNodes.length - 1];
            }
            return undefined;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Node.prototype, "nextSibling", {
        get: function () {
            if (!this.parentNode)
                return undefined;
            var nextSiblingIndex = this.parentNode.childNodes.indexOf(this) + 1;
            if (nextSiblingIndex >= this.parentNode.childNodes.length)
                return undefined;
            return this.parentNode.childNodes[nextSiblingIndex];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Node.prototype, "previousSibling", {
        get: function () {
            if (!this.parentNode)
                return undefined;
            var nextSiblingIndex = this.parentNode.childNodes.indexOf(this) - 1;
            if (nextSiblingIndex < 0)
                return undefined;
            return this.parentNode.childNodes[nextSiblingIndex];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Node.prototype, "textContent", {
        get: function () {
            return this.childNodes.map(function (node) { return node.textContent; }).join("");
        },
        set: function (text) {
            throw new Error("Not implemented");
        },
        enumerable: true,
        configurable: true
    });
    return Node;
}());
export { Node };
//# sourceMappingURL=Node.js.map