/* -*- javascript -*-
     Copyright 2006 Dr. Detlef Groth, Schwielowsee, Germany.
     License: http://creativecommons.org/licenses/LGPL/2.1/
     System        : JSCOMPONENTS_INIT_JS :
     Created By    : Dr. Detlef Groth, Schwielowsee, Germany
     Last Modified : <061121.0606>
     ID            : $Id: jsComponents.js,v 1.1 2007/12/13 12:00:49 city Exp $
     Source        : $Source: /rscvs/chessweb/js/jsComponents.js,v $
     $Log: jsComponents.js,v $
     Revision 1.1  2007/12/13 12:00:49  city
     no message

     Description
     Notes
*/
// Simon Willison's Weblog http://simon.incutio.com/archive/2004/05/26/addLoadEvent
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}
/* Event Utilities */
function evtGetTarget(evt) {
    var elem ;
    if (evt.target) {
        elem = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target ;
    } else {
        elem = evt.srcElement ;
    }
    return elem ;
}

/*
  more efficient to construct the functions ones
  Thanks to Dean Edwards http://dean.edwards.name/
  */
var evtAdd;
if (document.addEventListener) {
    evtAdd = function(element, type, handler) {
        element.addEventListener(type, handler, null);
    };
} else if (document.attachEvent) {
    evtAdd = function(element, type, handler) {
        element.attachEvent("on" + type, handler);
    };
} else {
    alert("Your browser is not supported!");
}
/* XMLHttpRequestLoader - Class */
function XMLHttpRequestLoader () {
    var xmlhttp = false ;
    if (typeof(XMLHttpRequest) != "undefined") {
        xmlhttp = new XMLHttpRequest();
    } else {
        // IE 5, 6
        try {
            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (ev0) {
            try {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (ev1) {
                xmlhttp = false;
            }
        }
    }
    function loadXML(url,cb) {
        if (typeof(XMLHttpRequest) != "undefined") {
            load(url,cb);
        } else if (xmlhttp) {
            loadIE(url,cb);
        } else {
            alert("Browser not supported or JavaScript or ActiveX (IE) is not enabled!");
        }
    }
    function load(srcUrl,cb) {
        var req = new XMLHttpRequest();
        req.overrideMimeType('text/xml');
        req.open("GET", srcUrl, true);

        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                if (cb) {
                    cb(req.responseXML);
                }
            }

        };
        req.setRequestHeader('Content-Type', 'text/xml');
        req.setRequestHeader('Cache-Control', 'no-cache');
        req.send(null);
    }

    function loadIE(srcUrl,cb) {
        xmlhttp.open("GET", srcUrl);
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4) {
                if (cb) {
                    var xmlObj = xmlhttp.responseXML;

                    if(!xmlObj.hasChildNodes) {
                        // seems that Mime-Type was not recognized
                        // we create the right object by hand
                        xmlObj = new ActiveXObject("Msxml2.DOMDocument");
                        var xmlText = xmlhttp.responseText;
                        xmlText = xmlText.replace(/<\/html>/,"");
                        xmlText = xmlText.slice(xmlText.indexOf("<body>"));
                        xmlObj.loadXML(xmlText);
                        cb(xmlObj);
                    } else {
                        cb(xmlhttp.responseXML);
                    }
                }
            }
        };
        xmlhttp.setRequestHeader('Content-Type', 'text/xml');
        xmlhttp.setRequestHeader('Cache-Control', 'no-cache');
        xmlhttp.send(null);
    }
    this.loadXML = loadXML  ;
}

function jsComponent (node) {
    try {
        eval("mfunc = "+node.className+";");
        mfunc(node);
    } catch (ev) {}
}

function init_jsComponents(node)
{
  if (node)
    var divs = node.getElementsByTagName("DIV") ;
  else
    var divs = document.getElementsByTagName("DIV") ;

/*
    var images = new Array("plus.gif","minus.gif","file2.gif","file.gif","up.gif","down.gif");
    for (var i = 0 ; i < images.length ; i++) {
        var img = new Image(); img.src = "../js/jsc/"+images[i] ;
    }
*/
  var l = divs.length ;
  for (var i = 0 ; i < l ; i++)
  {
      if (divs.item(i).className && divs.item(i).className.match(/JS.+/)) {
          var comp = new jsComponent(divs.item(i));
      }
  }
};

