// a library containing (HTML)node methods ======== // 
// (c) 2004 - 2006  Leen Besslink and Jan Vermaat = // 
// version 1.3 - march 2006 ======================= //

// methods ======================================== //
/*
childNodeBy (el[object], condition[string], deepChild[bool])
	return: het gewenste child-object of false

parentNodeBy (el[object], condition[string])
	return: het gewenste parentobject of false

getPreviousSibling (el[object], condition[string])
	return: het gewenste previous sibling object of false

getNextSibling (el[object], condition[string])
	return: het gewenste next sibling object of false

onload (this[object], functionname[string], arg1, arg2, arg3....)
	return : nothing
	
hasChildNodes ()
	return : true of false
	
// properties ===================================== //

version // versienummer zoals 1.3

hasChildren // true of false

*/
var nodes = {}

nodes.version = '1.3';
nodes.__n = 0;

nodes.childNodeBy = function (el, condition, deepChild) {
	if (this.is_node (el) == false)
		return false;

	if (condition == false)
		return false;

	if (typeof el == 'undefined' || typeof el == 'function')
		return false;

	if (!el.hasChildNodes ())
		return false;

	for (var el2 in el.childNodes)
		if (el2 != 'length') {
			var el3 = el.childNodes [el2];

			if (this.check_condition (el3, condition))
				return el3;

			var el4 = this.childNodeBy (el3, condition, deepChild);

			if (el4 !== false)
				if (deepChild === true)
					return el4;
				else
					return el3;
		}
	return false;
}

// parentNodeBy ==================================== //
// zoek een parent node die voldoet aan:
//  condition (a=b)
// voorbeeld
// (o,'nodeName=TD')
// o = het huidige object waarin men zich bevind
// zoek naar de eerste parent met de property nodeName=TD
// oftewel: zoek naar de eerste bovenliggende TD
// =================================================== //
nodes.parentNodeBy  = function (el, condition) {
	if (typeof condition != 'string')
		condition = false;

	while (true) {
		if (el == null)
			return false;
			
		if (typeof el.parentNode == 'undefined') 
			return false;

		if (condition == false) 
			return el.parentNode;

		if (this.check_condition (el.parentNode, condition)) 
			return el.parentNode;

		var el = el.parentNode;
	}
	return false;
}

// check_condition ============================================ //
/*
	zinnigeParentNode = parentNodeBy ('prop!=', thisNode);
*/
// hulpfunctie ================================================ //

nodes.check_condition = function (el, condition) {
	if (typeof condition != 'string')
		return false;

	var arr = condition.split ('=', 2);

	if (arr.length == 1)
		arr [1] = '';

	if (typeof arr.length != 'undefined' && arr.length == 2) {
		var negative = arr [0].replace (/\!$/, '');
		if (negative == arr [0]) {
			negative = false;
		} else {
			arr [0] = negative;
			negative = true;
		}
		try {
			if (negative) {
				if (nodes.make_string (el.getAttribute (arr [0])) != arr [1])
					return true;

				if (nodes.make_string (el [arr [0]]) != arr [1])
					return true;
			} else {
				if (nodes.make_string (el.getAttribute (arr [0])) == arr [1])
					return true;

				if (nodes.make_string (el [arr [0]]) == arr [1])
					return true;
			}
		} catch (e) {
		}
	}
	return false;
}

nodes.make_string = function (val) {
	switch (typeof val) {
	case 'undefined':
	case 'null':
		return '';
	case 'object':
		if (val === null)
			return '';
	}
	return val;
}

nodes.is_node = function (node) {
/*
	nodeType:
	3 == text-node (space, tab, newline)
	8 == comment
*/
	if (node != null && typeof node != 'undefined')
		if (typeof node.nodeType != 'undefined') {
			var nodeType = node.nodeType.toString ();
			if (nodeType !== '3' && nodeType !=='8')
				return true;
		}
	return false;
}

nodes.getPreviousSibling = function (p, cond) {
	var s = p.previousSibling;
	if (s === null)
		return false;

	if (typeof cond != 'undefined')
		if (this.check_condition (s, cond))
			return s;

	if (!this.is_node (s))
		return this.getPreviousSibling (s, cond);
	else
		return s;
}

nodes.getNextSibling = function (p, cond) {
	var s = p.nextSibling;
	if (s === null)
		return false;

	if (typeof cond != 'undefined')
		if (this.check_condition (s))
			return s;

	if (!this.is_node (s))
		return this.getNextSibling (s, cond);
	else
		return s;
}
/*
3 functies die de dom-onload regelen
of te wel: voer javascript functies uit op het moment dat de dom beschikbaar is. Dit voorkomt vervelende timings problemen

api : dom.onload(this, arguments)
this: dit is het object waar de methods aanhangen die je wil aanroepen
arguments: de arguments uit de functie die je aanroept

voorbeeld:

<script src="nodes.js" type="text/javascript"></script>
<script>
var box = function () { }

box.prototype.add = function () {
	dom.onload (this, 'functionName', argument1, argument2, argument3....)
}

box.prototype._add = function (a,b,c) {
	// deze functie wordt uitgevoerd
	// zodra de dom klaar is
	alert(a + b + c)
}

var b = new box();
b.add (1,2,3)
</script>
*/
nodes.onload = function () {
	this.readyList = this.readyList? this.readyList: new Array();
	var functionName = arguments[1];
	var obj = arguments[0];
	
	if (typeof functionName!='string' && arguments.length < 2 && typeof obj !='object')
		return false
	
	var args = [];
	
	for (var i=2 ; i<arguments.length; i++) 
		args[i-2] = arguments[i];

	this.readyList [this.readyList.length] = {'obj':obj, 'func':functionName, 'args':args};

	if (this.hasChildren === true)
		this.onReady ();
	else
		this._onload ();
}

nodes._onload = function () {
	
	if ( this.hasChildren )
		return false;
	
	if(this.__n++ < 60) 
		setTimeout('nodes._onload()', 250);
	
	if	(typeof document.getElementsByTagName != 'undefined' && (document.getElementsByTagName('body')[0] != null || document.body != null)) {
		this.hasChildren = true; 
		this.onReady ();
	} 
}

nodes.onReady = function () { 
	for (var el in this.readyList) { 
		var element = this.readyList [el]
		if (element.obj[element.func])
			element.obj[element.func].apply (element.obj, element.args );
	
	}
	this.readyList = [];
}

nodes.hasChildNodes = function () { return this.hasChildren? this.hasChildren: false; }

// dom is an alias of node; it is dom-scripting is n't it?
var dom = nodes;

