// Product title: Gurt JavaScript Menu
// Product version details: 1.1, 01-25-2006 (mm-dd-yyyy)
// Product URL: http://gurtom.com/products/menus/js
// Contact info: feedback@gurtom.com (specify product title in subject line)
// Notes: This script is free. Feel free to copy, use and change this script as 
// long as this head part remains unchanged. Visit official site for details.
// Copyright: (c) 2006 by Gurtom.Com

var menus = [],
aMenu = window.external ? ['', 'div onclick="', 'div'] : ['', 'a href="javascript:', 'a'],
//aMenu = window.external ? [' style="width:100%;height:100%"', 'div onclick="', 'div'] : ['', 'a href="javascript:', 'a'],
gMenuGetElem = document.getElementById
	? function(sId) { return document.getElementById(sId) }
	: function(sId) { return document.all[sId] },
_onStateId = 0, _onStateSubId = 0, _onStateChildCount = 0, _onStateChildIds = [];

function menu(aFields, oCfg) {
	var _ = this, i;
	_.aFields = aFields;
	_.oCfg = oCfg;
	_.sPath = '';
	_.id = menus.length;
	_.aAll = [];
	_.aKids = [];
	_.aOffset = [0, 0];
	
	_.oCfg[-1] = {
		'firstX' : 20,
		'firstY' : 20,
		'nextX' : 15,
		'nextY' : 15,
		'width' : 100,
		'height' : 22,
		'hideAfter' : 200,
		'target' : '_self',
		'trace' : 0,
		'css' : '',
		'cssSub' : '',
		'onStateItem' : '',
		'onStateSubItem' : ''
	};
	
	// Pre-determine onStateItem and its submenu, if any.
	i = 0;
	while (i < _.aFields.length && gItemCfg(i, oCfg, 'onStateItem') != _.aFields[i][0]) {
		_onStateId += _.aFields[i].length - 2;
		i ++;	
	}
	_onStateId += i;
	_onStateChildCount = _.aFields[i].length - 2;

	// Keep moving through the items and pre-determine the onStateSubItem.
	onStateChildFound = false;
	// Set the onStateSubItem to the onStateItem initially.
	_onStateSubId = _onStateId;
	while (i < _.aFields.length && !onStateChildFound) {
		j=0;
		while (j < _.aFields[i].length && !onStateChildFound) {
			if (_.aFields[i][j][0] == gItemCfg(i, oCfg, 'onStateSubItem')) {
				_onStateSubId += j - 1;
				onStateChildFound = true;
			}
			j++;	
		}
		i ++;	
	}

	for (i = 0; i < _.aFields.length; i++) 
		if (_.aFields[i])
			new gMenuItem(0, _, _, _.aFields[i], _onStateChildCount);	

	for (i = 0; i < _.aKids.length; i++)
		gItemShow(_.aKids[i], 1);
	menus[_.id] = _;
}

function gMenuHide (mId) {
	var i, a = menus[mId].aAll;
	for (i = 0; i < a.length; i++) {
		gItemShow(a[i], 0);
		if (i == _onStateId || i == _onStateSubId)
			gItemTrig(a[i],'on');
		else 
			gItemTrig(a[i],'norm');
	}
}

function gMenuOnclick (mId, iId) {
	var m = menus[mId], _ = m.aAll[iId].aFields[1];
	gItemTrig(m.aAll[iId], 'clck');
	if (_) open(_, gItemCfg(m.aAll[iId].depth, m.oCfg, 'target'));
}

function gMenuOnmouseout (mId, iId) {
	var m = menus[mId];
	m.nHideTimer = setTimeout('gMenuHide('+ mId +')', gItemCfg(m.oActiveItem.depth, m.oCfg, 'hideAfter'));
	if (m.oActiveItem.id == iId)
		m.oActiveItem = null;
}

function gMenuOnmouseover (mId, iId) {
	var m = menus[mId], _, bVisib, i;
	m.oActiveItem = _ = m.aAll[iId];
	if (m.nHideTimer) clearTimeout(m.nHideTimer);
	for (i = 0; i < m.aAll.length; i++) {
		_ = m.aAll[i];
		bVisib = !m.oActiveItem.sPath.indexOf(_.sPathShort);
		if (bVisib)
			if (i == _onStateId || i == _onStateSubId)
				gItemTrig(_, _ == m.oActiveItem ? 'over' : 'on');
			else 
				gItemTrig(_, _ == m.oActiveItem ? 'over' : 'norm');
			gItemShow(_, bVisib);
	}
	if (m.oActiveItem.bTrace)
		for (i = m.oActiveItem; i && i.aRefs; i = i.oParent)
			gItemTrig(i, 'over');
}

