/* ------------- Global variables and methods ------------- */

var
  arrMenus = [],
  intMenuItemIndex = 0;

try {
  var strMenuScriptPath = GetFilePath(document.getElementById('objMenuScript').src);
  document.write('<link href="' + strMenuScriptPath + 'menu.css" type="text/css" rel=stylesheet>');
} catch(e) {
  alert('objMenuScript object is not found');
}

function AddElementClass(objElement, strClassName) {
  objElement.className += ' ' + strClassName;
}

function GetElementPos(objElement) {
  var objResult = {x: objElement.offsetLeft, y: objElement.offsetTop};
  if (objElement.offsetParent && (objElement.style.position != 'absolute')) {
    var objTmp = GetElementPos(objElement.offsetParent);
    objResult.x += objTmp.x;
    objResult.y += objTmp.y;
  }
  return objResult;
}

function GetFilePath(strFile) {
  var strResult = '';
  var arrFolders = strFile.split('/');
  for (var i = 0; i < arrFolders.length - 1; i++)
    strResult += arrFolders[i] + '/';
  return strResult;
}

function HideMenus(objEvent) {
  if (!objEvent)
    objEvent = event;
  var objElement = objEvent.srcElement ? objEvent.srcElement : objEvent.target;
  var blnMouseOver = objEvent.type == 'mouseover';
  var blnClick = objEvent.type == 'click';
  if (blnMouseOver || blnClick)
    while (objElement != null) {
      var strClassName = new String(objElement.className);
      if ((blnMouseOver && (strClassName.indexOf('clsMenuItems') != -1)) ||
         (blnClick && (strClassName.indexOf('clsMenu') != -1) && (objElement.href == 'javascript:void(0)')))
        return;
      objElement = objElement.parentNode;
    }
  for (var i = 0; i < arrMenus.length; i++)
    if (blnClick)
      arrMenus[i].HideItems();
    else if (arrMenus[i].HideTimeout == null)
      arrMenus[i].HideTimeout = setTimeout('arrMenus[' + i + '].HideItems()', 1500);
}

function Item(strID, strCaption, strURL, strTarget, intImageIndex, strClassName, blnVerticalItems, arrItems) {
  return(new ItemClass(strID, strCaption, strURL, strTarget, intImageIndex, strClassName, blnVerticalItems, arrItems));
}

function Menu(arrItemImages, blnVerticalItems, arrItems) {
  return(new MenuClass(arrItemImages, blnVerticalItems, arrItems));
}

function RemoveElementClass(objElement, strClassName) {
  var arrClasses = objElement.className.split(' ');
  var strClasses = '';
  for (var i = 0; i < arrClasses.length; i++)
    if (arrClasses[i] != strClassName)
      strClasses += arrClasses[i] + ' ';
  objElement.className = strClasses.substr(0, strClasses.length - 1);
}

/* ------------- Item class ------------- */

function ItemClass(strID, strCaption, strURL, strTarget, intImageIndex, strClassName, blnVerticalItems, arrItems) {
  this.ID = strID;
  this.Index = intMenuItemIndex;
  this.Caption = strCaption;
  this.URL = strURL == '' ? 'javascript:void(0)' : strURL;
  this.Target = (strTarget == null) || (strTarget == '') ? '_self' : strTarget;
  this.ImageIndex = intImageIndex == null ? -1 : intImageIndex;
  this.ClassName = strClassName == null ? '' : strClassName;
  this.VerticalItems = (blnVerticalItems == null) || blnVerticalItems;
  this.Items = arrItems == null ? [] : arrItems;
  this.ItemsVisible = false;
  this.ItemsPosition = {Left: false, Top: false};
  this.Parent = null;
  this.Menu = null;
  intMenuItemIndex++;
}

