/* KaMenu Objects
  Menu Items:
  KaMenuBarItemFromText
  KaMenuItemFromText

  Menu:
  KaMenu - Must be defined within the <body> element.

  Other:
  KaMenuDefaults - Collection of default values for properties.
*/
/* KaMenu properties:
  action - Function or String.  Action to take when a user clicks on the menu item.
  submenu - KaMenu object.  Menu to show when mouse hover over the menu item or when
      a user clicks on the menu item and action==null.
  text - Text shown in a menu item built from text.

  "action", "text" and "submenu" properties apply only to menu items and are not inherited.
  All other properties are inherited.  If a property is not defined by any of the
  object's ascendants, then it is taken from the KaMenuDefault object.

  alignMenu - How to align menu in relation to its parent menu item.
  hOffset - Horizontal offset of the menu.
  vOffset - Vertical offset of the menu.
  color - Text color of the menu item.
  hoverColor - Text color when mouse hovers over the menu item.
  bgColor - Background color of the menu item.
  hoverBgColor - Background color when mouse hovers over the menu item.
  className - Name of a CSS class.
  menuTableClassName - Name of a CSS class applied to the menu table.
  menuCellClassName - Name of a CSS class applied to the <td> element in the menu table.
  menuDropDelay - The menu is shown menuDropDelay milliseconds after the mouse moves
      over the menu item.
  menuFoldDelay - The menu is hidden menuFoldDelay milliseconds after the mouse moves
      out of the menu item.
*/

var KaMenuDefaults = new Object();

KaMenuDefaults.menuDropDelay = 100;
KaMenuDefaults.menuFoldDelay = 500;
KaMenuDefaults.menuZIndex = 100;
KaMenuDefaults.frameUrl = window.location.protocol.toLowerCase()=="https:" ? "KaMenuDummy.htm" : "about:blank";
KaMenuDefaults.isMsieOnMac = window.navigator.userAgent.match(/\s+MSIE\s+5[^0-9]/i)!=null && window.navigator.platform.match(/^mac/i)!=null;

/* KaMenuBarItemFromText
Public properties:
  text
  action
  submenu
  alignMenu
  color
  hoverColor
  bgColor
  hoverBgColor
Public methods:
  render()
  setSubMenu(menu, alignMenu, hOffset, vOffset)
  disable()
  enable()
*/
function KaMenuBarItemFromText(text, color, hoverColor, bgColor, hoverBgColor, disabledColor, disabledBgColor) {
  KaMenuDefaults._registerMenuItem(this);
  this.text = text;
  this.color = color;
  this.hoverColor = hoverColor;
  this.disabledColor = disabledColor;
  this.bgColor = bgColor;
  this.hoverBgColor = hoverBgColor;
  this.disabledBgColor = disabledBgColor;
}

function KaMenuBarItemFromImage(imageUrl, hoverImageUrl, disabledImageUrl, width, height) {
  KaMenuDefaults._registerMenuItem(this);
  this.image = new Image();
  this.image.src = imageUrl;
  this.hoverImage = new Image();
  this.hoverImage.src = hoverImageUrl;
  this.disabledImage = new Image();
  this.disabledImage.src = disabledImageUrl;
  this.width = width;
  this.height = height;
}

/* KaMenuItemFromText
Public properties:
  text
  action
  submenu
  alignMenu
  color
  hoverColor
  bgColor
  hoverBgColor
Public methods:
  setSubMenu(menu, alignMenu, hOffset, vOffset)
  disable()
  enable()
*/
function KaMenuItemFromText(text, color, hoverColor, bgColor, hoverBgColor, disabledColor, disabledBgColor) {
  KaMenuDefaults._registerMenuItem(this);
  this.text = text;
  this.color = color;
  this.hoverColor = hoverColor;
  this.disabledColor = disabledColor;
  this.bgColor = bgColor;
  this.hoverBgColor = hoverBgColor;
  this.disabledBgColor = disabledBgColor;
}

