// ------------------------------------------------------------------------------------------------------------------------------------
// Thanks to: http://www.quirksmode.org/js/detect.html

var detect = navigator.userAgent.toLowerCase();
var OS, browser, version, total, thestring;

if (checkIt('konqueror'))
{
	browser = "Konqueror";
	OS = "Linux";
}
else if (checkIt('safari'))		browser = "Safari"
else if (checkIt('omniweb'))	browser = "OmniWeb"
else if (checkIt('opera'))		browser = "Opera"
else if (checkIt('webtv'))		browser = "WebTV";
else if (checkIt('icab'))		browser = "iCab"
else if (checkIt('msie'))		browser = "Internet Explorer"
else if (!checkIt('compatible'))
{
	browser = "Netscape Navigator"
	version = detect.charAt(8);
}
else browser = "An unknown browser";

if (!version) version = detect.charAt(place + thestring.length);

if (!OS)
{
	if (checkIt('linux'))		OS = "Linux";
	else if (checkIt('x11'))	OS = "Unix";
	else if (checkIt('mac'))	OS = "Mac"
	else if (checkIt('win'))	OS = "Windows"
	else						OS = "an unknown operating system";
}
			
function checkIt(string)
{
	place = detect.indexOf(string) + 1;
	thestring = string;
	return place;
}
// ----------------------------------------------------------------------------------------------------------------
// public class		DK_Menues
// Author:		Stephan Jank
// Last Modified:	Aug 2006
// ----------------------------------------------------------------------------------------------------------------
function DK_Menues(){
	// -------------------------------------------------------------------------------------------------------
	// some basic things to keep in mind
	// -------------------------------------------------------------------------------------------------------
	var _menues = new Array;


	// -------------------------------------------------------------------------------------------------------
	// function
	// name:		CollapseAll
	// access type:		public
	// parameters:		none
	// returns:		nothing
	// purpose:		collapses all menues held in the _menues array
	// remarks:		the function must be placed before installing
	//			the onmousedown handler for the window background
	// -------------------------------------------------------------------------------------------------------
	this.CollapseAll = function(){
		for(var i = 0; i < _menues.length; i++)
			_menues[i].CollapseComplete();
		return true;
	}
	// -------------------------------------------------------------------------------------------------------
	// installing the onmousedown handler for the window background
	// -------------------------------------------------------------------------------------------------------
	if(document.attachEvent)
		document.getElementsByTagName('body')[0].attachEvent('onmousedown', this.CollapseAll, false);
	else
		document.getElementsByTagName('body')[0].addEventListener('mousedown', this.CollapseAll, false);



	// -------------------------------------------------------------------------------------------------------
	// function
	// name:		Add
	// access type:		public
	// parameters:		MenuStruct:		the menu structure (recursive array) to be handled
	//			HTMLContainerID:	the ID of an HTML block level tag to contain the
	//						the menu. Typically this should be a <div> tag
	//			HTMLDebugDisplayID:	the ID an HTML block level tag to receive trace
	//						information. the parameter is optional if not
	//						present no tracing will occur
	// returns:		the index of the newly added menu for later reference
	// remarks:		no remarks
	// -------------------------------------------------------------------------------------------------------
	this.Add = function(MenuStruct, HTMLContainerID, HTMLDebugDisplayID){
		_menues.push(new Menu(MenuStruct, HTMLContainerID, HTMLDebugDisplayID));
		return _menues.length - 1;
	}
	
	// -------------------------------------------------------------------------------------------------------
	// private class Menu
	// -------------------------------------------------------------------------------------------------------
	function Menu(MenuStruct, ElementID, DebugDisplayID){


		// -----------------------------------------------------------------------------------------
		// function
		// name:		copymenustruct
		// access type:		private
		// parameters:		dst:	menu structure (recursive array) to be copied to
		//			src:	menu structure (recursive array) to be copied from
		// returns:		nothing
		// purpose:		copies a menu struct into another since javascript has no
		//			support for array assignment other than by reference and
		//			hence if the passed menu structure is the same for
		//			more than 1 menu we would get into troubles without
		//			providing a correct copy of the menu structure
		// remarks:		recursive
		// -----------------------------------------------------------------------------------------
		function copymenustruct(dst, src){
			if(isArray(src)){
				for(var i = 0; i < src.length; i += 3){
					dst.push(src[i]);
					dst[i + 1] = new Array();
					for(var j = 0; j < src[i + 1].length; j++)
						dst[i + 1].push(src[i + 1][j]);
					if(src[i + 2] == null)
						dst[i + 2] = null;
					else{
						dst[i + 2] = new Array();
						copymenustruct(dst[i + 2], src[i + 2]);
					}
				
				}
			}
		}
		// -----------------------------------------------------------------------------------------
		// Some basic things to keep in mind
		// -----------------------------------------------------------------------------------------
		var _menuindex				= _menues.length;
		var _menustruct				= new Array();
		copymenustruct(_menustruct, MenuStruct);	
		var _menuelement			= document.getElementById(ElementID);
		var _expanded				= false;
		var _debugdisplay			= null;
		// -----------------------------------------------------------------------------------------
		// Initializing CSS for Firefox
		// -----------------------------------------------------------------------------------------
		var _csscursorpointer			= 'pointer';
		var _cssmenufontsize			= '8pt';
		var _csslevel0height			= '1.8em';
		var _cssdivpadding			= '0.3em 0.5em 0.2em 0.5em';
		var _csslevel0background		= 'activeborder';
		var _cssmenubackground			= 'menu';
		var _cssmenutext			= 'menutext';
		var _cssmenubackgroundhighlight		= 'highlight';
		var _cssmenutexthighlight		= 'highlighttext';
		var _cssmenuitempaddingtop		= '0.2em 0.5em 0.1em 1.5em';
		var _cssmenuitempaddingmiddle		= '0.1em 0.5em 0.1em 1.5em';
		var _cssmenuitempaddingbottom		= '0.1em 0.5em 0.2em 1.5em';
		var _cssmenuitemborderleftstyle		= 'solid';
		var _cssmenuitemborderleftcolor		= '#FFFFFF';
		var _cssmenuitemborderleftwidth		= '1px';
		var _cssmenuarrowborderrightstyle	= 'solid';
		var _cssmenuarrowborderrightcolor	= '#FFFFFF';
		var _cssmenuarrowborderrightwidth	= '1px';
		var _cssmenupopupbordercolor		= '#999999';

		// -----------------------------------------------------------------------------------------
		// Adjusting CSS for other browsers
		// -----------------------------------------------------------------------------------------
		if(browser == 'Internet Explorer'){
			_csscursorpointer		= 'hand';
			_cssmenufontsize		= '8pt';
			_csslevel0height		= '1.8em';
			_cssdivpadding			= '0.3em 0.5em 0.2em 0.5em';
			_csslevel0background		= 'buttonface';
			_cssmenubackground		= 'menu'
			_cssmenutext			= 'menutext';
			_cssmenubackgroundhighlight	= 'highlight';
			_cssmnenutexthighlight		= 'highlighttext';
			_cssmenuitempaddingtop		= '0.2em 0.5em 0.1em 1.5em';
			_cssmenuitempaddingmiddle	= '0.1em 0.5em 0.1em 1.5em';
			_cssmenuitempaddingbottom	= '0.1em 0.5em 0.2em 1.5em';
			_cssmenuitemborderleftstyle	= 'solid';
			_cssmenuitemborderleftcolor	= '#FFFFFF';
			_cssmenuitemborderleftwidth	= '1px';
			_cssmenuarrowborderrightstyle	= 'solid';
			_cssmenuarrowborderrightcolor	= '#FFFFFF';
			_cssmenuarrowborderrightwidth	= '1px';
		}
		// -----------------------------------------------------------------------------------------
		// menues should look and feel like menues
		// -----------------------------------------------------------------------------------------
		_menuelement.style.position		= 'relative';
		_menuelement.style.padding		= '0em';
		_menuelement.style.backgroundColor	= 'Menu';
		_menuelement.style.fontFamily		= 'Microsoft Sans Serif, sans-serif';
		_menuelement.style.fontWeight		= 'normal';
		_menuelement.style.fontSize		= _cssmenufontsize;
		_menuelement.style.fontStyle		= 'normal';
		_menuelement.style.textDecoration	= 'none';
		_menuelement.style.letterSpacing	= '0';
		_menuelement.style.wordSpacing		= '0';
		_menuelement.style.color		= _cssmenutext;
		_menuelement.style.backgroundColor	= _csslevel0background;
		// -----------------------------------------------------------------------------------------
		// Initializing _errordisplay if wanted
		// -----------------------------------------------------------------------------------------
		if(DebugDisplayID){
			_debugdisplay = document.getElementById(DebugDisplayID);
			_debugdisplay.style.fontFamily = 'Verdana, sans-serif';
			_debugdisplay.style.fontSize = '12pt';
		}

		// -----------------------------------------------------------------------------------------
		// public Collapse the whole menu
		// -----------------------------------------------------------------------------------------
		this.CollapseComplete = function(){
			collapse(_menustruct, null);
			_expanded = false;
		}
		// -----------------------------------------------------------------------------------------
		// private trace debug messages
		// -----------------------------------------------------------------------------------------
		function trace(message){
			if(_debugdisplay != null)
				_debugdisplay.innerHTML += message + '<br>\n';
		}
		// -----------------------------------------------------------------------------------------
		// private trace the menu structure
		// -----------------------------------------------------------------------------------------
		function printmenu(menu, level){
			for(var i = 0; i < menu.length; i += 3){
				var sp = '';
				for(var j = 0; j < level; j++)
					sp += '&nbsp;&nbsp;&nbsp;&nbsp;';
				Error(	sp + menu[i] + ', ' +
					menu[i + 1][0] + ', ' +
					menu[i + 1][1] + ', ' +
					menu[i + 1][2] + ', ' +
					menu[i + 1][3]);
				if(menu[i] == 'popup')
					printmenu(menu[i + 2], level + 1);
			}
		}
		// -----------------------------------------------------------------------------------------
		// initializing the menu structure
		// -----------------------------------------------------------------------------------------
		initstruct(_menustruct, 'DK_m' + _menuindex, 0);
		var left = 0;
		var top;
		if(browser == 'Internet Explorer')
			top = _menuelement.offsetHeight - 1;
		else
			top = Math.round(parseFloat(window.getComputedStyle(_menuelement, null).getPropertyValue('height')));

		for(var i = 0; i < _menustruct.length; i += 3){
			if(_menustruct[i] == 'popup'){
				var table = document.getElementById(_menustruct[i + 1][3]);
				table.style.left = left + 'px';
				table.style.top = top + 'px';
				
			}
			var td = document.getElementById('DK_m' + _menuindex + 'p' + (i / 3) + 'l0');
			if(browser == 'Internet Explorer'){
				left += td.offsetWidth;
			}
			else{
				var tdstyle = window.getComputedStyle(td, null);
				left +=	parseFloat(tdstyle.getPropertyValue('width')) +
					parseFloat(tdstyle.getPropertyValue('padding-left')) +
					parseFloat(tdstyle.getPropertyValue('padding-right'));
			}
			left = Math.round(left);
		}
		// -----------------------------------------------------------------------------------------
		// function
		// name:		format_td_common
		// access type:		private
		// parameter:
		// -----------------------------------------------------------------------------------------
		function format_td_common(td){
			td.style.cursor		= _csscursorpointer;
			td.style.whiteSpace	= 'nowrap';
			td.style.fontSize	= _cssmenufontsize;
			td.style.color		= _cssmenutext;
			td.style.fontFamily	= 'MS sans serif, sans-serif';
			td.onmouseover		= onmouse;
			td.onmouseout		= onmouse;
			td.onmousedown		= onmouse;
		}
		// -----------------------------------------------------------------------------------------
		// function
		// name:		format_td_level0
		// access type:		private
		// parameter:
		// -----------------------------------------------------------------------------------------
		function format_td_level0(tr, id, text){

			var td = document.createElement('td');
			td.appendChild(document.createTextNode(text));
			var idnode = document.createAttribute('id');
			idnode.nodeValue = id;
			td.setAttributeNode(idnode);
			format_td_common(td);
			td.style.padding		= _cssdivpadding;			
			tr.appendChild(td);
		}
		// -------------------------------------------------------------------------------------------------------------
		function format_td(tbody, id, text, popup, pos){

			var tr = document.createElement('tr');
			
			var td = document.createElement('td');
			td.appendChild(document.createTextNode(text));
			var idnode = document.createAttribute('id');
			idnode.nodeValue = id;
			td.setAttributeNode(idnode);
			format_td_common(td);
			if	(pos == 0)	td.style.padding = _cssmenuitempaddingtop;
			else if	(pos == 2)	td.style.padding = _cssmenuitempaddingbottom;
			else			td.style.padding = _cssmenuitempaddingmiddle;
			td.style.borderLeftStyle = _cssmenuitemborderleftstyle;
			td.style.borderLeftColor = _cssmenuitemborderleftcolor;
			td.style.borderLeftWidth = _cssmenuitemborderleftwidth;
			tr.appendChild(td);

			td = document.createElement('td');
			td.appendChild(document.createTextNode(popup ? '>' : ''));
			format_td_common(td);
			if	(pos == 0)	td.style.padding = _cssmenuitempaddingtop;
			else if	(pos == 2)	td.style.padding = _cssmenuitempaddingbottom;
			else			td.style.padding = _cssmenuitempaddingmiddle;
			td.style.borderRightStyle = _cssmenuarrowborderrightstyle;
			td.style.borderRightColor = _cssmenuarrowborderrightcolor;
			td.style.borderRightWidth = _cssmenuarrowborderrightwidth;
			
			tr.appendChild(td);
			tbody.appendChild(tr);
		}
		// -----------------------------------------------------------------------------------------
		// function
		// name:		format_table_level0
		// -----------------------------------------------------------------------------------------
		function format_table_level0(table){
			var attr	= document.createAttribute('cellpadding'); attr.nodeValue = '0'; table.setAttributeNode(attr);
			attr		= document.createAttribute('cellspacing'); attr.nodeValue = '0'; table.setAttributeNode(attr);
			
		}
		// -----------------------------------------------------------------------------------------
		// function
		// name:		format_table
		// -----------------------------------------------------------------------------------------
		function format_table(table, id, level){
				var idnode = document.createAttribute('id');
				idnode.nodeValue = id;
				table.setAttributeNode(idnode);

				format_table_level0(table);
				table.style.position = 'absolute';
				table.style.zIndex		= level;
				table.style.backgroundColor	= _cssmenubackground;
				table.style.color	= '#FFFFFF';
				table.style.borderStyle		= 'solid';
				table.style.borderWidth		= '1px';
				table.style.borderColor		= _cssmenupopupbordercolor;
				table.style.display		= 'none';
		}
		// -----------------------------------------------------------------------------------------
		// private initialize menu structure
		// -----------------------------------------------------------------------------------------
		function initstruct(menu, htmlID, level){
			if(!isArray(menu)) return;
			var table	= document.createElement('table');
			var tbody	= document.createElement('tbody');
			if(level == 0){

				var tr = document.createElement('tr');
				for(var i = 0; i < menu.length; i += 3){
					var ID = htmlID + 'p'+ (i / 3);
					menu[i + 1][2] = ID + 'l0';
					menu[i + 1][3] = ID + 't';
					format_td_level0(tr, ID + 'l0', menu[i + 1][0]);
					initstruct(menu[i + 2], ID, level + 1);
				}
				tbody.appendChild(tr);
				format_table_level0(table);
			}
			else{
				for(var i = 0; i < menu.length; i += 3){
					var pos = (i == 0 ? 0 : ((i == menu.length - 3) ? 2 : 1));
					switch(menu[i]){
						case 'popup':{
							var ID = htmlID + 'p' + (i / 3);
							menu[i + 1][2] = ID;
							menu[i + 1][3] = ID + 't';
							format_td(tbody, ID, menu[i + 1][0], true, pos);
							initstruct(menu[i + 2], ID, level + 1);
							break;
						}
						case 'item':{
							var ID = htmlID + 'i' + (i / 3);
							menu[i + 1][2] = ID;
							menu[i + 1][3] = null;
							format_td(tbody, ID, menu[i + 1][0], false, pos);
							break;
						}
						default: alert('Incorrect menu struct');
					}
				}
				format_table(table, htmlID + 't', level);
			}
			table.appendChild(tbody);
			_menuelement.appendChild(table);
		}

		// -----------------------------------------------------------------------------------------
		// function
		// name:		collapse
		// access type:		private
		// parameters:		menu:	menu structure (recursive array) to be collapsed
		//			id:	HTML id of the tag causing the collpse action. this
		//				element and its siblings are not reset to background color
		// returns:		nothing
		// remark:		recursive
		// -----------------------------------------------------------------------------------------
		function collapse(menu, id){
			for(var i = 0; i < menu.length	; i += 3){

				var tableID = menu[i + 1][3];
				var item = document.getElementById(menu[i + 1][2]);
				if(item && menu[i + 1][2] != id){
					item.style.backgroundColor = (/l0$/.test(item.getAttribute('id')) ? _csslevel0background : _cssmenubackground);
					item.style.color = _cssmenutext;
					if(id && !/l0$/.test(item.getAttribute('id'))){
						item.nextSibling.style.backgroundColor = _cssmenubackground;
						item.nextSibling.style.color = _cssmenutext;
					}
				}
				if(tableID)	document.getElementById(tableID).style.display = 'none';
				if(menu[i + 2])	collapse(menu[i + 2], id);
			}
		}
		// -----------------------------------------------------------------------------------------
		// private onmouse
		// -----------------------------------------------------------------------------------------
		function onmouse(evt){

			// The following 2 lines are stolen from and thus thanked to:
			// http://www.mediaevent.de/javascript/event_properties.html
			// They provide a dapper IE/Mozilla fork.

			// getting the event
			evt = (evt) ? evt : ((window.event) ? window.event : "");

			// getting the causing menu item. we have to take into
			// account, that the event was caused by the second column
			// of our popup table
			var menuitem = (evt.target) ? evt.target : evt.srcElement;




			
			if(!/l0$/.test(menuitem.getAttribute('id'))){
				if(menuitem.previousSibling && menuitem.previousSibling.tagName == 'TD')
					menuitem = menuitem.previousSibling;
			}
			// Retrieving the ID of the processed menu item
			var id = menuitem.getAttribute('id');

		
 			// Parsing the ID of the menu item into a path within
			// the menu structure and a row within the actual popup	
			/.*?p([^il]*)/.exec(id);
			var path = RegExp.$1.split('p');
			var row  = path[path.length - 1];
			/(\d+)$/.exec(id);
			var itemID = RegExp.$1;
			trace('path: ' + path + ', itemID: ' + itemID);
			


			var rowheight = null;
			var top      = null;
			var left     = null;
		
			var parent	= null;
			var menu	= null;
			var child	= _menustruct;
		
			for(var i = 0; i < path.length; i++){
				parent = menu;
				menu = child;
				child = menu[path[i] * 3 + 2];
			}

			if(path.length > 1){
				var table = document.getElementById(parent[path[path.length - 2] * 3 + 1][3]);
				if(window.getComputedStyle){
					left = parseFloat(window.getComputedStyle(table, null).getPropertyValue('left')) +
				       	       parseFloat(window.getComputedStyle(table, null).getPropertyValue('width'));
					top  = parseFloat(window.getComputedStyle(table, null).getPropertyValue('top'));
					rowheight = parseFloat(window.getComputedStyle(table.firstChild.firstChild, null).getPropertyValue('height'));
				}
				else if(table.currentStyle){
					left = parseFloat(table.currentStyle.left) + parseFloat(table.offsetWidth);
					top  = parseFloat(table.offsetTop);
					rowheight = parseFloat(table.firstChild.firstChild.offsetHeight)
				}
				left -= 4;
			}		
			switch(evt.type){
				case 'mouseover':
					if(path.length != 1 || _expanded){
						collapse(menu, menu[path[path.length - 1] * 3 + 1][2]);
						menuitem.style.backgroundColor = _cssmenubackgroundhighlight;
						menuitem.style.color = _cssmenutexthighlight;
						if(!/l0$/.test(id)){
							menuitem.nextSibling.style.backgroundColor = _cssmenubackgroundhighlight;
							menuitem.nextSibling.style.color = _cssmenutexthighlight;
						}
						id = menu[path[path.length - 1] * 3 + 1][3];
						var table = document.getElementById(id)
						table.style.display = 'block';
				
						if(left){
							table.style.left = left + 'px';
							if(browser == 'Internet Explorer'){
								table.style.top = (top + rowheight * row - parseFloat(row)) + 'px';
							}
							else
								table.style.top = (top + rowheight * row - row) + 'px';
						}	
					}
					break;
				case 'mousedown':
					if(path.length == 1 && _expanded){
						collapse(menu);
						_expanded = false;
					}
					else if(path.length == 1 || !_expanded){
						if(path.length == 1)
							for(var i = 0; i < _menues.length; i++)
								_menues[i].CollapseComplete();
						else{
							collapse(menu, menu[path[path.length - 1] * 3 + 1][2]);
						}
						menuitem.style.backgroundColor = _cssmenubackgroundhighlight;
						menuitem.style.color = _cssmenutexthighlight;
						if(!/l0$/.test(id)){
							menuitem.nextSibling.style.backgroundColor = _cssmenubackgroundhighlight;
							menuitem.nextSibling.style.color = _cssmenutexthighlight;
						}
						id = menu[path[path.length - 1] * 3 + 1][3];
						var table = document.getElementById(id)
						table.style.display = 'block';
				
						if(left){
							table.style.left = left + 'px';
							if(browser == 'Internet Explorer'){
								table.style.top = (top + rowheight * row - parseFloat(row)) + 'px';
							}
							else
								table.style.top = (top + rowheight * row - row) + 'px';

						}
						_expanded = true;
					}
					//alert(id);
					if(/i/.test(id)){
						var href= child[itemID * 3 + 1][1];
						location.href = href;	
					}
					break;
			}
			if(evt.stopPropagation)
				evt.stopPropagation();
			else
				evt.cancelBubble = true;
			return true;
		}
		// -----------------------------------------------------------------------------------------
		// private some useful type checkers
		// -----------------------------------------------------------------------------------------
		function isFunction(a){	return typeof a == 'function';}
		function isObject(a){	return (typeof a == 'object' && !!a) || isFunction(a);}
		function isArray(a){	return isObject(a) && a.constructor == Array;}
	}
}