/* -*- javascript -*-
     Copyright 2006 Dr. Detlef Groth, Schwielowsee, Germany.
     License: http://creativecommons.org/licenses/LGPL/2.1/
     System        : JSDRAGCONTROLS_JS :
     Object Name   : $RCS_FILE$
     Revision      : $REVISION$
     Date          : Fri Nov 10 13:30:20 2006
     Created By    : Dr. Detlef Groth, RZPD Berlin
     Created       : Fri Nov 10 13:30:20 2006

     Last Modified : <061117.1508>
     ID            : $Id: jsComponents.js,v 1.1 2007/12/13 12:00:49 city Exp $
     Source        : $Source: /rscvs/chessweb/js/jsComponents.js,v $
     Description
     Notes
     */
var maxZ = 100 ;

function JSDragArea(element) {
    this.grabDown = grabDown;
    this.grabClick = grabClick;
    evtAdd(element,"mousedown",this.grabDown);
    evtAdd(element,"mouseclick",this.grabClick);

    /*    var dw = new DebugWindow();*/
    function grabClick(e) {
        e=e||window.event;
        var node = evtGetTarget(e);
        if (node.style.zIndex != maxZ) {
            maxZ++;
            node.style.zIndex = maxZ;
        }
    }

    function grabDown(e) {
        e=e||window.event;
        var node = evtGetTarget(e);
        if (node.style.zIndex != maxZ) {
            maxZ++;
            node.style.zIndex = maxZ;
        }
        var clientX0 = e.clientX;
        var clientY0 = e.clientY;
        var top=node.style.top;
        var left=node.style.left;
        //        dw.append("top:"+top);
        window.document.onmousemove = function (e) {
            var deltaX; var deltaY;
            e=e||window.event;
            deltaX = e.clientX - clientX0;
            deltaY = e.clientY - clientY0;
            node.style.left = parseInt(left)+parseInt(deltaX) + "px";
            node.style.top =  parseInt(top)+parseInt(deltaY) + "px";

        };
        // IE seems better without dragstart
        window.document.ondragstart = function(){return false};
        // cleanup after document.onmouseup

        window.document.onmouseup = function(e) {
            this.onmousemove = null;
            this.onmouseup = null;
            this.ondragstart = null;
        };
    }
}
/* -*- javascript -*-
     Copyright 2006 Dr. Detlef Groth, Schwielowsee, Germany.
     License: http://creativecommons.org/licenses/LGPL/2.1/
     System        : JSLISTCONTROLS_JS :
     Object Name   : $RCS_FILE$
     Revision      : $REVISION$
     Date          : Fri Nov 10 15:34:53 2006
     Created By    : Dr. Detlef Groth, RZPD Berlin
     Created       : Fri Nov 10 15:34:53 2006

     Last Modified : <061117.1508>
     ID            : $Id: jsComponents.js,v 1.1 2007/12/13 12:00:49 city Exp $
     Source        : $Source: /rscvs/chessweb/js/jsComponents.js,v $
     Description
     Notes
*/
function JSSearchList (element) {
    this.keyup = keyup ;
    var div = window.document.createElement("div");
    var text = window.document.createTextNode("Search: ");
    div.className = "input" ;
    div.appendChild(text);
    var input = window.document.createElement("input");
    input.setAttribute("name", "inputvalue");
    input.setAttribute("type", "text");
    evtAdd(input, "keyup", this.keyup);
    div.appendChild(input);
    element.insertBefore(div, element.firstChild);
    element.style.listStylePosition = "outside";
    function keyup(e) {
        //alert(element.getElementsByTagName("input")[0].value);
        //e=e || key.event;
        var input = evtGetTarget(e);
        var element = input.parentNode.parentNode ;
        var links = element.getElementsByTagName("A") ;
        var  m = input.value ;
        if (e.keyCode == 13) {
            for (var i = 0 ; i < links.length; i++) {
                if (links[i].parentNode.style.display == "") {
                    if ((links[i].getAttribute("target") == "" ||
                         links[i].getAttribute("target") == null) &&
                        (window.document.getElementsByTagName("BASE").item(0) == null ||
                         window.document.getElementsByTagName("BASE").item(0).getAttribute("target") == null ||
                        window.document.getElementsByTagName("BASE").item(0).getAttribute("target") == ""))
                    {
                        window.location.href = links[i].getAttribute("href") ;
                    } else {
                        if (links[i].getAttribute("target") != null && links[i].getAttribute("target") != "") {

                            eval("parent.frames."+links[i].getAttribute("target")+".location.href = '"+links[i].getAttribute("href")+"';");
                        } else {
                            eval("parent.frames."+window.document.getElementsByTagName("BASE").item(0).getAttribute("target")+".location.href = '"+links[i].getAttribute("href")+"';");
                        }
                    }
                    break;
                }
            }
        } else {
            var found = 0 ;
            if (m == "") {
                for (var i = 0 ; i < links.length; i++) {
                    links[i].parentNode.style.display ="";
                    if (found == 0) {
                        links[i].parentNode.style.backgroundColor = "#dddddd";
                    } else {
                        links[i].parentNode.style.backgroundColor = "white";
                    }
                    found ++ ;
                }
            } else {
                for (var i = 0 ; i < links.length; i++) {
                    if (links[i].firstChild.data.match(eval("/^"+m+"/i"))) {
                        links[i].parentNode.style.display ="";
                        if (found == 0) {
                            links[i].parentNode.style.backgroundColor = "#dddddd";
                        } else {
                            links[i].parentNode.style.backgroundColor = "white";
                        }
                        found ++ ;
                    } else {
                        links[i].parentNode.style.display ="none";
                        links[i].parentNode.style.backgroundColor = "white";
                    }
                }
            }
        }
    }

}
/* -*- javascript -*-
     Copyright 2006 MPIMG Berlin, Germany.
     All Rights Reserved
     System        : JSTABCONTROLS_JS :
     Object Name   : $RCS_FILE$
     Revision      : $REVISION$
     Date          : Fri Nov 10 05:52:41 2006
     Created By    : Dr. Detlef Groth, Schwielowsee, Germany
     Created       : Fri Nov 10 05:52:41 2006

     Last Modified : <061130.0909>
     ID            : $Id: jsComponents.js,v 1.1 2007/12/13 12:00:49 city Exp $
     Source        : $Source: /rscvs/chessweb/js/jsComponents.js,v $
     Description
     Notes
*/
function JSTabBox (element) {
    var ie5 = document.all &&
              document.getElementById &&
              navigator.userAgent.toLowerCase().indexOf('opera')==-1?1:0 ;

    this.raiseTab = raiseTab ;
    evtAdd(element, "click", this.raiseTab);
    var div = document.createElement("DIV") ;

    div.setAttribute("nowrap","true");


    element.insertBefore(div,element.firstChild) ;
    var ul = document.createElement("UL");
    div.appendChild(ul);
    var panels = element.getElementsByTagName("DIV") ;
    if (panels.item(1).getAttribute("title") == "N") {
        div.className = "JSTabNumbers" ;
    } else {
        div.className = "JSTabs" ;
    }
    var k = 0 ;
    var curr = 0 ;
    for (var j = 0 ; j < panels.length ; j++) {

        if (panels.item(j).className == "JSTabPanel" &&
            panels.item(j).parentNode == element) {
            var li = document.createElement("LI");
            if (panels.item(j).getAttribute("current")) {
                if (panels.item(j).getAttribute("current") == "true") {
                    li.className = "current" ;
                    curr = k ;
                }
            }
            var t ;
            if (div.className == "JSTabs") {
                t = document.createTextNode(" "+panels.item(j).getAttribute("title")+" ");
            } else {
                t = document.createTextNode(" "+(k+1)+" ");
            }
            panels.item(j).removeAttribute("title");
            li.appendChild(t);
            li.style.cursor = (ie5 ? "hand" : "pointer") ;
            ul.appendChild(li);
            k++ ;
        }
    }
    ul.getElementsByTagName("LI").item(curr).className = "current" ;
    ul.getElementsByTagName("LI").item(curr).pointer = "" ;
    if (k == 1) {
        div.style.display="none";
    }
    showPanel(element, curr);
    function showPanel (parent,index) {
        var child = parent.firstChild ;
        var  curr = 0 ;
        while (child != null) {
            if (child.className == "JSTabPanel") {
                if (index == curr) {
                    child.style.display = "block" ;
                } else {
                    child.style.display = "none" ;
                }
                curr++ ;
            }
            child = child.nextSibling ;
        }
    }
    function getIndex (el) {
        var idx = 0 ;
        var sibling  = el.previousSibling ;
        while (sibling != null)  {
            if (sibling.nodeName == el.nodeName) {
                idx++ ;
            }
            sibling = sibling.previousSibling ;
        }
        return idx ;
    }
    function raiseTab (e) {
        e=e||window.event;
        var node = evtGetTarget(e);
        var parent = node.parentNode ;
        if (parent.parentNode.className != "JSTabs" && parent.parentNode.className != "JSTabNumbers") { return }
        var a= parent.getElementsByTagName("LI");
        for (var x = 0 ; x < a.length ; x++) {
            a[x].className = "" ;
            a[x].style.cursor = (ie5 ? "hand" : "pointer") ;
        }
        node.className= "current" ;
        node.style.cursor = "" ;
        var index = getIndex(node) ;
        showPanel(node.parentNode.parentNode.parentNode, index);
    }
}
/* -*- javascript -*-
     Copyright 2006 Dr. Detlef Groth, Schwielowsee, Germany.
     License: http://creativecommons.org/licenses/LGPL/2.1/
     System        : SORT-TABLE_JS :
     Object Name   : $RCS_FILE$
     Revision      : $REVISION$
     Date          : Fri Oct 27 09:51:48 2006
     Created By    : Dr. Detlef Groth, RZPD Berlin
     Created       : Fri Oct 27 09:51:48 2006

     Last Modified : <061118.1042>
     ID            : $Id: jsComponents.js,v 1.1 2007/12/13 12:00:49 city Exp $
     Source        : $Source: /rscvs/chessweb/js/jsComponents.js,v $
     Description
     Notes
     */

