/*================================================================\
| geMenu | Dynamic JavaScript Menu                                |
| (C) GydruS, Alfa-group.biz                                      |
| v 1.0 RC1, may 2009.                                            |
| gydrus@alfa-group.biz                                           |
\================================================================*/

/*===================================\
| Config Section                     |
\===================================*/
// GE Dynamic Menu
var	geMenuElementClassName = 'geMenuElement'; // имя CSS-стиля для элементов меню
var	geMenuSelectedElementClassName = 'geMenuSelectedElement'; // имя CSS-стиля для выбранного элемента меню
var	geMenuHoveredElementClassName = 'geMenuHoveredElement'; // имя CSS-стиля для подсвеченного элемента меню
var	geMenuTableId = 'geMenu'; 				  // ИД таблицы в документе, в которой будет меню

/*===================================\
| Global Variables                   |
\===================================*/
var MenuMouseOver = false; 					  // флаг для определения, что мышка ушла с меню или подменю и все это хоз-во нужно скрыть
var Directions = Array(); 					  // массив с информацией направлений пунктов менюшек в таблицах - нужен для вычисления положений подменю

// GE Debug Maintanance
//geDebugEnabled = false;

/*===================================\
| Additional functions               |
\===================================*/
function getTextWidth(text)
{
	var spanElement = document.createElement('span');
	spanElement.style.whiteSpace = 'nowrap';
/**/spanElement.className = geMenuElementClassName;
	spanElement.innerHTML = text;
	document.body.appendChild(spanElement);
	var width = spanElement.offsetWidth;
	document.body.removeChild(spanElement);
	return width;
}

function getElementPosition(elemId)
{
    var elem = document.getElementById(elemId);
	
    var w = elem.offsetWidth;
    var h = elem.offsetHeight;
	
    var l = 0;
    var t = 0;
	
    while (elem)
    {
        l += elem.offsetLeft;
        t += elem.offsetTop;
        elem = elem.offsetParent;
    }

    return {"left":l, "top":t, "width": w, "height":h};
}

function setClassName(elemId, ClassName)
{
	var elem = document.getElementById(elemId);
	elem.className = ClassName;
}


/*===================================\
| GeMenu functions                   |
\===================================*/

// internal functions --------------\\

/*
 ф-я показывает подменю. при этом если у нужного к показу подменю много родителей-подменю - то они
 тоже будут видны. Все остальные подменющки "закроются".
 MenuTableId - id менюшки, в которой будем искать ElementId.
 ElementId - id элемента (TD из MenuTableId), подменю которого нам нужно в итоге показать.
 ф-я вызывается рекурсивно.
*/
function geMenuShowSubMenu(MenuTableId, ElementId)
{
///**/geDebugBeginFunct('geMenuShowSubMenu', 'MenuTableId="'+MenuTableId+'"', 'ElementId="'+ElementId+'"');

	var k = 0, j = 0;
	var found = false, foundAtCurrent = false;
	// получаем линк на sub-таблицу элементов меню
	var MenuTable = document.getElementById(MenuTableId);
	// берем в ней TRs
	for (j=0; j<MenuTable.rows.length; j++)
	{
		var TR = MenuTable.rows.item(j);
		// проходим по TD-шкам
		for (k=0; k<TR.cells.length; k++)
		{
			var TD = TR.cells.item(k);
			var SubMenuTable = document.getElementById(TD.id+'_SubMenuTable');
			// если у TD-шки есть подменю
			if (SubMenuTable!=null)
			{
//				geDebug('k='+k+'; TD.id="'+TD.id+'"; ElementId="'+ElementId+'"');
				// Если это то подменю, которое мы ищем
				if (ElementId == (TD.id+'_SubMenuTable'))
				{
//					geDebug('found!!!');
					foundAtCurrent = true;
					SubMenuTable.style.display='block';
					//break; - брек тут не делаем, чтобы была возможность захайдить остальные подменю;
				}
				// иначе (у TD-шки есть подменю, но оно не то, которое нам нужно) ищем глубже - идем дальше в подменю
				else
				{
					found = geMenuShowSubMenu(SubMenuTable.id, ElementId);
					//if (found) break; - брек тут тоже не делаем, чтобы была возможность "захайдить" остальные подменю;
					if (found) {foundAtCurrent = true; SubMenuTable.style.display='block';}
					else SubMenuTable.style.display='none';
				}
			}
		}
	}

	found = foundAtCurrent || found;
///**/geDebugEndFunct(found);
	return found;	
}

function geShowSubMenu(Id)
{
	MenuMouseOver = true;
	geMenuShowSubMenu(geMenuTableId,Id);
}

function geHideSubMenusEx()
{
	if (!MenuMouseOver)
	{
		// ниженаписанная хитрая конструкция оставит видимым только главное меню и закроет все подменю
		geMenuShowSubMenu(geMenuTableId,'no_element');
	}
}

