﻿/*
Adds CSS class names to the LI elements of a nested UL list.
leafes get the menu_leaf_class
open nodes get the menu_open_class
closed nodes get the menu_closed_class
the current node gets the menu_active_class
    
written 2004 by Ortwin Glueck
*/

//config
var menu_active_class = "active";
var menu_leaf_class = "leaf";
var menu_open_class = "open";
var menu_closed_class = "closed";

//the default page that is displayed if URL ends in /
var menu_default_page = "home.aspx";
var menu_url;

//main function
//menu_id : id of the element containing the navigation
function menu_main(menu_id) {
    var url = location.href;
    if (url.lastIndexOf("/") == (url.length - 1)) {
        url = url + menu_default_page;
    }
    if (url.lastIndexOf("?") >= 0) {
        url = url.substring(0, url.lastIndexOf("?"));
    }
    if (url.lastIndexOf("#") >= 0) {
        url = url.substring(0, url.lastIndexOf("#"));
    }
    menu_url = url;

    var main = document.getElementById(menu_id);
    if (!main) alert("No element with id '" + menu_id + "' found");
    menu_traverse(main);
}

/* Walks down the subtree and on the way back
sets properties.
returns bit set
1: set = element is a node, unset = element is a leaf
2: set = element contains the active node
4: set = element is the active A node
*/
function menu_traverse(element) {
    var props = 0;

    // walk down
    for (var i = 0; i < element.childNodes.length; i++) {
        var child = element.childNodes[i];
        props |= menu_traverse(child); // aggregate bits
    }

    // on the way back now
    switch (element.tagName) {
        case "UL":
            props |= 1;
            break;

        case "LI":
            var c1 = (props & 1) ?
                   ((props & (2 | 4)) ? menu_open_class : menu_closed_class)
                 : menu_leaf_class;
            element.className = element.className ? element.className + " " + c1 : c1;
            if (props & 4) {
                if (!(props & 2)) element.className += " " + menu_active_class;
                props |= 2;
                props &= 1 | 2; // reset bit 4
            }
            break;

        case "A":
            if (props & 2) break; // once is enough
            var href = element.getAttribute("href");
            if (menu_isSameUrl(menu_url, href)) props |= 4;
            break;
    }

    return props;
}

//matches two URIs when href is the last part of url
//.. and . are correctly resolved
function menu_isSameUrl(url, href) {
    var a = url.split(/[?\/]/i);
    var b = href.split(/[?\/]/i);
    var i = a.length - 1;
    var j = b.length - 1;
    while ((i >= 0) && (j >= 0)) {
        if (b[j] == "..") { j -= 2; continue; }
        if (a[i] == "..") { i -= 2; continue; }
        if ((b[j] == ".") || (b[j] == "")) { j--; continue; }
        if ((a[i] == ".") || (a[i] == "")) { i--; continue; }
        if (!(a[i] == b[j])) return false;
        i--;
        j--;
    }
    return true;
}