ItemClass.prototype.AsHTML = function () {
  if (this.Caption == '-')
    return('<div class=clsMenuSplitter><img src="' + strMenuScriptPath + (this.Parent.VerticalItems ?
      'images/splitter1.gif" class=clsMenuHorSplitterImage' :
      'images/splitter2.gif" class=clsMenuVertSplitterImage') + '></div>');
  var strUniqueID = this.Menu.ID + '_' + this.ID;
  var blnCaptionIsTitle = this.Caption.substr(0, 1) == '^';
  return('<a id=Item' + strUniqueID + ' href="' + this.URL + '" target="' + this.Target + '" class="' +
    (this.HasItems() ? (this.Parent.VerticalItems ? 'clsMenuVertGroupItem ' : 'clsMenuHorGroupItem ') :
    (this.Parent.VerticalItems ? 'clsMenuVertItem ' : 'clsMenuHorItem ')) + this.ClassName +
    '" onmouseover="arrMenus[' + this.Menu.ID + '].ItemByID(\'' + this.ID + '\').ShowItems()"' +
    (blnCaptionIsTitle ? ' title="' + this.Caption.substr(1) + '"' : '') + '><nobr>' +
    ((this.ImageIndex == -1) && !this.Parent.VerticalItems ? '' :
    '<img src="' + (this.ImageIndex > -1 ? this.Menu.ItemImages[this.ImageIndex] : strMenuScriptPath + 'images/empty.gif') +
    '" class=clsMenuItemImage align=absmiddle>') + '<img src="' + strMenuScriptPath + 'images/empty.gif" ' +
    'class=clsMenuSpecImage align=absmiddle' + ((this.Caption != '') && !blnCaptionIsTitle ? '' : ' style="width: 0px"') +
    '>' + (blnCaptionIsTitle ? '' : this.Caption) + '</nobr></a>');
}

ItemClass.prototype.HasItems = function () {
  return(this.Items.length > 0);
}

ItemClass.prototype.HideItems = function () {
  if (this.ItemsVisible) {
    for (var i = 0; i < this.Items.length; i++)
      this.Items[i].HideItems();
    this.ItemsVisible = false;
    if (this.HasItems()) {
      var strUniqueID = this.Menu.ID + '_' + this.ID;
      document.getElementById('Items' + strUniqueID).style.display = 'none';
      RemoveElementClass(document.getElementById('Item' + strUniqueID), 'clsMenuSelectedItem');
    }
  }
}

ItemClass.prototype.InitItems = function (objMenu) {
  for (var i = 0; i < this.Items.length; i++) {
    var objItem = this.Items[i];
    objItem.Menu = objMenu;
    objItem.Parent = this;
    objItem.InitItems(objMenu);
  }
}

ItemClass.prototype.ItemByID = function (strID) {
  var objResult = null;
  for (var i = 0; i < this.Items.length; i++) {
    var objItem = this.Items[i];
    if (objItem.ID == strID) {
      objResult = objItem;
      break;
    } else {
      objResult = objItem.ItemByID(strID);
      if (objResult != null)
        break;
    }
  }
  return objResult;
}

ItemClass.prototype.ItemByURL = function (strURL) {
  var objResult = null;
  for (var i = 0; i < this.Items.length; i++) {
    var objItem = this.Items[i];
    if (objItem.URL == strURL) {
      objResult = objItem;
      break;
    } else {
      objResult = objItem.ItemByURL(strURL);
      if (objResult != null)
        break;
    }
  }
  return objResult;
}

ItemClass.prototype.ItemsAsHTML = function () {
  if (!this.HasItems())
    return '';
  var strResult = '';
  var strItems = '';
  for (var i = 0; i < this.Items.length; i++) {
    strResult += (!this.VerticalItems && (strResult != '') ? '</td><td>' : '') + this.Items[i].AsHTML();
    strItems += this.Items[i].ItemsAsHTML();
  }
  var strUniqueID = (this.Parent ? this.Menu.ID : 'menu') + '_' + this.ID;
  return('<div id=Items' + strUniqueID + ' class="clsMenuItems' + (this.Parent ? '' : ' clsMenuTopItems') + '"' +
    (this.Parent ? ' style="display: none; position: absolute; z-index: ' + (2000 - this.Index) + '"' : '') +
    '><table cellpadding=0 cellspacing=0><tr><td>' + strResult + '</td></tr></table></div>' + strItems);
}