function geHideSubMenus()
{
	setTimeout( "geHideSubMenusEx()", 1000 );
}


function geGetParentTableDirection(Id)
{
	var ParentTable = document.getElementById(Id);
	while (ParentTable.parentNode.tagName != 'TABLE')
	{
		if (ParentTable.parentNode != null) ParentTable = ParentTable.parentNode;
		else break;
	}
	return Directions[ParentTable.parentNode.id];
}

function geMenuCreateHorizontalElement(RowId, Text, Id)
{
	var Row = document.getElementById(RowId);
	var Cell = document.createElement('td');
	Cell.id = Id;
	Cell.innerHTML = Text;
	Cell.className = geMenuElementClassName;
	Row.appendChild(Cell);
}

function geMenuCreateVerticalElement(TableId, Text, Id)
{
	var Table = document.getElementById(TableId);
	var Row = Table.insertRow(0);
	var Cell = document.createElement('td');
	Cell.id = Id;
	Cell.innerHTML = Text;
	Cell.className = geMenuElementClassName;
	Row.appendChild(Cell);
}


// functions for using to create menus \\

function geMenuAddHorizontal(ParentId)
{
	var Table;
	if (ParentId == null)
	{
		Table = document.getElementById(geMenuTableId);
	}
	else
	{
		Table = document.createElement('table');
		Parent = document.getElementById(ParentId);
		Table.id = ParentId+'_SubMenuTable';
		Table.style.position = 'absolute';
		Table.border = 0;
		Table.cellSpacing = 0;
		Table.cellPadding = 0;
		var pos = getElementPosition(ParentId);
		// парент - ячейка. А в массиве направлений данные ассоциируются с таблицей этой ячеки, посему:
		if (geGetParentTableDirection(ParentId) == 'v')
		{
			Table.style.left = (pos.left+pos.width)+'px';
			Table.style.top = pos.top+'px';
		}
		else
		{
			Table.style.left = pos.left+'px';
			Table.style.top = (pos.top+pos.height)+'px';
		}
		Table.onmouseover = function () {MenuMouseOver = true;}
		Table.onmouseout = function () {MenuMouseOver = false; geHideSubMenus();}
		document.body.appendChild(Table);
				
		Parent.onmouseover = function () {geShowSubMenu(Table.id); /*geMenuEnlight(ParentId)*/}
		Parent.onmouseout = function () {geHideSubMenus();}
	}
	Directions[Table.id] = 'h';

	var Row = Table.insertRow(0);
	Row.id = Table.id+'_Row';
	
	for (i=1; i<arguments.length; i=i+2)
	{
		geMenuCreateHorizontalElement(Row.id, arguments[i], arguments[i+1]);		
	}
}

function geMenuAddVertical(ParentId)
{
	var Table;
	if (ParentId == null) Table = document.getElementById(geMenuTableId);
	else
	{
		Table = document.createElement('table');
		Table.id = ParentId+'_SubMenuTable';
		Table.style.position = 'absolute';
		Table.border = 0;
		Table.cellSpacing = 0;
		Table.cellPadding = 0;
		var pos = getElementPosition(ParentId);
		// парент - ячейка. А в массиве направлений данные ассоциируются с таблицей этой ячеки, посему:
		if (geGetParentTableDirection(ParentId) == 'v')
		{
			Table.style.left = (pos.left+pos.width)+'px';
			Table.style.top = pos.top+'px';
		}
		else
		{
			Table.style.left = pos.left+'px';
			Table.style.top = (pos.top+pos.height)+'px';
		}
		Table.onmouseover = function () {MenuMouseOver = true;}
		Table.onmouseout = function () {MenuMouseOver = false; geHideSubMenus();}
		document.body.appendChild(Table);
		
		Parent = document.getElementById(ParentId);
		Parent.onmouseover = function () {geShowSubMenu(Table.id);}
		Parent.onmouseout = function () {geHideSubMenus();}
	}
	Directions[Table.id] = 'v';

	for (i=1; i<arguments.length; i=i+2)
	{
		geMenuCreateVerticalElement(Table.id, arguments[i], arguments[i+1]);		
	}
}

/*
 ф-я добавляет новые элементы меню в конец подменю для ячейки с ParentId.
*/
function geMenuAppend(ParentId)
{
	var MenuTable;
	if (ParentId == null) ParentId = geMenuTableId;
	else ParentId += '_SubMenuTable';
	MenuTable = document.getElementById(ParentId);
	if (Directions[ParentId] == 'v')
	{
		for (i=1; i<arguments.length; i=i+2) geMenuCreateVerticalElement(ParentId, arguments[i], arguments[i+1]);		
	}
	else
	{
		var RowId = ParentId+'_Row';
		for (i=1; i<arguments.length; i=i+2) geMenuCreateHorizontalElement(RowId, arguments[i], arguments[i+1]);		
	}
}

