// start info
if(typeof jsReport != 'undefined'){
	jsVersion = new Array(
	/*Name			=*/ 'Foldout Light',
	/*Version 		=*/ '0.94',
	/*Date 			=*/ 20030225,
	/*Author		=*/ 'Maurice van Creij',
	/*ProjectCode	=*/ 'l2_foldout_css',
	/*Summary		=*/ 'A simpler frameless foldout-menu, running exclusively on DOM compliant browsers.',
	/*Dependencies	=*/ new Array('foldout_css.js','foldout_css_0.css','browsercheck.js','easylayers.js','easystyles.js','content_ini.js','content_filter.js','stringfuncs.js'),
	/*Browsers		=*/ new Array('MO','IE'),
	/*Changes		=*/ new Array(
						'0.94: Added "arrIncludeRange" to exclude certain items from the menu. Made "arrLineHeight" recursive. Added global offset "intMenuOffsetX".',
						'0.93: Added the option "intShowRootStyle" to allow for permanently open/closed root menus.',
						'0.92: Added decorative icons and made the recursion indicators light-up. Extra redundancy check.',
						'0.91: With "strExternalOpen" a function can be set to trigger external menus.',
					  	'0.9: Basic functionality.'
					  	),
	/*Usage			=*/ new Array(
							'<link rel="StyleSheet" href="/~wmittensrd/resources/foldout_css.css" type="text/css">',
							'<script language="JavaScript" src="/~wmittensrd/resources/foldout_css.js" type="text/javascript"></script>',
							'',
							'Getter: setFoldId(intId); Setter: getFoldId();'
					  	)
	)
}else{
// end info


	// constants/configuration
		var booFormHandler = true;			// hide all 'select' form elements when menu is active
		var intShowRootStyle = -1;			// -1: open and close, 0: always closed, 1: always open				
		var fltMenuFade = 0.0;				// menu fading effect, in fraction of a second
		var fltItemFade = 0.0;				// item fading effect, in fraction of a second
		var booMarkParents = true;			// items with child-objects get a different style
		var intStyleMethod = 0;				// 0: same for all, 1: recursive levels, 2: use 'strType' from content_ini.js
		var intStyleRecursions = 1;			// recursion beyond this level will be extrapolated from the last one
		var booLiteBack = true;				// change the backgrounds of fold-out items
		var intBackField = 9;				// collumn in the DBarray[][] which contains the background names
		var booUseIcon = false;				// use decorative icons, named in the DBarray[][]
		var booLiteIcon = false;			// change the image when the item is activated	
		var intIconField = 5;				// collumn in the DBarray[][] which contains the icon names
		var booUseIndi = false;				// use recursion indicator icons
		var booLiteIndi = false;			// change the recursion indicator when the item is activated	
		var booFoldScrollLock = true;		// stop layers from scrolling with the content
		var booFoldOffScreenGuard = true;	// stop layers from going of the screen
		var intMenuOffsetX = 0;				// master correction offset for X
		var intMenuOffsetY = 0;				// master correction offset for Y
		var intMenuShiftXpos = 4;			// offset of sub-menus
		var intMenuShiftYpos = 4;			// offset of sub-menus
		var intMinWidth	= 0;				// minimal width of the menu
		var intMaxWidth = 1000;				// maximal width of the menu
		var booEstimateYpos = true;			// estimate vertical menu placement
		var arrLineHeight = new Array(16,16,16,16);	// values for lineheight per recursion
		var booEstimateXpos = true;			// estimate horizontal menu placement
		var intMinCharWidth = 2;			// estimated narrowest of the widest character
		var intMaxCharWidth = 10;			// estimated width of the widest character
		var intMenuOffsetWidth = 16;		// offset to estimated widths
		var booEstimateZpos = true;			// estimate depth of menu placement
		var intDepthOffset = 10;			// depth offset for recursive levels
		var intMenuOpenDelay = 0;			// ms delay before for changes to the menu get executed
		var intMenuCloseDelay = 512;		// ms delay before for changes to the menu get executed
		var intMenuRequest = 0;				// id for the timeout of the menu
		var arrPrevRoot = new Array();		// storage for the active items hierarcy
		var booExternalControl = true;		// execute code to control other menu's in sync
		var strExternalOpen = 'suggestFoldTabs(intActiveItem);setFoldBars(arrActiveRoot[2])';		// function-call to open the external menu (use arrActiveRoot and intActiveItem to pass information about active items)
		var strExternalClose = 'suggestFoldTabs(-1);setFoldBars(-1)';								// function-call to close the external menu
		var arrActiveRoot = new Array();	// global storage for the most recent active root
		var intActiveItem = 0;				// global storage for the most recent active item
		var strPixel = '/images/spacing.gif';	//one transparant pixel
		var arrIncludeRange = new Array(1,100);	// field 12 of the DBarray[][] will indicate, if the item is to be ignored
		var arrFoldLayers = new Array(		// extra information storage about the layers
							// new Array(intId,intParent,strName,intXpos,intYpos,intZpos,intWidth,intHeight,arrFoldButtons,arrDivStyles,arrTdStyles,arrAStyles,arrIcoStyles,arrIndicatorStyles,booFilled),
							);


	// primary functions - functionality
		// is a value within a range
		function isIncludeRange(intId){
			var intTerminate = DBarray[intId][12];
			return (intTerminate>=arrIncludeRange[0]&&intTerminate<=arrIncludeRange[1]);
		}
		
		
		// hide all 'select' form elements when menu is active
		function handleFormSelects(booShow){
			if(ie && booFormHandler){
				if(!booShow){strVis='hidden'}else{strVis='visible'}
				for(var intA=0; intA<document.forms.length; intA++){
					for(var intB=0; intB<document.forms[intA].elements.length; intB++){
						if(document.forms[intA].elements[intB].type.indexOf('select')>-1) document.forms[intA].elements[intB].style.visibility = strVis;
					}
				}
			}
		}

		// chooses a style based on the "type" property in the content_ini.js
		function setType(intId){
			if(!arrFoldLayers[intId][14]){
				// default value for styles
				var intStyleDf = 0;
				var intOffDf = 0;
				var intOnDf = 1;
				// basic value for styles
				var intStyleId = 0;
				var intOffId = 0;
				var intOnId = 1;
				// parent object exceptions
				if(booMarkParents && hasChild(intId)>0){
					intOffId = 2;
					intOnId = 3;
				}
				if(intId==0 && intShowRootStyle>=0){
					intOffDf = intShowRootStyle;
					intOnDf = intShowRootStyle;
				}
				// get the style with the given method
				if(intStyleMethod==0){
					// default
					intStyleId = 0;
				}else if(intStyleMethod==1){
					// pick the recursion
					intStyleId = TraceBranch(intId,true).length - 2;
					// validate it's maximum
					if(intStyleId>intStyleRecursions) intStyleId=intStyleRecursions;
				}else if(intStyleMethod==2){
					// from the content_ini.js
					intStyleId = DBarray[intId][intBackField];
				}
				// added data
				strIco =	DBarray[intId][intIconField];
				// set the names of the classes for any item
				arrFoldLayers[intId][9]  = new Array(	'fo' + intStyleDf + 'div0' + 'st' + intOffDf,			'fo' + intStyleDf + 'div0' + 'st' + intOnDf);
				arrFoldLayers[intId][10] = new Array(	'fo' + intStyleId + 'td0' + 'st' + intOffId,			'fo' + intStyleId + 'td0' + 'st' + intOnId);
				arrFoldLayers[intId][11] = new Array(	'fo0a0st0',												'fo0a0st0');
				arrFoldLayers[intId][12] = new Array(	'fo' + intStyleId + 'ico' + strIco + 'st' + intOffDf,	'fo' + intStyleId + 'ico' + strIco + 'st' + intOnDf);
				arrFoldLayers[intId][13] = new Array(	'fo' + intStyleId + 'ind0' + 'st' + intOffId,			'fo' + intStyleId + 'ind0' + 'st' + intOnId);
			}
		}
		
		// set all involved classes to a new state
		function setFoldClasses(intItemId,intStyle){
			// check the layer and change it's class
			if(validateFoldObject('fo0div0id'+intItemId))	setClassName('fo0div0id'+intItemId,arrFoldLayers[intItemId][9][intStyle],fltMenuFade);
			// check the cell and change it's class
			if(validateFoldObject('fo0td0id'+intItemId))	setClassName('fo0td0id'+intItemId,arrFoldLayers[intItemId][10][intStyle],fltItemFade);
			// check the icon and change it's class
			if(validateFoldObject('fo0ico0id'+intItemId))	setClassName('fo0ico0id'+intItemId,arrFoldLayers[intItemId][12][intStyle],fltMenuFade);
			// check the recursion indicator and change it's class
			if(validateFoldObject('fo0ind0id'+intItemId))	setClassName('fo0ind0id'+intItemId,arrFoldLayers[intItemId][13][intStyle],fltMenuFade);
		}
		
		// determine and store the position/dimensions of any given layer
		function getFoldPosition(intBlkId){
			// working variables
			var intParXpos,intParYpos,intParZpos,intParWidth,intParHeight,intParId;
			var intBlkXpos,intBlkYpos,intBlkZpos,intBlkWidth,intBlkHeight;
			// retrieve parent's data
				// get the parent's Id
				intParId = DBarray[intBlkId][1];
				// get the parent's position
				intParXpos = arrFoldLayers[intParId][3];
				intParYpos = arrFoldLayers[intParId][4];
				intParZpos = arrFoldLayers[intParId][5];
				// get the parent's width
				intParWidth = arrFoldLayers[intParId][6];
				// get the parent's height
				intParHeight = arrFoldLayers[intParId][7];
			// calculate new data
				// get the peers of the item
				arrPeers = peersOf(intBlkId);
				arrPeersIncluded = new Array();
				// remove excluded peers
				for(var intA=0; intA<arrPeers.length; intA++){
					if(isIncludeRange(arrPeers[intA])) arrPeersIncluded[arrPeersIncluded.length]=arrPeers[intA];
				}
				// get the recursion level of the item
				arrRecursion = TraceBranch(intBlkId,true);
				intRecursion = arrRecursion.length-1;
				// get the X-position (if defined -n)
				if(DBarray[intBlkId][6]==-1){
					// calculate the X offset using the position and width of the parent
					intBlkXpos = intParXpos + intParWidth + intMenuShiftXpos;
				}else{
					// or take the given one
					intBlkXpos = DBarray[intBlkId][6];
				}
				// get the Y-position (if defined -n)
				if(DBarray[intBlkId][7]==-1){
					// calculate the Y offset using the item number
					intBlkYpos = intParYpos + (isElementOfArray(intBlkId,arrPeersIncluded) * arrLineHeight[intRecursion]) + intMenuShiftYpos;
				}else{
					// or take the given one
					intBlkYpos = DBarray[intBlkId][7];
				}
				// calculate the z offset using the parent's and the recursion
				intBlkZpos = intParZpos + intDepthOffset;
				// calculate the width using the string lengths
				if(arrFoldLayers[intBlkId][6]<0){
					intBlkWidth = guessMenuWidth(intBlkId);
				}else{
					intBlkWidth = arrFoldLayers[intBlkId][6];
				}
				// calculate the height using the number of items
				if(arrFoldLayers[intBlkId][7]<0){
					intBlkHeight = arrPeersIncluded.length * arrLineHeight[intRecursion];
				}else{
					intBlkHeight = arrFoldLayers[intBlkId][7];
				}
			// store the item's position and width
				arrFoldLayers[intBlkId][3] = intBlkXpos;
				arrFoldLayers[intBlkId][4] = intBlkYpos;
				arrFoldLayers[intBlkId][5] = intBlkZpos;
				arrFoldLayers[intBlkId][6] = intBlkWidth;
				arrFoldLayers[intBlkId][7] = intBlkHeight;
			// give back working values for the dimension/position
			return new Array(intBlkXpos,intBlkYpos,intBlkZpos,intBlkWidth,intBlkHeight);
		}
		
		// check if an object exists
		function validateFoldObject(strName){
			// make the compare strings of compatible formats
			strValidOjects = ','+arrFoldLayers+',';
			strObject = ','+strName+',';
			// is the object in the list of available objects?
			if(strValidOjects.indexOf(strObject)<0){
				return false
			}else{
				return true
			}
		}
		
		// estimate the width of a menu
		function guessMenuWidth(intParentId){
			var intMaxLength = 0;
			// fetch the parent's titles
			arrTitles = FilterContent(1,intParentId,10);
			// find the longest string in the parent's menu
			for(var intB=0; intB<arrTitles.length; intB++){
				intFoundLength = guessStringLength(arrTitles[intB],intMinCharWidth,intMaxCharWidth);
				if(intFoundLength>intMaxLength) intMaxLength = intFoundLength;
			}
			// add the correction offset
			intMaxLength += intMenuOffsetWidth;
			// validate the length
			if(intMaxLength<intMinWidth) intMaxLength = intMinWidth;
			if(intMaxLength>intMaxWidth) intMaxLength = intMaxWidth;
			// return it's length
			return intMaxLength;
		}


	// secondary function - construction
		// return a complete foldout menu and register it in 'arrFoldLayers'
		function getFold(intId){
			var strMenu = '';
			// collect it's contents
			arrIndex = childrenOf(intId);
			// header
			strMenu += '<table border="0" cellpadding="0" cellspacing="0" id="fo0tb0id' + intId + '" class="fo0tbl0">\n';
			// for every item in the collection write a button
			for(var intA=0; intA<arrIndex.length; intA++){
				// data
				intIndex =		arrIndex[intA];
				strTitle =		DBarray[intIndex][10];
				strUrl =		DBarray[intIndex][3];
				strParent =		DBarray[intIndex][4];
				// exclude unwanted items
				if(isIncludeRange(intIndex)){
					// display styles
					setType(intIndex);
					strTdClass =	arrFoldLayers[intIndex][10][0];
					strAClass =		arrFoldLayers[intIndex][11][0];
					strIcoClass =	arrFoldLayers[intIndex][12][0];
					strIndClass =	arrFoldLayers[intIndex][13][0];
					// browser work-arounds
					strMSIE4workaround = (ie && v4) ? '&nbsp;&nbsp;&nbsp;' : '' ;
					// events
					strEvents = 'onmouseover="suggestFold(' + intIndex + ',true)" onmouseout="suggestFold(' + intIndex + ',false)"';
					// construction
						// prefix
						strMenu += ''	
							+ '<tr>'
								+ '<td id="fo0td0id' + intIndex + '" class="' + strTdClass + '" ' + strEvents + ' nowrap>';
						// filling
						strMenu += booUseIcon ? '<img border="0" alt="" src="' + strPixel + '" class="' + strIcoClass + '" id="fo0ico0id' + intIndex + '" hspace="0" vspace="0" align="left">' : '';
						strMenu += booUseIndi ? '<img border="0" alt="" src="' + strPixel + '" class="' + strIndClass + '" id="fo0ind0id' + intIndex + '" hspace="0" vspace="0" align="right">' : '';
						strMenu += '&nbsp;&nbsp;<a href="' + strUrl + '" parent="' + strParent + '" id="fo0a0id' + intIndex + '" class="' + strAClass + '">' + strTitle + strMSIE4workaround + '</a>&nbsp;&nbsp;';
						// suffix
						strMenu += ''
								+ '</td>'
							+ '</tr>\n';
					// administration - mark this menu as 'written and ready for use'
					if(booLiteBack)	arrFoldLayers[intId][8][arrFoldLayers[intId][8].length] = 'fo0td0id' + intIndex;
					if(booLiteIcon)	arrFoldLayers[intId][8][arrFoldLayers[intId][8].length] = 'fo0ico0id' + intIndex;
					if(booLiteIndi)	arrFoldLayers[intId][8][arrFoldLayers[intId][8].length] = 'fo0ind0id' + intIndex;
				}
			}
			
			// footer
			strMenu += '</table>\n'
			// update it's stored properties
			setType(intId);
			arrFoldLayers[intId][14] = true;
			// give the completed menu back
			return strMenu;
		}
		
		// prepare all foldout element's layers
		function makeFolds(){
			var strLayers = '';
			// for everything in the content_ini.js
			for(var intA=0; intA<DBarray.length; intA++){
				// data
				intId		= DBarray[intA][0];
				intParent	= DBarray[intA][1];
				intXpos		= DBarray[intA][6];
				intYpos		= DBarray[intA][7];
				// initial state of the menu
				strDivId		= 'fo0div0id'+intId;
				strDivClass		= 'fo0div0st0';
				strDivContent	= '';
				// construct the layer
				strMSIE4workaround = (ie && v4) ? 'style="position:absolute;"' : '' ;
				strLayers += '<div id="' + strDivId + '" ' + strDivClass + ' ' + strMSIE4workaround + '>' + strDivContent + '</div>\n';
				// update it's stored properties //new Array(intId,intParent,strName,intXpos,intYpos,intZpos,intWidth,intHeight,arrFoldButtons,arrDivStyles,arrTdStyles,arrAStyles,booFilled)
				arrFoldLayers[intA] =	new Array(intId,intParent,strDivId,intXpos,intYpos,10,-1,-1,new Array(),new Array(),new Array(),new Array(),false);
				// styles can be picked here, but it might slow down the start-up too much
					//setType(intId);
			}
			// write to the canvas
			document.writeln(strLayers);
		}


	// ternary function - operation 
		// return the current active item
		function getFoldId(intId){
			return arrPrevRoot[arrPrevRoot.length-1];
		}
	
		// set the styles of the layers to reflect the active menu item
		function setFoldId(intId,booState){
			// hide all 'select' form elements when menu is active
			if(booFormHandler) handleFormSelects(!booState);
			
			// determine the recursion path of the requested Id
			arrNewRoot = (booState) ? TraceBranch(intId,true) : new Array();
			
			// call any external menu if needed
			if(booExternalControl){
				intActiveItem = intId;
				arrActiveRoot = arrNewRoot;
				if(booState){
					smartEval(strExternalOpen);
				}else{
					smartEval(strExternalClose);
				}
			}
			
			// for every step in the previous recursion
			for(var intA=0; intA<arrPrevRoot.length; intA++){
				// Id of the previous item
				intPrevId = arrPrevRoot[intA];
				// if there is a change at this recusion
				if(arrPrevRoot[intA]!=arrNewRoot[intA]){
					// change the involved classes
					setFoldClasses(intPrevId,0);
				}
			}

			// for every step in the new recursion
			for(var intA=0; intA<arrNewRoot.length; intA++){
				// Id of the new item
				intNewId = arrNewRoot[intA];
				// if there is a change at this recusion
				if(arrPrevRoot[intA]!=arrNewRoot[intA]){
					// convert the boolean for on or off to style 1 or 0
					intOnOrOff = booState ? 1 : 0;
					// check the layer and change it's class
					if(validateFoldObject('fo0div0id'+intNewId)){
						// position
						arrPositions = getFoldPosition(intNewId);
						setPosition('fo0div0id'+intNewId,arrPositions[0],arrPositions[1],arrPositions[2],arrPositions[3],arrPositions[4],booFoldScrollLock,booFoldOffScreenGuard);
						// content
						if(!arrFoldLayers[intNewId][14]) setContent('fo0div0id'+intNewId,getFold(intNewId));
					}
					// change the involved classes
					setFoldClasses(intNewId,intOnOrOff);
				}
			}
			// store the current state
			arrPrevRoot = arrNewRoot;
		}
		
		// delay closing the menu until there's no cancelations
		function suggestFold(intId,booState){
			// whipe the previous request
			clearTimeout(intMenuRequest);
			// which delay to use
			if(booState){intMenuDelay=intMenuOpenDelay;}else{intMenuDelay=intMenuCloseDelay;}
			// set a new request
			intMenuRequest = setTimeout("setFoldId(" + intId + "," + booState + ")",intMenuDelay);
		}

		// startup events
		function startupFold(){
			if(intShowRootStyle==1){
				setFoldId(0,true);
			}
		}


	// executed inline
		// apply the master offset
		DBarray[0][6] += intMenuOffsetX;
		DBarray[0][7] += intMenuOffsetY;
		// write the layers
		makeFolds();
		// start the menu
		if(dom){startupFold();}else{onload = startupFold;}

}
