    /**
     * curtainMenu.js
     *
     * Creates a drop down menu based on an un numbered list element.
     *
     * @author Christian Hansen <christian@resource-it.dk>
     * @version 1.0
     * @copyright Christian Hansen, resource it.
     *
     * curtainMenu.js is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 2 of the License, or
     * (at your option) any later version.
     *
     * curtainMenu.js is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with curtainMenu.js; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     **/
    
    
//VARIABLES THAT SHOULD BE DEFINED IN TEMPLATE
    var animate_show                     = true;
    var animate_hide                     = false;
    var animate_steps                    = 5;
    var animate_speed                    = 35;
    var margin                           = 3;
    var l1icons                          = false;
    var menu_alignment                   = "h";  // h == horizontal level 1, v = vertical level 1;
    var menu_drop                        = "right"; //either right or left drop
    var img_path                         = "/misc/curtainMenu/themes/default/graphics/";

    var menuconf = new Array();


    menuconf["0-0"] = new Object();
    menuconf["0-0"]["style"]             = "css";
    menuconf["0-0"]["width"]             = "";
    menuconf["0-0"]["backgroundColor"]   = "#005295";
    menuconf["0-0"]["color"]             = "#EEEEEE";
    menuconf["0-0"]["border"]            = "solid 2px #005295";
    menuconf["0-0"]["mbackgroundColor"]  = "#005295";
    menuconf["0-0"]["mcolor"]            = "#EEEEEE";
    menuconf["0-0"]["mborder"]           = "none";
    menuconf["0-0"]["css"]               = "letter-spacing: 2px;padding:2px;padding-left:6px;height:20px;font-family:verdana, helvetica, arial, sans, sans-serif;font-size:12px;cursor:hand;font-weight:normal;";

    menuconf["0-1"] = new Object();
    menuconf["0-1"]["style"]             = "css";
    menuconf["0-1"]["width"]             = "140";
    menuconf["0-1"]["backgroundColor"]   = "transparent";
    menuconf["0-1"]["color"]             = "#EEEEEE";
    menuconf["0-1"]["border"]            = "none";
    menuconf["0-1"]["mbackgroundColor"]  = "transparent";
    menuconf["0-1"]["mcolor"]            = "#EEEEEE";
    menuconf["0-1"]["mborder"]           = "none";
    menuconf["0-1"]["css"]               = "letter-spacing:0px;padding:1px;cursor:hand;text-decoration:none;color:#EEEEEE;font-family:verdana,helvetica, arial, sans, sans-serif;font-size:12px:font-weight:normal;text-transform:uppercase";
    

    /**
     *Variables that is used globally by the script
     **/
    var levels = new Object();
    var curtains = new Array();
    var curtains_tmp = new Array();
    var hideAll = false;
    var timer = null;
    var timer_expand = null;
    var menuid = null;
    var moveby = null;
    var node_count = 0;
    var icons = false;
    var node_index = new Object();

    /**
     * Parses a well formattet unumberet list of lists.
     * @param object o - the ul node that should be parsed.
     * @param integer level - the initial level - most always 1.
     * @access private 
     **/
    function parseTree(o,l) {
        
        var out = new Array();
        var menu = o.childNodes;
        var li_count = 0;
        
        //get count of LIs
        for(var c = 0; c < menu.length; c++) if(menu[c].tagName == "LI") li_count++;
        
        for(var c = 0; c < menu.length; c++) {
            
            var hasChildren = false;                    
            
            if(menu[c].tagName == "LI") {                        
            
                //get submenu
                var submenu = menu[c].childNodes;                        
                
                //check if the node has got any children:
                for(var d = 0; d < submenu.length; d++) if(submenu[d].tagName == "UL") hasChildren = true;
                
                for(var d = 0; d < submenu.length; d++ ) {

                    if(submenu[d].tagName == "UL") {

                        if(li_count > 0) levels[l] = 1;
                        else levels[l] = 0;
                        var outtmp = parseTree(submenu[d],(l + 1));
                        for(var o = 0 ; o < outtmp.length; o++ ) out[out.length] = outtmp[o];
                        hasChildren = true;

                    } else if(submenu[d].tagName == "A") {
                        
                        var showlevels = new Array();
                        var f = 0;
                        for(e = 1; e < l; e++) if(levels[e] == 1) showlevels[f++] = e;
                    
                        var children = hasChildren ? "1" : "0";
                        var ahref = submenu[d].getAttribute("href");

                        //if an image is specified assign it to the imgsrc variable.
                        if(submenu[d].childNodes[0].tagName == "IMG") {
                            icons = true; 
                            var atitle = submenu[d].childNodes[1].data;
                            var imgsrc = submenu[d].childNodes[0].getAttribute("src");
                        } else {
                            var atitle = submenu[d].childNodes[0].data;
                            var imgsrc = false;
                        }//else

                        var atarget = submenu[d].getAttribute("target");
                        out[out.length] = new Array(l,children,--li_count,ahref,atitle,atarget,imgsrc);

                    }//else if

                }//for

            }//if
        
        }//for
                
        return out;
    
    }//parseTree


    /**
     * Creates the menu curtains
     * @param string id - the id of the div-element that contains the unnumbered list.
     * @access public
     * @return void
     **/
    function createCurtains(id) {

        menuid = id;

        var out = new Array();
        var menulevels = new Array();
        var out_count = 0;
        var menu_content = document.getElementById(id).childNodes;

        for(var d = 0; d < menu_content.length; d++) 
            if(menu_content[d].tagName == "UL") {
                var o = menu_content[d];
                break;
            }//if

        var tree = parseTree(o,1);
        var current_level = 0;
        var parents = 1;
        var colspan = icons ? ' colspan="2"' : "";

        for(var c = 0 ; c < tree.length ; c++ ) {

            node_index["node_" + c] = parents + "-" + current_level;
            
            //if top level menu entry
            if(tree[c][0] != current_level && current_level == 0) {
                current_level = tree[c][0];
                menulevels[current_level] = out_count;
                out[menulevels[current_level]]  = "<table cellpadding=\"0\" cellspacing=\"0\" mouse=\"clearTimeout(timer);\" border=\"0\" style=\"position:relative;z-index:" + (tree[c][0] + 2) + "\" id=\"cMenuTable\"><tr>";
                out[menulevels[current_level]] += getRow(tree[c],c,parents,current_level);
                if(menu_alignment == "v") out[menulevels[current_level]] += "</tr>";
            }//if

            //if returning to a parent level - assign new count to all levels in between
            else if ( tree[c][0] < current_level || tree[c][0] == 1) {

                for ( var m = current_level ; m > tree[c][0] ; m-- ) {
                    var attributes = getNodeStyle(parents + "-" + m);
                    if(attributes["style"] == "image" && attributes["lowerleft"] && attributes["lowermiddle"] && attributes["lowerright"]) {
                        out[menulevels[current_level]] += "<tr>";
                        out[menulevels[current_level]] += "<td><img src=\"" + img_path + attributes["lowerleft"] + "\"></td>";
                        out[menulevels[current_level]] += "<td style=\"background-image:url('" + img_path + attributes["lowermiddle"] + "')\" " + colspan + "></td>";
                        out[menulevels[current_level]] += "<td><img src=\"" + img_path + attributes["lowerright"] + "\"></td>";
                        out[menulevels[current_level]] += "</tr>";
                    }//if
                    out[menulevels[m]] += "</table></div>";

                }//for

                current_level = tree[c][0];

                if(tree[c][0] == 1) {
                    parents++;
                    if(menu_alignment == "v") out[menulevels[current_level]] += "<tr>";
                    out[menulevels[current_level]] += getRow(tree[c],c,parents,current_level);
                    if(menu_alignment == "v") out[menulevels[current_level]] += "</tr>";
                } else {
                    out[menulevels[current_level]] += "<tr>" + getRow(tree[c],c,parents,current_level) + "</tr>";
                }//else
            }//else if

            //moving to a child level menu entry
            else if ( tree[c][0] > current_level ) {

                //set current level:
                current_level = tree[c][0];
                menulevels[current_level] = ++out_count;
    
                var attributes = getNodeStyle(parents + "-" + current_level);

                var div_style  = "overflow:hidden";
                div_style     += ";display:none";
                div_style     += ";position:absolute";
                div_style     += ";z-index:" + (tree[c][0] + 2) + 10;
                div_style     += ";background-color:" + attributes["backgroundColor"];
                div_style     += ";color:" + attributes["color"];

                var table_style = "border:" + attributes["border"]; 

                if(attributes["width"] != "0") {
                    table_style += ";width:" + attributes["width"] + "px";
                }
                
                out[menulevels[current_level]]  = "<div style=\"" + div_style + "\" id=\"menu_" + c + "\">";
                out[menulevels[current_level]] += "<table style=\"" + table_style +"\" cellpadding=\"0\" cellspacing=\"0\" mouse=\"clearTimeout(timer);\" border=\"0\" onmouseout=\"hideAll = true;\">";

                if(attributes["style"] == "image" && attributes["upperleft"] && attributes["uppermiddle"] && attributes["upperright"]) {
                    out[menulevels[current_level]] += "<tr>";
                    out[menulevels[current_level]] += "<td><img src=\"" + img_path + attributes["upperleft"] + "\"></td>";
                    out[menulevels[current_level]] += "<td style=\"background-image:url('" + img_path + attributes["uppermiddle"] + "');background-position:top;\" " + colspan + "></td>";
                    out[menulevels[current_level]] += "<td><img src=\"" + img_path + attributes["upperright"] + "\"></td>";
                    out[menulevels[current_level]] += "</tr>";
                }//if

                out[menulevels[current_level]] += "<tr>" + getRow(tree[c],c,parents,current_level) + "</tr>";

            }//else if

            //if staying on sibling level menu entry
            else {

                if(tree[c][0] == 1) {
                    if(menu_alignment == "v") out[menulevels[current_level]] += "<tr>";
                    out[menulevels[current_level]] += getRow(tree[c],c,parents,current_level);
                    if(menu_alignment == "v") out[menulevels[current_level]] += "</tr>";
                } else {
                    out[menulevels[current_level]] += "<tr>" + getRow(tree[c],c,parents,current_level) + "</tr>";
                }//else
            }//else

        }//for

        for( var c = current_level; c > 0 ; c-- ) {
            if( c == 1 ) {
                if(menu_alignment == "h")
                    out[menulevels[c]] += "</tr></table>";
                else 
                    out[menulevels[c]] += "</table>";
            } else {
                out[menulevels[c]] += "</table></div>";
            }//if
        }//for

        node_count = tree.length;

        node_index["node_" + node_count] = parents + "-" + current_level;

        document.getElementById(id).innerHTML = out.join("\n");
                    
    }//createCurtains


    /**
     * implode or expand a given menu level.
     * @access private
     * @return void     
     **/
    function showCurtain(o,node,level) {

        if(node != curtains[curtains.length - 1]) {

            if(level == 1) {
                hideAll = true;
                hideCurtains();
            }//if

            if(node != "cMenuTable" && node != menuid) {
                if(curtains.length && level > 1 && o.parentNode.parentNode.parentNode.parentNode.id != curtains[curtains.length - 1]) {
                    var ooo = curtains.pop();
                    document.getElementById(ooo).style.display = "none";
                }//if
    
                var hidenode = false;
    
                if ( !in_array ( node , curtains ) ) {
    
                    if ( level == 1 ) {
                        hideAll = true;
                        hideCurtains();
                        if(menu_drop == "right" && menu_alignment == "h") {
                            var cTop = o.offsetTop + document.getElementById("cMenuTable").offsetTop;
                            cTop += document.getElementById("cMenuTable").offsetHeight;
                            var cLeft = o.offsetLeft + document.getElementById("cMenuTable").offsetLeft;
                        } else if(menu_drop == "right" && menu_alignment == "v") {
                            var cTop = o.offsetTop + document.getElementById("cMenuTable").offsetTop;
                            var cLeft = o.offsetLeft + document.getElementById("cMenuTable").offsetLeft;
                            cLeft += o.offsetWidth - margin;
                        } else if(menu_drop == "left" && menu_alignment == "v") {
                            var cTop = o.offsetTop + document.getElementById("cMenuTable").offsetTop;
                            var cLeft = o.offsetLeft + document.getElementById("cMenuTable").offsetLeft;
                            document.getElementById(node).style.left = "0px";
                            document.getElementById(node).style.display = "block";
                            var node_width = document.getElementById(node).offsetWidth;
                            cLeft -= node_width - margin;
                            document.getElementById(node).style.display = "none";
                        } else if(menu_drop == "left" && menu_alignment == "h") {
                            var cTop = o.offsetTop + document.getElementById("cMenuTable").offsetTop;
                            cTop += document.getElementById("cMenuTable").offsetHeight;
                            var cLeft = o.offsetLeft + document.getElementById("cMenuTable").offsetLeft;
                        }//elseif
                    } else {
                        if(menu_drop == "left") {
                            var cTop = o.offsetTop + o.parentNode.parentNode.parentNode.parentNode.offsetTop;
                            var cLeft = o.offsetLeft + o.parentNode.parentNode.parentNode.parentNode.offsetLeft;
                            document.getElementById(node).style.left = "0px";
                            document.getElementById(node).style.display = "block";
                            var node_width = document.getElementById(node).offsetWidth;
                            cLeft -= node_width - margin;
                        } else {
                            var cTop = o.offsetTop + o.parentNode.parentNode.parentNode.parentNode.offsetTop;
                            var cLeft = o.offsetLeft + o.parentNode.parentNode.parentNode.parentNode.offsetLeft;
                            cLeft += o.offsetWidth - margin;
                        }//else
                    }//else
    
                    curtains.push(node);
    
                    document.getElementById(node).style.top = cTop + "px";
                    document.getElementById(node).style.left = cLeft + "px";
    
                    if( animate_show ) {
                        moveby = animate_steps;
                        document.getElementById(node).style.display = "block";
                        var node_height = document.getElementById(node).offsetHeight;
    
                        document.getElementById(node).style.height = "0px";
                        expandMe(node,node_height);
                    } else {
                        document.getElementById(node).style.display = "block";
                    }//else
    
                } else {
    
                    var size = curtains.length;
    
                    for( var c = 0; c < size; c++ ) {
                        if(hidenode) {
                            var ooo = curtains.pop();
                            document.getElementById(ooo).style.display = "none";
                        }//if
                        if(curtains[c] == node) hidenode = true;
                    }//for
    
                }//if
    
            }//if
        }//if
    }//showCurtain

    
    function hideCurtains() {

        if( hideAll ) {
            var size = curtains.length; 

            if( animate_hide ) {

                if(curtains.length) {
                    curtains_tmp = curtains;
                    curtains = new Array();
                    var ooo = curtains_tmp.pop();
                    moveby = animate_steps;
                    implodeMe(ooo,parseInt(document.getElementById(ooo).style.height));
                }//if

            } else {

                for( var c = 0; c < size; c++ ) {
                    var ooo = curtains.pop();
                    document.getElementById(ooo).style.display = "none";
                }//for
            }//else

        }//if

        bgOver(false);

    }//hideCurtains;


    function in_array(key,arr) {
        for(var c=0;c<arr.length;c++) 
            if(key == arr[c]) return true;
        return false;
    }//in_array