/*
 ф-я пересчитывает положение всех подменю
 ее предназначение - работа после того, как родительская таблица меню сменила свое положение,
 например, при ресайзе окна
*/
function geMenuCalibrateSubMenus(ParentId)
{
///**/geDebugBeginFunct('geMenuCalibrateSubMenus', 'ParentId="'+ParentId+'"');

	var MenuTable;
	var k = 0, j = 0;

	if (ParentId == null) ParentId = geMenuTableId;
	MenuTable = document.getElementById(ParentId);
	// берем в полученной таблице TRs
	for (j=0; j<MenuTable.rows.length; j++)
	{
		var TR = MenuTable.rows.item(j);
		// проходим по TD-шкам
		for (k=0; k<TR.cells.length; k++)
		{
			var TD = TR.cells.item(k);
			var SubMenuTable = document.getElementById(TD.id+'_SubMenuTable');
			// если у TD-шки есть подменю
			if (SubMenuTable!=null)
			{
				var pos = getElementPosition(TD.id);
				// парент - ячейка. А в массиве направлений данные ассоциируются с таблицей этой ячеки, посему:
				if (geGetParentTableDirection(TD.id) == 'v')
				{
					SubMenuTable.style.left = (pos.left+pos.width)+'px';
					SubMenuTable.style.top = pos.top+'px';
				}
				else
				{
					SubMenuTable.style.left = pos.left+'px';
					SubMenuTable.style.top = (pos.top+pos.height)+'px';
				}

				// далее идем вглубь, чтобы "построить" "детей"
				// при этом таблицу-родителя делаем видимой на время этой процедуры!
				// иначе pos будет = 0
				SubMenuTable.style.display='block';
				geMenuCalibrateSubMenus(SubMenuTable.id);
				SubMenuTable.style.display='none';
			}
		}
	}
///**/geDebugEndFunct();
}

function geMenuEnlight(ElementId)
{
	setClassName(ElementId, geMenuSelectedElementClassName)
}

function geMenuDelight(ElementId)
{
	setClassName(ElementId, geMenuElementClassName)
}

// Call This function at BODY.onLoad()...
// You can change diz function's body as you like! ;P
function DoMenu()
{
	geMenuAddHorizontal(null, 'IdSect1', 'IdSect1', 'IdSect2', 'IdSect2', 'IdSect3', 'IdSect3');
	geMenuAddVertical('IdSect2', 'IdSubSect2.1', 'IdSubSect2.1', 'IdSubSect2.2', 'IdSubSect2.2', 'IdSubSect2.3', 'IdSubSect2.3');
	geMenuAddHorizontal('IdSubSect2.1', 'IdSubSect2.1.1', 'IdSubSect2.1.1');
	geMenuAddHorizontal('IdSect3', 'IdSubSect3.1', 'IdSubSect3.1', 'IdSubSect3.2', 'IdSubSect3.2');
	geMenuAddHorizontal('IdSubSect2.3', 'IdSubSect2.3.1', 'IdSubSect2.3.1', 'IdSubSect2.3.2', 'IdSubSect2.3.2');
	geMenuAddVertical('IdSubSect3.2', 'IdSubSect3.2.1', 'IdSubSect3.2.1', 'IdSubSect3.2.2', 'IdSubSect3.2.2');
	geMenuAddVertical('IdSubSect3.2.1', 'IdSubSect3.2.1.1', 'IdSubSect3.2.1.1', 'IdSubSect3.2.1.2', 'IdSubSect3.2.1.2');
	geMenuAppend(null,'1213','23212','ya','ya');
	geMenuAppend('IdSect2','1id3','2id12','ya2','ya2');
	//geMenuEnlight('IdSect2');
	geMenuCalibrateSubMenus();
}

//
// and don't forget put in body tag this attribute: 'onresize="geMenuCalibrateSubMenus();"'!
// 

function SPECgeMenuEnlight(ElementId)
{
	var Elem = document.getElementById(ElementId);
	Elem.className = geMenuSelectedElementClassName;
	var links = Elem.getElementsByTagName("a");
	if (links[0] != null)
	{
		links[0].innerHTML = '<span class = "'+geMenuSelectedElementClassName+'">'+links[0].innerHTML+'</span>';
	}
	//if (links[0] != null) {links[0].className = geMenuSelectedElementClassName;}
}


/*================================================================\
| geMenu | 2Do                                                    |
\================================================================*/
/*
 - Insert, Swap, Delete Elements;
 - OnClick handler! And address parameter. При этом тег А должен автоматом добавляться в элементы! Это нужно для поисковиков!
 - Different Styles For Hovered and Selected Elements!
 - function geMenuAdd(Direction, ParentId)
   {
	   if (Direction == 'h') 
	   else for (i=2; i<arguments.length; i=i+2) geMenuCreateVerticalElement(ParentId, arguments[i], arguments[i+1]);		
   }

*/
