/*
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
	// 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 ;
										}
			// 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;
										}
			// (cross)fader and pseudo event handler
			this.fader				=	new Fader;
			// get the previous node without worrying about text nodes
			this.nextNode			=	function(node){
											// look for the next html node
											do {
												node = node.nextSibling;
											} while(node.nodeName.indexOf('#text')>-1);
											// return it
											return node;
										}
			// get the next node without worrying about text nodes
			this.previousNode		=	function(node){
											// look for the previous html node
											do {
												node = node.previousSibling;
											} while(node.nodeName.indexOf('#text')>-1);
											// return it
											return node;
										}
			// 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]);
													}
												}
											}
										}
	}
	// create the main class-behaviour object
	var classBehaviour = new ClassBehaviour;
	
	// UTILITIES
		function Fader(){
			/* properties */
			/* methods */
			this.getFade	=	function(node){
									var fadeValue = null;
									// 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;
								}
			this.setFade	=	function(node, amount){
									// 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.fadeIn		=	function(idIn, step, delay, evalEvent){
									var cf = classBehaviour.fader;
									// get the fading object
									node = document.getElementById(idIn);
									// get the current fade
									fade = cf.getFade(node) + step;
									// if not 100%
									if((fade)<100){
										// set the new fade
										cf.setFade(node, fade);
										// next step
										cf.timeOut = setTimeout("classBehaviour.fader.fadeIn('"+idIn+"',"+step+","+delay+",'"+evalEvent+"')", delay);
									// else
									}else{
										// set the fade to 100%
										cf.setFade(node, 100);
										// trigger the end event
										eval(evalEvent);
									}
								}
			this.fadeOut	=	function(idOut, step, delay, evalEvent){
									var cf = classBehaviour.fader;
									// get the fading object
									node = document.getElementById(idOut);
									// get the current fade
									fade = cf.getFade(node) - step;
									// if not 100%
									if(fade>0){
										// set the new fade
										cf.setFade(node, fade);
										// next step
										cf.timeOut = setTimeout("classBehaviour.fader.fadeOut('"+idOut+"',"+step+","+delay+",'"+evalEvent+"')", delay);
									// else
									}else{
										// set the fade to 100%
										cf.setFade(node, 0);
										// trigger the end event
										eval(evalEvent);
									}
								}
			this.crossFade	=	function(idIn, idOut, amount, step, delay, evalEvent){
									var cf = classBehaviour.fader;
									// if the amount is not the end value yet
									if(amount<=100){
										// set the fade amounts
										cf.setFade(document.getElementById(idIn), amount);
										cf.setFade(document.getElementById(idOut), 100-amount);
										// unhide the new page
										document.getElementById(idIn).style.display = 'block';
										// construct the fade function
										var evalLoop = "classBehaviour.fader.crossFade('"+idIn+"', '"+idOut+"', "+(amount+step)+", "+step+", "+delay+", '"+evalEvent+"')";
										// repeat the fade
										setTimeout(evalLoop, delay);
									}else{
									// else
										// cancel the opacity style
										var node = document.getElementById(idIn);
										if(typeof(node.style.MozOpacity)!='undefined')	node.style.MozOpacity = 'auto';
										if(typeof(node.style.filter)!='undefined')		node.style.filter = 'none';
										if(typeof(node.style.opacity)!='undefined')		node.style.opacity = 'auto';
										// hide the old page
										document.getElementById(idOut).style.display = 'none';
										// trigger the end event
										cf.onEnd(evalEvent);
									}
								}
			/* events */
			this.onEnd		=	function(evalEvent){
									eval(evalEvent);
								}
		}

	// BEHAVIOURS
	// 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 ;
										// if this is not the image, it must be the parent
										if(!objNode.src) objNode = objNode.getElementsByTagName('IMG')[0];
										// 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 ;
									// if this is not the image, it must be the parent
									if(objNode.nodeName!='IMG') objNode = objNode.getElementsByTagName('IMG')[0];
									// 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 ;
									// if this is not the image, it must be the parent
									if(!objNode.src) objNode = objNode.getElementsByTagName('IMG')[0];
									// replace link by hover
									objNode.src = objNode.src.replace('_link','_hover');
								}
			this.remHover 	= 	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// if this is not the image, it must be the parent
									if(!objNode.src) objNode = objNode.getElementsByTagName('IMG')[0];
									// 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;
	
	// 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('a')[0];
									popUpCloser.onclick = olp.hide;
									// find the shadow overlay of the popup
									popUpOverlay = popUp.getElementsByTagName('div')[0];
									// remove the scroll bars
									if(navigator.appVersion.indexOf('MSIE 6')>-1 || navigator.appVersion.indexOf('MSIE 5')>-1){
										document.body.parentNode.style.overflow = "hidden";
										//allSelects = document.getElementById('content').getElementsByTagName('select');
										//for(var a=0; a<allSelects.length; a++) allSelects[a].style.visibility = 'hidden';
									}
									// fade the popup in
										//olp.fadeIn(popUp.id, 0);
										popUp.getElementsByTagName('div')[2].style.marginTop = Math.round((document.body.offsetHeight - 408) / 2) + 'px';
										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.parentNode.parentNode.style.display = 'none';
									// restore the scroll bars
									if(navigator.appVersion.indexOf('MSIE 6')>-1 || navigator.appVersion.indexOf('MSIE 5')>-1){
										document.body.parentNode.style.overflow = "visible";
										//allSelects = document.getElementById('content').getElementsByTagName('select');
										//for(var a=0; a<allSelects.length; a++) allSelects[a].style.visibility = 'visible';
									}
								}
		}
		// 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);
										classBehaviour.layerPopUp.showId(node.id);
									}
								}
			/* 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;
		
	// STARTUP-SEQUENCE
	// start the parsing of classes
	classBehaviour.parseDocument();
	
	
/* link with flash movie */
	function showPopUp(){
		classBehaviour.layerPopUp.showId('popup0');
	}