﻿/* --------- Список меню ----------- */
/* Пример
Menus = new Array(); //список
Menus[1] = new Menu
(
  [
  new MenuItem('Продать', ,'#1'),
  new MenuItem('Купить', ,'#2'),
  new MenuItem('Отнять','A(2)'),
  new MenuItem('Отнять несколько раз', ,'#31'),
  new MenuItem('----', ''),
  new MenuItem('Дать в долг', ,'#4','img/cmenu/point.gif')
  ]
  ,'|V|E|'
  ,'Купить'
);
*/

/* --------- Constants --------- */
var MN_NOITEMSTXT = 'No menu'; //Когда нет пунктов меню для отображения в меню

/* --------- Globals --------- */
var gMenuCurLevel = 1; //Текущий уровень меню - пока зашито. Других уровней нет


/* --------- Вызов и отображение меню --------- */

//Вызов меню объекта
/*
  -> obj - объект, на который нажали (this)
  -> event - передача событийщика (event)
  -> menuId - ид. меню, которое нужно вывести
              Вариант 1: menuId=Id, использует переменную Menus [отключено]
            !!!Вариант 2: menuId[0]=Id, menuId[1]=MenusObj (можно не указывать, тогда = переменной Menus)
              Вариант 3: menuId='', используется метод Mn_GetMenuId [отключено]
  -> button - по какой кнопке должно выводиться меню: 1 - левая кнопка, 2 - правая (по умолчанию)
  -> pos - необязательный параметр. pos[0]=posObj, pos[1]=offsetT, pos[2]=offsetL, pos[3]=dirH - СМ.ФУНКЦИЮ Mn_CreatePosAr()
         - posObj - объект, относительно которого позиционируется меню (если не передан, то используются координаты мыши)
         - offsetT - смещение сверху (используется, если передан posObj, необязат.)
         - offsetL - смещение слева (используется, если передан posObj, необязат.)
         - dirH - направление отсчета. по умолч. слева-направо. dirH=1 - справа-налево (не реализовано)
         !!! Можно передать в pos только объект (без массива), относительно которого будет выводиться меню
*/
function OnMenuClick(obj,event,menuId,button,pos)
{
  Mn_CreateDivs();
  // Разбор menuId
  var menuInfoArr = Mn_GetMenuInfo(menuId);
  var menusObjEx = menuInfoArr[0];
  var menuIdEx = menuInfoArr[1];
  

  // Ид. меню явно не указано
  if (menuIdEx === '') menuIdEx = Mn_GetMenuId(obj);

  if (menuIdEx === '') return; // Ид. меню найти не удалось

  if (!menusObjEx[menuIdEx]) return; // Нет такого меню

  if (button == undefined) {button = 2;};
  if (Mn_ButtonCorrect(event,button) == 0) return;

  SetMenuValue(0); //Выключение предыдущего меню
  if (button == 2)
  {
    obj.oncontextmenu = function() {return false;}; //Отключение у объекта вывода контекстного меню браузера
  };

  //Получение координат относительно body для posObj
  if ((pos === undefined)||(pos === '')) 
  {
    pos = new Array();
  }
  else if ((typeof(pos) == 'object')&&(!pos[0])) // если передан только объект, без координат
  {
    var tempObj = pos;
    pos = new Array();
    pos[0] = tempObj;
  }

  if (pos[0]) 
  {
    var posObj = pos[0];
	  var offAr = GetBodyOffset(posObj);
  	var posObjTop = offAr[0];	
  	var posObjLeft = offAr[1];
  	var y = posObjTop + posObj.offsetHeight - document.body.scrollTop;	
  	if (pos[1]) y += pos[1];
  	var x = posObjLeft;
  	if (pos[2]) x += pos[2];		
  }
  else 
  {
    var x = event.clientX;
    var y = event.clientY;
  	//alert(x + '|' + y);
  }

  //Показ меню
  menusObjEx[menuIdEx].onShow(x,y);

  Mn_MenuInitBody(event, event.button);
};

// Формирование массива pos для функции OnMenuClick
function Mn_CreatePosAr(obj,posTop,posLeft)
{
  var pos = new Array();
  pos[0] = obj;
  if (posTop) pos[1] = posTop;
  if (posLeft) pos[2] = posLeft;

  return pos;
};