/*=============================================
  FUNCTIONS FOR ANIMATING MENUES
  =============================================*/

    function expandMe(node,size) {

        clearTimeout(timer_expand);
        var curHeight = parseInt(document.getElementById(node).style.height);

        if(curHeight < size) {
            if((moveby + curHeight) <   size) 
                document.getElementById(node).style.height = (curHeight+ moveby)+"px";
            else 
                document.getElementById(node).style.height = size + "px";
            moveby *= 2;

            var timer_expand = setTimeout("expandMe('" +node+ "',"+size+")",animate_speed);
        }//if

    }//expandMe


    function implodeMe(node,size) {

        clearTimeout(timer_implode);
        var curHeight = parseInt(document.getElementById(node).style.height);

        if(curHeight > 0 && document.getElementById(node).style.display != "none") {
            if( (curHeight - moveby ) > 0) 
                document.getElementById(node).style.height = (curHeight - moveby)+"px";
            else 
                document.getElementById(node).style.height = "0px";
            moveby *= 2;

            var timer_implode = setTimeout("implodeMe('" +node+ "',"+size+")",animate_speed);
        } else {
            document.getElementById(node).style.height = size + "px";
            document.getElementById(node).style.display = "none";
            if(curtains_tmp.length) {
                var ooo = curtains_tmp.pop();
                moveby = animate_steps;
                implodeMe(ooo,parseInt(document.getElementById(ooo).style.height));
            }//if
        }//if

    }//implodeMe


    function bgOver(node,parents,current_level) {
        var attributes = getNodeStyle(parents + "-" + current_level);
        
        if(attributes["style"] == "css") {
            bgOverCSS(node,parents,current_level);
        }//if

        if(attributes["style"] == "image") {
            bgOverImage(node,parents,current_level);
        }//if

    }//bgOver

    
    function bgOverCSS(node,parents,current_level) {

        //reset node selections
        for( var c = 0 ; c <= node_count ; c++ ) {
            try {
                var nodename = "node_" + c;
                var attributes = getNodeStyle(node_index[nodename]);

                if(document.getElementById(nodename).parentNode.parentNode.parentNode.id == "cMenuTable") {
                    document.getElementById(nodename).style.backgroundColor = attributes["backgroundColor"];
                    document.getElementById(nodename).style.color = attributes["color"];
                } else {
                    document.getElementById(nodename).parentNode.style.backgroundColor = attributes["backgroundColor"];
                    document.getElementById(nodename).style.color = attributes["color"];
                }//else
            } catch(e) {
                //void
            }

        }//for 

        if(node) {

            //set style for selected parent nodes
            for(var c = 0 ; c < curtains.length; c++ ) {

                var nodename = curtains[c].replace(/menu/,"node");
                var attributes = getNodeStyle(node_index[nodename]);

                if(document.getElementById(nodename).parentNode.parentNode.parentNode.id == "cMenuTable") {
                    document.getElementById(nodename).style.backgroundColor = attributes["mbackgroundColor"];
                    document.getElementById(nodename).style.color = attributes["mcolor"];
                } else {
                    document.getElementById(nodename).parentNode.style.backgroundColor = attributes["mbackgroundColor"];
                    document.getElementById(nodename).style.color = attributes["mcolor"];
                }//else

            }//for

            var attributes = getNodeStyle(node_index[node]);

            if(document.getElementById(node).parentNode.parentNode.parentNode.id == "cMenuTable") {
                document.getElementById(node).style.backgroundColor = attributes["mbackgroundColor"];
                document.getElementById(node).style.color = attributes["mcolor"];
            } else {
                document.getElementById(node).parentNode.style.backgroundColor = attributes["mbackgroundColor"];
                document.getElementById(node).style.color = attributes["mcolor"];
            }//else

        }//if(node)

    }//bgOverCSS

    function bgOverImage(node,parents,current_level) {

        var attributes = getNodeStyle(node_index[node]);

        var idn = node.split(/_/)[1];
        document.getElementById("left_" + idn).src = img_path + attributes["left_mo"];
        document.getElementById("right_" + idn).src = img_path + attributes["right_mo"];
        document.getElementById("node_" + idn).style.backgroundImage = "url(" + img_path + attributes["fill_mo"] + ")";
    }//bgOverImage


    function getNodeStyle(node) {

        var g = node.split("-");

        //set styles to be used:
        if(menuconf[g[0] + "-" + g[1]])
            return menuconf[g[0] + "-" + g[1]];
        else if(menuconf[g[0] + "-0"])
            return menuconf[g[0] + "-0"];
        else if(menuconf["0-" + g[1]])
            return menuconf["0-" + g[1]];
        else
            return menuconf["0-0"];
    }//getStyle

    function getTdStyle(attributes) {
        

        var td_style = " style=\"";

        if(attributes["width"] != "0") {
            td_style += "width:" + attributes["width"] + "px";
        }//if 

        td_style += ";color:" + attributes["color"];

        if(attributes["css"].length > 0) td_style += ";" + attributes["css"];

        td_style += "\"";

        return td_style; 

    }//getTdStyle

    function getRow(tree,c,parents,current_level) {

        var attributes = getNodeStyle(parents + "-" + current_level);
        var td_style = getTdStyle(attributes); 

        //set onclick event
        if(/^javascript:/.test(tree[3])) {
            var onclick = " onClick=\"" + tree[3].replace(/^javascript:/,"") + "\"";
        } else {
            var onclick = " onClick=\"location.href = \'" + tree[3] + "\'\"";
        }

        var imgmouse  = onclick + " onmouseout=\"timer = setTimeout('hideCurtains()',1000);\" onmouseover=\"clearTimeout(timer);hideAll = false;showCurtain(" + (tree[0] == 1 ? "this," : "this.parentNode.childNodes[1],");
        imgmouse += (tree[1] == 1) ? "'menu_" + ( c + 1 ) + "'" : "this.parentNode.parentNode.parentNode.parentNode.id";
        imgmouse += "," + tree[0] + ");bgOver(this.parentNode.childNodes[1].id," + parents + "," + tree[0] + ");\"";

        if( icons && tree[6].length > 6 ) {
            var img = "<td " + imgmouse + "><img src=\"" + tree[6] + "\" alt=\"\"></td>";
        } else if ( icons ) {
            var img = "<td " + imgmouse + "></td>";
        } else var img = "";
        var mouse  = onclick + " onmouseout=\"timer = setTimeout('hideCurtains()',1000);\" onmouseover=\"clearTimeout(timer);hideAll = false;showCurtain(this,";
        mouse += (tree[1] == 1) ? "'menu_" + ( c + 1 ) + "'" : "this.parentNode.parentNode.parentNode.parentNode.id";
        mouse += "," + tree[0] + ");bgOver(this.id," + parents + "," + tree[0] + ");\" id=\"node_" + ( c + 1 ) + "\"";
        
        if(tree[0] == 1) {
            if(l1icons) var row = img + "<td " + mouse + td_style + " class=\"cml_" + current_level + "\">" + tree[4] + "</td>";
            else var row = "<td " + mouse + td_style + " class=\"cml_" + current_level + "\">" + tree[4] + "</td>";
        } else {
            var row = img + "<td " + mouse + td_style + " class=\"cml_" + current_level + "\">" + tree[4] + "</td>";
        }

        if(attributes["style"] == "image") {
            row =  "<td><img src=\"" + img_path + attributes["left"] + "\" id=\"left_" + ( c + 1 ) + "\"></td>" + row;
            row += "<td><img src=\"" + img_path + attributes["right"] + "\" id=\"right_" + ( c + 1 ) + "\"></td>";
        }//if

        return row

    }//getRow