function JSTableStripe(div) {
    var table = div.getElementsByTagName("table")[0];
    var types = new Array("even","odd");
    var trs = table.getElementsByTagName("tr") ;
    for (var i = 0 ; i < trs.length ;i++) {
        var mod = i % 2 ;
        trs.item(i).className = types[mod] ;
    }
}
function JSTableSort(div) {
    var table = div.getElementsByTagName("table")[0];
    var types = new Array();
    var headers = table.getElementsByTagName('th');
    var order = "asc" ;
    var lastI = 100 ;
    for (var i = 0; i < headers.length;i++) {
        types[i] = headers.item(i).className;
    }
    for (var i = 0; i < headers.length;i++) {
        if (headers.item(i).className == "SortNumber") {
            headers[i].onclick = build_sorter(table,i,"n") ;

        } else if (headers.item(i).className == "SortString") {
            headers[i].onclick = build_sorter(table,i,"s") ;
        }

    }
    function sort_table (table,extract_fct,sort_fct) {
        var clones = new Array();
        var tbody = table.getElementsByTagName('tbody')[0];
        var rows = tbody.getElementsByTagName('tr');
        var l = rows.length ;
        for (var i = 0; i < l;i++) {
            var r = rows[i];
            var v = extract_fct(r);
            clones[i] = {
                value : v,
                element : r
            };
        }
        if (sort_fct) {
            clones.sort(sort_fct);
        } else {
            clones.sort();

        }
        if (order == "asc") {
            clones.reverse();
        }
        while(tbody.firstChild) {
            tbody.removeChild(tbody.firstChild);
        }
        for (var i = 0; i < l; i++) {
            tbody.appendChild(clones[i].element);
        }
        if (rows.item(0).className == "even" || rows.item(0).className == "odd") {
            JSTableStripe(table.parentNode);
        }
    }
    function compare_numbers(a,b) {
        return (a.value-b.value);
    }
    function compare_strings(a,b) {
        a = a.value ; b = b.value ;
        if (""+a<""+b) return (-1) ;
        if (""+a>""+b) return (1) ;
        if (""+a==""+b) return (0) ;
    }

    function extract_string_ci (r,i) {
        var text = r.getElementsByTagName('td')[i].innerHTML.toLowerCase();
        text = text.replace(/<.+?>/g,"");
        return String(text) ;
    }

    function extract_string_c (r,i) {
        var text = r.getElementsByTagName('td')[i].innerHTML;
        text = text.replace(/<.+?>/g,"");
        return String(text) ;
    }
    function extract_number (r,i) {
        var n = r.getElementsByTagName('td')[i].innerHTML;
        return parseFloat(n) ;

    }

    function build_sorter(table,i,type) {
        return function() {
            var ths = table.getElementsByTagName("th");
            for (var j = 0 ; j < ths.length;j++) {
                table.getElementsByTagName("th").item(j).className = types[j] ;
            }
            if (order == 'desc' && lastI == 1) {
                order = "asc" ;
                table.getElementsByTagName('th').item(i).className="SortAsc";
            } else {

                table.getElementsByTagName('th').item(i).className="SortDesc";
                order = "desc" ;

            }
            lastI = 1 ;
            if(type == 'n') {
                sort_table(
                           table,function(r) {
                               return extract_number(r,i);
                           },
                           compare_numbers
                           );
            } else if (type == 's') {
                sort_table(
                           table, function (r) {
                               return extract_string_ci(r,i);
                           },
                           compare_strings
                           );
            }
        }
    }
}
/* -*- javascript -*-
     Copyright 2006 Dr. Detlef Groth, Schwielowsee, Germany.
     License: http://creativecommons.org/licenses/LGPL/2.1/
     System        : JSTOOLTIPCONTROLS_JS :
     Object Name   : $RCS_FILE$
     Revision      : $REVISION$
     Date          : Fri Nov 10 05:20:20 2006
     Created By    : Dr. Detlef Groth, Schwielowsee, Germany
     Created       : Fri Nov 10 05:20:20 2006

     Last Modified : <061117.1510>
     ID            : $Id: jsComponents.js,v 1.1 2007/12/13 12:00:49 city Exp $
     Source        : $Source: /rscvs/chessweb/js/jsComponents.js,v $
     Description
     Notes
*/
/* -*- javascript -*-
  Last Modified : <060929.1152>
  Author: Dr. Detlef Groth

  */
