function SetHover(name, status)
{
	document.images[name].src = menuimgs[name][status].src;
}

function push(value, stack)
{
	stack[stack.length] = value;
}

function pop(stack)
{
	if (stack.length == 0) return false;
	var ret = stack[stack.length - 1];
	stack.length--;
	return ret;
}

function menu_SetBgColor(nodenum)
{
	this.overnode = nodenum;
	var curnode = GetById('tr_' + this.instance + '_' + nodenum);
	curnode.className = 'hover';
}

function menu_RestoreBgColor(nodenum)
{
	this.overnode = -1;
	var curnode = GetById('tr_' + this.instance + '_' + nodenum);
	curnode.className = '';
}

function menu_GetNode(nodenum)
{
	var struct =  (menu_GetNode.arguments.length == 1) ? this.struct : menu_GetNode.arguments[1];
	var result = false;
	for(var i=0; i<struct.length; i++)
	{
		if (struct[i]['nodenum'] == nodenum) 
		{
			return struct[i];
		}
		if (struct[i]['child'] != null) 
		{
			result = this.GetNode(nodenum, struct[i]['child']);
			if (result != false) return result;
		}
	}
	return result;
}

function menu_Hide()
{
	var stacklength = this.stack.length;
	for(var i=0; i<stacklength; i++)
	{
		var curmenu = pop(this.stack);
		var struct = this.GetNode(this.overnode);
		if ((curmenu != this.overnode) && (struct['menunum'] != curmenu))
		{
			if (i == stacklength-1) SetHover(this.currentfirst, 'nor');
			GetById('table_' + this.instance + '_' + curmenu).style.visibility = 'hidden';
			this.lefttoright = true;
		}
		else
		{
			push(curmenu, this.stack);
			return;
		}
	}
}

function menu_Show(nodenum)
{
	if (!this.run) return false;
	this.SetBgColor(nodenum);
	this.Hide();	
	for(var i=0; i<this.stack.length; i++)
	{
		if (this.stack[i] == nodenum) return;
	}
	this.overnode = nodenum;
	var showmenu = GetById('table_' + this.instance + '_' + nodenum);
	this.nomenu = false;
	if (menu_Show.arguments.length == 2)
	{
		this.currentfirst = menu_Show.arguments[1];
		if (!showmenu) this.nomenu = true;
		SetHover(menu_Show.arguments[1], 'hov');
	}	
	if (!showmenu) return;
	push(nodenum, this.stack);	
	var struct = this.GetNode(nodenum);
	var curmenu = GetById('table_' + this.instance + '_' + struct['menunum']);
	var curnode = GetById('tr_' + this.instance + '_' + nodenum, curmenu.document); 
	if (this.isIe)
	{
		if (menu_Show.arguments.length == 2)
		{
			GetById("div_" + menu_Show.arguments[1]).style.height = 0;
		}
		curmenu.style.height = 0;
		curnode.style.height = 0;
	}
	var y = (menu_Show.arguments.length == 2) ? GetById("div_" + menu_Show.arguments[1]).offsetTop + this.firstLevelOffsetY : curmenu.offsetTop + curnode.offsetTop + this.otherLevelOffsetY;
	if (menu_Show.arguments.length == 2)
	{
		var x = GetById('div_' + menu_Show.arguments[1]).offsetLeft + this.firstLevelOffsetX;
	}
	else
	{
		var rightlimit = curmenu.offsetLeft + curmenu.offsetWidth + showmenu.offsetWidth;
		if (rightlimit > document.body.clientWidth) this.lefttoright = false;
		var leftlimit = curmenu.offsetLeft - showmenu.offsetWidth;
		
		if (leftlimit < 0) this.lefttoright = true;
		if (this.lefttoright)
		{
			var x = curmenu.offsetLeft + curmenu.offsetWidth + this.otherLevelOffsetX;
		}
		else
		{
			var x = leftlimit + 1;
		}
	}
	showmenu.style.left = x;
	showmenu.style.top = y;
	showmenu.style.visibility = 'visible';
}