/* KaMenu
Public properties:
  hOffset
  vOffset
Public methods:
  append(menuItem)
*/
function KaMenu() {
  KaMenuDefaults._registerMenuItem(this);
  this.items = new Array();
  for ( var i = 0 ; i < arguments.length ; ++i ) {
    var arg = arguments[i];
    //alert(arg.constructor);
    if ( arg.constructor == Array ) {
      for ( var j in arg ) {
        this.append(arg[j]);
      }
    } else {
      this.append(arg);
    }
  }

  var zIndex = KaMenuDefaults._attributeToStyle(this, 'menuZIndex', 'z-index');
  var visibility = KaMenuDefaults.isMsieOnMac ? "" : "visibility:hidden;";
  document.write('<iframe src="' + KaMenuDefaults.frameUrl + '" id=' + this._id + ' name=' + this._id +
    ' marginheight=0 marginwidth=0 frameborder=0 scrolling=no style="position:absolute;' + visibility + zIndex + '" width=1 height=1' +
    '></iframe>');
}
KaMenu.prototype.hOffset = 0;
KaMenu.prototype.vOffset = 0;
KaMenu.prototype.append = function(menuItem) {
  this.items[this.items.length] = menuItem;
  menuItem._parent = this;
}

// Internal Objects

function KaMenuItem() {
}
KaMenuItem.prototype.setSubMenu = function(submenu, alignMenu, hOffset, vOffset) {
  this._submenu = submenu;
  if ( submenu != null ) {
    submenu._parent = this;
    if ( alignMenu != null )
      submenu.alignMenu = alignMenu;
    if ( hOffset != null )
      submenu.hOffset = hOffset;
    if ( vOffset != null )
      submenu.vOffset = vOffset;
  }
}
KaMenuItem.prototype.disable = function() {
  this.disabled = true;
  this._foldMenu();
  if ( this._ondisable )
    this._ondisable();
}
KaMenuItem.prototype.enable = function() {
  this.disabled = false;
  if ( this._onenable )
    this._onenable();
}
KaMenuItem.prototype.hide = function() {
  this.isHidden = true;
  this._foldMenu();
}
KaMenuItem.prototype.show = function() {
  this.isHidden = false;
}
KaMenuItem.prototype.clone = function() {
  var ret = new Object();

  for ( var x in this ) {
    var y = this[x];
    if ( x.substr(0,1)!='_' || y.constructor==Function || x=='_defaultStyle' )
      ret[x] = this[x];
  }
  KaMenuDefaults._registerMenuItem(ret);

  return ret;
}
KaMenuItem.prototype._defaultStyle = new Object();
KaMenuItem.prototype._defaultStyle.alignMenu = "left=right; top=top";
KaMenuItem.prototype._onclick = function(element) {
  if ( this.disabled )
    return;
  if ( this.action ) {
    KaMenuDefaults.FoldAllMenus();
    if ( this.action.constructor == Function )
      this.action(this, element);
    else
      eval(this.action)
  } else if ( this.href ) {
    KaMenuDefaults.FoldAllMenus();
    window.location = this.href;
  } else if ( this._submenu ) {
    this._submenu._drop(element);
  }
}
KaMenuItem.prototype._onmouseoverhelper = function(element) {
  this._hasMouse = true;
  this._clearTimeout();
  this._element = element;
  this._timer = window.setTimeout('KaMenuDefaults._getMenuItem(' + this._ordinal + ')._dropMenu()',
    KaMenuDefaults._getAttribute(this, 'menuDropDelay'));
}
KaMenuItem.prototype._dropMenu = function() {
  if ( !this.disabled ) {
    if ( this._submenu )
      this._submenu._drop(KaMenuDefaults._getElement(this));
    else
      KaMenuDefaults._onMenuDrop(this);
  }
  this._clearTimeout();
}
KaMenuItem.prototype._onmouseouthelper = function() {
  this._hasMouse = false;
  this._mayHideSubMenu();
}
KaMenuItem.prototype._mayHideSubMenu = function() {
  this._clearTimeout();
  if ( this._submenu && !this._hasMouse && !this._submenu._hasMouse && this._submenu._visible && !this.disabled ) {
    this._timer = window.setTimeout('KaMenuDefaults._getMenuItem(' + this._ordinal + ')._foldMenu()',
      KaMenuDefaults._getAttribute(this, 'menuFoldDelay'));
  }
}
KaMenuItem.prototype._foldMenu = function() {
  if ( this._submenu ) {
    this._submenu._fold();
  }
  this._clearTimeout();
}
KaMenuItem.prototype._clearTimeout = function() {
  if ( this._timer ) {
    window.clearTimeout(this._timer);
    this._timer = null;
  }
}