// Получение информации из переменной menuId об используемом меню
// Возвращает:
// Массив [0] = menusObjEx - Массив списка меню
//        [1] = menuIdEx - Ид. меню
function Mn_GetMenuInfo(menuId)
{
  //Определение меню
  var menuIdInStr = true; // id меню в строке menuId
  var menuIdInArray = false; // id меню указан в массиве menuId
  var menusObjEx =null; //Объект списка меню
  var menuIdEx = ''; //Вычисленный Id меню (в списке)

  if ((typeof(menuId) === 'object')) menuIdInArray = true;
  if ((menuId === undefined)||(menuId === '')) menuIdInStr = false; 
  
  if (menuIdInStr) menuIdEx = menuId;

  // Ид. меню в массиве
  if (menuIdInArray)
  {
    menuIdEx = menuId[0];
    if (menuId[1]) menusObjEx = menuId[1];
  }

  if (menuIdEx == undefined) menuIdEx = '';

  var ar = new Array();
  ar[0] = menusObjEx;
  ar[1] = menuIdEx;
  return ar;
}

// Настройка Body для работы с меню
// Устанавливается обработчик для выключения меню, а также отключается показ контекстного меню на странице.
function Mn_MenuInitBody(event, evButton)
{
  //document.body.onresize = function() { SetMenuValue(0); };
  Wndw_RegOnResize('SetMenuValue', function(){SetMenuValue(0);});
  document.body.onscroll = function() { SetMenuValue(0); };
  document.body.onmousedown = function(event) { MenuBodyClick(event?event:window.event); }; // Чтобы работало и под Mozilla и под IE
  if (evButton == 2) document.body.oncontextmenu = function(){return false;};
}

// Показ одного уровня меню. По умолчанию - первый
// strAr - строки
// ToDo - для подменю нужно будет подругому считать позиционирование!!!
function Mn_DrawLevel(strAr,level,x,y)
{
  if (!level) level = 1;

  CMenuCreateDivs(level);

  var DIV=document.getElementById('CMenuLevel' + level)
  var str = strAr.join('');
  DIV.innerHTML = str;

  // Вычисление позиции DIV
  //_Включение DIV, получение размеров, Выключение
  DIV.style.display = 'inline';
  var CWidth = DIV.offsetWidth;
  var CHeight = DIV.offsetHeight; //Высота блока с меню
  DIV.style.display = 'none';

  //_Получение свободного места
  var TopHeight = y; // свободное место над курсором
  var VisibleHeight = document.body.clientHeight; // Высота видимой области
  var BotHeight = VisibleHeight - y; // свободное место под курсором
  var LeftWidth = x; // свободное место справа от курсора
  var RightWidth = document.body.clientWidth - x; // свободное место слева от курсора

  //alert(CHeight + ':' + TopHeight + '|' + BotHeight + '| x='+ x + ' y=' + y );

  // Проверка на свободное место: Вертикаль
  var TopPos = y;
  if ((BotHeight < CHeight)&&(TopHeight > BotHeight)) TopPos = y - CHeight;
  
  // Проверка на свободное место: Горизонталь
  var LeftPos = x;
  if ((RightWidth < CWidth)&&(LeftWidth > RightWidth)) LeftPos = x - CWidth;

  // Проверка, что меню помещается по высоте
  if ((CHeight + 20) > VisibleHeight)
  {
    CHeight = VisibleHeight - TopHeight - 10;
    CWidth = CWidth + 20;
    DIV.style.height = CHeight;
    DIV.style.width = CWidth;
    DIV.style.overflowY = 'auto';
  }

  TopPos = TopPos + document.body.scrollTop;
  DIV.style.top = TopPos;
  DIV.style.left = LeftPos;
  DIV.style.display = 'inline';
 
  DrawMenuShadow(level,TopPos,LeftPos);
  
  //WCH
  var id = 'CMenuLevel' + level + 'WCH';
  ShowWCH(CWidth, CHeight, TopPos, LeftPos, id);
}

// Тень меню
function DrawMenuShadow(level, topPos, leftPos)
{
  var mainDIV=document.getElementById('CMenuLevel' + level);
  var DIV=document.getElementById('CMenuLevel' + level + 'Shadow');

  var leftPlus = 5;

  //if (IsIE()) leftPlus = leftPlus + 2;

  DIV.style.top = topPos + 5;
  DIV.style.left = leftPos + leftPlus;
  DIV.style.width = mainDIV.offsetWidth;
  DIV.style.height = mainDIV.offsetHeight;
  DIV.style.display = 'inline';
}

