/*
**	This script is (c) 2004 Christian Chown (http://www.christianchown.com)
**
**	It may be used freely for non-commercial purposes providing this header is left intact
**
**	It may be used for commercial purposes by express permission of the author only.
**
*/

/*
**	To start with certain items open, place the following in the <body> tag:
**
**	<body onload="javascript:startopen('HEADING_ID')">
**
**	and replace HEADING_ID with the <div> id of the heading item you want open. 
**
**	To start with submenus open, open all of its parents:
**
**	<body onload="javascript:startopen('HEADING_ID'),startopen('SUB_HEADING_ID'),startopen('SUB_SUB_HEADING_ID')">
**
*/

	menus=new Array();
	log=new Array();
	logpos=0;

	function setstatus(text)
	{
		window.status=text;
	}

	function addlog(i)
	{
//		return;
		log[logpos] = i;
		logpos++;
	}

	function clearlog()
	{
		log.length = 0;
		logpos = 0;
	}

	function reportlog()
	{
		var r='';
		for (i=0; i < logpos; i++)
		{
			if (i >= 0)
			{
				r=r + i + ':' + log[i] + '\n<br />';
			}
		}
		windowhandle=document.open('MenuReport', 'report', '');
		if (windowhandle != null)
		{
			windowhandle.document.open();
			windowhandle.document.write('Report->\n<br />');
			windowhandle.document.write(r);
			windowhandle.document.close();
		}
		else
		{
			alert(r);
		}
	}

	function getprintable(a)
	{
		if (!(typeof a == 'object'))
			return a;

		var printable='';
		for (var i in a)
		{
			if ((a[i] != null) &&
				(a[i] != '')
			   )
			{
				printable=printable + i + '=' + a[i] + '\n';
			}
		}
		return printable;
	}

	function echo(a)
	{
		alert(getprintable(a));
	}

	function doreport(m, i)
	{
		echo(menus[m]['items'][i]);
	}

	function adjustz(m, i, a)
	{
		z = parseInt(menus[m]['items'][i]['item'].style.zIndex);
		z += a;
//		menus[m]['items'][i]['item'].style.zIndex = z;
	}

	function get_height(a)
	{
		a += '';
		var last = a.lastIndexOf('px');
		if (last==-1)
		{
			return parseInt(a);
		}
		return parseInt(a.substring(0, last));
	}

	function get_heightpx(value)
	{
		return get_height(value) + 'px';
	}

	function add_height(a, b)
	{
		return get_heightpx( get_height(a) + get_height(b) );
	}

	function get_rootheading(m, index, depth)
	{
		while ((index > 0) &&
			   ((menus[m]['items'][index]['depth'] > depth) ||
			   	(menus[m]['items'][index]['type']!='heading')
			   )
			  )
		{
			index--;
		}

		return index;
	}

	function needtoslide(m, subindex, index)
	{
		if (subindex <= index)
		{
			return false;
		}

		if (menus[m]['items'][subindex]['depth']==0)
		{
			return true;
		}

		if (menus[m]['items'][subindex]['type']!='heading')
		{
			var rootindex=get_rootheading(m, index, menus[m]['items'][index]['depth']-1);
			var rootsub=get_rootheading(m, subindex, menus[m]['items'][rootindex]['depth']);
			if (rootindex == rootsub)
			{
				return (menus[m]['items'][subindex]['depth'] <= menus[m]['items'][index]['depth']);
			}
			else
			{
				return (menus[m]['items'][subindex]['depth'] <= 1);
			}
		}
		return false;
	}

	function removehighlightname(anitem)
	{
		var name = anitem+'';
		if (name.length > 5)
		{
			var hitype = name.substring(name.length-5, name.length);
			if ( (hitype=='hilit') || (hitype=='oplit') )
			{
				return name.substring(0, name.length-5);
			}
		}
		return anitem;
	}

	function swapiconimage(foldid, newimagesrc)
	{
		var element = document.getElementById(foldid+'icon');
		if (element != null)
		{
			element.src=newimagesrc;
		}
	}

	function removehighlight(m, i)
	{
		if (menus[m]['items'][i]['highlight']!='')
		{
			var anitem=menus[m]['items'][i]['item'];
			anitem.className=removehighlightname(anitem.className);
			if (menus[m]['items'][i]['hasicon'])
			{
				var iconnew = menus[m]['items'][i]['icon'];
				var iconold = menus[m]['items'][i]['icon'+menus[m]['items'][i]['highlight']];
				if ((iconnew != '') && (iconnew != iconold))
				{
					swapiconimage(anitem.id, iconnew);
				}
			}
			menus[m]['items'][i]['highlight']='';
		}
	}

	function sethighlight(m, i, hitype)
	{
		if (menus[m]['items'][i]['highlight']!=hitype)
		{
			var anitem=menus[m]['items'][i]['item'];
			if ( (hitype == 'oplit') || (menus[m]['items'][i]['highlight'] != 'oplit') )
			{
				removehighlight(m, i);
				var name = anitem.className+'';
				anitem.className = anitem.className+hitype;
				if (menus[m]['items'][i]['hasicon'])
				{
					var iconold = menus[m]['items'][i]['icon'+menus[m]['items'][i]['highlight']];
					var iconnew = menus[m]['items'][i]['icon'+hitype];
					if ((iconnew != '') && (iconnew != iconold))
					{
						swapiconimage(anitem.id, iconnew);
					}
				}
				menus[m]['items'][i]['highlight']=hitype;
			}
		}
	}

	function setvisibilityup(m, i)
	{
		var currenttopy = get_height(menus[m]['items'][i]['item'].style.top);
		var thisheight = get_height(menus[m]['items'][i]['visible_height']);
		var currentbottomy = thisheight + currenttopy;
		var visibley = get_height(menus[m]['items'][i]['visible_at']);

			addlog('check visibility('+m+', '+i+') bot='+currentbottomy+' top='+currenttopy+' vis='+visibley);

		if (currentbottomy < visibley)
		{
			addlog('setvisibilityup('+m+', '+i+')');
			if (menus[m]['items'][i]['item'].style.display == '')
				menus[m]['items'][i]['item'].style.display = 'none';
		}
		else
		{
			var starty = visibley - currenttopy;
			if (starty < 0)
			{
				starty = 0;
			}
			var clipstring = 'rect('+starty+', '+menus[m]['items'][i]['width']+', '+(starty+thisheight)+', 0)';
//			menus[m]['items'][i]['item'].style.clip = clipstring;
		}
	}

	function setvisibilitydown(m, i)
	{
		var currenttopy = get_height(menus[m]['items'][i]['item'].style.top);
		var thisheight = get_height(menus[m]['items'][i]['visible_height']);
		var currentbottomy = thisheight + currenttopy;
		var visibley = get_height(menus[m]['items'][i]['visible_at']);

			addlog('check visibility('+m+', '+i+') bot='+currentbottomy+' top='+currenttopy+' vis='+visibley);

		if (currentbottomy >= visibley)
		{
			addlog('setvisibilitydown('+m+', '+i+')');
			if (menus[m]['items'][i]['item'].style.display == 'none')
				menus[m]['items'][i]['item'].style.display = '';

			var starty = visibley - currenttopy;
			if (starty < 0)
			{
				starty = 0;
			}
			var clipstring = 'rect('+starty+', '+menus[m]['items'][i]['width']+', '+(starty+thisheight)+', 0)';
//			menus[m]['items'][i]['item'].style.clip = clipstring;
		}
	}

	function unfurl(m, index)
	{
		addlog('unfurl ('+m+', '+index+')');

		menus[m]['unfurling'] = index;

		var instantly = menus[m]['items'][index]['instantly'];
		sethighlight(m, index, 'oplit');

		var depth = menus[m]['items'][index]['depth'];
		var subindex = index+1;

		if (menus[m]['items'][index]['depth'] > 0)
		{
			adjustz(m, index-1, (menus[m]['depthadjust'] * (menus[m]['items'][index-1]['depth']+1)));
		}
		adjustz(m, index, (menus[m]['depthadjust'] * (menus[m]['items'][index]['depth']+1)));

		var itemsvisibleat = get_height(menus[m]['items'][index]['top']);
		if (menus[m]['submenusunder'] || (menus[m]['horizontal'] && (menus[m]['items'][index]['depth']==0)))
		{
			itemsvisibleat = add_height(itemsvisibleat, menus[m]['items'][index]['height']);
		}

		menus[m]['nosliding']=0;
		var blockheight = 0;
		var suby = -1;
		while ( (subindex < menus[m]['items'].length) &&
				(menus[m]['items'][subindex]['depth'] > depth)
			  )
		{
			if (menus[m]['items'][subindex]['depth'] == (depth+1))
			{
//				if (menus[m]['items'][subindex]['type'] == 'fold')
				{
					var thisheight = get_height(menus[m]['items'][subindex]['height']);
					if (suby == -1)
					{
						// first child
						suby = get_heightpx( menus[m]['items'][subindex]['top'] );
					}
					else
					{
						// later children
						suby = add_height(suby, thisheight);
					}
					addlog('activate '+subindex);
					menus[m]['items'][subindex]['desiredtop'] = suby;
					menus[m]['items'][subindex]['movetime']=0;
					menus[m]['items'][subindex]['active']=true;
					menus[m]['items'][subindex]['visible_at']=itemsvisibleat;
					menus[m]['items'][subindex]['visible_height']=thisheight;
					menus[m]['items'][subindex]['sectionheight']=0;
					menus[m]['items'][subindex]['instantly']=instantly;
					blockheight = add_height(blockheight, thisheight);
					menus[m]['nosliding']++;
				}
			}
			else
			{
				// subsub chuld - skip it
			}
			subindex++;
		}
		if (suby == -1)
			return;	// no folds

		// set initial scroll positions
		subindex = index+1;
		while ( (subindex < menus[m]['items'].length) &&
				(menus[m]['items'][subindex]['depth'] > depth)
			  )
		{
			if (menus[m]['items'][subindex]['depth'] == (depth+1))
			{
//				if (menus[m]['items'][subindex]['type'] == 'fold')
				{
					menus[m]['items'][subindex]['top'] = add_height(menus[m]['items'][subindex]['top'], -get_height(blockheight));
					menus[m]['items'][subindex]['item'].style.top = menus[m]['items'][subindex]['top'];
					adjustz(m, subindex, (menus[m]['depthadjust'] * (menus[m]['items'][subindex]['depth']+1)));
				}
			}
			menus[m]['items'][subindex]['sectionheight']=0;
			subindex++;
		}

		if (menus[m]['adjustroom'])
		{
			var subsequentheight=add_height(blockheight, menus[m]['items'][subindex-1]['offsety']);
			if (subindex < menus[m]['items'].length)
			{
				subsequentheight=add_height(subsequentheight, menus[m]['items'][subindex-1]['border']);
				subsequentheight=add_height(subsequentheight, -get_height(menus[m]['items'][subindex]['border']));
			}
			while ( (subindex < menus[m]['items'].length) &&
					(!menus[m]['horizontal'] || (menus[m]['items'][subindex]['depth'] > 0))
				  )
			{
				if (needtoslide(m, subindex, index))
				{
					menus[m]['items'][subindex]['visible_at'] = menus[m]['items'][subindex]['top'];
					menus[m]['items'][subindex]['desiredtop'] = add_height(menus[m]['items'][subindex]['top'], subsequentheight );
					menus[m]['items'][subindex]['movetime']=0;
					menus[m]['items'][subindex]['sectionheight']=0;
					menus[m]['items'][subindex]['instantly']=instantly;
				}
				else
				{
				}
				subindex++;
			}
		}
		menus[m]['items'][index]['state']='out';
		var toroot=index;
		while (menus[m]['items'][toroot]["depth"] > 0)
		{
			menus[m]['items'][toroot-1]['visible_height']=add_height(menus[m]['items'][toroot-1]['visible_height'], blockheight);
			if (menus[m]['items'][toroot-1]['active'])
			{
				setvisibilitydown(m, toroot-1);
			}
			toroot = get_rootheading(m, toroot, menus[m]['items'][toroot]['depth']-1);
		}
	}

	function refurl(m, index)
	{
		function getsectionheight(m, index)
		{
			var subindex = index+1;
			var depth = menus[m]['items'][index]['depth'];
			var blockheight = 0;

			while ( (subindex < menus[m]['items'].length) &&
					(menus[m]['items'][subindex]['depth'] > depth)
				  )
			{
				if (menus[m]['items'][subindex]['depth'] == (depth+1))
				{
//					if (menus[m]['items'][subindex]['type'] == 'fold')
					{
						blockheight = add_height(blockheight, menus[m]['items'][subindex]['height']);
					}
				}
				else
				{
					// subsub chuld - skip it
				}
				subindex++;
			}
			return blockheight;
		}

		addlog('refurl ('+m+', '+index+')');

		menus[m]['refurling'] = index;

		var instantly = menus[m]['items'][index]['instantly'];
		removehighlight(m, index);

		var depth = menus[m]['items'][index]['depth'];
		var subindex=index+1;

		var itemsvisibleat = get_height(menus[m]['items'][index]['top']);
		if (menus[m]['submenusunder'] || (menus[m]['horizontal'] && (menus[m]['items'][index]['depth']==0)))
		{
			itemsvisibleat = add_height(itemsvisibleat, menus[m]['items'][index]['height']);
		}

		menus[m]['nosliding']=0;
  		var blockheight = get_height(getsectionheight(m, index));
  		// move all visible up
  		while ( (subindex < menus[m]['items'].length) &&
  				(menus[m]['items'][subindex]['depth'] > depth)
  			  )
  		{
  			if (menus[m]['items'][subindex]['depth'] == (depth+1))
  			{
// 				if (menus[m]['items'][subindex]['type'] == 'fold')
  				{
  					menus[m]['items'][subindex]['sectionheight']=blockheight;
  					menus[m]['items'][subindex]['desiredtop'] = add_height(menus[m]['items'][subindex]['top'], -blockheight );
  					menus[m]['items'][subindex]['movetime']=0;
					menus[m]['items'][subindex]['visible_at']=itemsvisibleat;
					menus[m]['items'][subindex]['instantly']=instantly;
					menus[m]['items'][subindex]['active']=true;
					menus[m]['nosliding']++;
					// moved z adjust to pop
				}
			}
			else
			{
				// subsub chuld - skip it
			}
			subindex++;
		}
		if (menus[m]['adjustroom'])
		{
			var subsequentheight=get_height(add_height(blockheight, menus[m]['items'][subindex-1]['offsety']));
			if (subindex < menus[m]['items'].length)
			{
				subsequentheight=add_height(subsequentheight, menus[m]['items'][subindex-1]['border']);
				subsequentheight=get_height(add_height(subsequentheight, -menus[m]['items'][subindex]['border']));
			}
			// move all others visible up
			while ( (subindex < menus[m]['items'].length) &&
					(!menus[m]['horizontal'] || (menus[m]['items'][subindex]['depth'] > 0))
				  )
			{
				if (needtoslide(m, subindex, index))
				{
					menus[m]['items'][subindex]['sectionheight']=0;
					menus[m]['items'][subindex]['movetime']=0;
					menus[m]['items'][subindex]['desiredtop'] = add_height(menus[m]['items'][subindex]['top'], -subsequentheight );
					menus[m]['items'][subindex]['visible_at'] = menus[m]['items'][subindex]['desiredtop'];
					menus[m]['items'][subindex]['instantly']=instantly;
					menus[m]['items'][subindex]['active']=true;
				}
				subindex++;
			}
		}

		menus[m]['items'][index]['state']='in';
		var toroot=index;
		while (menus[m]['items'][toroot]["depth"] > 0)
		{
			menus[m]['items'][toroot-1]['visible_height']=add_height(menus[m]['items'][toroot-1]['visible_height'], -blockheight);
			toroot = get_rootheading(m, toroot, menus[m]['items'][toroot]['depth']-1);
		}
	}

	function setupdatetime(m)
	{
		menus[m]['lastupdate']=new Date().getTime();
	}

	function is_parent(m, parent, child)
	{
		if (child <= parent)
			return false;

		if (menus[m]['items'][parent]['depth'] > menus[m]['items'][child]['depth'])
		{
			return false;
		}
		var rootindex=get_rootheading(m, parent, menus[m]['items'][parent]['depth']);
		var rootsub=get_rootheading(m, child, menus[m]['items'][parent]['depth']);
		return (rootindex == rootsub);
	}

	function updaterollovers(m)
	{
		function getpos(m, i)
		{
			function distthrough(a, b)
			{
				if ((b <= 0) || (a > b))
				{
					return 1;
				}
				return a/b;
			}

			var slidetime = menus[m]['slidetime'];
			if (menus[m]['items'][i]['instantly'])
			{
				slidetime = 0;
			}
			if (menus[m]['slideperitem'])
			{
				slidetime *= menus[m]['nosliding'];
			}
			return distthrough(menus[m]['items'][i]['movetime'], slidetime);
		}

		var closinglengthnotnought = false;
		var moving = false;
		var ROLLOVER_TIME = 10;
		var MAX_ROLLOVER_TIME = 40;
		var MIN_ROLLOVER_TIME = 5;

		var thistime = new Date().getTime();
		var elapsed = thistime - menus[m]['lastupdate'];
		if (elapsed > MAX_ROLLOVER_TIME)
		{
			elapsed = MAX_ROLLOVER_TIME;
		}
		if ((elapsed==null) || (elapsed < MIN_ROLLOVER_TIME))
		{
			elapsed = MIN_ROLLOVER_TIME;
		}
//		elapsed = ROLLOVER_TIME;
		var next_update = elapsed;
//		addlog('elapsed '+elapsed);

		var thismoving = false;
		var justrefurled = false;
		if (menus[m]['unfurling']!=-1)
		{
			var lastheight = menus[m]['items'][0]['height'];
			for (var i in menus[m]['items'])
			{
				if (get_height(menus[m]['items'][i]['item'].style.top) != get_height(menus[m]['items'][i]['desiredtop']))
				{
					menus[m]['items'][i]['movetime'] += elapsed;
					var pos = getpos(m, i);
					if ((menus[m]['slidetime'] <= 0) || (menus[m]['items'][i]['instantly']))
					{
						next_update = 0;
					}
					if (pos == 1)
					{
						menus[m]['items'][i]['item'].style.top = menus[m]['items'][i]['desiredtop'];
						menus[m]['items'][i]['top'] = menus[m]['items'][i]['desiredtop'];
						if (menus[m]['items'][i]['active'])
						{
							setvisibilitydown(m, i);
						}
						menus[m]['items'][i]['active']=false;
					}
					else
					{
						var diff = get_height(menus[m]['items'][i]['desiredtop']) - get_height(menus[m]['items'][i]['top']);
						var p = add_height(menus[m]['items'][i]['top'], diff*pos );
						menus[m]['items'][i]['item'].style.top = p;
						thismoving = true;
					}
				}
				if (menus[m]['items'][i]['active'])
				{
					setvisibilitydown(m, i);
			 	}
			}
			if (!thismoving)
			{
				addlog('unfurl end ('+m+', '+menus[m]['unfurling']+')');
				menus[m]['unfurling']=-1;
			}
		}
		else
		if (menus[m]['refurling']!=-1)
		{
			var lastheight = menus[m]['items'][0]['height'];
			var thismoving = false;
			for (var i in menus[m]['items'])
			{
				if (menus[m]['items'][i]['active'] &&
					(get_height(menus[m]['items'][i]['item'].style.top) != get_height(menus[m]['items'][i]['desiredtop']))
				   )
				{
					menus[m]['items'][i]['movetime'] += elapsed;
					var pos = getpos(m, i);
					if ((menus[m]['slidetime'] <= 0) || (menus[m]['items'][i]['instantly']))
					{
						next_update = 0;
					}
					if (pos == 1)
					{
						menus[m]['items'][i]['item'].style.top = menus[m]['items'][i]['desiredtop'];
						if (menus[m]['items'][i]['sectionheight'] > 0)
						{
							if (menus[m]['adjustroom'])
							{
								// pop newly hidden items back to their default unfurled positions
								menus[m]['items'][i]['top'] = add_height(menus[m]['items'][i]['desiredtop'], menus[m]['items'][i]['sectionheight']);
								menus[m]['items'][i]['desiredtop'] = menus[m]['items'][i]['top'];
							}
							menus[m]['items'][i]['active'] = false;
							menus[m]['items'][i]['item'].style.display = 'none';
							addlog('hideitem '+i);
							adjustz(m, i, -(menus[m]['depthadjust'] * (1+menus[m]['items'][i]['depth'])));
						}
						else
						{
							menus[m]['items'][i]['active'] = false;
							menus[m]['items'][i]['top'] = menus[m]['items'][i]['desiredtop'];
						}
					}
					else
					{
						var diff = get_height(menus[m]['items'][i]['desiredtop']) - get_height(menus[m]['items'][i]['top']);
						var p = add_height(menus[m]['items'][i]['top'], diff*pos );
						menus[m]['items'][i]['item'].style.top = p;
						thismoving = true;
					}
				}
				if (menus[m]['items'][i]['active'])
				{
					setvisibilityup(m, i);
			 	}
			}
			if (!thismoving)
			{
				addlog('refurl end ('+m+', '+menus[m]['refurling']+')');
				// reset clip visibility
				var toroot=menus[m]['refurling'];
				while (menus[m]['items'][toroot]["depth"] > 0)
				{
					setvisibilityup(m, toroot-1);
					toroot = get_rootheading(m, toroot, menus[m]['items'][toroot]['depth']-1);
				}

				justrefurled = true;
				if (menus[m]['items'][menus[m]['refurling']]['depth'] > 0)
				{
					adjustz(m, menus[m]['refurling']-1, -(menus[m]['depthadjust'] * (1+menus[m]['items'][menus[m]['refurling']-1]['depth'])));
				}
				adjustz(m, menus[m]['refurling'], -(menus[m]['depthadjust'] * (menus[m]['items'][menus[m]['refurling']]['depth']+1)));
				menus[m]['refurling']=-1;
			}
		}

		// pop closequeue item
		if ((!thismoving) && (menus[m]['closequeue'].length > 0))
		{
			var closeitem = menus[m]['closequeue'][menus[m]['closequeue'].length-1];
			refurl(m, closeitem);
			setupdatetime(m);
			thismoving=true;
			next_update = 0;
			menus[m]['closequeue'].length = menus[m]['closequeue'].length-1;
			// remove any children of the closequeue item from the openqueue list
			for (var c=menus[m]['openqueue'].length-1; c >= 0; c--)
			{
				if (is_parent(m, closeitem, menus[m]['openqueue'][c]))
				{
					for (var c2=c; c2 < menus[m]['openqueue'].length-1; c2++)
					{
						menus[m]['openqueue'][c2]=menus[m]['openqueue'][c2+1];
					}
					menus[m]['openqueue'].length=menus[m]['openqueue'].length-1;
				}
			}
		}

		// pop openqueue item
		if ((!thismoving) && (menus[m]['openqueue'].length > 0))
		{
			var openitem = menus[m]['openqueue'][menus[m]['openqueue'].length-1];
			unfurl(m, openitem);
			setupdatetime(m);
			if (!justrefurled)
			{
				next_update = 0;
			}
			thismoving=true;
			menus[m]['openqueue'].length = menus[m]['openqueue'].length-1;
		}
		
		moving|=thismoving;
		closinglengthnotnought |= (menus[m]['closequeue'].length > 0);
		closinglengthnotnought |= (menus[m]['openqueue'].length > 0);
		
		if (moving || closinglengthnotnought)
		{
			setupdatetime(m);
			if (next_update > 0)
			{
				setTimeout('updaterollovers('+m+')', next_update);
			}
			else
			{
				updaterollovers(m);
			}
		}
	}

	function addcloseitem(m, index, instantly)
	{
		var alreadyclosed = false;
		for (var c=menus[m]['openqueue'].length-1; (c >= 0); c--)
		{
			if (!menus[m]['items'][ menus[m]['openqueue'][c] ]['instantly'])
			{
				menus[m]['items'][ menus[m]['openqueue'][c] ]['instantly'] = instantly;
			}
			if (menus[m]['openqueue'][c] == index)
			{
				addlog('addclose remove openqueue ('+m+', '+index+')');
				// we've queued this for openqueue, so remove from openqueue list, then return
				for (var c2=c+1; c2 < menus[m]['openqueue'].length; c2++)
				{
					menus[m]['openqueue'][c2-1]=menus[m]['openqueue'][c2];
				}
				menus[m]['openqueue'].length=menus[m]['openqueue'].length-1;
				alreadyclosed = true;
			}
			else if (is_parent(m, index, menus[m]['openqueue'][c]))
			{
				addlog('addclose remove openqueue child ('+m+', '+menus[m]['openqueue'][c]+')');
				// remove child from openqueue queue
				for (var c2=c+1; c2 < menus[m]['openqueue'].length; c2++)
				{
					menus[m]['openqueue'][c2-1]=menus[m]['openqueue'][c2];
				}
				menus[m]['openqueue'].length=menus[m]['openqueue'].length-1;
			}
		}
		if (alreadyclosed)
		{
			addlog('addclose alreadyclosed ('+m+', '+index+')');
			return;
		}
		var alreadyclosing = false;
		for (var c=menus[m]['closequeue'].length-1; (c >= 0); c--)
		{
			if (!menus[m]['items'][ menus[m]['closequeue'][c] ]['instantly'])
			{
				menus[m]['items'][ menus[m]['closequeue'][c] ]['instantly'] = instantly;
			}
			if (menus[m]['closequeue'][c] == index)
			{
				addlog('addclose alreadyclosing ('+m+', '+index+')');
				// already closequeue this
				alreadyclosing = true;
			}
			else if (is_parent(m, index, menus[m]['closequeue'][c]))
			{
				addlog('addclose remove child closequeue ('+m+', '+menus[m]['closequeue'][c]+')');
				// remove child from closequeue queue
				for (var c2=c+1; c2 < menus[m]['closequeue'].length; c2++)
				{
					menus[m]['closequeue'][c2-1]=menus[m]['closequeue'][c2];
				}
				menus[m]['closequeue'].length=menus[m]['closequeue'].length-1;
			}
		}
		if (!alreadyclosing)
		{
			addlog('addclose ('+m+', '+index+')');
			menus[m]['closequeue'][menus[m]['closequeue'].length]=index;
			menus[m]['items'][index]['instantly'] = instantly;
		}
	}

	function addopenitem(m, index, instantly)
	{
		var alreadyopen = false;
		for (var c=menus[m]['closequeue'].length-1; c >= 0; c--)
		{
			if (!menus[m]['items'][menus[m]['closequeue'][c]]['instantly'])
			{
				menus[m]['items'][menus[m]['closequeue'][c]]['instantly'] = instantly;
			}
			if (menus[m]['closequeue'][c] == index)
			{
				addlog('addopen remove closequeue ('+m+', '+index+')');
				// we've queued this for closequeue, so remove from closequeue list, then return
				for (var c2=c+1; c2 < menus[m]['closequeue'].length; c2++)
				{
					menus[m]['closequeue'][c2-1]=menus[m]['closequeue'][c2];
				}
				menus[m]['closequeue'].length=menus[m]['closequeue'].length-1;
				alreadyopen = true;
			}
			else if (is_parent(m, menus[m]['closequeue'][c], index))
			{
				addlog('addopen remove parent closequeue ('+m+', '+menus[m]['closequeue'][c]+')');
				// remove parent from closequeue queue
				for (var c2=c+1; c2 < menus[m]['closequeue'].length; c2++)
				{
					menus[m]['closequeue'][c2-1]=menus[m]['closequeue'][c2];
				}
				menus[m]['closequeue'].length=menus[m]['closequeue'].length-1;
			}
		}
		if (alreadyopen)
		{
			return;
		}
		rootindex=index;
		if (menus[m]['items'][index]['depth'] > 0)
		{
			rootindex=get_rootheading(m, index, menus[m]['items'][index]['depth']-1);
		}
		if ((menus[m]['items'][index]['depth']>0) && (menus[m]['items'][rootindex]['state']!='out'))
		{
			addlog('addopen failroot ('+m+', '+index+')'+menus[m]['items'][rootindex]['state']);
		}
		else
		{
			if (menus[m]['closeothersubs'] && (menus[m]['openqueue'].length == 1))
			{
				addlog('addopen remove other open ('+m+', '+menus[m]['openqueue'][0]+'=>'+index+')');
				// remove the other openqueue one if we're only allowing one sub open at a time
				menus[m]['openqueue'][0]=index;
				menus[m]['items'][index]['instantly']=instantly;
			}
			else
			{
				for (var c=0; c < menus[m]['openqueue'].length; c++)
				{
					if (menus[m]['openqueue'][c] == index)
					{
						if (!menus[m]['items'][ menus[m]['openqueue'][c] ]['instantly'])
						{
							menus[m]['items'][ menus[m]['openqueue'][c] ]['instantly']=instantly;
						}
						// already openqueue this
						addlog('addopen already openqueue ('+m+', '+menus[m]['openqueue'][0]+')');
						return;
					}
				}
				addlog('addopen ('+m+', '+index+')');
				menus[m]['openqueue'][menus[m]['openqueue'].length]=index;
				menus[m]['items'][index]['instantly']=instantly;
			}
		}
	}

	function closemenuitem(m, index, instantly)
	{
		addlog('closemenuitem ('+m+', '+index+')');
		addcloseitem(m, index, instantly);
		var depth = menus[m]['items'][index]['depth'];
		// search for open children
		var subindex = index + 1;
		while ((subindex < menus[m]['items'].length) &&
			   (menus[m]['items'][subindex]['depth'] > depth)
			  ) 	
		{
			if ( (menus[m]['items'][subindex]['depth'] >= (depth+1)) &&
				 (menus[m]['items'][subindex]['state'] == 'out')
			   )
			{
				addcloseitem(m, subindex, instantly);
			}
			subindex++;
		}
	}

	function openmenuitem(m, index, instantly)
	{
		addlog('openmenuitem ('+m+', '+index+')');
		var depth = menus[m]['items'][index]['depth'];
		if (menus[m]['closeothersubs'])
		{
			for (var subindex=0; subindex < menus[m]['items'].length; subindex++)
			{
				if ( (menus[m]['items'][subindex]['depth'] == depth) &&
					 (menus[m]['items'][subindex]['state'] == 'out') &&
					 (subindex != index)
				   )
				{
					closemenuitem(m, subindex);
				}
			}
		}
		addopenitem(m, index, instantly);
	}

	function getmenuitem(m, anitem)
	{
		var index = 0;
		while ((index < menus[m]['items'].length) &&
			   (menus[m]['items'][index]['item']!=anitem)
			  )
		{
			index++;
		}
		return index;
	}

	function closefolds(m, index)
	{
		if (menus[m]['items'][index]['item'].style.display!='none')
		{
			var depth = menus[m]['items'][index]['depth'];
			if (menus[m]['closeothersubs'])
			{
				for (var subindex=0; subindex < menus[m]['items'].length; subindex++)
				{
					if ( (menus[m]['items'][subindex]['depth'] == depth) &&
						 (menus[m]['items'][subindex]['state'] == 'out') &&
						 (subindex != index)
					   )
					{
						closemenuitem(m, subindex, false);
					}
				}
			}
		}
		updaterollovers(m);
	}

	function forceopen(m, index)
	{
		if (menus[m]['items'][index]['item'].style.display!='none')
		{
			if (menus[m]['items'][index+1]['depth'] > menus[m]['items'][index]['depth'])
			{
				openmenuitem(m, index, true);
				updaterollovers(m);
			}
		}
	}

	function createmenuitem(theitems, itemtype, sourceitem)
	{
		var index = theitems.length;
		theitems[index] = new Array();
		theitems[index]['type']=itemtype;
		theitems[index]['top']=sourceitem.style.top;
		theitems[index]['visible_at']=theitems[index]['top'];
		theitems[index]['desiredtop']=theitems[index]['top'];
		theitems[index]['sectionheight']=0;
		theitems[index]['movetime']=0;
		theitems[index]['item']=sourceitem;
		theitems[index]['highlight']='';
		theitems[index]['act']=menuclass_act(sourceitem.className);
		theitems[index]['width']=menuclass_width(sourceitem.className);
		theitems[index]['height']=menuclass_height(sourceitem.className);
		theitems[index]['visible_height']=theitems[index]['height'];
		theitems[index]['offsetx']=menuclass_offsetx(sourceitem.className);
		theitems[index]['offsety']=menuclass_offsety(sourceitem.className);
		theitems[index]['border']=menuclass_border(sourceitem.className);
		theitems[index]['hasicon']=menuclass_hasicon(sourceitem.className);
		if (theitems[index]['hasicon'])
		{
			theitems[index]['icon']=menuclass_icon(sourceitem.className);
			theitems[index]['iconhilit']=menuclass_iconhover(sourceitem.className);
			theitems[index]['iconoplit']=menuclass_iconopen(sourceitem.className);
		}
		else
		{
			theitems[index]['icon']='';
			theitems[index]['iconhilit']='';
			theitems[index]['iconoplit']='';
		}
		var splitname = sourceitem.id;
		var splitarray = splitname.split('_');	// name_depth_id

		theitems[index]['depth']=parseInt(splitarray[splitarray.length-2]);

		theitems[index]['state']='in';
		theitems[index]['active']=false;
	}

	function menumoving(m)
	{
		return false;
		for (var m in menus)
		{
			if (menus[m]['closequeue'].length > 0)
			{
				return true;
			}
			if (menus[m]['openqueue'].length > 0)
			{
				return true;
			}
			if (menus[m]['unfurling'] != -1)
			{
				return true;
			}
			if (menus[m]['refurling'] != -1)
			{
				return true;
			}
		}
		return false;
	}

	function find_menuitem_class(source)
	{
		if (source == null)
		{
			return null;
		}
		if (is_menuitem_classname(removehighlightname(source.className)))
		{
			return source;
		}
		return find_menuitem_class(source.parentNode);
	}

	function find_header_class(source)
	{
		if (source == null)
		{
			return null;
		}
		if (is_header_classname(removehighlightname(source.className)))
		{
			return source;
		}
		return find_header_class(source.parentNode);
	}

	function in_dir_hierarchy(root, item)
	{
		if (item==null)
			return false;
		if (root==item)
			return true;
		return in_dir_hierarchy(root, item.parentNode);
	}

	function formmenurecurse(sourcemenu, theitems)
	{
		var source = !document.all ? sourcemenu.childNodes : sourcemenu.all;
		for (var i=0; i < source.length; i++)
		{
			var type = '';
			if (is_header_classname(removehighlightname(source.item(i).className)))
			{
				type='heading';
			}
			else
			if (is_menuitem_classname(removehighlightname(source.item(i).className)))
			{
				type='fold';
			}
			if (type!='')
			{
				createmenuitem(theitems, type, source.item(i));
			}
			if (!document.all && (source.item(i).childNodes.length > 0))
			{
				formmenurecurse(source.item(i), theitems);
			}
		}
	}

	function formmenu(sourcemenu)
	{
		var theitems = new Array();
		formmenurecurse(sourcemenu, theitems);
		return theitems;
	}

	function createmenu(m, item)
	{
		addlog('create');
		menus[m] = new Array();
		menus[m]['formed']=false;
		menus[m]['root']=item;
		menus[m]['items']=formmenu(item);
		menus[m]['slidetime']=menu_slidetime(item.className);
		menus[m]['zindex']=menu_zindex(item.className);
		menus[m]['closeothersubs']=is_menu_closeothersubs(item.className);
		menus[m]['horizontal']=is_menu_horizontal(item.className);
		menus[m]['slideperitem']=is_menu_slideperitem(item.className);
		menus[m]['adjustroom']=is_menu_adjustroom(item.className);
		menus[m]['depthadjust']=1;
		menus[m]['submenusunder']=is_menu_subsunder(item.className);
		if (menus[m]['submenusunder'])
		{
			menus[m]['depthadjust']=-1;
		}
		menus[m]['closequeue'] = new Array();
		menus[m]['openqueue'] = new Array();
		menus[m]['unfurling'] = -1;
		menus[m]['refurling'] = -1;
		menus[m]['formed']=true;
	}

	function getmenu(item)
	{
		var foundit = false;
		var m=0;
		while ( ( (m < menus.length) &&
				  (!in_dir_hierarchy(menus[m]['root'], item))
			    )
			  )
		{
			m++;
		}
		if (m == menus.length)
		{
			if (is_menu_classname(item.className))
			{
				createmenu(m, item);
			}
		}
		return m;
	}

	function setslidetime(menunode, time)
	{
		var menuno = getmenu(menunode);
		if (menuno < menus.length)
		{
			menus[menuno]['slidetime']=time;
		}
	}

	function alterfoldstate(m, index, actclick, rolloverindex)
	{
		if (menus[m]['items'][index]['item'].style.display!='none')
		{
			if (index == (menus[m]['items'].length-1))
			{
				closefolds(m, index);
			}
			else
			{
				if (menus[m]['items'][index+1]['depth'] > menus[m]['items'][index]['depth'])
				{
					if (menus[m]['items'][index]['state']=='in')
					{
						if ((menus[m]['act']=='click') ||
							((menus[m]['refurling']!=index) &&
							(menus[m]['unfurling']==-1))
						   )
						{
							openmenuitem(m, index, false);
						}
					}
					else
					if ((menus[m]['act']=='click') ||
						(actclick &&
						 (menus[m]['unfurling']!=index) &&
						 (menus[m]['refurling']==-1) &&
						 (index==rolloverindex)
						)
					   )
					{
						closemenuitem(m, index, false);
					}
				}
			}
		}
		updaterollovers(m);
	}

	function actonitem(anitem, acttype)
	{
		var source = null;
		var rollover = null;

		if (acttype=='open')
		{
			if (is_header_classname(anitem.className))
			{
				source = anitem;
			}
		}
		else
		{
			if(!document.all&&!document.getElementById)
				return;

			var rolloversource=!document.all? anitem.target : event.srcElement;

			source = find_header_class(rolloversource);
			rollover = find_menuitem_class(rolloversource);
		}

		var rolloverindex = 0;
		var rollovermenu = menus.length;
		if (rollover != null)
		{
			rollovermenu = getmenu(rollover.parentNode);
			if ((rollovermenu < menus.length) &&
				(menus[rollovermenu]['formed'])
			   )
			{
				rolloverindex = getmenuitem(rollovermenu, rollover);
			}
			else
			{
				rollovermenu = menus.length;
			}
		}
		if (source != null)
		{
			var menuno = getmenu(source.parentNode);
			if (menuno < menus.length)
			{
				if (menus[menuno]['formed'])
				{
					var index = getmenuitem(menuno, source);
					if (index < menus[menuno]['items'].length)
					{
						actclick = (acttype == 'click');
						if (((menus[menuno]['items'][index]['act']==acttype) || (actclick)) &&
							(!menumoving(menuno))
						   )
						{
							alterfoldstate(menuno, index, actclick, rolloverindex);
						}
						else
						if (acttype=='open')
						{
							forceopen(menuno, index);
						}
					}
				}
			}
		}
		else
		if (rollover != null)
		{
			if ( (rollovermenu < menus.length) &&
				 (rolloverindex < menus[rollovermenu]['items'].length) &&
				 (menus[rollovermenu]['items'][rolloverindex]['act']==acttype) &&
				 (!menus[rollovermenu]['closeothersubs']) &&
				 (!menumoving(menuno))
			   )
			{
				closefolds(rollovermenu, rolloverindex);
			}
		}

		if ( (rollovermenu < menus.length) &&
			 (rolloverindex < menus[rollovermenu]['items'].length)
		   )
		{
			if (acttype=='rollover')
			{
				sethighlight(rollovermenu, rolloverindex, 'hilit');
			}
			else
			if (acttype=='rollout')
			{
				if ((menus[rollovermenu]['items'][rolloverindex]['state']=='in') &&
					(menus[rollovermenu]['items'][rolloverindex]['highlight']=='hilit')
				   )
				{
					removehighlight(rollovermenu, rolloverindex);
				}
			}
//			setstatus(acttype + ' ' + rolloverindex + ' ' + menus[rollovermenu]['items'][rolloverindex]['item'].id+' '+xMousePos+','+yMousePos);
		}
		else
		{
//			setstatus(acttype + ' ' + rolloverindex);
		}
	}

	function rollovermenu(item)
	{
		actonitem(item, 'rollover');
	}

	function rolloverout(item)
	{
		actonitem(item, 'rollout');
	}

	function clickmenu(item)
	{
		actonitem(item, 'click');
	}

	function startopen(idname)
	{
		var element = document.getElementById(idname);
		if (element != null)
		{
			actonitem(element, 'open');
		}
	}

	document.onmouseout=rolloverout;
	document.onmouseover=rollovermenu;
	document.onclick=clickmenu;