KaInheritPrototype(KaMenuItemFromText.prototype, KaMenuItem.prototype);
KaMenuItemFromText.prototype._defaultStyle.width = '100%';
KaMenuItemFromText.prototype._render = function(doc) {
  return this._renderAs(doc);
}
KaMenuItemFromText.prototype._renderAs = function(doc, tagName, style) {
  if ( !tagName )
    tagName = 'div';
  var className = KaMenuDefaults._classAttrToHtml(this, 'className');
  var color = KaMenuDefaults._attributeToStyle(this, this.disabled?'disabledColor':'color', 'color');
  var bgColor = KaMenuDefaults._attributeToStyle(this, this.disabled?'disabledBgColor':'bgColor', 'background-color');
  var width = KaMenuDefaults._attributeToStyle(this, 'width');
  style = width + color + bgColor + (style?style:'');
  doc.write(
    '<' + tagName + ' id=' + this._id + className + ' style="' + style + '" ' +
    'onmouseover="KaMenuDefaults._onmouseover(' + this._ordinal + ',this)" ' +
    'onmouseout="KaMenuDefaults._onmouseout(' + this._ordinal + ',this)" ' +
    'onclick="KaMenuDefaults._onclick(' + this._ordinal + ',this)">' +
    this.text + '</' + tagName + '>');    
}
KaMenuItemFromText.prototype._onmouseover = function(element) {
  if ( !this.disabled )
    this._flipColors(element, 'hoverColor', 'hoverBgColor');
  this._onmouseoverhelper(element);
}
KaMenuItemFromText.prototype._onmouseout = function(element) {
  if ( !this.disabled )
    this._flipColors(element, 'color', 'bgColor');
  this._onmouseouthelper();
}
KaMenuItemFromText.prototype._flipColors = function(element, colorAttr, bgColorAttr) {
  var color = KaMenuDefaults._getAttribute(this, colorAttr);
  if ( color != null )
    element.style.color = color;
  var bgColor = KaMenuDefaults._getAttribute(this, bgColorAttr);
  if ( bgColor != null )
    element.style.backgroundColor = bgColor;
}
KaMenuItemFromText.prototype._ondisable = function() {
  var element = KaMenuDefaults._getElement(this);
  if ( element )
    this._flipColors(element, 'disabledColor', 'disabledBgColor');
}
KaMenuItemFromText.prototype._onenable = function() {
  var element = KaMenuDefaults._getElement(this);
  if ( element ) {
    if ( this._hasMouse )
      this._onmouseover(element);
    else
      this._onmouseout(element);
  }
}

KaInheritPrototype(KaMenuBarItemFromImage.prototype, KaMenuItem.prototype);
KaMenuBarItemFromImage.prototype.render = function() {
  this._render(document);
}
KaMenuBarItemFromImage.prototype._render = function(doc) {
  var className = KaMenuDefaults._classAttrToHtml(this, 'className');
  var size = "";
  if ( this.width != null )
    size += ' width="' + this.width + '"';
  if ( this.height != null )
    size += ' height="' + this.height + '"';
  var toolTip = this.toolTip!=null ? ' title="' + this.toolTip + '"' : '';
  var src = (this.disabled ? this.disabledImage : this.image).src;
  doc.write(
    '<img id=' + this._id + ' src="' + src + '" border=0' + className + size + toolTip +
    'onmouseover="KaMenuDefaults._onmouseover(' + this._ordinal + ',this)" ' +
    'onmouseout="KaMenuDefaults._onmouseout(' + this._ordinal + ',this)" ' +
    'onclick="KaMenuDefaults._onclick(' + this._ordinal + ',this)">');
}
KaMenuBarItemFromImage.prototype._onmouseover = function(element) {
  if ( !this.disabled )
    element.src = this.hoverImage.src;
  this._onmouseoverhelper(element);
}
KaMenuBarItemFromImage.prototype._onmouseout = function(element) {
  if ( !this.disabled )
    element.src = this.image.src;
  this._onmouseouthelper();
}
KaMenuBarItemFromImage.prototype._ondisable = function() {
  var element = KaMenuDefaults._getElement(this);
  if ( element )
    element.src = this.disabledImage.src;
}
KaMenuBarItemFromImage.prototype._onenable = function() {
  var el = KaMenuDefaults._getElement(this);
  if ( el ) {
    if ( this._hasMouse )
      this._onmouseover(el);
    else
      this._onmouseout(el);
  }
}

KaInheritPrototype(KaMenuBarItemFromText.prototype, KaMenuItemFromText.prototype);
KaMenuBarItemFromText.prototype._defaultStyle = new Object();
KaMenuBarItemFromText.prototype._defaultStyle.alignMenu = "left=left; top=bottom";
KaMenuBarItemFromText.prototype.render = function(tagName, style) {
  this._renderAs(document, tagName, style);
}

