/*	name			: Class Behaviour - Main Parsing Functions	update			: 20080820	author			: Maurice van Creij	dependencies	: classbehaviour.js	info			: http://www.classbehaviours.com/

    This file is part of classBehaviour.
    
    classBehaviour is a javascript framework based on class-name parsing.
    Copyright (C) 2008  Maurice van Creij

    classBehaviour is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    classBehaviour is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with classBehaviour.  If not, see http://www.gnu.org/licenses/gpl.html.*/

	// Some markup to avoid graphical glitches	document.writeln(
		'<style type="text/css">.toggleNextNode { cursor : pointer; }</style>' + 
		'<style type="text/css">.hideThisNode { overflow : hidden; visibility : hidden; height : 1px; }</style>' + 		'<style type="text/css">.showThisNode { overflow : hidden; visibility : visible; height : auto; }</style>' + 		'<style type="text/css">.alternative { visibility : hidden; }</style>'
	);
	//safari hack search button
	if (navigator.userAgent.indexOf('Safari')>-1) document.writeln (
		'<style type="text/css">.player .playername .flashTitle {margin-top: 5px;}</style>'
	);
	// create the classBehaviour object if it doesn't already
	if(typeof(classBehaviour)=='undefined'){
		function ClassBehaviour(){
			this.handlers = new Array();
		}
		classBehaviour = new ClassBehaviour();
	}
	
		// Parser functions
		function Parser(node){
			// status of the parser
			this.waiting		=	false;
			// verify the state of the object
			this.start			=	function(){
										// if the document is complete enough start the behaviours, else wait until everything is loaded
										this.waiting = (classBehaviour.handlers.length>0 && document.body) ? this.parseDocument() : classBehaviour.utilities.addEvent(window, 'load', this.parseDocument) ;
									}
			// scan the whole document
			this.parseDocument	=	function(){
										classBehaviour.parser.parseNode(document)
										// return the status
										return false;
									}
			// scan the document object model for target classNames
			this.parseNode		=	function(node){
										// for all behaviours										for(var a=0; a<classBehaviour.handlers.length; a++){
											// get all the nodes with this behaviour's name
											behaviourNodes = classBehaviour.utilities.getElementsByClassName(classBehaviour.handlers[a].name, node);
											// and start their behaviour functions
											for(var b=0; b<behaviourNodes.length; b++) classBehaviour.handlers[a].start(behaviourNodes[b]);
										}
									}
		}
		// add this module to the classBehaviour object
		classBehaviour.parser = new Parser;
					// general purpose functions		function Utilities(){
			// returns all nodes of the same class
			this.getElementsByClassName = 	function(className, node){
												// use the whole body if no target was provided												target = (node!=null) ? node : document ;
												// make an empty array for the results
												var foundNodes = new Array();
												// for all elements in the parent node
												var allNodes = (target.all) ? target.all : target.getElementsByTagName("*");
												for(var a=0; a<allNodes.length; a++){
													// if the item has a className
													if(allNodes[a].className){
														// process the classname
														nodeClass = allNodes[a].className + ' ';
														// add it to the results if the classname was found
														if(nodeClass.indexOf(className+' ')>-1) foundNodes[foundNodes.length] = allNodes[a];
													}
												}
												// return the list
												return foundNodes;
											}
			// detaries the available room on the screen			this.screenHeight 		= 	function(){											return (window.innerHeight) ? window.innerHeight : (document.documentElement.clientHeight) ? document.documentElement.clientHeight : document.body.clientHeight ;										}			// 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 ;										}			// gets the value of a parameter from a className			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 ;										}			// sets the value of a parameter from a className			this.setClassParameter	=	function(targetNode, paramName, newValue){											oldValue = this.getClassParameter(targetNode, paramName, null);
											if(oldValue!=null) targetNode.className = targetNode.className.replace(paramName+'_'+oldValue, paramName+'_'+newValue);										}			// get the next node without worrying about text nodes			this.nextNode			=	function(node, count){
											testNode = node;
											if(count==null) count = 1;											// look for the next html node
											for(var a=0; a<count; a++){												do {													testNode = testNode.nextSibling;
													if(testNode==null) testNode = node;												}while(testNode.nodeName.indexOf('#text')>-1);
											}											// return it											return testNode;										}			// get the previous node without worrying about text nodes			this.previousNode		=	function(node, count){
											testNode = node;
											if(count==null) count = 1;											// look for the previous html node
											for(var a=0; a<count; a++){												do {													testNode = testNode.previousSibling;
													if(testNode==null) testNode = node;												}while(testNode.nodeName.indexOf('#text')>-1);
											}											// return it											return testNode;										}
			// get the first real child node without worrying about text nodes			this.firstNode			=	function(node, count){											return this.nextNode(node.firstChild, count);										}
			// find the parent node with the given classname
			this.rootNode			=	function(node, rootTag, rootId, rootClass){
											// try parent nodes until you find the one which meets the conditions
											rootFound = false;
											while(!rootFound && node.nodeName!='BODY'){
												rootFound = (rootTag && node.nodeName) ? (node.nodeName.indexOf(rootTag)>-1) : rootFound ;
												rootFound = (rootId && node.id) ? (node.id.indexOf(rootId)>-1) : rootFound ;
												rootFound = (rootClass && node.className) ? (node.className.indexOf(rootClass)>-1) : rootFound ;
												node = (!rootFound) ? node.parentNode : node;
											}
											// pass it back
											return node;
										}			// 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;										}
			// hide select form elements for graphic glitches in certain browsers
			this.hideSelects		=	function(node){
											if(
												navigator.userAgent.indexOf('MSIE 6')>-1 || 
												(navigator.userAgent.indexOf('Firefox/2')>-1 && navigator.userAgent.indexOf('Mac')>-1)
											){
												allSelects = (node) ? node.getElementsByTagName('SELECT') : document.getElementsByTagName('SELECT') ;
												for(var a=0; a<allSelects.length; a++){
													allSelects[a].style.visibility = 'hidden';
												}
											}
										}
			this.showSelects		=	function(node){
											if(
												navigator.userAgent.indexOf('MSIE 6')>-1 || 
												(navigator.userAgent.indexOf('Firefox/2')>-1 && navigator.userAgent.indexOf('Mac')>-1)
											){
												allSelects = (node) ? node.getElementsByTagName('SELECT') : document.getElementsByTagName('SELECT') ;
												for(var a=0; a<allSelects.length; a++){
													allSelects[a].style.visibility = 'visible';
												}
											}
										}
			// adds an event-handler the proper way
			this.addEvent			=	function(node, eventName, eventHandler){
											if(node.addEventListener) 	node.addEventListener(eventName, eventHandler, false)
											else if(node.attachEvent) 	node.attachEvent("on"+eventName, eventHandler)
											else 						node["on"+eventName] = eventHandler;
											return true;
										}		}
		// add this module to the classBehaviour object		classBehaviour.utilities = new Utilities;
		
		// decorative fader animations		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										if(idIn!=null && idIn!=""){											// unhide the new page											document.getElementById(idIn).style.display = 'block';											// set the fade amount											cf.setFade(document.getElementById(idIn), amount);										}										if(idOut!=null && idOut!="" && idOut!="null"){											// unhide the new page											document.getElementById(idOut).style.display = 'block';											// set the fade amount											cf.setFade(document.getElementById(idOut), 100-amount);										}										// 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										if(idIn && idIn!=""){
											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										if(idOut && idOut!="" && idOut!="null") document.getElementById(idOut).style.display = 'none';										// trigger the end event										cf.onEnd(evalEvent);									}								}
			this.grow		=	function(id, width, height, step, delay, evalEvent){
									var cf = classBehaviour.fader;
									// validate the new size
									if(!width) width = -1;
									if(!height) height = -1;
									// get the object
									resizeObject = document.getElementById(id);
									// get the object's size
									objectWidth = parseInt(resizeObject.offsetWidth);
									objectHeight = parseInt(resizeObject.offsetHeight);
									// compare the sizes
									tooNarrow = objectWidth<width;
									tooShort = objectHeight<height;
									// if the height isn't big enough
									if(tooNarrow || tooShort){
										// increase it one increment
										if(tooNarrow) resizeObject.style.width = (objectWidth + step) + 'px';
										if(tooShort) resizeObject.style.height = (objectHeight + step) + 'px';
										// repeat
										setTimeout("classBehaviour.fader.grow('"+id+"', "+width+", "+height+", "+step+", "+delay+", '"+evalEvent+"');", delay);
									// else
									}else{
										// trigger the end event
										cf.onEnd(evalEvent);
									}
								}
			this.shrink		=	function(id, width, height, step, delay, evalEvent){
									var cf = classBehaviour.fader;
									// validate the new size
									if(!width) width = 99999;
									if(!height) height = 99999;
									// get the object
									resizeObject = document.getElementById(id);
									// get the object's size
									objectWidth = parseInt(resizeObject.offsetWidth);
									objectHeight = parseInt(resizeObject.offsetHeight);
									// compare the sizes
									tooWide = objectWidth>width;
									tooTall = objectHeight>height;
									// if the height isn't big enough
									if(tooWide || tooTall){
										// increase it one increment
										if(tooWide) resizeObject.style.width = (objectWidth - step) + 'px';
										if(tooTall) resizeObject.style.height = (objectHeight - step) + 'px';
										// repeat
										setTimeout("classBehaviour.fader.shrink('"+id+"', "+width+", "+height+", "+step+", "+delay+", '"+evalEvent+"');", delay);
									// else
									}else{
										// trigger the end event
										cf.onEnd(evalEvent);
									}
								}
			this.reveal		=	function(id, width, height, step, delay, evalEvent){
									var cf = classBehaviour.fader;
									// get the current values and convert them into numbers
									panelStyle = document.getElementById(id).style.clip;
									panelClip = (panelStyle!='') ? panelStyle.replace('rect(', '').replace(')', '').replace(/,/gi, '').split(' ') : new Array(0,0,0,0) ;
									for(var a=0; a<4; a++) panelClip[a] = (panelClip[a]=='auto') ? 9999 : parseInt(panelClip[a]) ;
									// update the clip amount
									panelClip[0] = panelClip[0];
									panelClip[1] = (panelClip[1]<width) ? panelClip[1]+step : width ;
									panelClip[2] = (panelClip[2]<height) ? panelClip[2]+step : height ;
									panelClip[3] = panelClip[3];
									// update the clipping settings
									panelTop = panelClip[0] + 'px';
									panelRight = (width<0) ? 'auto' : panelClip[1] + 'px';
									panelBottom = (height<0) ? 'auto' : panelClip[2] + 'px';
									panelLeft = panelClip[0] + 'px';
									// if the end situation wasn't reached yet
									if(panelClip[1]<width || panelClip[2]<height){
										// set the new clipping
										document.getElementById(id).style.clip = 'rect('+panelTop+' '+panelRight+' '+panelBottom+' '+panelLeft+')';
										// order the next step
										setTimeout('classBehaviour.fader.reveal("'+id+'", '+width+', '+height+', '+delay+', '+step+')', delay);
									}else{
										// set the default clipping
										document.getElementById(id).style.clip = 'rect(auto auto auto auto)';
										// trigger the end event
										cf.onEnd(evalEvent);
									}
								}
			this.vanish		=	function(id, evalEvent){
									var cf = classBehaviour.fader;
									// update the clipping settings
									parentPanel = document.getElementById(id);
									parentPanel.style.clip = 'rect(0px 0px 0px 0px)';
									// trigger the end event
									cf.onEnd(evalEvent);
								}			// events			this.onEnd		=	function(evalEvent){									eval(evalEvent);								}		}
		// add this module to the classBehaviour object
		classBehaviour.fader = new Fader;
		
		// AJAX interface
		function Ajax(){
			// properties
			this.queue			=	new Array();
			// utilities
			this.getNodeValue	=	function(objNode){
										strValue = (objNode.childNodes.length>0) ? objNode.firstChild.nodeValue : null ;
										return (isNaN(strValue) || strValue==null) ? strValue : parseInt(strValue);
									}
			this.setNodeValue	=	function(objNode,strValue){
										if(objNode.childNodes.length>0){
											objNode.firstChild.nodeValue = strValue;
										}else{
											var objNewNode = ajax.createTextNode(strValue);
											objNode.appendChild(objNewNode);
										}
									}
			this.getChildNumber =	function(objNode){
										var objNodes = objNode.parentNode.childNodes;
										var intTextNodes = 0;
										for(var intA=0; intA<objNodes.length; intA++){
											if(objNodes[intA].nodeName == '#text') intTextNodes += 1;
											if(objNode==objNodes[intA]) return intA - intTextNodes;
										}
										return null;
									}
			this.serialize		=	function serialize(ajax){
										ser = new XMLSerializer();
										str = ser.serializeToString(ajax);
										return(str);
									}
			// methods
			this.addRequest	=	function(url, loadHandler, progressHandler, post, referingObject){
										// get the first free slot in the que
										index = this.queue.length;
										// add new request to the end of the que
										this.queue[index] = new HttpRequest();
										// set request constants
										this.queue[index].idx			=	index;
										this.queue[index].url			=	url;
										this.queue[index].post			=	post;
										this.queue[index].method		=	(post) ? 'POST' : 'GET' ;
										// request events
										this.queue[index].doOnLoad		=	loadHandler;
										this.queue[index].doOnProgress	=	progressHandler;
										this.queue[index].referObject	=	referingObject;
										// ask the queue handler to handle the next queued item
										this.handleQueue();
									}
			this.makeRequest	=	function(queued){
										// branch for native XMLHttpRequest object
										if(window.XMLHttpRequest){
											queued.request = new XMLHttpRequest();
											queued.request.onreadystatechange = this.progress;
											queued.request.open(queued.method, queued.url, true);
											queued.request.send(queued.post);
										// branch for IE/Windows ActiveX version
										}else if(window.ActiveXObject){
											queued.request = new ActiveXObject("Microsoft.XMLHTTP");
											queued.request.onreadystatechange = this.progress;
											queued.request.open(queued.method, queued.url, true);
											queued.request.send(queued.post);
										// if all else fails: load the document in an iFrame
										}else if(window.frames){
											// create an iframe to read the document in
	 										objIframe = document.createElement("IFRAME");
	 										objIframe.src = queued.url;
	 										objIframe.id = "feedimport0";
	 										objIframe.name = "feedimport0";
											objIframe.style = "visibility : invisible;position : absolute;left : -1600px; top : -1600px;";
												//objIframe.onload = ajax_load; // Doesn't work in Opera
											// append the iframe to the document
	 										document.body.appendChild(objIframe);
											// wait for the iframe to load
											this.wait();
										}
									}
			this.handleQueue	=	function(){
										queue = classBehaviour.ajax.queue;
										// if the first item in the queue is a completed request
										if(queue.length>0){
											if(queue[0].ready==4 /*&& ajax.queue[0].status==200*/){
												// remove the completed request
												queue.reverse();
												queue.length = queue.length - 1;
												queue.reverse();
											}
										}
										// if the first item in the queue isn't allready in progress
										if(queue.length>0){
											if(!(queue[0].ready<4 && queue[0].ready!=null)){
												this.makeRequest(queue[0]);
											}
										}
									}
			// events
			this.progress		=	function(){
										queued = classBehaviour.ajax.queue[0];
										// remember the readyState
										queued.ready = queued.request.readyState;
										// only if req shows "complete"
										if(queued.request.readyState == 4){
											// remember the status
											queued.status = queued.request.status;
											// only if "OK"
											if(queued.request.status == 200 || queued.request.status == 304){
												// update optional progress indicator code
												if(queued.doOnProgress) queued.doOnProgress(1, queued.referObject);
												// prepare the document
												queued.document = queued.request.responseXML;
												queued.text = queued.request.responseText;
												// trigger the load event
												if(queued.doOnLoad) queued.doOnLoad(queued.document, queued.referObject, queued.text);
												// request the next item in the queue to be handled
												classBehaviour.ajax.handleQueue();
											}else{
												// update optional progress indicator code
												if(queued.doOnProgress) queued.doOnProgress(-1, queued.referObject, queued.request.status);
											}
										}else{
											// update optional progress indicator code
											if(queued.doOnProgress) queued.doOnProgress(queued.request.readyState/4, queued.referObject, 200);
										}
										// return the status if desired
										return queued.request.readyState;
									}
			this.wait			=	function(){
										queued = classBehaviour.ajax.queue[0];
										// if the xml document has loaded in the iframe
										if(window.frames["feedimport0"]){
											// define the xml document object
											queued.document = window.frames["feedimport0"].document;
											queued.text = window.frames["feedimport0"].document.body.innerHTML;
											// what to do after the xml document loads
											queued.doOnLoad(queued.document, queued.referObject, queued.text);
										// else try again in a while
										}else{
											setTimeout("ajax.wait()",256);
										}
									}
		}
		
			// prototype http request object
			function HttpRequest(){
				// request constants
				this.idx			=	null;
				this.url			=	null;
				this.post			=	null;
				this.method			=	'GET';
				// request events
				this.doOnLoad		=	null;
				this.doOnProgress	=	null;
				this.referObject	=	null;
				// request properties
				this.request		=	null;
				this.document		=	null;
				this.text			=	null;
				this.ready			=	null;
				this.status			=	null;
			}
		// add this module to the classBehaviour object
		classBehaviour.ajax = new Ajax;
			
		// debug console
		function Console(){
			// porperties
			this.id 		= 	'debugConsole0';
			this.limit 		= 	32;	
			// methods
			this.debug 		= 	function(){
									// create the debug console if it doesn't exist yet
									debugConsole = document.getElementById(classBehaviour.console.id);
									if(debugConsole==null){
										// create a new console node
										newConsole = document.createElement('div');
										newConsole.id = classBehaviour.console.id;
										newText = document.createTextNode('-- newest at top --');
										newConsole.appendChild(newText);
										document.body.appendChild(newConsole);
										debugConsole = document.getElementById(classBehaviour.console.id);
									}
									// set the console's properties
									if(debugConsole.style.background=='') 	debugConsole.style.background = '#ffffff url(../images/button_active.png) no-repeat 0px 0px';
									if(debugConsole.style.border=='') 		debugConsole.style.border = 'solid 1px #000000';
									if(debugConsole.style.bottom=='') 		debugConsole.style.bottom = 'auto';
									if(debugConsole.style.height=='') 		debugConsole.style.height = (navigator.userAgent.indexOf('MSIE 6')>-1) ? '580px' : '98%' ;
									if(debugConsole.style.left=='') 		debugConsole.style.left = 'auto';
									if(debugConsole.style.overflow=='') 	debugConsole.style.overflow = 'auto';
									if(debugConsole.style.padding=='') 		debugConsole.style.padding = '1% 1% 1% 1%';
									if(debugConsole.style.position=='') 	debugConsole.style.position = (navigator.userAgent.indexOf('MSIE 6')>-1) ? 'absolute' : 'fixed' ;
									if(debugConsole.style.right=='') 		debugConsole.style.right = '-1px';
									if(debugConsole.style.top=='') 			debugConsole.style.top = '-1px';
									if(debugConsole.style.width=='') 		debugConsole.style.width = '128px';
									debugConsole.onclick = classBehaviour.console.move;
									classBehaviour.fader.setFade(debugConsole, 75);
									// send all the incoming arguments to the debug console
									newList = document.createElement('ul');
									for(var a=0; a<arguments.length; a++){
										// create a list item for each argument
										newListItem = document.createElement('li');
										newListText = document.createTextNode(arguments[a]);
										newListItem.appendChild(newListText);
										newList.appendChild(newListItem);
									}
									debugConsole.insertBefore(newList, debugConsole.firstChild);
									// if there are too many enties, remove a few
									allLists = debugConsole.getElementsByTagName('ul');
									if(allLists.length>classBehaviour.console.limit) 
										for(var a=allLists.length-1; a>classBehaviour.console.limit; a--)
											removedChild = debugConsole.removeChild(allLists[allLists.length-1]);
								}
			this.clear 		= 	function(){
									// clear the entries
									debugConsole = document.getElementById(classBehaviour.console.id);
									if(debugConsole!=null){
										allLists = debugConsole.getElementsByTagName('ul');
										for(var a=allLists.length-1; a>=0; a--)
											removedChild = debugConsole.removeChild(allLists[allLists.length-1]);
									}
								}
			this.html 		= 	function(string){
									string = '<xmp>' + string + '</xmp>'
									this.debug(string)
								}
			// events
			this.move		=	function(that){
									var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
									// get the console
									debugConsole = document.getElementById(classBehaviour.console.id);
									// toggle through several console positions
									if(debugConsole.style.right == '-1px' && debugConsole.style.width == '128px'){
										debugConsole.style.bottom = 'auto';
										debugConsole.style.height = (navigator.userAgent.indexOf('MSIE 6')>-1) ? '580px' : '98%' ;
										debugConsole.style.left = '-1px';
										debugConsole.style.right = 'auto';
										debugConsole.style.top = '-1px';
										debugConsole.style.width = '128px';
									}else if(debugConsole.style.left == '-1px' && debugConsole.style.width == '128px'){
										debugConsole.style.bottom = '-1px';
										debugConsole.style.height = '128px';
										debugConsole.style.left = '-1px';
										debugConsole.style.right = 'auto';
										debugConsole.style.top = 'auto';
										debugConsole.style.width = '98%';
									}else if(debugConsole.style.bottom == '-1px' && debugConsole.style.width == '98%'){
										debugConsole.style.bottom = 'auto';
										debugConsole.style.height = (navigator.userAgent.indexOf('MSIE 6')>-1) ? '580px' : '98%' ;
										debugConsole.style.left = 'auto';
										debugConsole.style.right = '-1px';
										debugConsole.style.top = '-1px';
										debugConsole.style.width = '128px';
									}
								}
		}
		// add this module to the classBehaviour object
		classBehaviour.console = new Console;
		
		// cookies Library
		function Cookies(){
			// methods
			this.getDaysFromNow	=	function(intDays){
										var dateCurrent = new Date();
										var intCurrent = Date.parse(dateCurrent);
										var intPeriod = intDays*24*60*60*1000;
										var datePeriodInFuture = new Date(intCurrent+intPeriod);
										return datePeriodInFuture;
									}
			this.setCookie		=	function(name, value, expires, path, domain, secure) {
										var curCookie = name + "=" + escape(value) +
											((expires) ? "; expires=" + expires.toGMTString() : "") +
											((path) ? "; path=" + path : "") +
											((domain) ? "; domain=" + domain : "") +
											((secure) ? "; secure" : "");
										document.cookie = curCookie;
									}
			this.getCookie		=	function(name) {
										var dc = document.cookie;
										var prefix = name + "=";
										var begin = dc.indexOf("; " + prefix);
										if (begin == -1) {
											begin = dc.indexOf(prefix);
											if (begin != 0) return null;
										}else{
											begin += 2;
										}
										var end = document.cookie.indexOf(";", begin);
										if (end == -1)
											end = dc.length;
										return unescape(dc.substring(begin + prefix.length, end));
									}
			this.deleteCookie	=	function(name, path, domain) {
										if (getCookie(name)) {
											document.cookie = name + "=" + 
											((path) ? "; path=" + path : "") +
											((domain) ? "; domain=" + domain : "") +
											"; expires=Thu, 01-Jan-70 00:00:01 GMT";
										}
									}
			this.fixDate		=	function(date) {
										var base = new Date(0);
										var skew = base.getTime();
										if (skew > 0)
											date.setTime(date.getTime() - skew);
									}
			this.makeBoolean	=	function(strIn){
										if(strIn=='true'){
											booOut = true;
										}else{
											booOut = false;
										}
										return booOut;
									}
			this.csv2array		=	function(csvIn){
										return csvIn.split(',');
									}
			this.array2csv		=	function(arrIn){
										return ''+arrIn;
									}
		}
		// add this module to the classBehaviour object
		classBehaviour.cookies = new Cookies;
		
	// short-cut wrapper functions
	debug = classBehaviour.console.debug;
		// start the parsing of classes
	classBehaviour.parser.start();
	

