/**
 * Mango Menu JavaScript
 * copyright (c) 2003 WarpGear Software
 *
 * You are permitted to use this code under the conditions
 * outlined by an M.I.T. style license. According to this
 * license, YOU MAY NOT REMOVE THIS COPYRIGHT NOTICE.
 * The complete text of the license can be found here:
 * http://www.favorez.com/mango_menu_license.txt
 *
 * version: 1.0
 * last modified: Dec 15, 2003
 * author: Tom Kalmijn (freelance C++ & Java developer)
 **/

// define globals
var menu = null; // set to the DIV that contains the menu in init()
var nextId = 0; // counter to obtain unique TreeNode id's
var selId = 0; // id of last clicked link
var allNodes = new Array(); // lookup list for nodes (node.id == index)
var root; // TreeNode: root of all nodes
var prevID = -1; // keep track of hovering over same item (onmouseover)
var eventid = 0; // used to process only last incoming message
var scrollid = 0; // used to ignore multiple scroll events
var selPath = new Array(); // path with all currently selected items 
var curDepth = -1; // helper var for selection path
var bScrolling = false;
var brw = getBrowser();
var bSetBackColor = true; // true unless BACKIMG has been set
var bEmbedded = false; // false unless user uses function 'mango()' to insert menu in html 
if (typeof(basedir)=="undefined") basedir = '';

// event handlers
function onClick(id) {
    node = allNodes[id];
    if (node.canExpand) {
        var e = !node.isExpanded;
        node.expand(e);
        node.highLight(e);
        selPath[node.nesting]=node;
    }
}

function onMouseUp(id) {
    var node = allNodes[id];
    if (!node.canExpand) {
        prevID = -1;
        selId = id;
        collapse(root);
        window.open(node.path, (INT_LINK==""||node.path.indexOf(INT_LINK)==-1)?URL_TARGET:"_top");
    }
}

function onDocumentClick() {
    prevID = -1;
    collapse(root);
    if (doScroll) onScroll(++scrollid);
}

function onMouseOver(id) {
    cancelid++;
    if (prevID == id) return;
    prevID = id;
    var node = allNodes[id];
    collapse(node);
    node.highLight(true);
    if (SHOW_URL) window.status = node.canExpand ? "" : node.path;

    // delay-expand node
    id = (node.canExpand && !node.isExpanded) ? node.id : -1;
    setTimeout("expand("+id+","+(++eventid)+")", 100);
}

var cancelid = 0;

function onMouseOut() {
    setTimeout("cancelMenu("+(++cancelid)+")",300);
}

function cancelMenu(id) {
  if (id==cancelid) onDocumentClick();
}

function delayScroll() {
    setTimeout("onScroll("+(++scrollid)+")", 400);
}

function onScroll(id) {
    if (curDepth > 0 || (curDepth == 0 && selPath[curDepth].isExpanded))
        return; // do not move menu while it is open

    var bEndScroll = id==scrollid;
    var t = windowTop() + TOP;
    var l = windowLeft() + LEFT;

    if (bEndScroll) {
        setTop(root.div, t);
        if (!horizontal) setLeft(root.div, l);
        if (bScrolling) showMenu(root, true);
        bScrolling = false;
        prevID = -1;
    }
    else {
        if (t != getTop(root.div) || (l != getLeft(root.div) && !horizontal)) {
            showMenu(root, false);
            bScrolling = true;
        }
    }
}

function expand(id, eid) {
    if (eid == eventid && id >= 0) allNodes[id].expand(true);
}

function collapse(node) {
    var depth = node.nesting;
    for (i = curDepth; i >= depth; i--) {
        var n = selPath[i];
        if (n) {
            if (n.canExpand && n.isExpanded && n != root) n.expand(false);
            n.highLight(false);
            selPath[i] = null;
        }
    }
    curDepth = depth;
    selPath[depth] = node;
    if (SHOW_URL && node == root) window.status = "";
}

// generic helper functions
function getBrowser() {
    var brw = "any"; // = modern browsers (e.g. IE 5+, Netscape 7+, Mozilla 1+, Opera 7+)
    if (document.all&&(!window.opera)) { // Internet Explorer
		var mac = (navigator.userAgent.indexOf('Mac')!=-1)? true:false;
        var av = navigator.appVersion;
        av = av.substring(av.indexOf("MSIE ")+5);
        if ((parseInt(av) < 5) || mac) brw = "ie4";
    }
    else if (document.layers) { // Netscape 4.x
        brw = "ns4";
    }
    else if (window.sidebar) {
        var ua = navigator.userAgent;
        if (ua.indexOf("Netscape6")!=-1)
            brw = "ns6";
    }
    return brw;
}