KaMenu.prototype._initCanvas = function() {
  if ( this._canvas && this._element )
    return true;
  this._canvas = window.frames[this._id];
  this._element = document.getElementById(this._id);
  if ( this._canvas && this._element )
    return true;
}
KaMenu.prototype._drop = function(parentElement) {
  if ( !this._rendered ) {
    if ( this._initCanvas() ) {
      var doc = this._canvas.document;
      if ( doc != null ) {
        this._documentElement = doc;
        this._renderMenu(doc);
      }
      this._rendered = true;
    }
  }
  if ( !parentElement )
    return;
  var frm = this._element;
  var offsetLeft = 0;
  var offsetTop = 0;
  var alignMenu = KaMenuDefaults._getAttribute(this, "alignMenu");
  if ( alignMenu != null ) {
    var align = alignMenu.split(/\s*[,;]\s*/);
    for ( var i = 0 ; i < align.length ; ++i ) {
      switch ( align[i].replace(/\s+/g, '').toLowerCase() ) {
      case "left=left":
        break;
      case "left=right":
        offsetLeft = parentElement.offsetWidth;
        break;
      case "right=right":
        offsetLeft = parentElement.offsetWidth - frm.offsetWidth;
        break;
      case "right=left":
        offsetLeft = -frm.offsetWidth;
        break;
      case "top=top":
        break;
      case "top=bottom":
        offsetTop = parentElement.offsetHeight;
        break;
      case "bottom=bottom":
        offsetTop = parentElement.offsetHeight - frm.offsetHeight;
        break;
      case "bottom=top":
        offsetTop = -frm.offsetHeight;
        break;
      case "":
        break;
      default:
        alert('Alignment "' + align[i] + '" in alignMenu="' + alignMenu + '" is invalid');
        return false;
      }
    }
  }
  for ( var el = parentElement ; el != null ; el = el.offsetParent ) {
    offsetLeft += el.offsetLeft;
    offsetTop += el.offsetTop;
  }
  frm.style.left = offsetLeft + this.hOffset;
  frm.style.top = offsetTop + this.vOffset;
  KaMenuDefaults._onMenuDrop(this);
  frm.style.visibility = "visible";
  this._visible = true;
  return true;
}
KaMenu.prototype._renderMenu = function(doc) {
  var i, j;

  var TableId = "KaMenuTableId" + this._ordinal;
  doc.write('<html><head><script>var KaMenuDefaults = parent.KaMenuDefaults;</script>');
  doc.write('<style>');
  for ( i = 0 ; i < document.styleSheets.length ; ++i ) {
    var css = document.styleSheets[i];
    if ( css.disabled )
      continue;
    if ( css.cssText ) { // MSIE
      doc.writeln(css.cssText);
    } else if ( css.cssRules ) {  // NS
      var rules = css.cssRules;
      for ( j = 0 ; j < rules.length ; ++j ) {
        var rule = rules[j];
        doc.writeln(rule.selectorText+'{'+rule.style.cssText+'}');
      }
    }
  }
  doc.write('</style>');
  doc.write('</head><body  onmouseover="KaMenuDefaults._getMenuItem('+this._ordinal+')._onmouseover()" onmouseout="KaMenuDefaults._getMenuItem('+this._ordinal+')._onmouseout()">');
  doc.write('<table cellspacing=0 cellpadding=0 id=' + TableId +
    KaMenuDefaults._classAttrToHtml(this, 'menuTableClassName') +
    '>');
  for ( i = 0 ; i < this.items.length ; ++i ) {
    var item = this.items[i];
    if ( item.isHidden )
      continue;
    doc.write('<tr><td nowrap' + KaMenuDefaults._classAttrToHtml(item, 'menuCellClassName') + '>');
    if ( item._render )
      item._render(doc);
    doc.write('</td></tr>');
  }
  doc.write("</table></body></html>");
  doc.close();
  var tbl = doc.all ? doc.all[TableId] : doc.getElementById(TableId);  // doc.all is needed for IE5 on Mac
  this._element.width = tbl.offsetWidth;
  this._element.height = tbl.offsetHeight;
  doc.KaMenuId = this._ordinal;
  doc.onmouseover = function() {
    KaMenuDefaults._getMenuItem(this.KaMenuId)._onmouseover();
  }
  doc.onmouseout = function() {
    KaMenuDefaults._getMenuItem(this.KaMenuId)._onmouseout();
  }
}
KaMenu.prototype._fold = function() {
  this._element.style.visibility = "hidden";
  this._visible = false;
  KaMenuDefaults._onMenuFold(this);
  if ( this._parent && !this._parent._hasMouse && this._parent._parent && !this._parent._parent._hasMouse ) {
    this._parent._parent._fold();
  }
}
KaMenu.prototype._onmouseover = function() {
  this._hasMouse = true;
  if ( this._visible && this._parent )
    this._parent._clearTimeout();
}
KaMenu.prototype._onmouseout = function() {
  this._hasMouse = false;
  if ( this._visible && this._parent )
    this._parent._mayHideSubMenu();
}


