/* addition for site functionality */

function setMainNav(){
  if(SelectMainNav !=null && SelectMainNav != ""){
    elMainNav = document.getElementById("imgnav"+SelectMainNav); 
    if(elMainNav){
     srcval = elMainNav.src;
     pre = srcval.substr(0, srcval.lastIndexOf("_"));
     suf = srcval.substr(srcval.lastIndexOf('.'), srcval.length-srcval.lastIndexOf('.'));
//      alert(pre+ "_active" + suf );
      elMainNav.src = pre+'_active'+suf;
    }
  }
}
window.name = "page";
setMainNav();

/*
name			: Class Behaviour
update			: 20051129
author			: Xander Bindt, Frank van Rooijen, Maurice van Creij
dependencies		: lib_classbehaviour.js
info				: http://www.woollymittens.nl/content/details.asp?id=20040805133501

history
20051129		: a radio button checker was added to the form validator
20051121		: dropDownMenu now closes peer nodes before opening a new branch
20051118		: foldoutMenu was further stabilized, addressing problems with the delayed fold-back
20051031		: drag and drop's horizontal position can be correlated to a form value
20050819	: all code was changed to object oriented, for modularity
20050810	: fixed the onclick events on node toggling images in the dropDownMenu
20050705	: drag and drop works better with miltiple layers
20050511		: no prior updates report

notes
1. Replace "link" in class
   class="classMouseHover"
2. Replace "link" in src
   class="srcMouseHover"
3. Add display:none; on parse
   class="hideThisNode"
   class="showThisNode"
4. Add or remove display:none; onclick
   class="toggleNextNode [closePrevious_no id_myId useParent_1]"
   (Everything between [brackets] is optional. Leave out the [brackets] in the classname)
   closePrevious = close the previous node, before opening a new one (default: no)  
   id = Override the next node with an ID (default: none)   
   useParent = Use the parent node as a starting point for finding the target node
5. Add display:none; to parent node
   class="closeParentNode [parent_0]"
   parent = amount of recursions to use as a parent
6. Replace image with transparent version, invoke directX background loader
   class="pngAlpha"
7. Handle ondrag events
   class="dragAndDrop [limitTop_0 limitRight_100 limitBottom_100 limitLeft_0 gridX_16 gridY_16]"
   gridX = grid rounding in the X axis
   gridY = grid rounding in the Y axis
   limitTop = top limit 
   limitRight = right limit
   limitBottom = bottom limit 
   limitLeft = left limit
 8. Open links in a popup
   class="openAsPopUp [width_400 height_300 toolbar_yes scrollbars_yes resizable_yes status_yes location_yes menubar_yes name_myname]"
   width = width (default: automatic)
   height = height (default: automatic)
   toolbar = toolbars (default: no)
   scrollbars = Scrollbars (default: no)
   resizable = Resizable (default: no)
   status = Status bar (default: no)
   location = Location bar (default: no)
   menubar = Menus (default: no)
   name = Window name (default: popup)
9. Shows the contents of a container as raw code
   class="showAsCode"
10. Chooses a random increment of an image source
   class="setRandomSrc [min_0 max_1]"
   min = minimum (default: 0)
   max = maximum (default: 1)
11. Class a link matching the document's url
   class="matchActiveUrl [toParent_0 fromParent_0]"
   toParent = Apply class to parent (default: 0)
   fromParent = Take the HREF from parent (default: 0)
12 Add a className to a tag using the query parameter "class"
   class="addQueryToClassName"
13 Add a suffix to an image source using the query parameter "src"
   class="addQueryToSrc"
14 Validate the value of a for element to a predefined regular expression
   form class="validateAllInput [summaryId_summary0]"
   input class="validateInput [type_email allowEmpty_no warningId_error0 noWarning]"
   (Everything between [brackets] is optional. Leave out the [brackets] in the classname)
   type = validator type (email,phone,dutchzipcode,date,number,money,bankaccount,alphanumeric,notempty,isradiochecked)
   allowEmpty = Allow the field to be empty (default: no)
   warningId = use an Id for the error message instead of the next node
   noWarning = Don't hightlight this label as a validation warning
   ifCheckedId = This validation is only active when the refered id is checked
   explanation = There's explanation text in the field until it's clicked for the first time
15 Triggers all validateInput class behaviours within a node after the onsubmit event.
   class="validateAllInput"
16 Resizes the window to avoid a scrollbar
   class="resizeToFit"
17 Alternates the classes of a table's rows and columns
   class="zebraTable"
18 Makes the headers of a table click/sortable
   class="sortColumn"
19 Enforces minimal height of a container
   class="minHeight [height_100pct heightOffset_100px]"
   height = height + unit (default: no minimum. units: pct, px)
   heightOffset = offset + unit (default: 0. units pct, px)
20 Enforces maximal width of a container
   class="maxWidth [width_768px widthOffset_100px]"
   width = width + unit (default: no minimum. units: pct, px)
   widthOffset = offset + unit (default: 0. units pct, px)
21 Blinks
   class="blink"
22 Open a print dialog
   class="openAsPrintable"
23 Apply the relevant event handlers for a dropdown menu
   class="dropDownMenu"
24 Apply the relevant event handlers for a foldout menu
   class="foldOutMenu"
25 Scroll the list items of a container
   class="listScroller [width_256 height_96 left_1 top_0 delay_0]"
   width = distance to travel for one element (default: 256)
   height = distance to travel for one element (default: 75)
   left = horizontal speed (default: 2 pixel per second)
   top = vertical speed (default: 0 pixel per second)
   delay = delay after each element (default: 64 miliseconds)
26 Remove this tag if it's found to be empty
   class="removeIfEmpty"
27 Fixes the position of an element, relative to the screen. This compensates for MSIE's lack of CSS2 compliance.
   class="fixedPosition"
28 Enlarges a container to the largest size, without scrolling
   class="resizeToFit"
29 Toggle hidden siblings when clicking this node
   class="toggleHiddenSiblings"
30 Open links in the opener of this window
   class="openInOpener[closeParent_true]"
   closeParent = Close the popup after opening this link the in the opener
31 Open links in a new window
   class="openAsWindow"
32 Correlate a dragable object to an input value
   div class="sliderInput [valueToId_myInputField minValue_0 maxValue_100]"
   input class="[valueFromId_slider0]"
   valueToId = The input field converted position values will be transported to
   valueFromId = Placed as a classname in the input field to reference back to the slider
   minValue = minimum x conversion value
   maxValue = maximum x conversion value
33 Tabbed content
   ul class="tabbedContent"
   div class="contentTab"
   pagerId = the Id of the pager, set in the tabs-list.
   tabsId = The Id of the tabs, set in the pager-list.
34 CloseThisWindow
   class="CloseThisWindow"
35 Manage all event handler for an imagemap
   class="imageMap"
36 Allows a file upload element to recieve fake markup
   class="fileBrowser"
37 Sizes an element according to a value
   class="chartValue [value_50]"
   value = the value the chart is supposed to indicate (default 100%)
38 Copies selected text to a target container
   class="textSelection [id_selectedText]"
   id = Target element for the text (default: selectedText)
39 Shows elements based on the state of a related radio button or checkbox
   class="displayIfChecked id_displayThisIdIfChecked"
   id = Target element to hide of show
40 Disable form elements during a submit, to avoid multiple submits on slow servers
   class="disableAfterSubmit"
41 Stops events from cascading up in the document object model
   class="noBehaviour"
42 Replaces all png's in the container with gif alternatives in Internet Explorer 6 and lower.
   class="pngAlternative"
43 Fade an element in when the page loads
   class="fadeElement [wait_1024 start_0 end_100 step_10 increment_5]"
   wait = Delay before starting in miliseconds
   start = percentage start opacity value
   end = percentage end opacity value
   step = timed delay between each fade step in miliseconds
   increment = percentage op opacity increase or decrease per step
44 Replaces all png's in the container with gif alternatives in Internet Explorer 6 and lower.
   class="pngAlternative"
45 Make a decorative popup from a longdesc attribute
   class="showLongDesc"
46 Open an overlay as a popup window
   class="openLayerPopUp" and
   class="layerPopUp [autodeploy_1000]"
   autodeploy = timed delay in miliseconds before it pops up automaticaly.
*/

	// main class-behaviour object
	function ClassBehaviour(){
		/* properties */
			this.handlers			=	new Array();
		/* methods */
			// return a parameter from the url's query strings
			this.getQueryParameter 	= 	function(paramName, defaultValue){
											// split the query string at the parameter name
											var queryParameters = document.location.search.split(paramName+"=");
											// split the parameter value from the rest of the string
											var queryParameter = (queryParameters.length>1) ? queryParameters[1].split("&")[0] : null ;
											// return the value
											return (queryParameter!=null) ? queryParameter : defaultValue ;
										}
			// returns a string of parameters found in the classname which can be [eval]uated
			this.getClassParameter	=	function(targetNode, paramName, defaultValue){
											// get the class parameter from the classname
											var classParameter = targetNode.className;
											// split the classname between the parameter name
											classParameter = classParameter.split(paramName + '_');
											// split the second piece between spaces and take the first part,  if there are two pieces
											classParameter = (classParameter.length>1) ? classParameter[1].split(' ')[0] : null ;
											// return the value
											return (classParameter!=null) ? classParameter : defaultValue ;
										}
			// parse the document for classnames
			this.parseDocument		=	function(){
											// get all document nodes
											var allNodes = (document.all) ? document.all : document.getElementsByTagName("*");
											// for all tags
											for(var a=0; a<allNodes.length; a++){
												// if the item has a className
												if(allNodes[a].className){
													// get the classname
													nodeClass = allNodes[a].className;
													// for all behaviours
													for(var b=0; b<this.handlers.length; b++){
														// if the behaviour's name exists in the class name, apply it's events
														if(nodeClass.indexOf(this.handlers[b].name)>-1) this.handlers[b].start(allNodes[a]);
													}
												}
											}
										}
			// returns the visible display state needed for this element
			this.getVisibleState	=	function(node){
											// what kind of node is this
											switch(node.nodeName.toLowerCase()){
												case 'table' : visibleState='table' ; break;
												case 'thead' : visibleState='table-header-group' ; break;
												case 'tfoot' : visibleState='table-footer-group' ; break;
												case 'tbody' : visibleState='table-row-group' ; break;
												case 'tr' : visibleState='table-row' ; break;
												case 'td' : visibleState='table-cell' ; break;
												case 'th' : visibleState='table-cell' ; break;
												default : visibleState='block';
											}
											// apply the state
											return (document.all && navigator.userAgent.indexOf('Opera')<0) ? 'block' : visibleState;
										}
	}
	// create the main class-behaviour object
	var classBehaviour = new ClassBehaviour;

	// blinks
		// define this class behaviour
		function Blink(){
			/* properties */
			this.name 		= 	'blink';
			this.nodes 		= 	new Array();
			/* methods */
			this.start		=	function(node){
									// set the starting class, if not present
									if(node.className.indexOf('blinkon')<0) node.className += " blinkon";
									// make new blink entry
									this.nodes[this.nodes.length] = new Array(node,null,1024);
									// start blink loop
									this.loop(this.nodes.length-1);
								}
			/* events */
			this.loop		=	function(blinkIndex){
									// what object goes with this index
									blinkObject = this.nodes[blinkIndex][0];
									// toggle the blink class of this object
									blinkObject.className = (blinkObject.className.indexOf('blinkoff')>-1) ? blinkObject.className.replace('blinkoff','blinkon') : blinkObject.className.replace('blinkon','blinkoff');
									// set timeout till the next blink toggle
									this.nodes[blinkIndex][1] = setTimeout('classBehaviour.blink.loop('+blinkIndex+')',this.nodes[blinkIndex][2]);
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.blink = new Blink;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.blink;
		
	// replace in class
		// define this class behaviour
		function ClassMouseHover(){
			/* properties */
			this.name 		= 	'classMouseHover';
			/* methods */
			this.start		=	function(node){
									node.onmouseover = this.addHover;
									node.onmouseout = this.remHover;
								}
			this.hasNoStateClass 	= 	function(objNode){
											return (objNode.className.indexOf('link')<0 && objNode.className.indexOf('hover')<0 && objNode.className.indexOf('active')<0);
										}
			/* events */
			this.addHover 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var cmh = classBehaviour.classMouseHover;
									// replace link by hover
									objNode.className = (cmh.hasNoStateClass(objNode)) ? 'hover ' + objNode.className : objNode.className.replace('link','hover') ;
								}
			this.remHover 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var cmh = classBehaviour.classMouseHover;
									// replace hover by link
									objNode.className = (cmh.hasNoStateClass(objNode)) ? 'link ' + objNode.className : objNode.className.replace('hover','link') ;
								}
			this.addActive 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var cmh = classBehaviour.classMouseHover;
									// replace link by active
									objNode.className = objNode.className.replace('link','active') ;
									// replace hover by active
									objNode.className = objNode.className.replace('hover','active') ;
									// if there's still no active class
									if(cmh.hasNoStateClass(objNode)) objNode.className = 'active ' + objNode.className;
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.classMouseHover = new ClassMouseHover;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.classMouseHover;
		
	// replace in src sub-string
		// define this class behaviour
		function SrcMouseHover(){
			/* properties */
			this.name 			= 	'srcMouseHover';
			this.cache 			= new Array();
			/* methods */
			this.start			=	function(node){
										this.cacheImages(node);
										node.onmouseover = this.addHover;
										node.onmouseout = this.remHover;
									}
			this.cacheImages	 = 	function(that) {
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										// replace link by hover
										var cacheIdx = this.cache.length;
										// hover version
										this.cache[cacheIdx] = new Image();
										this.cache[cacheIdx].src = objNode.src.replace('_link','_hover');
										// active version
										this.cache[cacheIdx+1] = new Image();
										this.cache[cacheIdx+1].src = objNode.src.replace('_link','_active');
									}
			/* events */
			this.addActive 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// replace link by active
									objNode.src = objNode.src.replace('_link','_active');
									// replace hover by active
									objNode.src = objNode.src.replace('_hover','_active');
								}
			this.addHover 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// replace link by hover
									objNode.src = objNode.src.replace('_link','_hover');
								}
			this.remHover 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// replace link by hover
									objNode.src = objNode.src.replace('_hover','_link');
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.srcMouseHover = new SrcMouseHover;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.srcMouseHover;
		
	// add display='none'; on parse
		// define this class behaviour
		function HideThisNode(){
			/* properties */
			this.name 		= 	'hideThisNode';
			/* methods */
			this.start		=	function(node){
									node.style.display = 'none';
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.hideThisNode = new HideThisNode;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.hideThisNode;
		
	// affirms the visibility status in regard to toggles
		// define this class behaviour
		function ShowThisNode(){
			/* properties */
			this.name 		= 	'showThisNode';
			/* methods */
			this.start		=	function(node){
									// apply the visible state
									node.style.display = classBehaviour.getVisibleState(node);
									// fill the "previous node" parameters of a related object
									classBehaviour.toggleNextNode.lastNode = node;
// TODO: untested test for childnodes
									// if this isn't the first node
									if(node.parentNode.childNodes[0] != node){
										// pick the previousnode
										objPreviousNode = (node.previousSibling.nodeName.indexOf("text")<0) ? node.previousSibling : node.previousSibling.previousSibling ;
										// store it as the 'previous' toggle
										if(objPreviousNode!=null) classBehaviour.toggleNextNode.lastNext = objPreviousNode;
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.showThisNode = new ShowThisNode;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.showThisNode;
		
	// add display='none'; to parent node
		// define this class behaviour
		function CloseParentNode(){
			/* properties */
			this.name 		= 	'closeParentNode';
			/* methods */
			this.start		=	function(node){
									/*event*/;
									node.onclick = this.process;
								}
			/* events */
			this.process 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var tnn = classBehaviour.toggleNextNode;
									// get the desired parent recursion
									targetParent = parseInt(classBehaviour.getClassParameter(objNode, 'parent', '0'));
									objTarget = objNode.parentNode;
									for(var a=0; a<targetParent; a++) objTarget = objTarget.parentNode;
									// hide the parent node
									objTarget.style.display = 'none';
									// restore previous node's click state
									if(tnn.lastNext!=null && tnn.lastNext!=objNode) tnn.lastNext.className = tnn.lastNext.className.replace('active','link');
									// cancel onclick event
									return false;
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.closeParentNode = new CloseParentNode;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.closeParentNode;
		
	// replace image with transparent version, invoke activeX background loader
		// define this class behaviour
		function PngAlpha(){
			/* properties */
			this.name 		= 	'pngAlpha';
			/* methods */
			this.start		=	function(node){
									/*event*/;
									this.process(node);
									node.onload = this.process;
								}
			/* events */
			this.process 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// if the image has been processed before
									if(objNode.src.indexOf('_alpha')<0){
										// alpha image url
										var strAlphaSrc = objNode.src.replace(/\.png|\.jpg|\.gif/gi,"_alpha.png");
										// for the downlevel browser MSIE
										if(typeof(objNode.style.filter)!='undefined'){
											// change the image styles
											objNode.style.width		= objNode.width + 'px';
											objNode.style.height	= objNode.height + 'px';
											objNode.style.filter	= "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + strAlphaSrc + "', sizingMethod='crop')";
											// get the path to the image folder
											var strPathSrc = '';
											var arrPathSrc = objNode.src.split('/');
											for(var intA=0; intA<arrPathSrc.length-1; intA++){strPathSrc += arrPathSrc[intA] + '/'};
											// replace the original with the alpha variant
											objNode.src = strPathSrc + '_alpha.png';
										// for the rest of the world
										}else{
											// replace the image source with the alpha channel version
											objNode.src = strAlphaSrc;
										}
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.pngAlpha = new PngAlpha;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.pngAlpha;

	// handle ondrag events
		// define this class behaviour
		function DragAndDrop(){
			/* properties */
			this.name 		= 	'dragAndDrop';
			this.node		=	null;
			this.grid		=	new Coordinates(16,16);
			this.minPos	=	new Coordinates();
			this.maxPos	=	new Coordinates();
			this.pickup	=	new Coordinates();
			this.mouse		=	new Coordinates();
			this.style		=	new Coordinates();
			this.onMove	=	null;
			/* methods */
			this.start		=	function(node){
									// event
									node.onmousedown 			= this.pickUp;
									document.onmouseup 			= this.dropDown;
										// document.onmousemove 		= this.moveAway;
									node.onmousemove 			= this.moveAway;
									// exctract the limits from the class parameters
									this.grid.x	=	parseInt(classBehaviour.getClassParameter(node, 'gridX', null));
									this.grid.y	=	parseInt(classBehaviour.getClassParameter(node, 'gridY', null));
									this.minPos.x	=	parseInt(classBehaviour.getClassParameter(node, 'limitLeft', null));
									this.minPos.y	=	parseInt(classBehaviour.getClassParameter(node, 'limitTop', null));
									this.maxPos.x	=	parseInt(classBehaviour.getClassParameter(node, 'limitRight', null));
									this.maxPos.y	=	parseInt(classBehaviour.getClassParameter(node, 'limitBottom', null));
									// saved position
									this.restore(node);
								}
			this.restore 	= 	function(objNode){
									// is lib_cookies available
									if(typeof(setCookie)!='undefined'){
										var strStyles, arrStyles;
										// retrieve styles string
										strStyles = getCookie('dragposition');					
										// were any styles recovered
										if(strStyles!=null){
											arrStyles = strStyles.split(',');
											// does the stored positions match the object
											if(arrStyles[0]==objNode.id && arrStyles.length>2){
												objNode.style.left = arrStyles[1];
												objNode.style.top = arrStyles[2];
											}
										}
									}
								}
			this.store 		= 	function(objNode){
									// is lib_cookies available
									if(typeof(setCookie)!='undefined'){
										// store styles
										setCookie('dragposition', objNode.id + ',' + objNode.style.left + ',' + objNode.style.top, null, '/', null, null);
									}
								}
			/* events */
			this.pickUp 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var dnd = classBehaviour.dragAndDrop;
									// accept no new pickups before dropdown
									if(dnd.pickupObj==null){
										// store the object being picked up
										dnd.node = objNode;
										// store pickup location
										dnd.pickup.x = (typeof(event)!='undefined') ? event.clientX : that.clientX ;
										dnd.pickup.y = (typeof(event)!='undefined') ? event.clientY : that.clientY ;
										dnd.pickup.z = (objNode.style.zIndex=='') ? objNode.style.zIndex : 0;
										// default starting position if none was given
										if(objNode.style.position!='absolute') objNode.style.position = 'absolute';
										if(objNode.style.left=='') objNode.style.left = /*dnd.pickup.x +*/ '0px'; 
										if(objNode.style.top=='') objNode.style.top = /*dnd.pickup.y +*/ '0px';
										// promote z position
										objNode.style.zIndex = 1024;
									}
									// cancel browser mouse handler
									return false;
								}
			this.dropDown 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var dnd = classBehaviour.dragAndDrop;
									// only if a pickup is active
									if(dnd.node!=null){
										// snap coordinates to grid
										if(dnd.grid.x>0) dnd.node.style.left = Math.round(parseInt(dnd.node.style.left)/dnd.grid.x)*dnd.grid.x + "px";
										if(dnd.grid.y>0) dnd.node.style.top = Math.round(parseInt(dnd.node.style.top)/dnd.grid.y)*dnd.grid.y + "px";
										// restore z position
										dnd.node.style.zIndex = dnd.pickup.z;
										// store the position in a cookie
										dnd.store(dnd.node);
										// release the picked up object
										dnd.node = null;
										// clear pickup location
										dnd.pickup.x = null;
										dnd.pickup.y = null;
										dnd.pickup.z = null;
									}
									// cancel browser mouse handler
									return false;
								}
			this.moveAway 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var dnd = classBehaviour.dragAndDrop;
									// only if a pickup is active
									if(dnd.node!=null){
										// mouse position
										dnd.mouse.x = (typeof(event)!='undefined') ? event.clientX : that.clientX ;
										dnd.mouse.y = (typeof(event)!='undefined') ? event.clientY : that.clientY ;
										// current object position
										dnd.style.x = (dnd.node.style.left.indexOf('px')<0) ? 0 : parseInt(dnd.node.style.left) ;
										dnd.style.y = (dnd.node.style.top.indexOf('px')<0) ? 0 : parseInt(dnd.node.style.top) ;
										// calculate new object position
										var newXpos = dnd.style.x + dnd.mouse.x - dnd.pickup.x;
										var newYpos = dnd.style.y + dnd.mouse.y - dnd.pickup.y;
										// limit new object position
										if(newXpos<dnd.minPos.x) newXpos = dnd.minPos.x;
										if(newXpos>dnd.maxPos.x) newXpos = dnd.maxPos.x;
										if(newYpos<dnd.minPos.y) newYpos = dnd.minPos.y;
										if(newYpos>dnd.maxPos.y) newYpos = dnd.maxPos.y;
										// apply new object position
										if(dnd.pickup.x!=null) dnd.node.style.left = newXpos + 'px';
										if(dnd.pickup.y!=null) dnd.node.style.top = newYpos + 'px';
										// update pickup location
										dnd.pickup.x = dnd.mouse.x;
										dnd.pickup.y = dnd.mouse.y;
										// execute custom event handler
										if(dnd.onMove!=null) dnd.onMove(dnd.node);
									}
									// cancel browser mouse handler
									return false;
								}
		}
			function Coordinates(x,y,z){
				this.x = x;
				this.y = y;
				this.z = z;
			}
		// add this function to the classbehaviour object
		classBehaviour.dragAndDrop = new DragAndDrop;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.dragAndDrop;

	// Correlate a dragable object to an input value
		// define this class behaviour
		function SliderInput(){
			/* properties */
			this.name 			= 	'sliderInput';
			this.allowNudge	=	true;
			/* methods */
			this.start			=	function(node){
										// event
										node.parentNode.onclick	= this.nudgeInput;
										// get the target Id
										valueToId =	classBehaviour.getClassParameter(node, 'valueToId', null);
										// get the object
										valueToObject = document.getElementById(valueToId);
										// assign the event handler
										valueToObject.onchange = this.inputToSlider;
										// add the drag and drop classbehaviour and give it out event handlers
										classBehaviour.dragAndDrop.onMove = this.sliderToInput;
										classBehaviour.dragAndDrop.start(node); 
										// trigger the starting value
										this.inputToSlider(valueToObject);
										// allow nudging
										this.allowNudge = true;
									}
			/* events */
			this.inputToSlider = 	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var sli = classBehaviour.sliderInput;
										// get the the slider to sync with from the classname
										sliderTarget = objNode;
										sliderButtonId = classBehaviour.getClassParameter(sliderTarget, 'valueFromId', null);
										sliderButton = document.getElementById(sliderButtonId);
										// get the limit values from the slider
										curValue	=	parseFloat(sliderTarget.value);
										minValue	=	parseFloat(classBehaviour.getClassParameter(sliderButton, 'minValue', null));
										maxValue	=	parseFloat(classBehaviour.getClassParameter(sliderButton, 'maxValue', null));
										minPos		=	parseInt(classBehaviour.getClassParameter(sliderButton, 'limitLeft', null));
										maxPos		=	parseInt(classBehaviour.getClassParameter(sliderButton, 'limitRight', null));
										// correct improper input
										if(isNaN(curValue)){
											curValue = Math.round((maxValue-minValue)/2 + minValue);
											sliderTarget.value = curValue;
										}
										// apply limits
										if(curValue>maxValue){curValue = maxValue; sliderTarget.value = curValue;}
										if(curValue<minValue){curValue = minValue; sliderTarget.value = curValue;}
										// adjust slider
										sliderButton.style.left 	= 	Math.round(
																			(curValue - minValue) / (maxValue - minValue) * (maxPos - minPos) + minPos
																		) + 'px';
									}
			this.sliderToInput	= 	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var dnd = classBehaviour.dragAndDrop;
										var sli = classBehaviour.sliderInput;
										// disable the onclick on the sliderTrack 
										sli.allowNudge = false ;
										// get the the input field to sync with from the classname
										sliderButton	=	objNode;
										sliderTargetId	=	classBehaviour.getClassParameter(sliderButton, 'valueToId', null);
										sliderTarget	=	document.getElementById(sliderTargetId);
										// get the limit values from the slider
										curValue	=	parseFloat(sliderTarget.value);
										minValue	=	parseFloat(classBehaviour.getClassParameter(sliderButton, 'minValue', null));
										maxValue	=	parseFloat(classBehaviour.getClassParameter(sliderButton, 'maxValue', null));
										minPos		=	parseInt(classBehaviour.getClassParameter(sliderButton, 'limitLeft', null));
										maxPos		=	parseInt(classBehaviour.getClassParameter(sliderButton, 'limitRight', null));
										// translate the slider value to the input box
										sliderTarget.value 	= 	Math.round(
																	(dnd.style.x - dnd.minPos.x) / (dnd.maxPos.x - dnd.minPos.x) * 
																	(maxValue - minValue) + minValue
																);
									}
			this.nudgeInput	=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var dnd = classBehaviour.dragAndDrop;
										var sli = classBehaviour.sliderInput;
										// if nudging is allowed
										if(sli.allowNudge){
											// slider objects
											sliderTrack		=	objNode;
											sliderButton	=	sliderTrack.getElementsByTagName('div')[0];
											sliderTargetId	=	classBehaviour.getClassParameter(sliderButton, 'valueToId', null);
											sliderTarget	=	document.getElementById(sliderTargetId);
											// slider limits
											minPos			=	parseInt(classBehaviour.getClassParameter(sliderButton, 'limitLeft', null));
											maxPos			=	parseInt(classBehaviour.getClassParameter(sliderButton, 'limitRight', null));
											minValue		=	parseFloat(classBehaviour.getClassParameter(sliderButton, 'minValue', null));
											maxValue		=	parseFloat(classBehaviour.getClassParameter(sliderButton, 'maxValue', null));
											// click position
											clickX = (typeof(event)!='undefined') ? event.x : that.layerX ;
											// slider position
											sliderX = (sliderButton.style.left.indexOf('px')<0) ? 0 : parseInt(sliderButton.style.left) ;
											// nudge the value of the slider closer towards the click
											newValue = Math.round(parseInt(sliderTarget.value) + ((clickX - sliderX) / (maxPos - minPos) * (maxValue - minValue)) / 2);
											// apply limits
											if(newValue>maxValue){newValue = maxValue; sliderTarget.value = curValue;}
											if(newValue<minValue){newValue = minValue; sliderTarget.value = curValue;}
											// adjust slider and input
											sliderTarget.value			=	newValue;
											sliderButton.style.left 	= 	Math.round(
																				(newValue - minValue) / (maxValue - minValue) * (maxPos - minPos) + minPos
																			) + 'px';
										// else the nudging was locked
										}else{
											// unlock the nudging
											sli.allowNudge = true;
										}
									}
		}
		// add this function to the classbehaviour object
		classBehaviour.sliderInput = new SliderInput;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.sliderInput;
		
	// show contents as code
		// define this class behaviour
		function ShowAsCode(){
			/* properties */
			this.name 		= 	'showAsCode';
			/* methods */
			this.start		=	function(node){
									/* event */
									this.process(node);
								}
			this.process 	= 	function(objNode){
									// replace html tags
									objNode.innerHTML = objNode.innerHTML.replace(/</gi,"&lt;").replace(/>/gi,"&gt;\n").replace(/ /gi,"&nbsp;").replace(/\t/gi,"&nbsp;&nbsp;&nbsp;").replace(/\n/gi,"<br />");
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.showAsCode = new ShowAsCode;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.showAsCode;
		
	// Add a className to a tag using the query parameter "class"',
		// define this class behaviour
		function AddQueryToClassName(){
			/* properties */
			this.name 		= 	'addQueryToClassName';
			/* methods */
			this.start		=	function(node){
									this.process(node);
								}
			this.process	= 	function(objNode){
									// get the query parameter
									var strQueryParameter = classBehaviour.getQueryParameter("class");
									// add to front of classNames
									if(strQueryParameter!=null) objNode.className = strQueryParameter + ' ' + objNode.className;
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.addQueryToClassName = new AddQueryToClassName;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.addQueryToClassName;
		
	// Add a suffix to an image source using the query parameter "src"',
		// define this class behaviour
		function AddQueryToSrc(){
			/* properties */
			this.name 		= 	'addQueryToSrc';
			/* methods */
			this.start		=	function(node){
									this.process(node);
								}
			this.process 	= 	function(objNode){
									// get the query parameter
									var strQueryParameter = classBehaviour.getQueryParameter("src")
									// add to front of classNames
									if(strQueryParameter!=null) objNode.src = objNode.src.replace('.','_'+strQueryParameter+'.');
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.addQueryToSrc = new AddQueryToSrc;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.addQueryToSrc;
		
	// Resizes the window to avoid a scrollbar
		// define this class behaviour
		function ResizeToFit(){
			/* properties */
			this.name 		= 	'resizeToFit';
			/* methods */
			this.start		=	function(node){
									node.onload = this.process;
									this.process(node);
								}
			/* events */
			this.process 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var objIframe = window.parent.document.getElementById('resizeToFit');
									var intScrollX, intScrollY, intWinWidth, intWinHeight, intMaxWidth, intMaxHeight;
									// max dimensions
									intMaxWidth = (objIframe!=null) ? 9999 : screen.availWidth;
									intMaxHeight = (objIframe!=null) ? 9999 : screen.availHeight;
									// while the scroll position is not 0
									var intWhileCount = 0;
									do{
										// scroll the document by 1 pixel
										window.scrollTo(1,1);
										// measure the scroll position			
										intScrollX = (document.all) ?  document.body.scrollLeft : window.pageXOffset ;
										intScrollY = (document.all) ? document.body.scrollTop : window.pageYOffset ;
										// measure window size
										intWinWidth = (document.all) ? document.body.offsetWidth : window.innerWidth ;
										intWinHeight = (document.all) ? document.body.offsetHeight : window.innerHeight ;
										// if the scroll position is not 0
										if(intScrollX>0){
											// make the window larger
											window.resizeBy(32,0);
											// make the iframe larger
											if(objIframe!=null && !document.all) objIframe.style.width = (objIframe.style.width=='') ? '64px' : (parseInt(objIframe.style.width) + 32) + 'px';
										}
										if(intScrollY>0){
											// make the window larger
											window.resizeBy(0,32);
											// make the iframe larger
											if(objIframe!=null && !document.all) objIframe.style.height = (objIframe.style.height=='') ? '64px' : (parseInt(objIframe.style.height) + 32) + 'px';
										}
										// count the steps
										intWhileCount += 1;
									}while((intScrollX>0 || intScrollY>0) && intWinWidth<intMaxWidth && intWinHeight<intMaxHeight && intWhileCount<32);
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.resizeToFit = new ResizeToFit;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.resizeToFit;
		
	// Resizes the window to avoid a scrollbar
		// define this class behaviour
		function FitToWindow(){
			/* properties */
			this.name 		= 	'fitToWindow';
			/* methods */
			this.start		=	function(node){
									node.onresize = this.process;
									this.process(node);
								}
			/* events */
			this.process 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// while the scroll position is not 0
									var intWhileCount = 0;
									do{
										// scroll the document by 1 pixel
										window.scrollTo(1,1);
										// measure the scroll position			
										intScrollX = (typeof(document.body.scrollLeft)!='undefined') ?  document.body.scrollLeft : window.pageXOffset ;
										intScrollY = (typeof(document.body.scrollTop)!='undefined') ? document.body.scrollTop : window.pageYOffset ;
										// if the scroll position is not 0
										if(intScrollX==0){
											// was a height specified
											if(objNode.style.width=='') objNode.style.width = '100px';
											// make the container larger
											objNode.style.width = (parseInt(objNode.style.width) + 32) + 'px';
										}
										if(intScrollY==0){
											// was a height specified
											if(objNode.style.height=='') objNode.style.height = '100px';
											// make the container larger
											objNode.style.height = (parseInt(objNode.style.height) + 32) + 'px';
										}
										// count the steps
										intWhileCount += 1;
									}while((intScrollX==0 || intScrollY==0) && intWhileCount<32);	
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.fitToWindow = new FitToWindow;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.fitToWindow;
		
	// Alternates the classes of a table's rows and columns
		// define this class behaviour
		function ZebraTable(){
			/* properties */
			this.name 		= 	'zebraTable';
			/* methods */
			this.start		=	function(node){
									this.process(node);
								}
			this.process 	= 	function(objNode){
									var objRows, objCols, intCellNumber;
									// get all table rows
									objRows = objNode.getElementsByTagName('TR');
									// for all table rows
									for(var intRow=0; intRow<objRows.length; intRow++){
										// undo any previous classing
										objRows[intRow].className = objRows[intRow].className.replace('odd','');
										objRows[intRow].className = objRows[intRow].className.replace('even','');
										// add oddrow or evenrow class to the row
										objRows[intRow].className += (intRow%2==0) ? ' odd' : ' even' ;
										// and row and col counters if they're not allready present
										if(objRows[intRow].className.indexOf('row_')<0) objRows[intRow].className += ' row_' + intRow;
										// get all nodes in this row
										objCols = objRows[intRow].childNodes;
										// for every node in the row
										intCellNumber = 0;
										for(var intCol=0; intCol<objCols.length; intCol++){
											// is this a cell or a header
											if(objCols[intCol].nodeName.indexOf('text')<0){
												// undo any previous classing
												objCols[intCol].className = objCols[intCol].className.replace('odd','');
												objCols[intCol].className = objCols[intCol].className.replace('even','');
												// add oddcol or evencol class
												objCols[intCol].className += (intCellNumber%2==0) ? ' odd' : ' even' ;
												// and row and col counters if they're not allready present
												if( objCols[intCol].className.indexOf('col_')<0) objCols[intCol].className += ' col_' + intCellNumber;
												// keep cell numbers
												intCellNumber += 1;
											}
										}
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.zebraTable = new ZebraTable;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.zebraTable;
		
	// Makes the headers of a table click/sortable
		// define this class behaviour
		function SortColumn(){
			/* properties */
			this.name 		= 	'sortColumn';
			this.column	=	0;
			/* methods */
			this.start		=	function(node){
									node.onclick = this.sort;
									// apply the default sort direction style
									if(node.className.indexOf('sorted')<0) node.className += ' unSorted';
								}
			this.forward 	= 	function(rowA,rowB){
									var st = classBehaviour.sortColumn;
									var regTags = new RegExp('<(.|\n)+?>','gi');
									// get the string values from the node
									strA = (rowA.childNodes[st.column].childNodes.length == 0) ? ' ' : rowA.childNodes[st.column].innerHTML.replace('---','0,00').replace(regTags,'');
									strB = (rowB.childNodes[st.column].childNodes.length == 0) ? ' ' : rowB.childNodes[st.column].innerHTML.replace('---','0,00').replace(regTags,'');
									// get the numeric values from the node
									intA = parseInt(strA.replace(',',''));
									intB = parseInt(strB.replace(',',''));
									// compare the values for the sort funtion
									if(strA==strB || (navigator.appVersion.indexOf('MSIE 5.0')>-1)){
										// equal
										return 0;
									}else if(isNaN(intA) || isNaN(intB)){
										// compare the textual values
										return (strA<strB) ? 1 : -1 ;
									}else{
										// compare the numeric values
										return intB - intA;
									}
								}
			this.reverse 	= 	function(rowA,rowB){
									var st = classBehaviour.sortColumn;
									var regTags = new RegExp('<(.|\n)+?>','gi');
									// get the string values from the node
									strA = (rowA.childNodes[st.column].childNodes.length == 0) ? ' ' : rowA.childNodes[st.column].innerHTML.replace('---','0,00').replace(regTags,'');
									strB = (rowB.childNodes[st.column].childNodes.length == 0) ? ' ' : rowB.childNodes[st.column].innerHTML.replace('---','0,00').replace(regTags,'');
									// get the numeric values from the node
									intA = parseInt(strA.replace(',',''));
									intB = parseInt(strB.replace(',',''));
									// compare the values for the sort funtion
									if(strA==strB || (navigator.appVersion.indexOf('MSIE 5.0')>-1)){
										// equal
										return 0;
									}else if(isNaN(intA) || isNaN(intB)){
										// compare the textual values
										return (strA>strB) ? 1 : -1 ;
									}else{
										// compare the numeric values
										return intA - intB;
									}
								}
			/* events */
			this.sort 		= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var st = classBehaviour.sortColumn;
									// defaults
									sortDirection	= 'sortedForward';
									// find column number
									var objSiblings	= objNode.parentNode.childNodes;
									for(var intA=0; intA<objSiblings.length; intA++){
										// is this a cell of a text-node
										if(objSiblings[intA].nodeName=="TD" || objSiblings[intA].nodeName=="TH"){
											// test if this is the clicked node
											if(objSiblings[intA] == objNode){
												// remember the clicked column
												st.column = intA;
												// toggle the sort direction
												sortDirection = (objSiblings[intA].className.indexOf('sortedForward')>-1) ? 'sortedReverse' : 'sortedForward' ;
												// adjust the sorting direction classname
												objSiblings[intA].className = objSiblings[intA].className.replace('sortedReverse', sortDirection);
												objSiblings[intA].className = objSiblings[intA].className.replace('sortedForward', sortDirection);
												objSiblings[intA].className = objSiblings[intA].className.replace('unSorted', sortDirection);
											}else{
												// unmark any previously sorted column
												objSiblings[intA].className = objSiblings[intA].className.replace('sortedReverse', 'unSorted');
												objSiblings[intA].className = objSiblings[intA].className.replace('sortedForward', 'unSorted');
											}
										}
									}
									// make a nodelist
									var fullTable		= objNode.parentNode.parentNode.parentNode;
									var sortParent		= fullTable.getElementsByTagName('TBODY')[0];
									var nodeList		= sortParent.childNodes;
									var nodeArray		= new Array();
									// for all table rows
									for(var intA=0; intA<nodeList.length; intA++){
										if(nodeList[intA].nodeName.indexOf('TR')>-1){
											// store it in an array
											nodeArray[nodeArray.length] = nodeList[intA];
										}
									}
									// sort the collection using a helper function
									nodeArray = (sortDirection=='sortedForward') ? nodeArray.sort(st.forward) : nodeArray.sort(st.reverse);
									// clear the unsorted nodelist
									for(var intA=0; intA<nodeList.length; intA++){
										if(nodeList[intA].nodeName.indexOf('TR')>-1){
											sortParent.removeChild(nodeList[intA]);
										}
									}
									// append the sorted nodelist
									for(var intA=0; intA<nodeArray.length; intA++){
										sortParent.appendChild(nodeArray[intA]);
									}
									// reapply the zebra effect
									if(fullTable.className.indexOf('zebraTable')>-1) classBehaviour.zebraTable.process(fullTable);
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.sortColumn = new SortColumn;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.sortColumn;
		
	// Open print dialog
		// define this class behaviour
		function OpenAsPrintable(){
			/* properties */
			this.name 		= 	'openAsPrintable';
			/* methods */
			this.start		=	function(node){
									node.onclick = this.process;
								}
			this.process 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// If there is a demo popup
									if(document.getElementById('tgtPopTitle')){
										// copy the title to the print popup title
										document.getElementById('tgtPopTitle').innerHTML = document.getElementById('content').getElementsByTagName('h1')[0].innerHTML;
										// copy the content tot the print popup content
										document.getElementById('tgtPopText').innerHTML = (document.getElementById('content').innerHTML.indexOf('</h1>')>-1) ? document.getElementById('content').innerHTML.split('</h1>')[1] : document.getElementById('content').innerHTML.split('</H1>')[1];
										// show the print popup
										classBehaviour.openLayerPopUp.show(document.getElementById('popup0'));
										// open the print dialog
										setTimeout("window.print();",2048);
									}else{
										window.print();
									}
									// cancel the click
									return false;
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.openAsPrintable = new OpenAsPrintable;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.openAsPrintable;

	// Close the window (it's cold)
		// define this class behaviour
		function CloseThisWindow(){
			/* properties */
			this.name 		= 	'closeThisWindow';
			/* methods */
			this.start		=	function(node){
									node.onclick = this.process;
								}
			this.process 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									window.close();
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.closeThisWindow = new CloseThisWindow;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.closeThisWindow;
		
      // Jump back to the previous page
            // define this class behaviour
            function GoToPrevious(){
                  /* properties */
                  this.name         =     'goToPrevious';
                  /* methods */
                  this.start        =     function(node){
                                                      node.onclick = this.process;
                                                }
                  this.process      =     function(that){
                                                      var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
                                                      // open the print dialog
                                                      window.history.go(-1);
                                                }
            }
            // add this function to the classbehaviour object
            classBehaviour.goToPrevious = new GoToPrevious;
            classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.goToPrevious;

		
	// Make dropdown menu
		// define this class behaviour
		function DropDownMenu(){
			/* properties */
			this.name 		= 	'dropDownMenu';
			/* methods */
			this.start		=	function(node){
									this.process(node);
								}
			this.recurse 	= 	function(objParentNode){
									var cmh = classBehaviour.classMouseHover;
									var tnn = classBehaviour.toggleNextNode;
									// mark the node as active
									cmh.addActive(objParentNode);
									// add active class to the anchor
									if(objParentNode.getElementsByTagName('A').length>0) cmh.addActive(objParentNode.getElementsByTagName('A')[0]);
									// replace image source for active version
									if(objParentNode.getElementsByTagName('IMG').length>0)  tnn.toggleNext(objParentNode.getElementsByTagName('IMG')[0]);
									// next recursion to same node type
									if(objParentNode.nodeName == objParentNode.parentNode.parentNode.nodeName) this.recurse(objParentNode.parentNode.parentNode);
								}
			this.process 	= 	function(objNode){
									var mau = classBehaviour.matchActiveUrl;
									var objNodes, objMatch, objNextNode;
									// apply default settings to all LIs
									objNodes = objNode.getElementsByTagName('LI');
									for(var intNode=0; intNode<objNodes.length; intNode++){
										// hideThisNode
										if(objNodes[intNode].className.indexOf('link')<0 && objNodes[intNode].className.indexOf('active')<0) objNodes[intNode].className += ' link';
									}
									// apply default settings to all IMGs
									objNodes = objNode.getElementsByTagName('IMG');
									for(var intNode=0; intNode<objNodes.length; intNode++){
										// if this node has children
										if(objNodes[intNode].parentNode.getElementsByTagName('UL').length>0){
											// set a starting value for the open and closed toggle
											objNodes[intNode].parentNode.getElementsByTagName('UL')[0].style.display  = 'none';
											// rename the image to indicate it's subnodes.
											objNodes[intNode].src = objNodes[intNode].src.replace('_child', '_parent');
										}
										// toggleNextNode
										objNodes[intNode].onclick = this.togglePeers;
									}
									// apply default settings to all As
									objNodes = objNode.getElementsByTagName('A');
									for(var intNode=0; intNode<objNodes.length; intNode++){
										// if the item has no valid link
										if(objNodes[intNode].href.indexOf("#")==objNodes[intNode].href.length-1){
											// make it the link of it's first child
											objNodes[intNode].href = objNodes[intNode+1].href
										}
										// use matchActiveUrl to find active items OR use the ones marked manualy
										objMatch = (mau.process(objNodes[intNode]) || objNodes[intNode].className.indexOf('active')>-1) ? objNodes[intNode] : objMatch ;
									}
									// recurse back the last matching node
									if(objMatch!=null) this.recurse(objMatch.parentNode);
								}
			this.togglePeers=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var tnn = classBehaviour.toggleNextNode;
									// get all the peers of this node
									allPeers = objNode.parentNode.parentNode.childNodes;
									// for all peers
									for(var a=0; a<allPeers.length; a++){
										// if the peer is no textnode and not the target node
										if(allPeers[a].nodeName.toLowerCase().indexOf('li')>-1 && objNode.parentNode!=allPeers[a]){
											// if the peer has a submenu toggle
											subToggles = allPeers[a].getElementsByTagName('img');
											if(subToggles.length>0){
												// if the node is opened
												if(subToggles[0].src.indexOf('active')>-1){
													// close it
													tnn.toggleNext(subToggles[0]);
												}
											}
										}
									}
									// toggle the current noce
									tnn.toggleNext(objNode);
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.dropDownMenu = new DropDownMenu;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.dropDownMenu;
		
	// Make foldout menu
		// define this class behaviour
		function FoldOutMenu(){
			/* properties */
			this.name 		= 	'foldOutMenu';
			this.timeout	=	null;
			this.delay		=	1024;
			this.foldIns 	= 	new Array();
			this.activeNode =	null;
			/* methods */
			this.start		=	function(node){
									this.process(node);
								}
			this.process 	= 	function(objNode){
									var objNodes, objMatch;
									var mau = classBehaviour.matchActiveUrl;
									// apply events to all LIs
									objNodes = objNode.getElementsByTagName('LI');
									for(var intNode=0; intNode<objNodes.length; intNode++){
										// mouseover events
										objNodes[intNode].onmouseover	= this.addHover;
										objNodes[intNode].onmouseout	= this.remHover;
									}
									// apply default settings to all As
									objNodes = objNode.getElementsByTagName('A');
									for(var intNode=0; intNode<objNodes.length; intNode++){
										// if the item has no valid link
										if(objNodes[intNode].href.indexOf("#")==objNodes[intNode].href.length-1){
											// make it the link of it's first child
											objNodes[intNode].href = objNodes[intNode+1].href
										}
										// use matchActiveUrl to find active items OR use the ones marked manualy
										objMatch = (mau.process(objNodes[intNode]) || objNodes[intNode].className.indexOf('active')>-1) ? objNodes[intNode] : objMatch ;
									}
									// recurse back the last matching node
									if(objMatch!=null){
										this.recurse(objMatch.parentNode);
									}
								}
			this.recurse 	= 	function(objParentNode){
									var cmh = classBehaviour.classMouseHover;
									// add active class to the anchor
									if(objParentNode.getElementsByTagName('A').length>0) cmh.addActive(objParentNode.getElementsByTagName('A')[0]);
									// store the active node
									this.activeNode = objParentNode;
									// add the active src to any image in the node
									imgNodes = objParentNode.getElementsByTagName('img');
									if(imgNodes.length>0) imgNodes[0].src = imgNodes[0].src.replace('_link','_active');
									// next recursion to same node type
									if(objParentNode.nodeName == objParentNode.parentNode.parentNode.nodeName) this.recurse(objParentNode.parentNode.parentNode);
								}
			/* events */
			this.addHover 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var cmh = classBehaviour.classMouseHover;
									var fom = classBehaviour.foldOutMenu;
									// if a delay is required
									if(fom.delay>0){
										// cancel the timeout on the delayed mouseevents
										clearTimeout(fom.timeout);
										// handle the delayed mouseouts
										while(fom.foldIns.length>0){
											// change the stored active node to "active"
											if(fom.activeNode!=null) if(fom.activeNode.getElementsByTagName('IMG').length>0) fom.activeNode.getElementsByTagName('IMG')[0].src = fom.activeNode.getElementsByTagName('IMG')[0].src.replace('_link','_hover');
											// change the src of a child image
											imgNodes = fom.foldIns[fom.foldIns.length-1].getElementsByTagName('img');
											if(imgNodes.length>0) imgNodes[0].src = imgNodes[0].src.replace('_active','_link');
											// remove the active classes from every item to be folded in
											cmh.remHover(fom.foldIns[fom.foldIns.length-1]);
											fom.foldIns.length = fom.foldIns.length - 1;
										}
										// restore all select form elements
										/*allSelects = document.getElementsByTagName('SELECT');
										if(document.all){
											for(var a=0; a<allSelects.length; a++){
												allSelects[a].style.visibility = 'visible';
											}
										}*/
									}
									// is the node exists
									if(objNode!=null){
										// emulate the parent node's mouseout event
										cmh.addHover(objNode);
										// change the stored active node to "link"
										if(fom.activeNode!=null) if(fom.activeNode.getElementsByTagName('IMG').length>0) fom.activeNode.getElementsByTagName('IMG')[0].src = fom.activeNode.getElementsByTagName('IMG')[0].src.replace('_active','_link');
										// change the src of a child image
										imgNodes = objNode.getElementsByTagName('img');
										if(imgNodes.length>0) imgNodes[0].src = imgNodes[0].src.replace('_link','_active');
										// hide all select form elements
										/*allSelects = document.getElementsByTagName('SELECT');
										if(document.all){
											for(var a=0; a<allSelects.length; a++){
												allSelects[a].style.visibility = 'hidden';
											}
										}*/
									}
								}
			this.remHover 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var cmh = classBehaviour.classMouseHover;
									var fom = classBehaviour.foldOutMenu;
									// if no delay is required
									if(fom.delay==0){
										// emulate the parent node's mouseout event
										cmh.remHover(objNode);
										// change the stored active node to "active"
										if(fom.activeNode!=null){}
										// change the src of a child image
										imgNodes = objNode.getElementsByTagName('img');
										if(imgNodes.length>0) imgNodes[0].src = imgNodes[0].src.replace('_active','_link');
										// restore all select form elements
										/*allSelects = document.getElementsByTagName('SELECT');
										if(document.all){
											for(var a=0; a<allSelects.length; a++){
												allSelects[a].style.visibility = 'visible';
											}
										}*/
									}else{
										// cancel the timeout on the delayed mouseevents
										clearTimeout(fom.timeout);
										// store the mouseout for delayed closing
										fom.foldIns[fom.foldIns.length] = objNode;
										// order a delayed handling of the saved up mouseouts
										fom.timeout = setTimeout('classBehaviour.foldOutMenu.addHover()',fom.delay);
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.foldOutMenu = new FoldOutMenu;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.foldOutMenu;
		
	// Remove this tag if it's found to be empty
		// define this class behaviour
		function RemoveIfEmpty(){
			/* properties */
			this.name 		= 	'removeIfEmpty';
			/* methods */
			this.start		=	function(node){
									this.process(node);
								}
			this.process 	= 	function(objNode){
									// doesn't this node have child nodes?
									if(objNode.childNodes.length==0){
										// remove the node
										objNode.parentNode.removeChild(objNode);
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.removeIfEmpty = new RemoveIfEmpty;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.removeIfEmpty;
		
	// Fixes the position of an element
		// define this class behaviour
		function FixedPosition(){
			/* properties */
			this.name 		= 	'fixedPosition';
			this.nodes 		= 	new Array();
			/* methods */
			this.start		=	function(node){
									this.nodes[this.nodes.length] = node;
									if(document.all){
										window.onscroll = this.process;
									}else{
										node.style.position = 'fixed';
									}
								}
			/* events */
			this.process 	= 	function(){
									var fp = classBehaviour.fixedPosition;
									// this is only needed in internet explorer
									for(var a=0; a<fp.nodes.length; a++){
										fp.nodes[a].style.marginTop = (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + 'px';
										fp.nodes[a].style.marginLeft = (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft) + 'px';
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.fixedPosition = new FixedPosition;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.fixedPosition;
		
	// Open links in a popup
		// define this class behaviour
		function OpenAsPopUp(){
			/* properties */
			this.name 		= 	'openAsPopUp';
			this.window		=	null;
			/* methods */
			this.start		=	function(node){
									node.onclick = this.process;
								}
			/* events */
			this.process 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var oap = classBehaviour.openAsPopUp;
									// get the parameters from the classname
									var strWidth 		= 'width=' + classBehaviour.getClassParameter(objNode, 'width', '630');
									var strHeight 		= ',height=' + classBehaviour.getClassParameter(objNode, 'height', '385');
									var strLeft			= ',left=' + classBehaviour.getClassParameter(objNode, 'left', '');
									var strTop			= ',top=' + classBehaviour.getClassParameter(objNode, 'top', '');
									var strToolbars 	= ',toolbar=' + classBehaviour.getClassParameter(objNode, 'toolbar', 'no');
									var strScrolling 	= ',scrollbars=' + classBehaviour.getClassParameter(objNode, 'scrollbars', 'no');
									var strStatus 		= ',status=' + classBehaviour.getClassParameter(objNode, 'status', 'no');
									var strResize 		= ',resizable=' + classBehaviour.getClassParameter(objNode, 'resizable', 'yes');
									var strLocation 	= ',location=' + classBehaviour.getClassParameter(objNode, 'location', 'no');
									var strMenu 		= ',menu=' + classBehaviour.getClassParameter(objNode, 'menu', 'no');
									var strName 		= classBehaviour.getClassParameter(objNode, 'name', 'popup');
									// open requested window
									oap.window = window.open(objNode.getAttribute('href'), strName, strWidth+strHeight+strScrolling+strToolbars+strStatus+strResize+strLocation+strMenu+strLeft+strTop);
									oap.window.focus();
									// cancel click
									return false;
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.openAsPopUp = new OpenAsPopUp;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.openAsPopUp;
		
	// Open links in the opener of this window
		// define this class behaviour
		function OpenInOpener(){
			/* properties */
			this.name 		= 	'openInOpener';
			/* methods */
			this.start		=	function(node){
									node.onclick = this.process;
								}
			/* events */
			this.process 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// open the href in the opener of this window
									window.opener.location.href = objNode.href;
									// optionaly close the window
									if(classBehaviour.getClassParameter(objNode, 'closeParent', 'false')=='true') window.close();
									// cancel the link
									return false;
									
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.openInOpener = new OpenInOpener;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.openInOpener;

	// Open links in a new window
		// define this class behaviour
		function OpenAsWindow(){
			/* properties */
			this.name 		= 	'openAsWindow';
			/* methods */
			this.start		=	function(node){
									node.target = "_blank"
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.openAsWindow = new OpenAsWindow;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.openAsWindow;
		
	// Chooses a random increment of an image source
		// define this class behaviour
		function SetRandomSrc(){
			/* properties */
			this.name 		= 	'setRandomSrc';
			/* methods */
			this.start		=	function(node){
									this.process(node);
								}
			this.process 	= 	function(objNode){
									// get min parameter
									var intMin = parseInt(classBehaviour.getClassParameter(objNode, 'min', '0'));
									// get max parameter
									var intMax = parseInt(classBehaviour.getClassParameter(objNode, 'max', '1'));
									// generate random number
									var intRandom = Math.round(Math.random()*(intMax-intMin))+intMin;
									// replace default increment by random number
									if(objNode.src!=null) objNode.src = objNode.src.replace('_0','_'+intRandom);
									objNode.className = objNode.className.replace('_0','_'+intRandom);
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.setRandomSrc = new SetRandomSrc;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.setRandomSrc;
		
	// Chooses a random increment of an image source
		// define this class behaviour
		function SetRandomClassName(){
			/* properties */
			this.name 		= 	'setRandomClassName';
			/* methods */
			this.start		=	function(node){
									this.process(node);
								}
			this.process 	= 	function(objNode){
									// get min parameter
									var intMin = parseInt(classBehaviour.getClassParameter(objNode, 'min', '0'));
									// get max parameter
									var intMax = parseInt(classBehaviour.getClassParameter(objNode, 'max', '1'));
									// generate random number
									var intRandom = Math.round(Math.random()*(intMax-intMin))+intMin;
									// replace default increment by random number
									if(objNode.className!=null) objNode.className = objNode.className.replace('_0','_'+intRandom);
									objNode.className = objNode.className.replace('_0','_'+intRandom);
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.setRandomClassName = new SetRandomClassName;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.setRandomClassName;
		
	// Add or remove display:none; onclick
		// define this class behaviour
		function ToggleNextNode(){
			/* properties */
			this.name 		= 	'toggleNextNode';
			this.lastNode	=	null;
			this.lastNext	=	null;
			/* methods */
			this.start		=	function(node){
									node.onclick = this.toggleNext;
								}
			/* events */
			this.toggleThis = 	function(that, strClosePrevious){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var tnn = classBehaviour.toggleNextNode;
									// restore previous node
									if(tnn.lastNode!=null && tnn.lastNode!=objNode && strClosePrevious=='yes') tnn.lastNode.style.display = 'none';
									// toggle node's visibility
									objNode.style.display = (objNode.style.display=='none') ? classBehaviour.getVisibleState(objNode) : 'none' ;
									// remember last node
									tnn.lastNode = objNode;	
								}
			this.toggleNext = 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var tnn = classBehaviour.toggleNextNode;
									// get parent recursion
									var intParentRecursion = parseInt(classBehaviour.getClassParameter(objNode,'useParent','0'));
									var objParentNode = objNode;
									for(var a=0; a<intParentRecursion; a++) objParentNode = objParentNode.parentNode;
									// check if a previousnode needs closing
									var strClosePrevious = classBehaviour.getClassParameter(objNode,'closePrevious','no');
									// get optional id
									var strCloseId = classBehaviour.getClassParameter(objNode, 'id', null);
									// determine the next node
									var objNextNode;
									if(strCloseId!=null){
										objNextNode = document.getElementById(strCloseId);
									}else if(objParentNode.nextSibling){
										objNextNode = (objParentNode.nextSibling.nodeName.indexOf("text")<0) ? objParentNode.nextSibling : objParentNode.nextSibling.nextSibling ;
									}
									// if there is a next node
									if(objNextNode!=null){
										// toggle it's visibility
										tnn.toggleThis(objNextNode, strClosePrevious);
										// If the next node has been hidden
										if(objNextNode.style.display=='none'){
											// restore current node's click state
											objNode.className = objNode.className.replace('active','link');
											if(objNode.src!=null) objNode.src = objNode.src.replace('active','link');
											// do the same to the parent node
//											objNode.parentNode.className = objNode.parentNode.className.replace('active','link');
										}else{
											// mark current node as active
											objNode.className = objNode.className.replace('link','active');
											objNode.className = objNode.className.replace('hover','active');
											if(objNode.src!=null) objNode.src = objNode.src.replace('link','active');
											if(objNode.src!=null) objNode.src = objNode.src.replace('hover','active');
											// do the same to the parent node
//											objNode.parentNode.className = objNode.parentNode.className.replace('link','active');
//											objNode.parentNode.className = objNode.parentNode.className.replace('hover','active');
											// restore previous node's click state
											if(tnn.lastNext!=null && tnn.lastNext!=objNode && strClosePrevious=='yes'){
												tnn.lastNext.className = tnn.lastNext.className.replace('active','link');
												if(objNode.src!=null) tnn.lastNext.src = tnn.lastNext.src.replace('active','link');
												// do the same to the parent node
//												tnn.lastNext.parentNode.className = tnn.lastNext.parentNode.className.replace('active','link');
											}
										}
										// remember last node
										tnn.lastNext = objNode;
									}
									// cancel onclick event
									return false;
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.toggleNextNode = new ToggleNextNode;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.toggleNextNode;
		
	// Class a link matching the document's url
		// define this class behaviour
		function MatchActiveUrl(){
			/* properties */
			this.name 		= 	'matchActiveUrl';
			/* methods */
			this.start		=	function(node){
									this.process(node);
								}
			this.convertAbsToRelUrls 	= 	function(strUrl){
												// is the url a relative path
												if(strUrl.indexOf('/')<0 || strUrl.substr(0,1)=='.' || strUrl.substr(0,1)=='/'){
													// the current absolute path
													strAbs = document.location.href;
													// remove the filename from the end
													strAbs = strAbs.substring(0, strAbs.lastIndexOf('/'));
													// while there are parent markers in the url
													while(strUrl.indexOf('../')==0){
														// remove one level from the absolute path
														strUrl = strUrl.replace('../','');
														// remove one parent marker from the relative path
														strAbs = strAbs.substring(0, strAbs.lastIndexOf('/'));
													}
													// remove all current dir markers from the relative url
													strUrl = strUrl.replace(/\.\//gi,'');
													// add the url to the absolute path
													strUrl = strAbs + '/' + strUrl;
												}
												return strUrl;
											}
			this.compareUrls 	= 	function(strUrlA,strUrlB){
										var intCurScore = 0;
										var intPotScore = 0;
										var intMaxScore = 0;
										var intA,intB;
										// replace most common illegal characters
										strUrlA = strUrlA.replace(/ /gi,"%20");
										strUrlB = strUrlB.replace(/ /gi,"%20");
										// remove anchors
										strUrlA = strUrlA.split('#')[0];
										strUrlB = strUrlB.split('#')[0];
										// make sure both paths are absolute
										strUrlA = this.convertAbsToRelUrls(strUrlA);
										strUrlB = this.convertAbsToRelUrls(strUrlB);
										// split the urls into manageable strings
										var arrUrlA = strUrlA.split(/[?&#\/]/i);
										var arrUrlB = strUrlB.split(/[?&#\/]/i);
										// for every string of UrlA
										for(intA=0; intA<arrUrlA.length; intA++){
											// is the string in the substrings of UrlB
											intB = 0; while(intB<arrUrlB.length && arrUrlA[intA]!=arrUrlB[intB]) intB += 1;
											// if a match was found, add length of string A to current score
											if(intB<arrUrlB.length) intCurScore += arrUrlA[intA].length;
											// add length of string A to potential score
											intPotScore += arrUrlA[intA].length;
										}
										// calcultate maximum score possible
										intMaxScore = strUrlB.length - arrUrlB.length + 1;
										// return the compare-score
										return intCurScore/intPotScore;
									}
			this.process 	= 	function(objNode){
									var cmh = classBehaviour.classMouseHover;
									var smh = classBehaviour.srcMouseHover;
									// get parent recursion
									var intToParent	= parseInt(classBehaviour.getClassParameter(objNode, 'toParent', '0'));
									// get parent href
									var intFromParent = parseInt(classBehaviour.getClassParameter(objNode, 'fromParent', '0'));
									// get the url and clean it up
									var strUrl = this.convertAbsToRelUrls(document.location.href);
									// get the href and clean it up
									var strHref = (intFromParent>0) ? this.convertAbsToRelUrls(objNode.parentNode.getAttribute('href')) : this.convertAbsToRelUrls(objNode.getAttribute('href')) ;
									// was the data bad
									if(strHref!=null){
										// compare score
										var ftlCompareScore = this.compareUrls(strUrl, strHref) * this.compareUrls(strHref, strUrl);
										// if the href matches the url 
										if(ftlCompareScore==1){
											// add the active class to the target item
											cmh.addActive(objNode);
											if(objNode.nodeName=='IMG') smh.addActive(objNode);
											// if a parent node also needs to be marked
											if(intToParent>0){
												// get the relevant parent node
												for(var intA=0; intA<intToParent; intA++) objNode = objNode.parentNode;
												// if the href matches the url
												if(ftlCompareScore==1){
													// add the active class to the parent item
													cmh.addActive(objNode);
												}
											}
											// report a match
											return true;
										}
									}
									// report no match
									return false;
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.matchActiveUrl = new MatchActiveUrl;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.matchActiveUrl;

	// Triggers all validateInput class behaviours within a node after the onsubmit event.',
		// define this class behaviour
		function ValidateAllInput(){
			/* properties */
			this.name 		= 	'validateAllInput';
			/* methods */
			this.start		=	function(node){
									// set the form validation eventhandler
									node.onsubmit = classBehaviour.validateInput.all;
									// if there's a place for a summary store the id
									classBehaviour.validateInput.summaryId = classBehaviour.getClassParameter(node, 'summaryId', null);
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.validateAllInput = new ValidateAllInput;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.validateAllInput;

	// Validate the value of a for element to a predefined regular expression
		// define this class behaviour
		function ValidateInput(){
			/* properties */
			this.name 		= 	'validateInput';
			this.summaryId	=	null;
			/* methods */
			this.start	=	function(node){
								// was a summary requested?
								this.summaryId = classBehaviour.getClassParameter(node, 'summaryId', this.summaryId);
								
								// apply the event to all form-element childnodes
								var nodes = (this.isFormElement(node)) ? new Array(node) : node.getElementsByTagName('*');
								for(var a=0; a<nodes.length; a++){
									if(this.isFormElement(nodes[a])){
										// give it the event handler
										nodes[a].onfocus = this.clear;
										nodes[a].onblur = this.input;
										nodes[a].onchange = this.input;
										// if the form is small enough one could revalidate the whole thing at every change
											//nodes[a].onblur = this.all;
											//nodes[a].onchange = this.all;
										// and the parent's classname
										nodes[a].className = node.className;
									}
								}
								// if there's a greyed axplanation
								hasExplanation = classBehaviour.getClassParameter(node, 'explanation', 'no');
								if(hasExplanation=='yes'){
									// remove it if a value is restored by a form manager
									setTimeout("classBehaviour.validateInput.restore('"+node.id+"','"+node.value+"')", 1000);
								}
							}
			this.all 	= 	function(that){
								var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
								var vi = classBehaviour.validateInput;
								var booPassed = true;
								// get all subnodes in the form
									//var objSubNodes = objNode.getElementsByTagName("*") ;
									var objSubNodes = document.getElementsByTagName("*") ;
								// for all nodes
								for(var intA=0; intA<objSubNodes.length; intA++){
									// Does this node have the validateInput put class? Invoke the validator function upon it.
									if(objSubNodes[intA].className.toLowerCase().indexOf('validateinput')>-1 && vi.isFormElement(objSubNodes[intA])) booPassed = (vi.input(objSubNodes[intA], false) && booPassed);
								}
								// is a summary required
								if(vi.summaryId){
								   summaryObj = document.getElementById(vi.summaryId);
									if(summaryObj != null){
									if(summaryObj && booPassed==false){
									  summaryObj.style.display="block";
									}else{
									  summaryObj.style.display="none";
									}
									}
									/*summaryTxt = '';
									// for all nodes
									for(var a=0; a<objSubNodes.length; a++){
										// if this node a visible warning
										if(objSubNodes[a].className.indexOf('validationWarning')>-1 && objSubNodes[a].style.display!='none'){
											// copy it's contents to the summary text
											summaryTxt += '<li>' + objSubNodes[a].innerHTML + '</li>';
										}
									}
									// add the summary text to the summary
									summaryObj.innerHTML = (summaryTxt.length>0) ? '<ul>' + summaryTxt + '</ul>' : '' ;
								   */
								}
								// is the form valid enough?
								return booPassed;
							}
			this.input = 	function(that, override){
								var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
								var vi = classBehaviour.validateInput;
								// default validator values
								var booEmptyValidator, booValueValidator;
								// get the type of validation required			
								strValidatorName	= classBehaviour.getClassParameter(objNode, 'type', '');
								allowEmpty			= classBehaviour.getClassParameter(objNode, 'allowEmpty', 'no');
								ifCheckedId			= classBehaviour.getClassParameter(objNode, 'ifCheckedId', null);
								hasExplanation 		= classBehaviour.getClassParameter(objNode, 'explanation', 'no');
								// check a special dependency on a parent checkbox
								if(ifCheckedId){
									if(!document.getElementById(ifCheckedId).checked) allowEmpty = 'yes';
								}
								// validation tests
									// empty test	objNode.value!=''
									booEmptyValidator = (allowEmpty=='yes' && (objNode.value=='' || hasExplanation=='yes'));
									// bizarre exception for MSIE 5.0
									if(navigator.appVersion.indexOf('MSIE 5.0')>-1 && strValidatorName=='money') strValidatorName = null;
									// test expressions
									switch(strValidatorName){
										// regular expression tests
										case 'email' : 
											booValueValidator = (objNode.value.match(/^[\w\.\-\,\+]+@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/)!=null);
											break;
										case 'phone' : 
											booValueValidator = (objNode.value.match(/(^\+[0-9]{2}|^\+[0-9]{2}\(0\)|^\(\+[0-9]{2}\)\(0\)|^00[0-9]{2}|^0)([0-9]{9}$|[0-9\-\s]{10}$)/)!=null); 
											break;
										case 'dutchzipcode' : 
											booValueValidator = (objNode.value.match(/^[0-9]{4}\s{0,1}[a-zA-Z]{2}$/)!=null); 
											break;
										case 'date' : 
											booValueValidator = (objNode.value.match(/^\d{4}\-\d{1,2}\-\d{1,2}$/)!=null);
											// booRegExpValidator = (objNode.value.match(/^\d{1,2}\-\d{1,2}\-(\d{2}|\d{4})$/)!=null); 
											break;
										case 'number' : 
											booValueValidator = (objNode.value.match(/^[0-9]+$/)!=null); 
											break;
										case 'money' :
											booValueValidator = (objNode.value.match(/^[0-9]+(\.[0-9]{1,2})?$/)!=null); 
											break;
										case 'alphanumeric' :
											booValueValidator = (objNode.value.match(/^[a-zA-Z0-9]/)!=null);
											break;
										// custom tests
										case 'bankaccount' :
											booValueValidator = vi.bankAccount(objNode);
											break;
										case 'isradiochecked' :
											booValueValidator = vi.isRadioChecked(objNode);
											break;
										case 'anyofthesechecked' : 
											booValueValidator = vi.anyOfTheseChecked(objNode);
											break;
										case 'notempty' :
										case 'text' :
											booValueValidator = (objNode.value!="");
											break;
										default :
											booValueValidator = true;
									}
								// does the input validate when the field is not empty or not allowed to be empty
								validates = (!booEmptyValidator) ? (booValueValidator && hasExplanation=='no') : true ;
								// show or hide the warning message based on the validator's match
								vi.warning(objNode, validates);
								// return a pass of fail boolean to whoever may want to know the results of the test
								return (override!=null) ? validates : override;
							}
			this.warning =	function(objNode, status){
								var vi = classBehaviour.validateInput;
								// for all inputs with the same name
								allWithSameName = document.getElementsByName(objNode.name);
								for(var b=0; b<allWithSameName.length; b++){
									objNode = allWithSameName[b];
								// Show the foldout warning
									// is the warning node named?
									idWarningNode		= classBehaviour.getClassParameter(objNode, 'warningId', null);
									// check if the next node is for summaries
									nextNode 			= (objNode.nextSibling.nodeName.indexOf("text")<0) ? objNode.nextSibling : objNode.nextSibling.nextSibling ;
									// if there's an id given for thewarning message use it. Otherwise use the next node
									objWarningNode		= (idWarningNode) ? document.getElementById(idWarningNode) : nextNode ;
									// show or hide the warning, if the warning node was found
									if(objWarningNode) if(objWarningNode.className.indexOf('validationWarning')>-1) objWarningNode.style.display = (status) ? 'none' : 'block' ;
								// Highlight the label
									// get all labels
									allLabels = document.getElementsByTagName('label');
									// for all labels
									for(var a=0; a<allLabels.length; a++){
										// if the label matches this input
										if(allLabels[a].getAttributeNode('for').nodeValue == objNode.id){
											// add or remove the warning colour
											if(allLabels[a].parentNode.className.indexOf('noWarning')<0 && allLabels[a].className.indexOf('noWarning')<0) allLabels[a].className = (status) ? '' : 'warning' ;
										}
									}
								}
							}
			this.clear	=	function(objNode){
			if(typeof(this.nodeName)=='undefined'){
   			 objNode =  that ;
			 }else{
		   	 objNode = this ;
			}
								// if there was an explanation provides as a value
								hasExplanation = classBehaviour.getClassParameter(objNode, 'explanation', 'no');
								if(hasExplanation=='yes'){
									// clear the value
									objNode.value = '';
									// che change the class back to normal
									objNode.className = objNode.className.replace('explanation_yes', 'explanation_no');
								}
							}
			this.restore =	function(id, value){
								var objNode = document.getElementById(id);
								// if this input has a value which doesn't match the current value, a form manager has restored a value
								if(objNode.value!=value){
									objNode.className = objNode.className.replace('explanation_yes','explanation_no');
								}
							}
			/* utility functions */
			this.isFormElement		=	function(objNode){
											return (objNode.nodeName=='INPUT' || objNode.nodeName=='SELECT' || objNode.nodeName=='TEXTAREA');
										}
			/* custom validation functions */
			this.bankAccount 		= 	function(objNode){
											var intDeel, intRest;
											var strInput = objNode.value;
											var intTot=0;
											if (strInput.length!=9){
												return false;
											}else{
												for (i=0; i<strInput.length; i++) intTot += strInput.substr(i,1) * (9 - i);
												intDeel = intTot/11;
												intRest = intTot%11;
												return (intRest==0);
											}
										}
			this.isRadioChecked	=	function(objNode){
											// get all inputs with this name
											allInputs = document.getElementsByTagName('input');
											// for all inputs
											for(var a=0; a<allInputs.length; a++){
												// If the input has the same name. 
												if(allInputs[a].name == objNode.name){
													// If the input is checked set the validator to true
													if(allInputs[a].checked) return true;
												}
											}
											return false;
										}
			this.anyOfTheseChecked	=	function(objNode){
												// default validatie
												anyChecked = false;
												// get all inputs from the parentnode
												allChecks = objNode.parentNode.parentNode.getElementsByTagName('input');
												// for all inputs
												for(var a=0; a<allChecks.length; a++){
													// if this checkbox is checked remember is
													if(allChecks[a].checked) anyChecked = true;
												}
												return anyChecked;
											}
		}
		// add this function to the classbehaviour object
		classBehaviour.validateInput = new ValidateInput;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.validateInput;
		
	// Enforces minimal height of a container
		// define this class behaviour
		function MinHeight(){
			/* properties */
			this.name 		= 	'minHeight';
			this.adjusts 	= 	new Array();
			this.timeout 	= 	null;
			/* methods */
			this.start		=	function(node){
									// immediate event
									this.process(node);
									// store object for later resize
									this.adjusts[this.adjusts.length] = node;
									window.onresize = this.delay;
								}
			this.adjust	 	= 	function(){
									for(var intA=0; intA<this.adjusts.length; intA++){
										this.adjusts[intA].style.height = 'auto';
										this.process(this.adjusts[intA]);
									}
								}
			/* events */
			this.delay 		= 	function(){
									clearTimeout(classBehaviour.minHeight.timeout);
									// maxWidth might want to re-adjusted too
									classBehaviour.minHeight.timeout = setTimeout('classBehaviour.minHeight.adjust();classBehaviour.maxWidth.adjust();',  256);
								}
			this.process 	= 	function(objNode){
									// get the height parameters
									var strMinHeight, strOffSet;		
									strMinHeight	= classBehaviour.getClassParameter(objNode, 'height', '100pct');
									strOffSet		= classBehaviour.getClassParameter(objNode, 'heightOffset', '0px');
									// get the current document and window dimensions
									var intDocHeight, intCanvasHeight;
									intDocHeight	= document.body.scrollHeight;
									intCanvasHeight	= (typeof(window.innerHeight)!='undefined') ? window.innerHeight : document.body.offsetHeight ;
									// adjust target container to fill the difference in dimensions
									var intMinHeight= (strMinHeight.indexOf('pct')>-1) ? Math.round(intCanvasHeight * parseInt(strMinHeight) / 100) : parseInt(strMinHeight) ;
									var intOffSet	= (strOffSet.indexOf('pct')>-1) ? Math.round(intCanvasHeight * parseInt(strOffSet) / 100) : parseInt(strOffSet) ;
									// set the page's minimum height
									if(document.all){
										intOffSet -= 1;
										objNode.style.height = (intMinHeight - intOffSet) + 'px';
									}else{
										objNode.style.minHeight = (intMinHeight - intOffSet) + 'px';
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.minHeight = new MinHeight;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.minHeight;
		
	// Enforces maximal width of a container
		// define this class behaviour
		function MaxWidth(){
			/* properties */
			this.name 		= 	'maxWidth';
			this.adjusts 	= 	new Array();
			/* methods */
			this.start		=	function(node){
									// immediate event
									this.process(node);
									// store object for later resize
									this.adjusts[this.adjusts.length] = node;
									window.onresize = this.delay;
								}
			this.adjust	 	= 	function(){
									for(var intA=0; intA<this.adjusts.length; intA++){
										this.adjusts[intA].style.width = 'auto';
										this.process(this.adjusts[intA]);
									}
								}
			/* events */
			this.delay 		= 	function(){
									clearTimeout(classBehaviour.maxWidth.timeout);
									// minHeight might want to re-adjusted too
									classBehaviour.minHeight.timeout = setTimeout('classBehaviour.minHeight.adjust();classBehaviour.maxWidth.adjust();',  256);
								}
			this.process 	= 	function(objNode){
									// get the width parameters
									var strMaxWidth, strOffSet;
									strMaxWidth		= classBehaviour.getClassParameter(objNode, 'width', '100pct');
									strOffSet		= classBehaviour.getClassParameter(objNode, 'widthOffset', '0px');
									// get the current document and window dimensions
									var intDocWidth, intCanvasWidth;
									intDocWidth		= document.body.scrollWidth;
									intCanvasWidth	= (typeof(window.innerWidth)!='undefined') ? window.innerWidth : document.body.offsetWidth ;
									// adjust target container to fill the difference in dimensions
									var intMaxWidth	= (strMaxWidth.indexOf('pct')>-1) ? Math.round(intCanvasWidth * parseInt(strMaxWidth) / 100) : parseInt(strMaxWidth) ;
									var intOffSet	= (strOffSet.indexOf('pct')>-1) ? Math.round(intCanvasWidth * parseInt(strOffSet) / 100) : parseInt(strOffSet) ;
									objNode.style.width = (intDocWidth>intMaxWidth) ? (intMaxWidth - intOffSet) + 'px' : 'auto' ;
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.maxWidth = new MaxWidth;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.maxWidth;
		
	// Scroll the list items of a container
		// define this class behaviour
		function ListScroller(){
			/* properties */
			this.name 		= 	'listScroller';
			this.object	=	null;
			this.dimensions =	new Coordinates();
			this.limits	=	new Coordinates();
			this.speed		=	new Coordinates();
			this.distance	=	new Coordinates();
			this.delay		=	null;
			this.interval	=	null;
			/* methods */
			this.start		=	function(node){
									// make a new instance of the scroller object
									this.object			= node;
									this.dimensions.x	= parseInt(classBehaviour.getClassParameter(node, 'width', '112'));
									this.dimensions.y	= parseInt(classBehaviour.getClassParameter(node, 'height', '120'));
									this.speed.x		= -1 * parseInt(classBehaviour.getClassParameter(node, 'left', '2'));
									this.speed.y		= -1 * parseInt(classBehaviour.getClassParameter(node, 'top', '0'));
									this.delay			= parseInt(classBehaviour.getClassParameter(node, 'delay', '64'));
									this.distance.x		= 0;
									this.distance.y		= 0;
									// clone the list items for double buffering
									var scrollList		= this.object.getElementsByTagName('UL')[0];
									var scrollItems		= scrollList.getElementsByTagName('LI');
									var itemsMax		= scrollItems.length;
									for(var a=0; a<itemsMax; a++){
										var new_node = scrollItems[a].cloneNode(true);
										scrollList.appendChild(new_node); 
									}
									// note the scrolling limits
									this.limits.x	= this.dimensions.x * itemsMax;
									this.limits.y	= this.dimensions.y * itemsMax;
									// set prerequisite styles
										//	UL settings
										scrollList.style.width	= (this.dimensions.x * 2 * itemsMax) + 'px';
										scrollList.style.height	= (this.dimensions.y * 2 * itemsMax) + 'px';
										// LI settings
										for(var a=0; a<scrollItems.length; a++){
											scrollItems[a].style.width	= this.dimensions.x + 'px';
											scrollItems[a].style.height	= this.dimensions.y + 'px';
										}
									// set the mouseover events
									this.object.onmouseout	= this.scroll;
									this.object.onmouseover = this.pause;
									// if there are direction controls give them events
									if(document.getElementById('prevControl')) document.getElementById('prevControl').onclick = this.goLeft;
									if(document.getElementById('nextControl')) document.getElementById('nextControl').onclick = this.goRight;
									// initiate the scroll interval
									this.scroll();
								}
			this.step		=	function(){
									var scrollCanvas =	this.object.getElementsByTagName('UL')[0];
									// calculate the new positions - loop on the right
									if(this.speed.x<=0) newLeftPos	=	(this.distance.x <= -1*this.limits.x) ? '0px' : (this.distance.x + this.speed.x) + 'px';
									if(this.speed.y<=0) newTopPos		=	(this.distance.y <= -1*this.limits.y) ? '0px' : (this.distance.y + this.speed.y) + 'px';
									// loop on the right
									if(this.speed.x>0) newLeftPos		=	(this.distance.x > 0) ? (-1*this.limits.x + this.speed.x) + 'px' : (this.distance.x + this.speed.x) + 'px';
									if(this.speed.y>0) newTopPos		=	(this.distance.y > 0) ? (-1*this.limits.y + this.speed.y) + 'px' : (this.distance.y + this.speed.y) + 'px';
									// update styles
									scrollCanvas.style.left	= newLeftPos;
									scrollCanvas.style.top	= newTopPos;
									// update stored positions
									this.distance.x			=	parseInt(newLeftPos);
									this.distance.y			=	parseInt(newTopPos);
									// cancel something
									return 0;
								}
			/* events */
			this.goLeft	=	function(){
									var lsc = classBehaviour.listScroller;
									// set the scrolling
									lsc.speed.x = Math.abs(lsc.speed.x);
									// cancel the click
									return false;
								}
			this.goRight	=	function(){
									var lsc = classBehaviour.listScroller;
									// set the scrolling
									lsc.speed.x = -1 * Math.abs(lsc.speed.x);
									// cancel the click
									return false;
								}
			this.scroll		=	function(){
									classBehaviour.listScroller.interval = setInterval('classBehaviour.listScroller.step()', classBehaviour.listScroller.delay);
									return 0;
								}
			this.pause		=	function(){
									clearInterval(classBehaviour.listScroller.interval);
									return 0;
								}
		}
		/* allready defined elsewhere
			function Coordinates(x,y,z){
				this.x = x;
				this.y = y;
				this.z = z;
			}
		*/
		// add this function to the classbehaviour object
		classBehaviour.listScroller = new ListScroller;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.listScroller;
		
/* TODO: controls for the scroller
	<li><a href="?3" id="prevControl"><img alt="Vorige" src="../images/movieGallery_previous_link.gif"/></a></li>
	<li><a href="?4" id="nextControl"><img alt="Volgende" src="../images/movieGallery_next_link.gif"/></a></li>
*/
		
		
	// Toggle hidden siblings when clicking this node
		// define this class behaviour
		function ToggleHiddenSiblings(){
			/* properties */
			this.name 		= 	'toggleHiddenSiblings';
			this.lastNode	=	null;
			this.lastNext	=	null;
			/* methods */
			this.start		=	function(node){
									node.onclick = this.process;
								}
			/* events */
			this.process	=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// If this node is a real check box
									var prefState = null;
									if(objNode.getAttribute('type')=='checkbox'){
										// take it's state for hiding or showing
										prefState = objNode.checked;
									}
									// from this node upwards, find the tbody or the table
									var testNode = objNode.parentNode;
									while(
										testNode.nodeName.toLowerCase()!='tbody' && 
										testNode.nodeName.toLowerCase()!='table' && 
										testNode.nodeName.toLowerCase()!='div' && 
										testNode.nodeName.toLowerCase()!='fieldset' && 
										testNode.nodeName.toLowerCase()!='body'
									){
										testNode = testNode.parentNode;
									}
									var allNodes = testNode.getElementsByTagName('*');
									// for the nodes within
									for(var a=0; a<allNodes.length; a++){
										// check if it is part of the hiding/showing action
										if(allNodes[a].className.indexOf('hideThisNode')>-1){
											// take the prefered state from the current state if the original node wasn't a checkbox
											if(prefState==null) prefState = (allNodes[a].style.display=='none') ? true : false ;
												// show of hide the sibling
												if(prefState){
													// show thenode using the correct visible state
													node.style.display = classBehaviour.getVisibleState(node);
												}else{
													allNodes[a].style.display = 'none';
												}

										}
									}
								}

		}
		// add this function to the classbehaviour object
		classBehaviour.toggleHiddenSiblings = new ToggleHiddenSiblings;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.toggleHiddenSiblings;

	// tabbed content
		// define this class behaviour
		function TabbedContent(){
			/* properties */
			this.name 		= 	'tabbedContent';
			/* methods */
			this.start		=	function(node){
									// get all tabs
									allTabs = node.getElementsByTagName('a');
									// store the most likely opened tab
									openedTab = allTabs[0];
									// for all tabs
									for(var a=0; a<allTabs.length; a++){
										// get the id this tab refers to
										tabId = allTabs[a].href.split('#')[1];
										// apply onclick events to the referred tab
										allTabs[a].onclick = this.open;
										// apply the starting state of the tab if needed
										if(allTabs[a].className.indexOf('closedTab')<0) allTabs[a].className += ' closedTab';
										// apply the starting state of the referred content if needed
										if(document.getElementById(tabId).className.indexOf('closedTab')<0) document.getElementById(tabId).className += ' closedTab';
										// if this tab is referred to in the page url, remember it as active
										if(document.location.href.indexOf(allTabs[a].href)>-1) openedTab = allTabs[a];
										// if this tab was manualy set
										if(allTabs[a].className.indexOf('openedTab')>-1) openedTab = allTabs[a];
									}
									// if there is a pager
									pager = document.getElementById(classBehaviour.getClassParameter(node, 'pagerId', 'none'));
									if(pager){
										// assign the events for the buttons
										pager.getElementsByTagName('a')[0].onclick = this.previous;
										pager.getElementsByTagName('a')[1].onclick = this.next;
									}
									// open the most like first tab
									this.open(openedTab);
								}
			/* events */
			this.next		=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var tbd = classBehaviour.tabbedContent;
									// get the pager information
									pagerInfo = objNode.parentNode.parentNode.getElementsByTagName('span')[0].firstChild.nodeValue;
									// what is the current pagenumber
									currentPage = parseInt(pagerInfo.split('/')[0]);
									// how many pages are there
									totalPages = parseInt(pagerInfo.split('/')[1]);
									// what is the next page
									nextPage = (currentPage<totalPages) ? currentPage + 1 : 1 ;
									// what is the tabs strip
									tabStrip = document.getElementById(classBehaviour.getClassParameter(objNode.parentNode.parentNode, 'tabsId', 'none'));
									if(tabStrip){
										// get the relevant page from the tab strip
										targetTab = tabStrip.getElementsByTagName('a')[nextPage-1];
										// activate it's click
										tbd.open(targetTab);
									}
								}
			this.previous	=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var tbd = classBehaviour.tabbedContent;
									// get the pager information
									pagerInfo = objNode.parentNode.parentNode.getElementsByTagName('span')[0].firstChild.nodeValue;
									// what is the current pagenumber
									currentPage = parseInt(pagerInfo.split('/')[0]);
									// how many pages are there
									totalPages = parseInt(pagerInfo.split('/')[1]);
									// what is the next page
									previousPage = (currentPage>1) ? currentPage - 1 : totalPages ;
									// what is the tabs strip
									tabStrip = document.getElementById(classBehaviour.getClassParameter(objNode.parentNode.parentNode, 'tabsId', 'none'));
									if(tabStrip){
										// get the relevant page from the tab strip
										targetTab = tabStrip.getElementsByTagName('a')[previousPage-1];
										// activate it's click
										tbd.open(targetTab);
									}
								}
			this.open		=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var tbd = classBehaviour.tabbedContent;								
									// get all tabs
									allTabs = objNode.parentNode.parentNode.getElementsByTagName('a');
									pageNumber = 0;
									// reset all tabs
									for(var a=0; a<allTabs.length; a++){
										// mark the previous tab as passive
										allTabs[a].className = allTabs[a].className.replace('openedTab', 'closedTab');
										// hide the previous tabbed content
										tabId = allTabs[a].href.split('#')[1];
										document.getElementById(tabId).className = document.getElementById(tabId).className.replace('openedTab', 'closedTab');
										// count the new pagenumber
										if(allTabs[a]==objNode) pageNumber = a;
									}
									// mark the next tab as active
									objNode.className = objNode.className.replace('closedTab', 'openedTab');
									// show the next tabbed content
									tabId = objNode.href.split('#')[1];
									document.getElementById(tabId).className = document.getElementById(tabId).className.replace('closedTab', 'openedTab');
									// update page-numbering
									pager = document.getElementById(classBehaviour.getClassParameter(objNode.parentNode.parentNode, 'pagerId', 'none'));
									if(pager){
										pager.getElementsByTagName('span')[0].firstChild.nodeValue = (pageNumber+1) + '/' + allTabs.length ;
									}
									// cancel the jump to the anchor
									return false;
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.tabbedContent = new TabbedContent;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.tabbedContent;
		
	// replace in src sub-string
		// define this class behaviour
		function TitleMouseHover(){
			// properties
			this.name 			= 	'titleMouseHover';
			this.cache 		= 	new Array();
			this.limitRight	=	9999;
			this.limitLeft		=	0;
			this.mouseX		=	0;
			this.mouseY		=	0;
			// methods
			this.start			=	function(node){

											this.cacheImages(node);
											node.onmouseover = this.addHover;
											node.onmouseout = this.remHover;
											node.onmousemove = this.positionHover;
											// set limits
											this.limitRight = parseInt(classBehaviour.getClassParameter(node, 'limitRight', '9999'));
											this.limitLeft = parseInt(classBehaviour.getClassParameter(node, 'limitLeft', '0'));
											// start mouse position manager, if present
											//if(setMouseHandler) setMouseHandler('hoverCanvas');
									}
			this.cacheImages	 = 	function(that) {
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										// replace link by hover
										var cacheIdx = this.cache.length;
										// hover version
										this.cache[cacheIdx] = new Image();
										this.cache[cacheIdx].src = objNode.src.replace('_link','_hover');
										// active version
										this.cache[cacheIdx+1] = new Image();
										this.cache[cacheIdx+1].src = objNode.src.replace('_link','_active');
									}
			// events
			this.positionHover	=	function(that){
										tmh = classBehaviour.titleMouseHover;
										objHover = document.getElementById('hoverTitle');
										// mouse position
										tmh.mouseX = (typeof(event)!='undefined') ? event.clientX : that.clientX ;
										tmh.mouseY = (typeof(event)!='undefined') ? event.clientY : that.clientY ;
										// label position
										objHover.style.left = (tmh.mouseX>tmh.limitRight) ? tmh.limitRight + 'px' : tmh.mouseX + 'px';
										objHover.style.top =  tmh.mouseY + 'px';
									}
			this.addActive 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// replace link by active
									objNode.src = objNode.src.replace('_link','_active');
									// replace hover by active
									objNode.src = objNode.src.replace('_hover','_active');
								}
			this.addHover 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var objHover = document.getElementById('hoverTitle');
									// replace link by hover
									objNode.src = objNode.src.replace('_link','_hover');
									// fill the label with the contents of the title attribute
									objHover.innerHTML = objNode.title.replace('{img:','<img src="').replace('}','" class="left"/>');
									// show the title div
									objHover.style.display = 'block';
								}
			this.remHover 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// replace link by hover
									objNode.src = objNode.src.replace('_hover','_link');
									// hide the title div
									objHover = document.getElementById('hoverTitle');
									objHover.style.display = 'none';
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.titleMouseHover = new TitleMouseHover;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.titleMouseHover;

	// Add or remove display:none; onclick
		// define this class behaviour
		function AdjustSize(){
			// properties
			this.name 		= 	'adjustSize';
			// methods 
			this.start		=	function(){
									window.onresize = this.resize;
									this.resize();
								}
			// events
			this.delay		=	function(){
			
								}
			this.resize	= 	function(){
									// measure window size
									winWidth = (document.all) ? document.body.offsetWidth : window.innerWidth ;
									winHeight = (document.all) ? document.body.offsetHeight : window.innerHeight ;
									// adjust the classname according to the size
									if(winWidth>1024){
										document.body.className = document.body.className.replace('small','large').replace('medium','large');
									}else if(winWidth<800){
										document.body.className = document.body.className.replace('medium','small').replace('large','small');
									}else{
										document.body.className = document.body.className.replace('small','medium').replace('large','medium');
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.adjustSize = new AdjustSize;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.adjustSize;

	// Manage all event handler for an imagemap
		// define this class behaviour
		function ImageMap(){
			// properties
			this.name 		= 	'imageMap';
			this.map		=	new Map;
			this.areas		=	new Areas;
			// methods
			this.start		=	function(node){
									// start the storing of the map object
									node.onmouseover = this.map.over;
									this.map.over(node);
									// get all areas in this map
									areas = document.getElementById(this.map.name).getElementsByTagName('area');
									// for all areas in this map
									for(var a=0; a<areas.length; a++){
										// cache it's image equivalent
										this.cache(node.src.replace(this.map.passive, areas[a].id));
										// give the area event handlers
										areas[a].onmouseover = this.areas.over;
										areas[a].onmouseout = this.areas.out;
									}
								}
			// events
			this.cache		= 	function(url) {
										var imp = classBehaviour.imageMap;
										// preload the image into an array
										imp.map.images[imp.map.images.length] = new Image();
										imp.map.images[imp.map.images.length-1].src = url;
								}
		}
			function Map(){
				// properties
				this.object	=	null;
				this.name		=	null;
				this.passive	=	'nederland';
				this.images		=	new Array();
				// methods
				this.over		=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										var imp = classBehaviour.imageMap;
										// store the currently active map
										imp.map.object = objNode;
										imp.map.name = objNode.getAttributeNode('usemap').value.replace('#','');
									}
			}
			function Areas(){
				// methods
				this.over	=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var imp = classBehaviour.imageMap;
									// apply the area id to the map's source
									imp.map.object.src = imp.map.object.src.replace(imp.map.passive, objNode.id);
								}
				this.out	=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var imp = classBehaviour.imageMap;
									// apply the area id to the map's source
									imp.map.object.src = imp.map.object.src.replace(objNode.id, imp.map.passive);
								}
			}
		
		
		
		// add this function to the classbehaviour object
		classBehaviour.imageMap = new ImageMap;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.imageMap;

	// Allows a file upload element to recieve fake markup
		// define this class behaviour
		function FileBrowser(){
			// properties
			this.name 		= 	'fileBrowser';
			this.fileElement	=	null;
			this.textElement	=	null;
			this.buttonElement	=	null;
			// methods 
			this.start			=	function(node){
										allInputs = node.getElementsByTagName('input');
										// get the form elements
										this.fileElement = allInputs[0];
										this.textElement = allInputs[1];
										this.buttonElement = allInputs[2];
										// when the file is entered
										this.fileElement.onchange = this.transfer;
										this.fileElement.onmouseover = this.addHover;
										this.fileElement.onmouseout = this.remHover;
									}
			// events
			this.addHover		=	function(){
										fb = classBehaviour.fileBrowser;
										fb.buttonElement.onmouseover();
									}
			this.remHover		=	function(){
										fb = classBehaviour.fileBrowser;
										fb.buttonElement.onmouseout();
									}
			this.transfer		=	function(){
										fb = classBehaviour.fileBrowser;
										fb.textElement.value = fb.fileElement.value;
									}
		}
		// add this function to the classbehaviour object
		classBehaviour.fileBrowser = new FileBrowser;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.fileBrowser;

	// sizes an element according to a value
		// define this class behaviour
		function ChartValue(){
			// properties 
			this.name 			= 	'chartValue';
			// methods 
			this.start			=	function(node){
										widthValue = parseInt(classBehaviour.getClassParameter(node, 'value', '0'));
										widthValue -= 1;
										if(widthValue<1) widthValue = 1;
										node.style.width = (widthValue-1) + '%';
									}
		}
		// add this function to the classbehaviour object
		classBehaviour.chartValue = new ChartValue;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.chartValue;
		
	// Copies selected text to a target container
		// define this class behaviour
		function TextSelection(){
			// properties 
			this.name 			= 	'textSelection';
			// methods 
			this.start			=	function(node){
										node.onmouseup = this.process;
									}
			// events
			this.process		=	function(that){
										var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
										// get the target field
										var target = document.getElementById(classBehaviour.getClassParameter(objNode, 'id', 'selectedText'));
										// get the text selection
										var selected;
										if(window.getSelection){
											selected = window.getSelection();
										}else if(document.selection){
											selected = document.selection.createRange().text;
										}
										// copy the text to the target field
										if(target) target.value = selected;
										
									}
		}
		// add this function to the classbehaviour object
		classBehaviour.textSelection = new TextSelection;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.textSelection;

	// Shows elements based on the state of a related radio button or checkbox
		// define this class behaviour
		function DisplayIfChecked(){
			// properties
			this.name 		= 	'displayIfChecked';
			this.timeout	= 	null;
			// methods 
			this.start		=	function(node){
									node.onclick = this.delay;
									node.onchange = this.delay;
									this.delay(node);
								}
			// events
			this.delay  	=   function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var hsic = classBehaviour.displayIfChecked;
									// cancel the previous timeout
								//	clearTimeout(hsic.timeout);
									// wait a little while for MSIE
									hsic.timeout = setTimeout("classBehaviour.displayIfChecked.toggle('" + objNode.id + "')", 100);
								}
			this.toggle		= 	function(id){
									// source object
									var objNode = document.getElementById(id);
									// get all inputs
									var allInputs = document.getElementsByTagName('input');
									// for all inputs
									for(var a=0; a<allInputs.length; a++){
										// if this is a radio and it belong to the same named group
										if(allInputs[a].name==objNode.name){
											// get the target id
											targetId = classBehaviour.getClassParameter(allInputs[a], 'id', 'displayThisIdIfChecked');
											targetObj = document.getElementById(targetId);
											// hide the targetnode if checked
											if(targetObj){
												targetObj.style.display = (allInputs[a].checked) ? classBehaviour.getVisibleState(targetObj) : 'none' ;
											}
										}
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.displayIfChecked = new DisplayIfChecked;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.displayIfChecked;
		
	// Disable form elements during a submit, to avoid multiple submits on slow servers
		// define this class behaviour
		function DisableAfterSubmit(){
			// properties
			this.name 		= 	'disableAfterSubmit';
			// methods
			this.start		=	function(node){
									node.onsubmit = this.disable;
									// get all elements in this form
									allNodes = node.getElementsByTagName("*");
									// is this a form using microsoft's postbacks
									if(typeof(__doPostBack)!='undefined'){
										// for all nodes in this form
										for(var a=0; a<allNodes.length; a++){
											// if this form element has a _dopostback
											if(allNodes[a].onchange!=null){
												if(allNodes[a].onchange.toString().indexOf('__doPostBack')>-1){
													// overrule microsoft's postback event
													allNodes[a].onchange = this.disable;
												}
											}
											if(allNodes[a].onclick!=null){
												if(allNodes[a].onclick.toString().indexOf('__doPostBack')>-1){
													// overrule microsoft's postback event
													allNodes[a].onclick = this.disable;
												}
											}
										}
									}
									// if there's also a validation behaviour defined, trigger it
									if(node.className.indexOf('validateAllInput')>-1) classBehaviour.validateAllInput.start(node);
								}
			// events
			this.disable	=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// trigger microsoft's postback
									if(typeof(__doPostBack)!='undefined') __doPostBack(objNode.id, objNode.value);
									// get all elements in this form
									allNodes = document.getElementsByTagName("*");
									// for all nodes in this form
									for(var a=0; a<allNodes.length; a++){
										// if this is a form element
										if(
											allNodes[a].nodeName.indexOf('INPUT')>-1 ||
											allNodes[a].nodeName.indexOf('SELECT')>-1 ||
											allNodes[a].nodeName.indexOf('TEXTAREA')>-1
										){
											// disable the form element
											allNodes[a].disabled = false;
											// deny focus
											allNodes[a].onfocus = blur;
										}
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.disableAfterSubmit = new DisableAfterSubmit;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.disableAfterSubmit;

	// Stops events from cascading up in the document object model
		// define this class behaviour
		function NoBehaviour(){
			/* properties */
			this.name 		= 	'noBehaviour';
			this.start		=	function(node){
									/*event*/;
									node.onmousedown = classBehaviour.noBehaviour.cancelEvent;
									node.onmouseup = classBehaviour.noBehaviour.cancelEvent;
								}
			this.cancelEvent=	function(e) {
									(e) ? e.stopPropagation() : event.cancelBubble = true;
								}
		}
		classBehaviour.noBehaviour = new NoBehaviour;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.noBehaviour;
		
	// fade the element in
		// define this class behaviour
		function FadeElement(){
			/* properties */
			this.name 		= 	'fadeElement';
			/* methods */
			this.start		=	function(node){
									this.process(node);
								}
			this.set		=	function(id, amount){
									var node = document.getElementById(id);
									// set the fade value using the proper method
									if(typeof(node.style.MozOpacity)!='undefined')	node.style.MozOpacity = amount/100;
									if(typeof(node.style.filter)!='undefined')		node.style.filter = "alpha(opacity=" + amount + ")";
									if(typeof(node.style.opacity)!='undefined')		node.style.opacity = amount/100;
										/*
										filter:alpha(opacity=50);	imageobject.filters.alpha.opacity=opacity
										-moz-opacity: 0.5;			imageobject.style.MozOpacity=opacity/100
										opacity: 0.5;
										-khtml-opacity: 0.5;
										*/
								}
			this.get		=	function(id){
									var fadeValue = null;
									var node = document.getElementById(id);
									// get the fade value using the proper method
									if(typeof(node.style.MozOpacity)!='undefined')	fadeValue = Math.round(parseFloat(node.style.MozOpacity)*100);
									if(typeof(node.style.filter)!='undefined')		fadeValue = parseInt(node.filters.alpha.opacity);
									if(typeof(node.style.opacity)!='undefined')		fadeValue = Math.round(parseFloat(node.style.opacity)*100);
									// return the value
									return fadeValue;
								}
			/* events */
			this.process	=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// the node need an id
									if(objNode.id==''){
										objNode.id = 'fader' + Math.round(Math.random()*10000);
									}
									// fade parameters
									id		= objNode.id;
									wait	= parseInt(classBehaviour.getClassParameter(objNode, 'wait', '1024'));
									start	= parseInt(classBehaviour.getClassParameter(objNode, 'start', '0'));
									// start value
									this.set(objNode.id, start);
									// start the fade
									setTimeout("classBehaviour.fadeElement.loop('"+ id +"')", wait);
								}
			this.loop		=	function(id){
									var fe = classBehaviour.fadeElement;
									var objNode = document.getElementById(id);
									// fade parameters
									end			= parseInt(classBehaviour.getClassParameter(objNode, 'end', '100'));
									step		= parseInt(classBehaviour.getClassParameter(objNode, 'step', '10'));
									increment	= parseInt(classBehaviour.getClassParameter(objNode, 'increment', '5'));
									next		= fe.get(id) + increment;
									// set next fade status
									fe.set(id, next);
									// order a new step if needed
									if(next<end) setTimeout("classBehaviour.fadeElement.loop('" + id + "')", step);
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.fadeElement = new FadeElement;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.fadeElement;
		
	// Replaces all png's in the container with gif alternatives in Internet Explorer 6 and lower.
		// preload cosmetic tweak
		if(document.all && (navigator.userAgent.indexOf('MSIE 6.0')>-1 || navigator.userAgent.indexOf('MSIE 5')>-1) && navigator.userAgent.indexOf('Opera')<0)
				document.writeln("<style>.pngAlternative img {visibility:hidden;}</style>");
		// define this class behaviour
		function PngAlternative(){
			/* properties */
			this.name 		= 	'pngAlternative';
			this.lastNode	=	null;
			this.lastNext	=	null;
			/* methods */
			this.start		=	function(node){
									this.process();
								}
			/* events */
			this.process	=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// if this is a crappy browser
									if
									(
										document.all && 
										(navigator.userAgent.indexOf('MSIE 6.0')>-1 || navigator.userAgent.indexOf('MSIE 5')>-1) && 
										navigator.userAgent.indexOf('Opera')<0
									)
									{
										// get all image tags
										var allImages = document.getElementsByTagName('img');
										// for all images
										for(var a=0; a<allImages.length; a++){
											// replace it with it's gif alternative
											allImages[a].src = allImages[a].src.replace('.png', '.gif');
											allImages[a].style.visibility = 'visible';
										}
									}
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.pngAlternative = new PngAlternative;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.pngAlternative;

	// make a decorative popup from a longdesc
		// define this class behaviour
		function ShowLongDesc(){
			/* properties */
			this.name 		= 	'showLongDesc';
			/* methods */
			this.start		=	function(node){
									// apply the event handler to the link
									loadXmlDoc(node.getAttribute('longdesc') + '?rnd='+Math.round(Math.random()*10000), this.load, this.wait, false, node);
									node.onmouseover = this.show;
									node.onmouseout = this.hide;
								}
			/* events */
			this.over		=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var sld = classBehaviour.showLongDesc;
									// if this node doesn't have a display-node
									if(objNode.previousSibling.className != 'longDesc'){
										// make an AJAX call using the longdesc from the link
											loadXmlDoc(objNode.getAttribute('longdesc') + '?rnd='+Math.round(Math.random()*10000), sld.load, sld.wait, false, objNode);
									}else{
										// just show the link
										sld.show(objNode)
										// cancel click on the link
										return false;
									}
									return true;
               }
			this.wait		=	function(status, targetObject){
									/* debug(status, targetObject.nodeName); */
								}
			this.load		=	function(xmlReply, targetObject){
									var sld = classBehaviour.showLongDesc;
									var objNode = targetObject;
									// create a display-node right after the link-node
									var displayNode = document.createElement('span');
									// add the replied xml content to the new node
									displayNode.innerHTML = xmlReply.getElementsByTagName('body')[0].firstChild.nodeValue;
									// apply a markup class to the new node
									displayNode.className = 'longDesc';
									// give the original link a special markup
									objNode.className += ' longDesc';
									objNode.parentNode.insertBefore(displayNode, objNode);
								}
			this.show		=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// show the displaynode
									if(objNode.previousSibling.className=='longDesc') objNode.previousSibling.style.display = 'block';
								}
			this.hide		=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// hide the node
									if(objNode.previousSibling.className=='longDesc') objNode.previousSibling.style.display = 'none';
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.showLongDesc = new ShowLongDesc;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.showLongDesc;

	// Open an overlay as a popup window
		// define this class behaviour
		function OpenLayerPopUp(){
			/* properties */
			this.name 		= 	'openLayerPopUp';
			/* methods */
			this.start		=	function(node){
									// find the target layer
									targetPopUp = null;
									// process the node
									this.process(node);
									// the node's open button
									node.onclick = this.show;
								}
			this.fadeIn	=	function(id, amount){
									node = document.getElementById(id);
									nodes = node.getElementsByTagName('div');
									nodeShadow = nodes[0];
									nodeContent = nodes[1];
									// if the amount is not 50
									if(amount<50){
										// hide the popup content
										nodeContent.style.display = 'none';
										// set the shadow's fade to the next step
										nodeShadow.style.display = 'block';
										if(typeof(nodeShadow.style.MozOpacity)!='undefined')	nodeShadow.style.MozOpacity = amount/100;
										if(typeof(nodeShadow.style.filter)!='undefined')		nodeShadow.style.filter = "alpha(opacity=" + amount + ")";
										if(typeof(nodeShadow.style.opacity)!='undefined')		nodeShadow.style.opacity = amount/100;
										// show the popup collection
										node.style.display = 'block';
										// repeat the fade
										setTimeout("classBehaviour.openLayerPopUp.fadeIn('" + id + "'," + (amount+10) + ")",10);
									}else{
									// else
										// show the popup content
										nodeContent.style.display = 'block';
									}
								}
			this.fadeOut	=	function(id, amount){
									node = document.getElementById(id);
									nodes = node.getElementsByTagName('div');
									nodeShadow = nodes[0];
									nodeContent = nodes[1];
									// if the amount is not 100
									if(amount>0){
										// hide the popup content
										nodeContent.style.display = 'none';
										// set the fade to the next step
										if(typeof(nodeShadow.style.MozOpacity)!='undefined')	nodeShadow.style.MozOpacity = amount/100;
										if(typeof(nodeShadow.style.filter)!='undefined')		nodeShadow.style.filter = "alpha(opacity=" + amount + ")";
										if(typeof(nodeShadow.style.opacity)!='undefined')		nodeShadow.style.opacity = amount/100;
										// repeat the fade
										setTimeout("classBehaviour.openLayerPopUp.fadeOut('" + id + "'," + (amount-10) + ")",10);
									}else{
										// show the popup content
										node.style.display = 'none';
									}
								}
			/* events */
			this.process	=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// prepare the popup's layout
								}
			this.show		=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var olp = classBehaviour.openLayerPopUp;
									// get the popup from the href or the popup itsself
									popUp = (objNode.href) ? document.getElementById(objNode.href.split('#')[1]) : objNode ;
									// find the close gadget
									popUpCloser = popUp.getElementsByTagName('span')[0];
									popUpCloser.onclick = olp.hide;
									// find the shadow overlay of the popup
									popUpOverlay = popUp.getElementsByTagName('div')[0];
									// set the overlay size in internet explorer
										//popUpOverlay.style.width = document.body.offsetWidth + 'px';
									popUpOverlay.style.height = (document.body.scrollHeight) ? document.body.scrollHeight + 'px' : document.body.offsetHeight + 'px';
									// fade the popup in
									olp.fadeIn(popUp.id, 0);
										//popUp.style.display = 'block';
									// cancel the click
									return false;
								}
			this.hide		=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									var olp = classBehaviour.openLayerPopUp;
									// fade the popup out
									olp.fadeOut(objNode.parentNode.parentNode.parentNode.id, 50);
										//objNode.parentNode.parentNode.style.display = 'none';
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.openLayerPopUp = new OpenLayerPopUp;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.openLayerPopUp;
		
	// Defines something a layer popup and automaticaly opens it after a set time
		// define this class behaviour
		function LayerPopUp(){
			/* properties */
			this.name 		= 	'layerPopUp';
			/* methods */
			this.start		=	function(node){
									// get the required time delay
									delay = parseInt(classBehaviour.getClassParameter(node, 'autodeploy', '9999'));
									// if the delay is a rational one
									if(delay!=9999){
										// set a timeout for the popup
										setTimeout("classBehaviour.layerPopUp.showId('" + node.id + "')",delay);
									}
								}
			/* events */
			this.showId	=	function(id){
									classBehaviour.openLayerPopUp.show(document.getElementById(id));
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.layerPopUp = new LayerPopUp;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.layerPopUp;
		
/* TODO: document this */
	// Toggle nodes of a certain class
		// define this class behaviour
		function ToggleMarkedNodes(){
			/* properties */
			this.name 		= 	'toggleMarkedNodes';
			this.lastNode	=	null;
			this.lastNext	=	null;
			/* methods */
			this.start		=	function(node){
									node.onclick = this.process;
								}
			/* events */
			this.process	=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;

									// toggleMarkedNodes id_myNodeList openText_Open_the_list closeText_Close_the_list
									
									listId = classBehaviour.getClassParameter(objNode, 'id', 'myNodeList');
									openText = classBehaviour.getClassParameter(objNode, 'openText', 'Show more...').replace(/_/gi,' ');
									closeText = classBehaviour.getClassParameter(objNode, 'closeText', 'Show less...').replace(/_/gi,' ');
									
									// get all nodes from the list
									allNodes = document.getElementById(listId).childNodes;
									// for every node in the list
									for(var a=0; a<allNodes.length; a++){
										// is it marked for hiding, show it if hidden, hide it if visible
										if(allNodes[a].className) 
											if(allNodes[a].className.indexOf('markedNode')>-1) 
												allNodes[a].style.display = (allNodes[a].style.display!='none') ? 'none' : 'block' ;
									}
									// if the button is set to open, set is to close, else, set it to open
									if(objNode.nodeName=='A'){
										objNode.firstChild.nodeValue = (objNode.firstChild.nodeValue==openText) ? closeText : openText;
									}else if(objNode.nodeName=='INPUT'){
										objNode.value = (objNode.value==openText) ? closeText : openText;
									}
									
								}
		}
		// add this function to the classbehaviour object
		classBehaviour.toggleMarkedNodes = new ToggleMarkedNodes;
		classBehaviour.handlers[classBehaviour.handlers.length] = classBehaviour.toggleMarkedNodes;
/* /TODO */

	// start the parsing of classes
	classBehaviour.parseDocument();
