/**
 * Node Tree Walking Utility
 * Author: Nick Crohn (nick@meltmedia.com)
 */

meld.utilities.TreeWalker = Class.create({
        initialize: function(node, filterFunction, removeWhiteSpace) {
            if(!node.innerHTML) node = meld.utilities.DomUtil.cloneNode(node, true);
            this._node = node;
            this.currentNode = this._node;
            this.nodeList = new Array();
            this._filterFunction = filterFunction;
            this._removeWhiteSpace = removeWhiteSpace;
            this.walk(this._node);
        }
    });

meld.utilities.TreeWalker.prototype.walk = function(node) {
    var next = node.firstChild;
    while (next) {
        this.currentNode = next;
        // If we are ignoring white space in the document check the node for whitespace and remove the node.
        // Return if we are a whitespace node so we can get the next valid node
        if(this._removeWhiteSpace && 
           next.nodeType == 3 && 
           !next.nodeValue.match(/[\w\d\|!@#$%^&*()©®™»+=]/g)) {
            var removeNode = next;
            next = next.nextSibling;
            removeNode.parentNode.removeChild(removeNode);
        } else {
            try {
                this._performNodeActions(next);
            } catch(e) {
                //console.error("TreeWalker: "+e.message);
                throw new Error(e.message);
            }
            if(next.hasChildNodes()) {
                this.walk(next);
            }
            next = next.nextSibling;
        }
    }
};

meld.utilities.TreeWalker.prototype._performNodeActions = function(node) {
    if(!node.hasClassName) node = $(node);
    if(this._filterFunction(node)) {
        this.nodeList.push(node);
    }
};

meld.utilities.TreeWalker.prototype.update = function() {
    delete this.nodeList;
    this.nodeList = new Array();
    this.walk(this._node);
};

meld.utilities.TreeWalker.prototype.getNodeById = function(id) {
    for(var i=0;i<this.nodeList.length;i++) {
        if(this.nodeList[i].id == id) return this.nodeList[i];
    }
    return false;
};

/* Not Implemented Yet -- Next version...

//Travels to and returns the first child of the current node.
meld.utilities.TreeWalker.prototype.firstChild = function() {
    if(this.currentNode.hasChildNodes()) {
        this.currentNode = this.currentNode.firstChild;
        return this.currentNode;
    }
    return false;
};

//Travels to and returns the last child of the current node.
meld.utilities.TreeWalker.prototype.lastChild = function() {
    if(this.currentNode.hasChildNodes()) {
        this.currentNode = this.currentNode.childNodes[this.currentNode.childNodes.length-1]
        return this.currentNode;
    }
    return false;
};

//Travels to and returns the next node within the filtered collection of nodes.
meld.utilities.TreeWalker.prototype.nextNode = function() {
    if(this.currentNode.hasChildNodes()) {
        return this.firstChild()
    }
    return this.nextSibling();
};

//Travels to and returns the next sibling of the current node.
meld.utilities.TreeWalker.prototype.nextSibling = function() {
    if(this.currentNode.nextSibling) {
        this.currentNode = this.currentNode.nextSibling;
        return this.currentNode;
    }
    return false;
};

//Travels to and returns the current node's parent node.
meld.utilities.TreeWalker.prototype.parentNode = function() {
    if(this.currentNode.parentNode) {
        this.currentNode = this.currentNode.parentNode;
        return this.currentNode;
    }
    return false;
};

//Travels to and returns the previous node of the current node.
meld.utilities.TreeWalker.prototype.previousNode = function() {
    if(this.currentNode.previousSibling) {
        return this.previousSibling();
    }
    return this.parentNode();
};

//Travels to and returns the previous sibling of the current node.
meld.utilities.TreeWalker.prototype.previousSibling = function() {
    if(this.currentNode.previousSibling) {
        this.currentNode = this.currentNode.previousSibling;
        return this.currentNode;
    }
    return false;
};

*/
