var console = null;

function debug(msg) {
  if(console == null || console.closed) {
    console = window.open("","console","width=600,height=300,scrollbars");
    console.document.open("text/plain");
  }
  console.focus();
  console.document.writeln(msg);
}

var debugbody = '';

// Set up the event handlers
if(document.all) { 
  document.onmouseout = ehandler;
  document.onmouseover = ehandler;
  document.onmousedown = ehandler;
} else { 
  document.addEventListener("mousedown", ehandler, true);
  document.addEventListener("mouseover", ehandler, true);
  document.addEventListener("mouseout", ehandler, true);
}

//
// No real need to do anything as MenuContainer is purely a 
// 'marker' identifier; however Javascript doesn't provide default
// constructors and complains.
//
// MenuContainer Constructor
//

// More of a marker interface than anything else
MenuContainer.prototype = new Menu();
MenuContainer.incontainer = 0;
Menu.prototype.active = false; 
MenuItem.prototype = new Menu(); 
MenuItem.prototype.outcolor = '#333366';
MenuItem.prototype.overcolor = '#FFA500';
MenuItem.prototype.outbgcolor = '#FFA500';
MenuItem.prototype.overbgcolor = '#333366';
MenuItem.prototype.font = 'verdana';
MenuItem.prototype.width = '100px';

// this.onerror = reporterror;

var itemindex = 0;

function reporterror(msg,url,line) {
  alert('Error: ' + msg + ' at ' + line + ' within ' + url);
}

function MenuContainer() {
}

// Get the children from this menuitem
Menu.prototype.getChildren = function() {
  return this.children;
};

// Add a child to this menu
Menu.prototype.addChild = function() {
  if(!this.children) {
    this.children = [];
  }
  this.children[this.children.length] = arguments[0];
  if(arguments[0] instanceof MenuItem) {
    arguments[0].id = 'item' + itemindex++;
  }
  if(arguments[0].url) {
    // debug('Adding child ' + arguments[0].id + ' (' + arguments[0].url + ') to ' + this.id);  
  }
  arguments[0].parent = this; 
};

// Hide this menu and all it's children
Menu.prototype.hideMenu = function() {
  var children = this.children;
  for(var j = 0; j < children.length; j++) {
    var elem = children[j];
    getElement(elem.id).style.visibility = "hidden";
    getElement(elem.id).style.backgroundColor = elem.backgroundColor;
    if(elem.children) {
      elem.hideMenu();
    }
  }
}

// Display this menu in the co-ordinates given
Menu.prototype.displayMenu = function() {
  var children = this.children; 
  for(var j = 0; j < children.length; j++) {
    var elem = children[j];
    if(arguments[0] && arguments[1]) {
      getElement(elem.id).style.left = arguments[0];
      getElement(elem.id).style.top = arguments[1]; 
    }
    getElement(elem.id).style.color = '#000000';
    getElement(elem.id).style.visibility = "visible";
    getElement(elem.id).style.color = elem.outcolor;
    getElement(elem.id).style.backgroundColor = elem.outbgcolor;
    getElement(elem.id).style.fontFamily = elem.font;
    getElement(elem.id).style.fontWeight = 'bold';
    getElement(elem.id).style.fontSize = '8pt';
    getElement(elem.id).style.textDecoration = 'none';
    getElement(elem.id).style.filter = 'alpha(opacity=90)';
    // debug(dumpobject(getElement(elem.id).style));
    if(elem.children) {
      if(arguments[0] && arguments[1]) {
        elem.displayMenu(arguments[0],arguments[1]); 
      } else {
        elem.displayMenu(); 
      }
    }
  }
}

// Locate a menu item 
Menu.prototype.findMenuItem = function() {
  var id = arguments[0];
  if(!id) {
    return;
  }
  if(this.id && this.id.match(id)) {
    return this;
  }
  // debug(this.id + ' vs ' + id);
  if(this.children) { 
    var c = this.children; 
    for(var i = 0; i < c.length; i++) {
      // debug('Searching for ' + id + ' against ' + c[i].id + ' ' + this.children.length);
      if(c[i].id.match(id)) {
        // debug(id + ' matches ' + c[i].id);
        return c[i];
      } 
      if(c[i].children) {
        var fi = c[i].findMenuItem(id);
        if(fi) {
          return fi;
        }
      }
    }
  } 
}

// Render this menu tree using the supplied renderer
Menu.prototype.render = function(renderer) {
  renderer(this);
}

