// Config:
Hilite = {
    elementid: 'matches',
    max_nodes: 1000,
    style_name: 'hilite'
};

Hilite.hiliteElement = function(elm, query) {
    if (isempty(query) || elm.childNodes.length == 0)
		return;

	qre = new RegExp(query.toLowerCase(),"i");
    var textproc = function(node) {
        var match = qre.exec(node.data);
        if (match) {
            var val = match[0];
            var k = '';
            var node2 = node.splitText(match.index);
            var node3 = node2.splitText(val.length);
            var span = node.ownerDocument.createElement('SPAN');
            node.parentNode.replaceChild(span, node2);
            span.className =  Hilite.style_name;
            span.appendChild(node2);
            return span;
        } else {
            return node;
        }
    };
    Hilite.walkElements(elm.childNodes[0], 1, textproc);
};

Hilite.hilite = function(pattern) {
		if(!isempty(pattern))
		{
			var e = document.getElementById(Hilite.elementid);
			Hilite.hiliteElement(e, pattern);
		}
};

Hilite.walkElements = function(node, depth, textproc) {
    var skipre = /^(script|style|textarea|input)/i;
    var count = 0;
    while (node && depth > 0) {
        count ++;
        if (count >= Hilite.max_nodes) {
            var handler = function() {
                Hilite.walkElements(node, depth, textproc);
            };
            setTimeout(handler, 50);
            return;
        }

        if (node.nodeType == 1) { // ELEMENT_NODE
            if (!skipre.test(node.tagName) && node.childNodes.length > 0) {
                node = node.childNodes[0];
                depth ++;
                continue;
            }
        } else if (node.nodeType == 3) { // TEXT_NODE
            node = textproc(node);
        }

        if (node.nextSibling) {
            node = node.nextSibling;
        } else {
            while (depth > 0) {
                node = node.parentNode;
                depth --;
                if (node.nextSibling) {
                    node = node.nextSibling;
                    break;
                }
            }
        }
    }
};