// --- menu item Class ---
function gMenuItem (l, p, m, aFields, onStateChildCount) {
	var _ = this, i, c = p.aKids.length, oCfg = m.oCfg, state = "norm", xOffset, yOffset;
	_.aFields = aFields;
	_.oParent = p;
	_.sPathShort = p.sPath;
	_.sPath = p.sPath + c + ':';
	_.depth = l;
	_.id = m.aAll.length;
	m.aAll[_.id] = _;
	p.aKids[c] = _;
	var id = m.id + ',' + _.id, nX, nY;
	_.bTrace = gItemCfg(l, oCfg, 'trace');
	
	for (i = l; i >= -1; i --) {
		if (oCfg[i] && oCfg[i]['nextX'] != null)
			nX = oCfg[i]['nextX'];
		if (oCfg[i] && oCfg[i]['nextY'] != null)
			nY = oCfg[i]['nextY'];
		if (nX != null || nY != null)
			break;
	}
	
	// If the id of the current item is the _onStateId, set the state to "on".
	if (_.id == _onStateId) {
		state = "on";
	}

	xOffset = p.aOffset[0] + gItemCfg(l, oCfg, 'firstX') + (nX != null ? nX * c + gItemCfg(l, oCfg, 'width') * c : 0);
	yOffset = p.aOffset[1] + gItemCfg(l, oCfg, 'firstY') + (nY != null ? nY * c + gItemCfg(l, oCfg, 'height') * c : 0);
	
	// If the id of the current item is greater than _onStateId then change yOffset value.
	if (_.id > _onStateId) {
		yOffset = p.aOffset[1] + gItemCfg(l, oCfg, 'firstY') + (nY != null ? (nY * c + gItemCfg(l, oCfg, 'height') * c) + (onStateChildCount * gItemCfg(l, oCfg, 'height')) : 0);
	}
	
	_.aOffset = [xOffset, yOffset];

	document.write('<', aMenu[1], 'gMenuOnclick(', id, ')" id="me', id, '" style="position:absolute;top:', _.aOffset[1], 'px;left:', _.aOffset[0], 'px;width:', gItemCfg(l, oCfg, 'width'), 'px;height:', gItemCfg(l, oCfg, 'height'), 'px;visibility:hidden;z-index:', l, ';text-decoration:none" onmouseout="gMenuOnmouseout(', id, ')" onmouseover="gMenuOnmouseover(', id, ')"><div', aMenu[0], ' id="mi', id, '" class="', gItemCfg(l, oCfg, 'css'), state,'">', aFields[0], '</div></', aMenu[2], '>');
		
	_.aRefs = [gMenuGetElem('me' + m.id + ',' + _.id), gMenuGetElem('mi' + m.id + ',' + _.id), gItemCfg(l, oCfg, 'css')];

	if (aFields.length > 2) {
		_.aKids = [];
		for (i = 2; i < aFields.length; i++)
			if (aFields[i]) {
				if (_.id == _onStateId)
					new gSubMenuItem(0, _, m, aFields[i], 1);
				else
					new gMenuItem(l + 1, _, m, aFields[i], 0);
			}
	}
}

function gSubMenuItem (l, p, m, aFields, onStateChildCount) {
		var _ = this, i, c = p.aKids.length, oCfg = m.oCfg, state = "norm", xOffset, yOffset;
	_.aFields = aFields;
	_.oParent = p;
	_.sPathShort = p.sPath;
	_.sPath = p.sPath + c + ':';
	_.depth = l;
	_.id = m.aAll.length;
	m.aAll[_.id] = _;
	p.aKids[c] = _;
	var id = m.id + ',' + _.id, nX, nY;
	_.bTrace = false;
	
	for (i = l; i >= -1; i --) {
		if (oCfg[i] && oCfg[i]['nextX'] != null)
			nX = oCfg[i]['nextX'];
		if (oCfg[i] && oCfg[i]['nextY'] != null)
			nY = oCfg[i]['nextY'];
		if (nX != null || nY != null)
			break;
	}
	
	// If the id of the current item is the _onStateId, set the state to "on".
	if (_.id == _onStateSubId) {
		state = "on";
	}

	xOffset = p.aOffset[0] + gItemCfg(l, oCfg, 'firstX') + (nX != null ? nX * c + gItemCfg(l, oCfg, 'width') * c : 0);
	yOffset = p.aOffset[1] + gItemCfg(l, oCfg, 'firstY') + (nY != null ? (c + gItemCfg(l, oCfg, 'height') * c) + (onStateChildCount * gItemCfg(l, oCfg, 'height')) : 0);
	
	_.aOffset = [xOffset, yOffset];
	
	document.write('<', aMenu[1], 'gMenuOnclick(', id, ')" id="me', id, '" style="position:absolute;top:', _.aOffset[1], 'px;left:', _.aOffset[0], 'px;width:', gItemCfg(l, oCfg, 'width'), 'px;height:', gItemCfg(l, oCfg, 'height'), 'px;visibility:visible;z-index:', l, ';text-decoration:none" onmouseout="gMenuOnmouseout(', id, ')" onmouseover="gMenuOnmouseover(', id, ')"><div', aMenu[0], ' id="mi', id, '" class="', gItemCfg(l, oCfg, 'cssSub'), state,'">', aFields[0], '</div></', aMenu[2], '>');
	_.aRefs = [gMenuGetElem('me' + m.id + ',' + _.id), gMenuGetElem('mi' + m.id + ',' + _.id), gItemCfg(l, oCfg, 'cssSub')];

}

function gItemShow(_, is_visible) {
	if (_.oVisible == is_visible) return;
	_.oVisible = is_visible;
	if (is_visible)
		_.aRefs[0].style.visibility = 'visible';
	else if (_.depth)
		_.aRefs[0].style.visibility = 'hidden';
}

function gItemTrig(_, nState) {
	if (_.aRefs[3] == nState) return;
	_.aRefs[3] = nState;
	_.aRefs[1].className = _.aRefs[2] + nState
}

function gItemCfg(l, oCfg, k) {
	for (var i = l; i >= -1; i --)
		if (oCfg[i] && oCfg[i][k] != null)
			return oCfg[i][k];
}