"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var type_1 = __importDefault(require("./nodes/type"));
function isTag(node) {
    return node && node.nodeType === type_1.default.ELEMENT_NODE;
}
function getAttributeValue(elem, name) {
    return isTag(elem) ? elem.getAttribute(name) : undefined;
}
function getName(elem) {
    return ((elem && elem.rawTagName) || '').toLowerCase();
}
function getChildren(node) {
    return node && node.childNodes;
}
function getParent(node) {
    return node ? node.parentNode : null;
}
function getText(node) {
    return node.text;
}
function removeSubsets(nodes) {
    var idx = nodes.length;
    var node;
    var ancestor;
    var replace;
    // Check if each node (or one of its ancestors) is already contained in the
    // array.
    while (--idx > -1) {
        node = ancestor = nodes[idx];
        // Temporarily remove the node under consideration
        nodes[idx] = null;
        replace = true;
        while (ancestor) {
            if (nodes.indexOf(ancestor) > -1) {
                replace = false;
                nodes.splice(idx, 1);
                break;
            }
            ancestor = getParent(ancestor);
        }
        // If the node has been found to be unique, re-insert it.
        if (replace) {
            nodes[idx] = node;
        }
    }
    return nodes;
}
function existsOne(test, elems) {
    return elems.some(function (elem) {
        return isTag(elem) ? test(elem) || existsOne(test, getChildren(elem)) : false;
    });
}
function getSiblings(node) {
    var parent = getParent(node);
    return parent && getChildren(parent);
}
function hasAttrib(elem, name) {
    return getAttributeValue(elem, name) !== undefined;
}
function findOne(test, elems) {
    var elem = null;
    for (var i = 0, l = elems.length; i < l && !elem; i++) {
        var el = elems[i];
        if (test(el)) {
            elem = el;
        }
        else {
            var childs = getChildren(el);
            if (childs && childs.length > 0) {
                elem = findOne(test, childs);
            }
        }
    }
    return elem;
}
function findAll(test, nodes) {
    var result = [];
    for (var i = 0, j = nodes.length; i < j; i++) {
        if (!isTag(nodes[i]))
            continue;
        if (test(nodes[i]))
            result.push(nodes[i]);
        var childs = getChildren(nodes[i]);
        if (childs)
            result = result.concat(findAll(test, childs));
    }
    return result;
}
exports.default = {
    isTag: isTag,
    getAttributeValue: getAttributeValue,
    getName: getName,
    getChildren: getChildren,
    getParent: getParent,
    getText: getText,
    removeSubsets: removeSubsets,
    existsOne: existsOne,
    getSiblings: getSiblings,
    hasAttrib: hasAttrib,
    findOne: findOne,
    findAll: findAll
};