KaMenuDefaults._getAttribute = function(menuItem, sAttrName) {
  for ( ; menuItem != null ; menuItem = menuItem._parent ) {
    var ret = menuItem[sAttrName];
    if ( ret != null )
      return ret;
    ret = this._getAttribute(menuItem.styleBag, sAttrName);
    if ( ret != null )
      return ret;
    var ds = menuItem._defaultStyle;
    if ( ds ) {
      ret = ds[sAttrName];
      if ( ret != null )
        return ret;
    }
  }
  return KaMenuDefaults[sAttrName];
}
KaMenuDefaults._attributeToHtml = function(menuItem, sAttrName, sAttrHtml) {
  var attr = this._getAttribute(menuItem, sAttrName);
  if ( attr == null )
    return '';
  if ( sAttrHtml == null )
    sAttrHtml = sAttrName;
  return ' ' + sAttrHtml + '="' + attr + '"';
}
KaMenuDefaults._classAttrToHtml = function(menuItem, sAttrName) {
  return this._attributeToHtml(menuItem, sAttrName, 'class');
}
KaMenuDefaults._attributeToStyle = function(menuItem, sAttrName, sAttrSelector) {
  var attr = this._getAttribute(menuItem, sAttrName);
  if ( attr == null )
    return '';
  if ( sAttrSelector == null )
    sAttrSelector = sAttrName;
  return sAttrSelector + ':' + attr + ';';
}

KaMenuDefaults._menuItems = new Array();
KaMenuDefaults._registerMenuItem = function(menuItem) {
  var ordinal = this._menuItems.length;
  this._menuItems[ordinal] = menuItem;
  menuItem._ordinal = ordinal;
  menuItem._id = "KaMenuId" + ordinal;
}
KaMenuDefaults._getMenuItem = function(ordinal) {
  return this._menuItems[ordinal];
}
KaMenuDefaults._getElement = function(menuItem) {
  if ( !menuItem._element ) {
    var frame = menuItem._parent;
    var doc = frame ? frame._documentElement : null;
    if ( !doc || !doc.getElementById )
      doc = document;
    var el = doc.getElementById(menuItem._id);
    if ( el )
      menuItem._element = el;
  }
  return menuItem._element;
}
KaMenuDefaults._onmouseover = function(ordinal, element) {
  return this._getMenuItem(ordinal)._onmouseover(element);
}
KaMenuDefaults._onmouseout = function(ordinal, element) {
  return this._getMenuItem(ordinal)._onmouseout(element);
}
KaMenuDefaults._onclick = function(ordinal, element) {
  return this._getMenuItem(ordinal)._onclick(element);
}

KaMenuDefaults._openMenus = new Object();
KaMenuDefaults._onMenuDrop = function(menu) {
  var keepOpened = new Object();
  var m, ordinal;
  for ( m = menu._parent ; m != null ; m = m._parent ) {
    keepOpened[m._ordinal] = true;
  }
  var toFold = new Object();
  for ( ordinal in this._openMenus ) {
    if ( !keepOpened[ordinal] ) {
      toFold[ordinal] = this._openMenus[ordinal];
    }
  }
  for ( ordinal in toFold )
    toFold[ordinal]._fold();
  if ( menu._fold )
    this._openMenus[menu._ordinal] = menu;
}
KaMenuDefaults._onMenuFold = function(menu) {
  delete this._openMenus[menu._ordinal];
}
KaMenuDefaults.FoldAllMenus = function() {
  var toFold = new Object();
  for ( ordinal in this._openMenus ) {
    toFold[ordinal] = this._openMenus[ordinal];
  }
  for ( ordinal in toFold )
    toFold[ordinal]._fold();
}

function KaInheritPrototype(derivationProto, baseProto) {
  for ( var member in baseProto ) {
    derivationProto[member] = baseProto[member];
  }
}