// Включение DIV, выключающего доступ к BODY сайта
// Служит для закртия меню, если нажать вне меню
function ShowMenuHider()
{
  // Включение фонового экрана
  var HDIV = document.getElementById('MenuHider');
  var SizeDIV = document.getElementById('MainDiv'); //Вычисление полного размера страницы
  
  // _Вычисление размера:
  var HWidth = document.body.clientWidth;
  if (HWidth < SizeDIV.offsetWidth) {HWidth = SizeDIV.offsetWidth;};
  HDIV.style.width = HWidth;

  var HHeight = document.body.clientHeight;
  if (HHeight < SizeDIV.offsetHeight) {HHeight = SizeDIV.offsetHeight};
  HDIV.style.height = HHeight;
   
  HDIV.style.display = 'inline';
}

// Нажатие на прячущий DIV = value=0
function SetMenuValue(value)
{
  if (value == 0)
  {
    var DIVL1 = document.getElementById('CMenuLevel1');

    if (DIVL1.style.display == 'none') return false;

    var DIVL1S = document.getElementById('CMenuLevel1Shadow');
    var HDIV = document.getElementById('MenuHider');

    document.body.onmousedown = null;
    document.body.oncontextmenu = '';
    Wndw_UnRegOnResize('SetMenuValue');

    DIVL1.style.display = 'none';
    DIVL1S.style.display = 'none';
    HDIV.style.display = 'none';

    //WCH
    var id = 'CMenuLevel' + gMenuCurLevel + 'WCH';
    HideWCH(id);

    DIVL1.style.height = null;
    DIVL1.style.width = null;
    DIVL1.style.overflowY = 'visible';
  }
}

// Нажатие на пункт меню
function CMenuClick(url)
{
  document.location.href=url;
  SetMenuValue(0);
}

// Формирование DIV с меню - визуализация
function CMenuCreateDivs(level)
{
  if (!level) {level = 1;}

  CMDiv = document.getElementById('CMenu');
  //alert(CMDiv.innerHTML);

  var id = 'CMenuLevel' + level + 'WCH';
  WCH = document.getElementById(id);
  if (!WCH)
  {
    var zindex = 200 + ((level-1) * 10);
    var str = '<DIV id="' + id + '" class="CMenuWCHDiv" style="z-index:' + zindex + ';"><IFRAME></IFRAME></DIV>';
    CMDiv.innerHTML = CMDiv.innerHTML + str;
  }
}

// Нажатие мыши на странице. Событие onmousedown для body
// Служит для закрытия активного меню.
function MenuBodyClick(event,doClose)
{
  if (doClose == undefined) doClose = 1;
  
  // Проверка - нажали на включенное меню, или нет
  var x = event.clientX
  x = x + document.body.scrollLeft;
  var y = event.clientY
  y = y + document.body.scrollTop;
  var DIV = document.getElementById('CMenuLevel1');
  var top = DIV.style.top;
  top = +top.match(/\d*/)[0]; //Перевод из строки 435px в число -> 435
  var left = DIV.style.left;
  left = +left.match(/\d*/)[0];
  var w = +DIV.offsetWidth;
  var h = +DIV.offsetHeight;

  var inX = ((x >= left)&&(x <= (left + w)));
  var inY = ((y >= top)&&(y <= (top + h)));

  //alert(x + ' : ' + left + ' : ' + (left + w) + ' = ' + inX);
  //alert(y + ' : ' + top + ' : ' + (top + h) + ' = ' + inY);

  if (inX && inY) doClose = 0;

  if (doClose == 1) SetMenuValue(0);
}

// Получение ид. меню из атрибутов объекта
// Ид. кодируется в атрибуте id = "|MId=<ид.>|"
function Mn_GetMenuId(obj)
{
  var values = obj.id;
  if (values == '') return '';

  var r = /\|MId=.*?\|/;
  var str = values.match(r);

  if (str != null) //|Mid=<id>|
  {
    str = str[0];
    var L = str.length;
    L = L-6;
    str = str.substr(5,L);
  }
  else
  {
    str = '';
  }

  return str;
}

