var dymenuRev = "$Revision: 1858 $";
var absUrlRe = new RegExp("^[a-z]+:");

/* To work around IE bug (in IE 7 at least), where HTML base href setting
 * is ignored by javascript "[window.]location =" settings, set this variable.
 */
var baseHref = null;

function borderize(el) {
    $(el).toggleClassName("active").toggleClassName("inactive");
}
function clickAction(el) {
    if ($(el).script) {
        clearSubs();
        window.setTimeout($(el).script, 0);
    } else if ($(el).loc) {
        var loc = $(el).loc;
        var prefix = ((baseHref != null && loc.substring(0, 1) != "/"
                    && !absUrlRe.test(loc)) ? baseHref : "");
        //alert("Redirecting local => '" + prefix + $(el).loc + "'");
        window.location = prefix + loc;
    }
    else {
        alert( "No action for triggerer");
    }
}

window.setInterval(function() {
    if (exitedMenuAt < 1) return;
    //console.log("T");
    if (new Date().getTime() - exitedMenuAt < menuExitGrace) return;
    clearSubs();
}, 100); // Units is milliseconds
console.info("dymenu monitor thread started");

function clearSubs(divId) {
    exitedMenuAt = 0;
    if (divId) {
        $$("#" + divId + " table.dymagic").invoke("hide");
    } else {
        console.warn("Clearing all Submenus");
        $$("table.dymagic").invoke("hide");
    }
}

var exitedMenuAt = 0;
var menuExitGrace = 1000; // in millis

function prototypeCssSingleton() {
    var els = $$($A(arguments));
    if (els.length != 1) {
        alert("Page has wrong number (" + els.length
                + ") of elements matching CSS specs '" + arguments[0] + "...'");
        for (var i = 0; i < els.length; i++)
            console.error("Element " + i + ": " + els[i]);
        return ((els.length > 0) ? els[0] : null);
    }
    return els[0];
}

var bodyEl = null; // Body will not be loaded if this file loaded from HEAD

function genMenu() {
    console.log("dymenu library, " + dymenuRev);
    bodyEl = prototypeCssSingleton("body");
    var dyTable = prototypeCssSingleton("table.dymenu");
    dyTable.addClassName("static");
    dyTable.cellSpacing = 0;
    new Ajax.Request("gmenu.json", {
        onSuccess: function(req) {
            insertMenu(dyTable, bodyEl, req.responseText.evalJSON());
        },
        method: "get"
    });
}

/**
 * tableContainer must be inserted OUTSIDE of this method.
 * This method inserts the triggers into the supplied triggerTable.
 */