// Add event handling code for all the elements
Menu.prototype.addhandlers = function() {
  var c = this.getChildren();
  for(var i = 0; i < c.length; i++) {
    if(c[i].children) {
      c[i].addhandlers;
    }
    getElement(c[i].id).onmouseover = mouseoverhandler;
    getElement(c[i].id).onmouseout = mouseouthandler;
    getElement(c[i].id).menuitem = c[i];
  }
}

function Menu() {
}

// MenuItem Constructor
function MenuItem(id,name,url) {
  this.id = arguments[0];
  this.name = arguments[1];
  this.url = arguments[2];
}

function getElementPosition(elemID) {
    var offsetTrail = document.getElementById(elemID);
    var offsetLeft = 0;
    var offsetTop = 0;
    while (offsetTrail) {
        offsetLeft += offsetTrail.offsetLeft;
        offsetTop += offsetTrail.offsetTop;
        offsetTrail = offsetTrail.offsetParent;
    }
    if (navigator.userAgent.indexOf("Mac") != -1 && 
        typeof document.body.leftMargin != "undefined") {
        offsetLeft += document.body.leftMargin;
        offsetTop += document.body.topMargin;
    }
    return {left:offsetLeft, top:(offsetTop + 20)};
}


// Render it - use a pluggable renderer
function defaultRenderer() {
  var node = arguments[0];
  if(node instanceof MenuContainer) {
    var style = '';
    style += 'border: 1px solid #000000';
    style += ';width: 120px; background-color: #000066';
    style += ';visibility: hidden; position: absolute';
    document.write('<div id="' + node.id + '" style="' + style + '">');
    debugbody += '<div id="' + node.id + '" style="' + style + '">\n';
  } else if (node instanceof MenuItem) {
    var style = '';
    style += 'visibility: hidden; width: 120px; padding: 2px; cursor: hand';
    document.write('<div class="menuitem" id="' + node.id + '" style="' + style + '">');
    document.write(node.name);
    debugbody += '<div class="menuitem" id="' + node.id + '" style="' + style + '">\n';
    debugbody += node.name + '\n';
  } 
  if(node.children) {
    var c = node.getChildren();
    for(var i = 0; i < c.length; i++) {
      defaultRenderer(c[i]);
    }
  } 
  if(node instanceof MenuItem || node instanceof MenuContainer) {
    debugbody += '</div>\n';
    document.write('</div>');
  }
}

// Debugging method
function dumpobject() {
  var e = arguments[0]; 
  var p = ""; 
  for(var i in e) {
    p += (i + ' = ' + e[i] + '\n');
  } 
  debug('dumpobject: ' + p);
}

//
// I really hate the way IE handles nested 'div's with mouseout 
// and mouseover
//
function ehandler(event) {
  var evt = (window.event) ? window.event : event; 
  var target = (document.all) ? evt.srcElement : evt.target;  
  var mi = mm.findMenuItem(target.id);
  if(mi) { 
    if(evt.type == 'mousedown') {
      if(mi instanceof MenuItem) {
        document.location = mi.url;
      } else if(mi instanceof Menu) {
        // debug('Active page: ' + mm.active.id + ' mouse down page: ' + mi.id + ' ' + mi.active);
        if(mm.active && (mi == mm.active)) {  
          // debug('Active page = active page');
          mm.active.active = false;
          mm.active.hideMenu();
          mm.active = null;
          mi.hideMenu();
        } else {
          if(mm.active) {
            mm.active.hideMenu();
            mm.active = false;
          }
          var ep = getElementPosition(target.id);
          var y = ep.top;
          var x = ep.left;
          mm.active = mi;
          // debug('displaying ' + mi.id);
          mi.displayMenu(x,y);
          mi.active = true;
        }
      } 
    } else if(evt.type == 'mouseover') {
      if(mi instanceof MenuItem) {
        // debug(mi.id);
        getElement(mi.id).style.backgroundColor = mi.overbgcolor;
        getElement(mi.id).style.color = mi.overcolor;
      } else if(mi instanceof Menu) {
        // var y = target.offsetTop + target.clientHeight;
        // var x = target.offsetLeft;
        // mi.displayMenu(x,y);
      }
    } else if(evt.type == 'mouseout') {
      if(mi instanceof MenuItem) {
        getElement(mi.id).style.backgroundColor = mi.outbgcolor;
        getElement(mi.id).style.color = mi.outcolor;
      } else if(mi instanceof MenuContainer) {
        // 
      } else if(mi instanceof Menu) {
        // 
      } 
    }
  }
}


// Browser incompatibilies
function getElement(id) {
  if(document.all)
    return document.all[id];
  else 
    return document.getElementById(id);
}
