
function contains(array, value)
{
    for (a in array) {
        if (array[a] == value) return true;
        }
    return false;
}

function get_depth(element, topelement, count_only_ids)
{
    if (element==topelement) return 1;
    var parentelement = element.parentNode;
    if (!parentelement) return 0;
    if (!count_only_ids) return 1 + get_depth(parentelement, topelement, count_only_ids);
    if (element.id) {
        return 1 + get_depth(parentelement, topelement, count_only_ids);
        }
    else {
        return get_depth(parentelement, topelement, count_only_ids);
        }
}

function walk_dom(node, callback, data, level)
{   
    for (var i=0; i<node.childNodes.length; ++i) {
        subnode = node.childNodes[i];
        if (callback.before) callback.before(subnode, data, level);
        if (subnode.childNodes) {
            walk_dom(subnode, callback, data, level+1);
            }
        if (callback.after) callback.after(subnode, data, level);
        }
}

function walk_tree(node, callback, data, level)
{   
    for (var i=0; i<node.children.length; ++i) {
        subnode = node.children[i];
        if (callback.before) callback.before(subnode, data, level);
        if (subnode.children) {
            walk_tree(subnode, callback, data, level+1);
            }
        if (callback.after) callback.after(subnode, data, level);
        }
}

function has_id_and_isnot_a(node, data, level)
{
    if (node.id && node.tagName!='a') data.push(node);
}
function deactivate_if_not_selected(node, data, level)
{
    var p = data.node;
    while(p) {
        if (p==node) return;
        p = p.p;
        }
    if (data.callback) data.callback(node);
    if (node.a.treenode.block) {
        node.a.treenode.block.style.display = 'none';
        //removeElementClass(node.a.parentNode, 'z-top');
        }
}
function tree_string(node, data, level)
{
    data.push(level + ' ' + node.a.innerHTML + '\n');
}

function deactivate_menu(tree)
{
    if (tree.activate_click) {
        tree.activate_click = false;
        return;
        }
    if (tree.active) walk_tree(tree.root, {'before':deactivate_if_not_selected}, {'node':null, 'callback':tree.callback_deactivate}, 0);
    tree.active = false;
}

function make_menu(id, settings)/*callback_activate, callback_deactivate)*/
{
    var tree = new Object();
    var topelement = document.getElementById(id);
    if (!topelement) return false;

    mode = 'top_no_link'; // or 'top_link'
    callback_activate = null;
    callback_deactivate = null;
    if (settings) {
        if (settings.mode) mode = settings.mode;
        if (settings.callback_activate) callback_activate = settings.callback_activate;
        if (settings.callback_deactivate) callback_deactivate = settings.callback_deactivate;
        }

    // find links on different levels
    var a = topelement.getElementsByTagName('a');
    tree.root = new Object();
    tree.active = false;
    tree.activate_click = false;
    tree.mode = mode;
    tree.callback_activate = callback_activate;
    tree.callback_deactivate = callback_deactivate;
    lastdepth = 0;
    currentnode = tree.root;
    currentnode.p = null;
    for(i=0; i<a.length; ++i) {
        depth = get_depth(a[i], topelement, true);
        depthdiff = depth - lastdepth;
        if (depthdiff == 0) {
            currentnode.p.children.push({'p':currentnode.p, 'a':a[i]});
            currentnode = currentnode.p.children[currentnode.p.children.length-1];
            }
        if (depthdiff > 0) {
            currentnode.children = new Array();
            currentnode.children.push({'p':currentnode, 'a':a[i]});
            currentnode = currentnode.children[currentnode.children.length-1];
            lastdepth = depth;
            }
        if (depthdiff < 0) {
            while (depthdiff) {
                currentnode = currentnode.p;
                depthdiff+= 1;
                }
            currentnode.p.children.push({'p':currentnode.p, 'a':a[i]});
            currentnode = currentnode.p.children[currentnode.p.children.length-1];
            lastdepth = depth;
            }
        // find matching elements with 'id' set (elements follow <a> element)
        blocks = new Array();
        walk_dom(a[i].parentNode, {'before':has_id_and_isnot_a}, blocks, 0);
        currentnode.block = blocks.length? blocks[0]: null;
        a[i].tree = tree;
        a[i].treenode = currentnode;
        // on each link, set the onmouseover or onclick events
        if (a[i].treenode.p == tree.root) {
            a[i].onclick = menu_onclick_root;
            a[i].onmouseover = menu_onmouseover_root;
            }
        else {
            a[i].onmouseover = menu_onmouseover;
            }
        }
    //textlines = new Array();
    //walk_tree(tree.root, tree_string, textlines, 0);
    //alert(textlines);

    return tree;
}

function destroy_menu(id)
{
    var topelement = document.getElementById(id);
    if (!topelement) return false;
    var a = topelement.getElementsByTagName('a');
    for(i=0; i<a.length; ++i) {
        if (a[i].onclick) a[i].onclick = null;
        if (a[i].onmouseover) a[i].onmouseover = null;
        if (a[i].tree) a[i].tree = null;
        if (a[i].treenode) a[i].treenode = null;
        }
}

function menu_onclick_root()
{
    if (this.tree.callback_activate) this.tree.callback_activate(this.treenode);
    if (this.treenode.a.treenode.block) {
        this.treenode.a.treenode.block.style.display = 'block';
        //addElementClass(this.treenode.a.parentNode, 'z-top');
        }
    switch (this.tree.mode) {
        case 'top_link':
            if (this.treenode.children) {
                this.tree.active = true;
                this.tree.activate_click = true;
                return false;
                }
            break;
        case 'top_no_link':
        default:
            this.tree.active = true;
            this.tree.activate_click = true;
            return false;
        }
}

function menu_onmouseover_root()
{
    if (this.tree.active) {
        if (this.tree.callback_activate) this.tree.callback_activate(this.treenode);
        if (this.treenode.a.treenode.block) {
            this.treenode.a.treenode.block.style.display = 'block';
            //addElementClass(this.treenode.a.parentNode, 'z-top');
            }
        walk_tree(this.tree.root, {'before':deactivate_if_not_selected}, {'node':this.treenode, 'callback':this.tree.callback_deactivate}, 0);
        }
}

function menu_onmouseover()
{
    if (this.tree.callback_activate) this.tree.callback_activate(this.treenode);
    if (this.treenode.a.treenode.block) this.treenode.a.treenode.block.style.display = 'block';
    walk_tree(this.tree.root, {'before':deactivate_if_not_selected}, {'node':this.treenode, 'callback':this.tree.callback_deactivate}, 0);
}