ItemClass.prototype.ShowItems = function () {
  var intLeft, intRight, intTop, intBottom;
  if (this.Menu.HideTimeout != null) {
    clearTimeout(this.Menu.HideTimeout);
    this.Menu.HideTimeout = null;
  }
  if (this.Menu.SelectedItem == this)
    return;
  for (var i = 0; i < this.Parent.Items.length; i++)
    if (this.Parent.Items[i] != this)
      this.Parent.Items[i].HideItems();
  this.Menu.SelectedItem = this;
  if (this.ItemsVisible || !this.HasItems())
    return;
  this.ItemsVisible = true;
  var strUniqueID = this.Menu.ID + '_' + this.ID;
  var objItem = document.getElementById('Item' + strUniqueID);
  AddElementClass(objItem, 'clsMenuSelectedItem');
  var objItems = document.getElementById('Items' + strUniqueID);
  var objItemPos = GetElementPos(objItem);
  this.ItemsPosition.Left = this.Parent.ItemsPosition.Left;
  this.ItemsPosition.Top = this.Parent.ItemsPosition.Top;
  objItems.style.display = '';
  var intItemsWidth = objItems.getElementsByTagName('TABLE')[0].offsetWidth;
  var intItemsHeight = objItems.offsetHeight;
  if (this.Parent.VerticalItems) {
    intLeft = objItemPos.x - intItemsWidth;
    intRight = objItemPos.x + objItem.offsetWidth;
    intTop = objItemPos.y + objItem.offsetHeight + 1 - intItemsHeight;
    intBottom = objItemPos.y - 1;
  } else {
    intLeft = objItemPos.x + objItem.offsetWidth + 1 - intItemsWidth;
    intRight = objItemPos.x - 1;
    intTop = objItemPos.y - intItemsHeight;
    intBottom = objItemPos.y + objItem.offsetHeight;
  }
  var intWindowWidth = document.body.clientWidth ? document.body.clientWidth : window.innerWidth;
  var intWindowHeight = document.body.clientHeight ? document.body.clientHeight : window.innerHeight;
  if (this.ItemsPosition.Left && (intLeft < 0) && (intRight + intItemsWidth <= intWindowWidth))
    this.ItemsPosition.Left = false;
  else if (!this.ItemsPosition.Left && (intRight + intItemsWidth > intWindowWidth) && (intLeft >= 0))
    this.ItemsPosition.Left = true;
  if (this.ItemsPosition.Top && (intTop < 0) && (intBottom + intItemsHeight <= intWindowHeight))
    this.ItemsPosition.Top = false;
  else if (!this.ItemsPosition.Top && (intBottom + intItemsHeight > intWindowHeight) && (intTop >= 0))
    this.ItemsPosition.Top = true;
  objItems.style.left = (this.ItemsPosition.Left ? intLeft : intRight) + 'px';
  objItems.style.top = (this.ItemsPosition.Top ? intTop : intBottom) + 'px';
}

/* ------------- Menu class ------------- */

function MenuClass(arrItemImages, blnVerticalItems, arrItems) {
  this.ID = arrMenus.length;
  this.Menu = this;
  this.Menu.ID = this.ID;
  this.ItemImages = arrItemImages;
  this.VerticalItems = blnVerticalItems;
  this.Items = arrItems;
  this.ItemsPosition = {Left: false, Top: false};
  this.HideTimeout = null;
  this.SelectedItem = null;
  this.InitItems(this);
  arrMenus[this.ID] = this;
  if (arrMenus.length == 1) {
    if (document.attachEvent) {
      document.attachEvent('onclick', HideMenus);
      document.attachEvent('onmouseover', HideMenus);
    } else if (document.addEventListener) {
      document.addEventListener('click', HideMenus, true);
      document.addEventListener('mouseover', HideMenus, true);
    } else {
      document.onclick = HideMenus;
      document.onmouseover = HideMenus;
    }
  }
}

MenuClass.prototype.HideItems = function () {
  for (var i = 0; i < this.Items.length; i++)
    this.Items[i].HideItems();
  this.SelectedItem = null;
}

MenuClass.prototype.Render = function () {
  document.write(this.ItemsAsHTML());
}

MenuClass.prototype.HasItems = ItemClass.prototype.HasItems;
MenuClass.prototype.InitItems = ItemClass.prototype.InitItems;
MenuClass.prototype.ItemByID = ItemClass.prototype.ItemByID;
MenuClass.prototype.ItemByURL = ItemClass.prototype.ItemByURL;
MenuClass.prototype.ItemsAsHTML = ItemClass.prototype.ItemsAsHTML;