/*
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
*/

	// 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++){
				// get the classname
				nodeClass = allNodes[a].className;
				// if there was a classname
				if(nodeClass!='') {
					// 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;
	
	// 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;
		
	// 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;
		
	// 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;
	
	// 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;
		
	// 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;
		
	// start the parsing of classes
	classBehaviour.parseDocument();




	
	function showDescription(id, name) {
		hideAll();
		
		var change = false;	// true > foto's gaan in elkaar over; false > elke foto begint apart vanaf de "blur" versie
		
		var logo = document.getElementById('logo');
		var div = document.getElementById('leftColumn');
		var laag = document.getElementById('templaag');
		if ( laag  &&  !change )
			var old = div.removeChild(laag);
		laag = document.createElement('div');
		laag.id = 'templaag';
		laag.style.background = "url(images/back_coach_" + name + "_hover.jpg) no-repeat top right";
		laag.style.position = 'absolute';
		laag.style.top = '0';
		laag.style.left = '0';
		laag.style.width = '595px';
		laag.style.height = '600px';
		laag.style.opacity = '0';
		laag.style.filter = 'alpha(opacity=0)';
		
		div.style.background = "url(images/back_coach_" + name + "_blur.jpg) no-repeat top right";
		div.insertBefore(laag, logo);
		
		var textDiv = document.getElementById('descText' + id);
		textDiv.style.background = "url(images/coaches_" + name + "_name.gif) no-repeat top left";
		textDiv.style.display = "block";
		
		divOp = 0;
		fadeOver( laag );
	}

	function hideAll() {
		var i = 1;
		var desc = document.getElementById('descText' + i++);
		while (desc != null) {
			desc.style.display = "none";
			desc = document.getElementById('descText' + i++);
		}
	}
	
	function showBackground(tipo) {
		var div = document.getElementById('leftColumn');
		var bgAnterior = div.style.background;

		if ((tipo == 'hover') && (bgAnterior != '')) {
			div.style.background = bgAnterior.replace('_blur','_hover');
		} else if (bgAnterior != ''){
			div.style.background = bgAnterior.replace('_hover','_blur');
		}

	}
function fadeOver( div )
{
	clearInterval( intv );
	intv = setInterval(
		function()
		{
			if( divOp < 1 )
			{
				divOp += 0.02;
				div.style.opacity = "" + divOp;
				div.style.filter = 'alpha(opacity='+ divOp*100 +')';
			}
			else
			{
				clearInterval(intv);
			}
		}, 
		50
	);
}
var intv = null, divOp;