function insertMenu(triggerTable, tableContainer, dataArray) {
    var triggerContainer = null; // Container for drillable div/td's
    var newTd, newTr, newMagicT, triggerEl, newArrow, newDiv, newIcon;

    if (triggerTable.hasClassName("dymenu")) {
        triggerContainer = new Element("tr").addClassName("static");
        triggerTable.insert({bottom: new Element("tbody").
                insert({bottom: triggerContainer})});
    } else {
        triggerContainer = new Element("tbody");
        triggerTable.insert({top: triggerContainer});
    }
    // The tableContainer tag will remain empty if this menu level has no
    // nested menus in it.
    // If this matters, remove it at end of this method if it is empty.

    for (var i = 0; i < dataArray.length; i++) {
        if (typeof(dataArray[i]) == "undefined") {
            alert("Menu data has an empty element");
            return;
        }
        if (typeof(dataArray[i].link) != "undefined"
                && typeof(dataArray[i].submenu) != "undefined") {
            alert("Menu data has an item with both 'link' and 'submenu' set");
            return;
        }
        if (typeof(dataArray[i].label) == "undefined") {
            alert("Menu data has an item with no 'label' property");
            return;
        }
        newIcon = null;
        if (typeof(dataArray[i].icon) != "undefined") {
            log.error("Adding icon w/ src " +
                    "images/" + dataArray[i].icon);
            newIcon = new Element("img");
            newIcon.src = "images/" + dataArray[i].icon;
        }
        if (dataArray[i].label.indexOf("\n") > -1)
            dataArray[i].label = dataArray[i].label.replace(/\n/g, "<BR/>");
        newMagicT = null;
        if (typeof(dataArray[i].submenu) != "undefined") {
            newMagicT = new Element("table").addClassName("dymagic").
                    hide().setOpacity(.8).setStyle({
                        position: "absolute",
                        top: "0px",
                        left: "0px"
                    });
            newMagicT.cellSpacing = 0;
            newMagicT.onmouseover = enteredMenu;
            newMagicT.onmouseout = exitedMenu;
            newDiv = new Element("div").insert({bottom: newMagicT});
            newDiv.identify();
            tableContainer.insert({bottom: newDiv});
            // Inserting the new tableContainer right here.
            // We do not "insert" the new triggerTable directly (newMagicT),
            // because that is already inserted under newDiv, and will be
            // presented by show().
            insertMenu(newMagicT, newDiv, dataArray[i].submenu);
            //Recursion right here!
        }

        // tableContainer is either body or div tag.
        // triggerContainer is either tbody or tr tag.

        // Set up Trigger for i
        newTd = new Element("td");
        if (triggerTable.hasClassName("static")) {
            // In this case, triggerContainer is a TR
            triggerContainer.insert({bottom: newTd});
            triggerEl = new Element("div").addClassName("inactive").
                    update(dataArray[i].label);
            newTd.insert({bottom: triggerEl});
            if (newMagicT != null) {
                // Just adding the arrow icon
                newArrow = new Element("img").addClassName("downArrow");
                newArrow.src = "images/dymenu/arrow-down.png";
                triggerEl.insert({bottom: newArrow});
            }
        } else {
            // In this case, triggerContainer is a TBODY
            newTd.addClassName("inactive");
            triggerEl = newTd;
            triggerContainer.insert({bottom: new Element("tr").
                    insert({bottom: newTd})});
            if (newMagicT == null) {
                newTd.update(dataArray[i].label);
            } else {
                newTable = new Element("table");
                newTable.cellSpacing = 0;
                newTr = new Element("tr");
                newTd.insert({bottom: newTable.
                        insert({bottom: new Element("tbody").
                        insert({bottom: newTr})})});
                newTr.insert({bottom: new Element("td").update(
                        dataArray[i].label)});
                newArrow = new Element("img");
                newArrow.src = "images/dymenu/arrow-right.png";
                newTr.insert(
                          {bottom: new Element("td").addClassName("rightArrow").
                        insert({bottom: newArrow})});
                triggerEl.nestingDivId = tableContainer.id;
            }
        }
        if (dataArray[i].tooltip) triggerEl.title = dataArray[i].tooltip;
if (newIcon != null) log.error("Inserting new icon under triggerEl");
        if (newIcon != null) triggerEl.insert({top: newIcon});

        if (typeof(dataArray[i].link) != "undefined") {
            if (dataArray[i].link.
                    substring(0, ("javascript:".length)) == "javascript:")
                triggerEl.script =
                    dataArray[i].link.substring("javascript:".length);
            else
                triggerEl.loc = dataArray[i].link;
            triggerEl.onmouseover = function() {
                borderize(this);
                this.setStyle({cursor: "pointer"});
            }
            triggerEl.onmouseout = function() {
                borderize(this);
                this.setStyle({cursor: "auto"});
            }
            triggerEl.onclick = function() {
                clickAction(this);
            }
        } else if (newMagicT != null) {
            triggerEl.childMenu = newMagicT;
            triggerEl.myMenu = triggerTable;
            triggerEl.onmouseout = function() {
                borderize(this);
            }
            if (triggerTable.hasClassName("static")) {
                triggerEl.onmouseover = function() {
                    borderize(this);
                }
                triggerEl.onclick = function() {
                    var celPos = this.cumulativeOffset();
                    this.childMenu.setStyle({
                        top: ("" + (celPos[1] + this.getHeight()) + "px"),
                        left: ("" + celPos[0] + "px")
                    });
                    clearSubs();
                    this.childMenu.show();
                }
            } else {
                triggerEl.onmouseover = function() {
                    borderize(this);
                    var celPos = this.cumulativeOffset();
                    this.childMenu.setStyle({
                        top: ("" + celPos[1] + "px"),
                        left: ("" + (celPos[0] + this.getWidth() ) + "px")
                    });
                    clearSubs(this.nestingDivId);
                    this.myMenu.show();
                    this.childMenu.show();
                }
            }
        }
    }
    // $$("table.dymenu table.worker").invoke("setOpacity", .7);
    // The opacity setting above applies increasing (nested) transparency to
    // each dymagic level.
    // That's cool, except that the text keeps getting more transparent.
    // (In svn history is a solution to make text fully opaque, but that
    // solution has portability issues, plus it's very complex).
}

function enteredMenu() {
    exitedMenuAt = 0;
}
function exitedMenu() {
    exitedMenuAt = new Date().getTime(); // millis
}