/* JSTTip-Class */
function JSTTip (varname,filename,t) {
    var tipId ;
    var lastTipId = "null" ;
    var responseXML = false ;
    var vname = varname ;
    var file = filename ;
    var timeout = t ;
    // first tooltip might take more time because the
    // document must be downloaded
    var timeMulti = 2 ;
    function getTooltip() {
        /* tooltip construction */
        var id = "ttip" ;
        if (arguments[0]) { id = arguments[0]; }
        var tooltip ;
        if (!document.getElementById(id)) {
            tooltip = document.createElement("DIV");
            tooltip.visibility = "hidden" ;
            tooltip.setAttribute("id", id);
            document.body.appendChild(tooltip);
        }  else {
            tooltip = document.getElementById(id);
        }
        return tooltip ;
    }
    function getTTip (evt) {
        /* event resolution and tip positioning */
        var e = evt || window.event ;

        var node = evtGetTarget(e);
        if (node.className == "JSTTip") {
            // at the right place
            // we can stop event propagation
            if (e.stopPropagation) e.stopPropagation();
            e.cancelBubble = true;
        }

        tipId = node.getAttribute("id");
        window.setTimeout(''+vname+'.hideTTip()',timeout);
        if (tipId) {
            tipId = tipId.slice(0, 6);
            var div = getTooltip() ;
            div.style.visibility = "visible" ;
            div.innerHTML = "Loading data ..." ;
            if (window.pageXOffset || window.pageYOffset) {
                x = window.pageXOffset+e.clientX ;
                y = window.pageYOffset+e.clientY ;
            } else if (document.documentElement.scrollTop || document.documentElement.scrollLeft) {
                x = document.documentElement.scrollLeft+e.clientX ;
                y = document.documentElement.scrollTop+e.clientY ;
            } else {
                // ie < 6
                x = document.body.scrollLeft+e.clientX ;
                y = document.body.scrollTop+e.clientY ;
            }
            if (x > 500) {
                // we put it on the left side of the event
                // otherwise it might went out of the window
                x -= 250 ;
            }
            if (y > 300) {
                // like with x
                y -= 30;
            }
            div.style.left = x+"px";
            div.style.top = y+"px";
            // get content
            if (!responseXML) {
                var loader = new XMLHttpRequestLoader;
                loader.loadXML(file,displayTTip);

            } else {
                timeMulti = 1 ;
                displayTTip(responseXML);
            }
        }
    }
    function displayTTip (response) {
        // parsing of the reponse
        // loading the right tip
        responseXML=response ;
        var divs = responseXML.getElementsByTagName("div");
        for (var x = 0 ; x < divs.length ; x++) {
            if (divs.item(x).getAttribute('id').search(tipId) >= 0) {
                var div = getTooltip() ;
                if (divs.item(x).innerHTML) {
                    div.innerHTML = divs.item(x).innerHTML;
                } else if (divs.item(x).xml) {
                    div.innerHTML = divs.item(x).xml ;
                }

                break ;
            }
        }


    }
    function hideTTip() {
        if (lastTipId == tipId) {
            var div = getTooltip() ;
            div.style.visibility = "hidden" ;
        } else {
            window.setTimeout(''+vname+'.hideTTip()',timeout*timeMulti);
        }
        lastTipId = tipId ;
    }
    function addEventsTTips () {
        var spans = document.getElementsByTagName("span");
        for (var i = 0 ; i< spans.length;i++) {
            if(spans.item(i).className == "JSTTip") {
                evtAdd(spans.item(i),"mouseover",getTTip);
            }
        }
    }
    this.hideTTip = hideTTip;
    addEventsTTips();
}
var jstt ;
function JSToolTip (element) {
    // wrapper function
    // we need the global variable name for window.setTimeout
    // Parameters JSTTip(varName filename, timeout)
    var path ;
    var outtime ;
    if (element.getAttribute("data") == null) {
        alert("JSToolTip: error you need data attribute like so data='path/tips.xhtml,timout'!");
    } else {
        var text = element.getAttribute("data");
        var items = text.split(",");
    }
    jstt = new JSTTip('jstt',items[0],items[1]);
}
/* -*- javascript -*-
     Copyright 2006 Dr. Detlef Groth, Schwielowsee, Germany.
     License: http://creativecommons.org/licenses/LGPL/2.1/
     System        : JSTREECONTROLS_JS :
     Object Name   : $RCS_FILE$
     Revision      : $REVISION$
     Date          : Fri Nov 10 04:55:18 2006
     Created By    : Dr. Detlef Groth, Schwielowsee, Germany
     Created       : Fri Nov 10 04:55:18 2006

     Last Modified : <061130.0607>
     ID            : $Id: jsComponents.js,v 1.1 2007/12/13 12:00:49 city Exp $
     Source        : $Source: /rscvs/chessweb/js/jsComponents.js,v $
     Description
     Notes
*/
function JSCollapse(element) {
    var c = new JSTree(element);
}
function JSTree (element) {
    var lists = element.getElementsByTagName("LI") ;
    this.toggleDisplay = toggleDisplay ;
    this.expandcollapse = expandcollapse ;
    this.hideAllSubLists = hideAllSubLists ;
    evtAdd(element, "click", this.expandcollapse);
    for (var i = 0 ; i < lists.length; i++) {
        var listslists = lists.item(i).getElementsByTagName("LI") ;
        if (listslists.length > 0) {

            if (lists.item(i).className != "opened") {
               toggleDisplay(lists.item(i));
            }
        } else {
            lists.item(i).className = "leaf" ;
        }
    }
    hideAllSubLists(element, "");
    function hideAllSubLists(element, display) {
        var ul = element.childNodes ;
        for (var i = 0 ; i < ul.length ; i++) {
            var node = ul.item(i) ;
            if (node.nodeName == "LI" && node.getElementsByTagName("UL").item(0) &&
                node.getElementsByTagName("UL").item(0).nodeName == "UL") {
                node = node.getElementsByTagName("UL").item(0) ;
            }
            if (node.nodeName == "UL") {
                node.style.display = display ;
            }
        }
    }
    function getNodeUp (node, nodeType) {
        while (node.nodeName != nodeType) {
            node=node.parentNode;
        }
        return node ;
    }
    function expandcollapse (e) {
        e=e||window.event;
        var element = evtGetTarget(e);
        var child ;

        // to avoid closing the upper list-item
/*        e.cancelBubble = true;*/

/*        if (e.stopPropagation) e.stopPropagation();*/
        // to avoid closing the upper list-item if clicking on a link
        //alert(element.nextSibling.nodeName);
        try { if(window.event.srcElement.tagName != "LI" && window.event.srcElement.tagName != "SPAN") return; } catch (ev) {}
        toggleDisplay(element) ;
    }
    function toggleDisplay(el) {
        child = el.getElementsByTagName("UL")[0];
        if (!child) {
            // we have mozilla which correctly finds it as s sibling
            child = el.nextSibling ;
            while (child != null) {
                if (child.nodeName == "UL") { break } ; //"[object HTMLUListElement]") { break }
                child = child.nextSibling ;
            }
        }
        if (child) {
            bCollapsed = (child.style.display == "none");
            // Toggle the display and listStyleImage properties depending
            // on the expanded or collapsed state of the list.
            if (bCollapsed) {
                if (element.className == "JSTree") {
                    el.className = "opened" ;
                }
                child.style.display = "";
            } else {
                if (element.className == "JSTree") {
                    el.className = "" ;
                }
                child.style.display = "none" ;
            }
        } else {
            // no child so it is a simple listitem
            el.className = "leaf" ;
        }
    }

}