function menu_Out(nodenum)
{
	if (!this.run) return false;
	if (this.nomenu) SetHover(this.currentfirst, 'nor');
	this.RestoreBgColor(nodenum);
	clearTimeout(this.timeout);
	this.timeout = setTimeout(this.instance + '.Hide()', this.overTimeout);
}

function menu_Run()
{
	this.run = true;
	var firstlevel = (menu_Run.arguments.length == 0);
	var struct =  firstlevel ? this.struct : menu_Run.arguments[0];
	var tableid = firstlevel ? -1 : menu_Run.arguments[1];
	this.tmpcreatemenu[this.menucounter] = '<div id="table_' + this.instance + '_' + tableid + '" style="position:absolute; z-index:' + this.menucounter + ';visibility:hidden">';
	this.tmpcreatemenu[this.menucounter] += '<table border="0" cellspacing="0" cellpadding="0" class="popup">';
	for(var i=0; i<struct.length; i++)
	{
		this.tmpcreatemenu[this.menucounter] += '<tr bgcolor="' + this.outBgColor + '" onmouseover="' + this.instance + '.Show(' + struct[i]['nodenum'] + ')" onmouseout="' + this.instance + '.Out(' + struct[i]['nodenum'] + ')">';
		this.tmpcreatemenu[this.menucounter] += '<td><div style="width:100%; position:relative;" id="tr_' + this.instance + '_' + struct[i]['nodenum'] + '">' + struct[i]['text'] + '</div></td>';
		struct[i]['menunum'] = tableid;
		if (struct[i]['child'] != null)
		{
			this.menucounter++;
			this.Run(struct[i]['child'], struct[i]['nodenum']);
		}
		this.tmpcreatemenu[this.menucounter] += '</tr>';
	}
	this.tmpcreatemenu[this.menucounter] += '</tr><tr><td class="bottom"><img src="/img/sp.gif" width="1" height="6" alt="" border="0"></td></tr></table></div>';
	WriteHtml(this.tmpcreatemenu[this.menucounter]);
	this.menucounter--;
}

function menu_AddNode(text, parnum)
{
	if (parnum == null)
	{
		var rootlength = this.struct.length;
		this.struct[rootlength] = new Array(4);
		this.struct[rootlength]['text'] = text;
		this.struct[rootlength]['nodenum'] = this.curnode;
		this.struct[rootlength]['child'] = null;
		this.struct[rootlength]['menunum'] = -1;
	}
	else
	{
		var struct = this.GetNode(parnum);
		var tmparr = new Array(4);
		tmparr['text'] = text;
		tmparr['nodenum'] = this.curnode;
		tmparr['child'] = null;		
		tmparr['menunum'] = -1;
		
		if (struct['child'] == null)
		{
			struct['child'] = new Array();
		}
		curlength =  struct['child'].length;
		struct['child'][curlength] = tmparr;
	}
	return this.curnode++;
}

function Menu(instance)
{
	// Параметры конструктора
	this.instance = instance;

	// Private переменные
	this.isIe = navigator.appName == "Microsoft Internet Explorer";
	this.struct = new Array();
	this.tmpcreatemenu = new Array();
	this.menucounter = 0;
	this.curnode = 0; // Уникальный идентификатор узла
	this.lefttoright = true;
	this.stack = new Array();
	this.overnode = -1;
	this.timeout = 0;
	this.overTimeout = 1500;
	this.firstLevelOffsetX = 0;
	this.firstLevelOffsetY = 40;
	this.otherLevelOffsetX = -1;
	this.otherLevelOffsetY = -1;
	this.padding_left = '11px';
	this.run = false;

	// Private методы
	this.Hide = menu_Hide;
	this.GetNode = menu_GetNode;	
	this.SetBgColor = menu_SetBgColor;
	this.RestoreBgColor = menu_RestoreBgColor;
	
	// Public методы
	this.AddNode = menu_AddNode;
	this.Run = menu_Run;
	this.Show = menu_Show;
	this.Out = menu_Out;	
}