function i2h(n) { // IntToHex
    n = Math.round(n);
	var result = n.toString(16);
	if (result.length==1) result = "0"+result;
	return result;
}

function h2i(hex) { // HexToInt
	return parseInt(hex, 16);
}

function ab(color, factor) { // adjust brightness
	var r = Math.min(h2i(color.substring(1,3))*factor,255);
	var g = Math.min(h2i(color.substring(3,5))*factor,255);
	var b = Math.min(h2i(color.substring(5,7))*factor,255);
    return "#"+i2h(r)+i2h(g)+i2h(b);
}

function out(html){
  if(brw=="ns4") document.open();
  document.write(html);
  if(brw=="ns4") document.close();
}

function include(file) {
    out("<script type=\"text/javascript\" language=\"JavaScript\" src=\""+basedir+file+"\"></script>");
}

// declare & define class TreeNode
// *** this class is browser independant, no html allowed ***
function TreeNode(canExpand) {
    this.id = 0;
    this.subNodes = null;
    this.parent = null;
    this.horz = false;
    this.index = -1;
    this.isExpanded = false;
    this.canExpand = canExpand;
    this.nesting = -1;
    this.subIcons = false;

    // assign methods (needs to be done only once)
    if (typeof(_TreeNode_prototype_called) == "undefined") {
        _TreeNode_prototype_called = true;
        TreeNode.prototype.expand = expand;
        TreeNode.prototype.add = add;
        TreeNode.prototype.highLight = highLight;
    }

    function add(node) {
        // init subNodes lazily
        if (!this.subNodes)
            this.subNodes = new Array();
        node.parent = this;
        node.nesting = this.nesting+1;
        node.index = this.subNodes.length;
        node.horz = node.parent == root && horizontal;
        if (!node.canExpand) {
          if (node.icon==""||node.icon=="01.png") node.icon = ICON_LINK;
          node.bIcon = (LINK_ICONS==1 || (LINK_ICONS==2 && node.icon!=ICON_LINK));
        }
        else node.bIcon = (FOLDER_ICONS==1 || (FOLDER_ICONS==2 && this!=root));
        if ((node.bIcon || FORCE_GUTTER) && !this.subIcons) this.subIcons = true;
        this.subNodes[node.index] = node;
        allNodes[node.id] = node;
        return node;
    }

    function expand(expand) {
        if (this.subNodes) {
            this.isExpanded = expand;
            this.show(expand);
        }
    }

    function highLight(show) {
        setHighLight(this, show);
    }
}

// Menu extends AbsTreeNode, renders a node as a Menu.
// (see prototype assignment at end of class)
function Menu(name) {
    this.id = nextId++;
    this.bInit = false;
    this.name = name;
    this.div = null;
    this.leftExpand = false;

    // assign methods
    if (typeof(_Menu_prototype_called) == "undefined") {
        _Menu_prototype_called = true;
        Menu.prototype.al = al; // add link
        Menu.prototype.am = am; // add (sub) menu
        Menu.prototype.init = init;
        Menu.prototype.show = show; // override abstract TreeNode.show
        Menu.prototype.setZIndex = setZIndex;
        Menu.prototype.setPos = setPos;
        Menu.prototype.left = left;
        Menu.prototype.top = top;
        Menu.prototype.width = width;
        Menu.prototype.height = height;
        Menu.prototype.itemHeight = itemHeight;
        Menu.prototype.show = show;
    }

    function left() { // try and keep menu on the screen
        var lw = windowLeft();
        if (this==root) return lw+LEFT;        
        var ww = windowWidth();
        var rs = lw+ww; // right side
        var w = getWidth(this.div);
        if (this.horz) {
            var totalWidth = bEmbedded ? getRLeft(root.div) : LEFT;
            for (i = 0; i < this.index; i++) totalWidth += this.parent.subNodes[i].w;
            var l = totalWidth+BORDER_SIZE;
            return l+w > rs ? rs-w : l;
        }
        var lp = bEmbedded && this.parent==root ? getRLeft(root.div) : getLeft(this.parent.div);
        var wp = getWidth(this.parent.div);
        var sd = this.parent!=root||sdwMain?sdwSize:0;
        var l = lp+wp+OFFX-sd;
        this.leftExpand = (this.parent.leftExpand || (l+w>rs)) && (l-wp-w>lw);
        return this.leftExpand ? lp-w-OFFX+sd : (l+w>rs ? rs-w:l);
    }

    function top() {
        if (this==root) return windowTop()+TOP;
        if (this.horz) return (bEmbedded ? getRTop(root.div) : getTop(root.div))+root.height()-(sdwMain?sdwSize:0);
        return (this.parent==root && bEmbedded ? getRTop(root.div) : getTop(this.parent.div))+this.index*this.parent.itemHeight()+OFFY;
    }

    function height() {
        return getHeight(this.div);
    }

    function width() {
		if (!this.w) this.w = getWidth(this.div);
        return this.w;
    }

    function itemHeight() {        
        if (!this.ih) { 
          var sd = this!=root||sdwMain?sdwSize:0;
          this.ih = (getHeight(this.div)-2*BORDER_SIZE-sd)/(this==root&&horizontal?1:this.subNodes.length);
        }
        return this.ih;
    }

    function setPos(left, top) {
        setLeft(this.div, left);
        setTop(this.div, top);
    }

    function setZIndex(z) {
        setZ(this.div, z);
    }

    // al = add link
    function al(name, path, icon) {
        return this.add(new Url(name, path, icon));
    }

    // am = add Menu
    function am(name) {
        return this.add(new Menu(name));
    }

    function init() {
        if (!this.div) this.div = insertDIV();
        this.setZIndex(this.nesting);
        drawMenu(this);
        this.bInit = true;
    }

    function show(show) {
        if (!this.bInit) this.init();
        if (show && (this!=root || !bEmbedded)) this.setPos(this.left(), this.top());
        showMenu(this, show && this.isExpanded);
    }
}
Menu.prototype = new TreeNode(true);