// Проверка, что нажата нужная кнопка для показа меню
// <- 0: неправильная кнопка, 1:правильная
function Mn_ButtonCorrect(event,button)
{
  var evButton = event.button;
  if (evButton == undefined) evButton = 1;
  if (button == undefined) {button = 2;};
  if (evButton == 0) {evButton = 1}; // В мозиле левая кнопка = 0, а в ИЕ = 1
  // Нажата неправильная кнопка
  if (evButton != button) {return 0};
  event.returnValue = false;
  event.cancelBubble = true;

  return 1;
}

/* ----------- Menu  ----------- */

// Создание Меню для объекта
// -> items - массиво элементов меню
// -> codes - коды пунктов меню "|A1|A2|...|An|". Исп. для объединения
// -> cur   - текст текущего пункта меню (необязат.)
// -> curID - ID текущего пункта меню (необязат.)
function Menu(items, codes , cur, curID)
{
  this.items = items;
  this.codes = codes;
  this.current = cur;
  this.currentID = curID;
}

// Показ меню
Menu.prototype.onShow = function (x,y)
{
  var strAr = new Array();
  strAr[strAr.length]='<table cellpadding="0" cellspacing="0" border="0">';
  strAr[strAr.length]='<tr><td><img src="/images/_n.gif" width="5" height="1" alt="" /></td><td><img src="/images/_n.gif" width="125" height="1" alt="" /></td></tr>';
  for (var i=0; i < this.items.length; i++ )
  {
    var item = this.items[i];
    if (item) item.onShow(strAr, this.current, this.currentID);
  }

  strAr[strAr.length]='</table>';
  Mn_DrawLevel(strAr,gMenuCurLevel,x,y)
}

/* --------- Menu Item ----------- */

// Создание Пнукта меню
// -> subMenu - объект "под-меню"
function MenuItem(name,action,url,img,subMenu,ItemID)
{
  this.name = name;
  this.url = url;
  this.img = img;
  this.subMenu = subMenu;
  this.action = action;
  this.ItemID = ItemID
}

// Формирование визуализации пункта меню
MenuItem.prototype.onShow = function (strAr, curTxt, curID)
{
  Mn_MenuItemOnShow(this, strAr, curTxt, curID)
}

// Непосредственное формирование визуализации Одного пункта меню
function Mn_MenuItemOnShow(menuObj, strAr, curTxt, curID)
{
  var name = menuObj.name;
  var ItemID = menuObj.ItemID;
  if (curID == undefined) curID='';
  if (curTxt == undefined) curTxt='';
  var str = '';

  if (name != '----') // Если не разделитель
  {
    if ((ItemID == curID)&(curID != '')) name = '<b>' + name + '</b>'; 
    var img = menuObj.img;
    if (img ) //Есть картинка
    {
      img = '<img src="'+img+'" width="16" height="16" alt="" class="CMI" />';
    }
    else
    {
      img = '';
    }

    str = str + '<tr class="CMITr" onmouseover="this.className=\'CMITrOver\'" onmouseout="this.className=\'CMITr\'" ';
    var url='CMenuClick(\'' + menuObj.url + '\');';
    var action = (menuObj.action=='') ? url : menuObj.action + 'SetMenuValue(0);';
    str = str + 'onclick="' + action + '">';
    str = str + '<td class="CMITdImg" width="1px" NoWrap>' + img + '</td>';
    str = str + '<td class="CMITdA">' + name + '</td></tr>'
  }
  else // Если разделитель
  {
    str = str + '<tr><td colspan="2" class="CMITdDiv"><div><img src="/images/_n.gif" width="1" height="1" alt="" /></div></td></tr>';
  };

  strAr[strAr.length] = str ;
}

// Создание необходимых элементов
function Mn_CreateDivs()
{
  var div = document.getElementById('CMenu');
  if (div) return;
  
  div = document.createElement('DIV');
  document.body.appendChild(div);
  div.id = 'CMenu';
  
  var str='';
  str = str + '<DIV id="CMenuLevel1" oncontextmenu="return false;"></DIV>';
  str = str + '<DIV id="CMenuLevel1Shadow" oncontextmenu="return false;"></DIV>';
  str = str + '<DIV id="MenuHider" onclick="SetMenuValue(0);" oncontextmenu="return false;"></DIV>';
  div.innerHTML = str;
}