/*

	constructor:  new JTreeWalker( DOMNode );
		DOMNode should be a node of elements, such as "document",
			"document.body", or that returned by document.getElementById("arbitraryId")
		
	methods:      getElements( [sElementName] );
		returns an array of elements in DOMNode with nodeName matching sElementName
		sElementName can be "*" or the name of an element e.g. input, a, b, div etc...case-insensitive
		getElements() will return the root node of DOMNode, if sElementName == "*" or root.nodeName == sElementName
*/

self.ELEMENT_NODE = 1;
self.TEXT_NODE = 3;

function JTreeWalker(DOMNode) {
	this.tree = DOMNode;
}

function JNodeWalker(node) {
	this.node = node;
}

JTreeWalker.prototype.getElements = function(sElementName, el, ar) {
	var sElementName = sElementName ? sElementName.toLowerCase() : "*";
	var el = el ? el : this.tree;
	var ar = ar ? ar : [];

	if (sElementName == "*" || (el.nodeName.toLowerCase() == sElementName)) {
		ar.push(el);
	}

	for (var x = 0; x < el.childNodes.length; x++) {
		var node = new JNodeWalker(el.childNodes[x]);
		var els = node.getElements(sElementName);
		if (els.length > 0) {
			ar = ar.concat(els);
		}
	}
	return ar;
}

JNodeWalker.prototype.getElements = function(sElementName, el, ar) {
	var sElementName = sElementName ? sElementName.toLowerCase() : "*";
	var el = el ? el : this.node;
	var ar = ar ? ar : [];

	if (el.nodeType == ELEMENT_NODE) {
		if (sElementName == "*" || (el.nodeName.toLowerCase() == sElementName)) {
			ar.push(el);
		}
	}

	if (el.childNodes && el.childNodes.length) {
		for (var x = 0; x < el.childNodes.length; x++) {
			var child = el.childNodes[x];

			if (child.childNodes && child.childNodes.length > 0) {
				var els = new JNodeWalker(child).getElements(sElementName);
				if (els.length > 0) ar = ar.concat( els );
			}
			else {
				if (child.nodeType == ELEMENT_NODE) {
					if (sElementName == "*" || (child.nodeName.toLowerCase() == sElementName)) {
						ar.push( child );
					}
				}
			}
		}
	}
	return ar;
}