// Url extends AbsTreeNode, renders a node as a menu item (url).
function Url(name, path, icon) {
    this.id = nextId++;
    this.name = name;
    this.path = path;
    this.icon = icon;
}
Url.prototype = new TreeNode(false);

allNodes[0]=root=m0=new Menu(""); 
// load data and browser dependent routines
// note that these includes are direct (not deferred), 
// they must be put below the menu class definition.
include("data.js");
include("brw_"+brw+".js");

var img; // image cache
function si(index, filename) { img[index].src = basedir+filename; } // si=set image
function loadImages() {
    img = new Array(ICON_COUNT+5);
    for (var i = 0; i < img.length; i++) img[i] = new Image();

    // default link icon
    if (LINK_ICONS!=0) {
        si(0, ICON_LINK);
    }
    // folder icons
    if (FOLDER_ICONS!=0) {
        si(1, ICON_CLOSED);
        si(2, ICON_OPEN);
    }
    // folder arrows
    if (ARROWS!=0) {
        if (COLOR_FG=="#FFFFFF") { ARWLTB = ARWLTW; ARWDNB =ARWDNW; }
        si(3, ARWLTB);
        si(4, ARWLTW);
        si(5, ARWDNB);
        si(6, ARWDNW);
    }  
    if (FOLDER_ICONS!=1 || LINK_ICONS!=1) {
      si(7, "spacer.gif");
    }    
    // favicons
    if (LINK_ICONS!=0) {
      for (var i = 4; i <= ICON_COUNT; i++)  {
          si(i+4, (i <= 9 ? "0" : "") + i + ".png");
      }
    }    
    bSetBackColor = BACKIMG=="";    
    if (BACKIMG!="") BACKIMG = basedir+BACKIMG;
}

var ol = window.onload;
var strol = new String(ol);
if (strol.indexOf("initMango")==-1) 
  window.onload = new Function("initMango()");
else 
  ol = false;
function initMango() {
    if (ol) ol();

    if (!root.subNodes || root.subNodes.length<=0) {
      alert("menu is empty?");
      return;      
    }
    loadImages();
    if (TEXT_ALIGN=="auto") TEXT_ALIGN = horizontal?"center":"left";

    root.div = getElement("menu");
    initBrowser();
    if (PRE_LOAD) render(root);
    root.expand(true);
}

function render(node) {
    node.init()
    var len = node.subNodes.length;
    for (var i = 0; i < len; i++) {
        var n = node.subNodes[i];
        if (n.canExpand && n.subNodes) render(n);
    }
}

function mango() {
  bEmbedded = true;
  doScroll = false;
  if (ITEM_WIDTH==0||ITEM_HEIGHT==0) {
    alert("Minimum item width and height need to be set to embed the Mango Menu in your HTML.");
    return;
  }  
  var l = root.subNodes?root.subNodes.length:1;
  var width = 2*BORDER_SIZE+(horizontal ? l*ITEM_WIDTH : ITEM_WIDTH);
  var height = 2*BORDER_SIZE+(horizontal ? ITEM_HEIGHT : l*ITEM_HEIGHT);
  out("<table width=\""+width+"px\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">");
  out("<tr><td  height=\""+height+"px\" valign=\"top\">");
  if (brw=="ns4")
    out("<a name=\"ns4\">&nbsp;</a>");
  else
    out("<div id=\"menu\">&nbsp;</div>");
  out("</td></tr></table>");
}

