/* Script zum Ein-Ausblenden von Untermenü-Einträgen
 * Das Menü muss in einer vordefinierten Struktur vorliegen.
 * Alle Funktionalitäten sind im Objekt klapper gekapselt.
 */
var klapper=(function(){
    // Default-Angaben für die ersten Zeichen von Unterkategorie (aufgeklappt), Unterkategorie-Alternative (zugeklappt) und SubLink
    var _firstCharOnSubCategories = String.fromCharCode(8226);  //"•"
    var _firstCharOnSubCatAlternate = "+" //
    var _fistCharOnSubLinks = String.fromCharCode(172);        //"¬"
    
    /* Weist den Kindelementen von tableId das onclick-Event zu.
     * Erwartet die Id eines Table-Elements und untersucht die darin enthaltenen
     * Datenzellen. Wenn der Inhalt mit Text beginnt und der Text mit \u0149 beginnt,
     * dann wird das onclick-Attribut hinzugefügt.     */
    function _SetEventhandlerInTable(tableId){
        // Table-Element referenzieren und prüfen
        var tbl=document.getElementById(tableId);
        if(tbl && tbl.nodeType==1 && tbl.nodeName=="TABLE" && tbl.hasChildNodes()){
            // alle td-Elemente der Tabelle in einem Array referenzieren
            var tdAll=tbl.getElementsByTagName("TD");
            // alle td-Elemente untersuchen
            for(var z=0;z<tdAll.length;z++){
                // hat td Inhalt(e)?
                if(tdAll[z].hasChildNodes()){                    
                    // erstes Kind referenzieren
                    var tdFirstChld=tdAll[z].firstChild;
                    // Ist es ein span?
                    if(tdFirstChld.nodeType==1 && tdFirstChld.nodeName=="SPAN" && tdFirstChld.hasChildNodes()){
                        // erstes Kind vom span referenzieren
                        var fstChd=tdFirstChld.firstChild;
                        // ist es vom Typ TextNode?
                        if(fstChd.nodeType==3){
                            // Text des Textknotens auslesen
                            var txt=fstChd.data;
                            // Leerzeichen, Textumbruch, Tabstopp usw. entfernen
                            txt=txt.replace(/\s/g,"");
                            // Wenn jetzt das erste Zeichen die Unterkategorie symbolisiert, dann TREFFER
                            if(txt.indexOf(klapper.FirstCharOnSubCategories) == 0){
                                tdAll[z].onclick=klapper.ToggleViewState;
                                //tdAll[z].style.fontStyle="italic";
                               tdAll[z].onclick();  // per default alle zugeklappt
                            }
                        }
                    }
                }
            }
        }
    }
    // Schaltet die Sichtbarkeit der SubLinks des aufrufenden Unterkategorie-Elements um.
    function _ToggleViewState(){
        var caller = this;  // this ist das aufrufende (angeklicḱte) Element
        // prüfe, ob Aufrufer wirklich ein td-Element ist
        if(caller.nodeType == 1 && caller.nodeName == "TD"){                                                            //alert("Caller ist TD");
            var callerTxtNode;      // Referenz auf Textknoten mit dem Anzeigetext des Aufrufers
            var haveToHide = null;  // muss aus oder eingeblendet werden?
            
            // Aufrufer analysieren, wir brauchen später dessen Text
            if(caller.hasChildNodes()){
                var callerChild = caller.firstChild;
                // der erste Kindknoten sollte ein span-Element sein, muss aber nicht.
                // MS gibt Zeilenwechsel im HTML als Textknoten zurück.
                while(callerChild != null){
                    // prüfe auf span, wenn falsch, dann zum nächsten Knoten 
                    if(callerChild.nodeType == 1 && callerChild.nodeName == "SPAN" && callerChild.hasChildNodes()){     //alert("Caller-span gefunden");
                        // span gefunden, erstes Kind muss jetzt ein Textknoten sein
                        var spanChild = callerChild.firstChild;
                        if(spanChild.nodeType == 3){                                                                    //alert("Caller-Text ist:"+spanChild.data);
                            callerTxtNode = spanChild;  // Textknoten des callers referenzieren
                            
                            break;  // Schleife verlassen, keine weiteren Knoten prüfen
                        }
                    }
                    // nächsten Bruderknoten referenzieren
                    callerChild = callerChild
                }
            }
            
             // Zeile des Aufrufers referenzieren und prüfen
            var callerTr = caller.parentNode;
            if(callerTr.nodeType != 1 || callerTr.nodeName != "TR"){
                alert("Unerwartete Struktur in TableNavi!");
                return;   // wenn Aufrufer kein tr als Vater hat stimmt was nicht
            }
            
            // nächstfolgende Zeile referenzieren
            var tr = callerTr.nextSibling;
            // diese und weitere Zeilen bearbeiten
            while(tr != null){
                // ist tr ein Elementeknoten und ein "tr" und hat tr Kindknoten?
                if(tr.nodeType == 1 && tr.nodeName == "TR" && tr.hasChildNodes()){                                       //alert("next TR gefunden");
                    var td = tr.firstChild; // kann die erwartete Datenzelle sein, aber auch ein Textknoten mit Zeilenumbruch als Inhaltstext
                    // solange td auf ein Objekt zeigt...
                    while(td != null){
                        // ist td ein "TD" und hat es Kinder?
                        if(td.nodeType == 1 && td.nodeName == "TD" && td.hasChildNodes()){                               //alert("TD gefunden");
                            var tdChild = td.firstChild;
                            while(tdChild != null){
                                // ist tdChild ein span und hat es Kinder?
                                if(tdChild.nodeType == 1 && tdChild.nodeName == "SPAN" && tdChild.hasChildNodes()){     //alert("SPAN gefunden");
                                    var spanChild = tdChild.firstChild;
                                    if(spanChild.nodeType == 3){
                                        var txt = spanChild.data;                                                       //alert("SPAN-Text ist\n|"+txt);
                                        rx = new RegExp();
                                        rx.compile(String.fromCharCode(160),"g");   // RegEx-Ausdruck für &nbsp;
                                        txt = txt.replace(/\s/g,"").replace(rx,"");                                     //alert("nach Trim\n|"+txt);alert("Pos:"+txt.indexOf(klapper.FistCharOnSubLinks));
                                        // Wenn jetzt das erste Zeichen den SubLink symbolisiert, dann ist Zeile ein SubLink
                                        if(txt.indexOf(klapper.FistCharOnSubLinks) == 0){                               
                                            // SubLink-Zeile gefunden
                                            // erster SubLink? Dann ist haveToHide noch null.
                                            if(haveToHide == null){
                                                haveToHide = (tr.style.display == "");  // erster SubLink bestimmt den Wechsel für alle SubLinks
                                            
                                                if(haveToHide){                  
                                                    // verstecken
                                                    tr.style.display="none";
                                                    
                                                    // 1.Zeichen des Aufrufers wechseln
                                                    var txtSplits = callerTxtNode.data.split(klapper.FirstCharOnSubCategories);
                                                    if(txtSplits.length == 1)
                                                        callerTxtNode.data = klapper.FirstCharOnSubCatAlternate+txtSplits.join(klapper.FirstCharOnSubCategories);
                                                    else{
                                                        var first = txtSplits.shift();
                                                        callerTxtNode.data = first + klapper.FirstCharOnSubCatAlternate + txtSplits.join(klapper.FirstCharOnSubCategories);
                                                    }
                                                }
                                                else{
                                                    // nein, also anzeigen
                                                    tr.style.display = "";
                                                    // 1.Zeichen des Aufrufers wechseln
                                                    var txtSplits = callerTxtNode.data.split(klapper.FirstCharOnSubCatAlternate);
                                                    if(txtSplits.length == 1)
                                                        allerTxtNode.data = klapper.FirstCharOnSubCategories+txtSplits.join(klapper.FirstCharOnSubCatAlternate);
                                                    else{
                                                        var first = txtSplits.shift();
                                                        callerTxtNode.data = first + klapper.FirstCharOnSubCategories + txtSplits.join(klapper.FirstCharOnSubCatAlternate);
                                                    }
                                                }
                                            }
                                            else
                                            {   // 2. oder folgender SubLink
                                                if(haveToHide){
                                                    tr.style.display="none";
                                                }else{
                                                    tr.style.display="";
                                                }
                                            }
                                            
                                            break;  // kein weiteres td in dieser Zeile suchen, habe eins gefunden, das reicht mir
                                        }
                                        else
                                            return; // Abbruch weil diese Zeile kein SubLink ist
                                    }
                                }
                                // Schleife wurde nicht abgebrochen, also wurde noch nicht der richtige Knoten gefunden. Deshalb jetzt den nächsten probieren.
                                tdChild=tdChild.nextSibling();
                            }
                        }
                        td = td.nextSibling; //nachfolgenden Knoten referenzieren 
                    }
                }
                tr = tr.nextSibling;  //nachfolgenden Knoten referenzieren
            }
        }
    }
    
    // Initialwertzuweisung
    function _Init(){
        // Hier können Inititialisierungseinstellungen ausgeführt werden.
    }
    
    // Öffentliche Eigenschaften und Methoden
    return {
        SetEventhandlerInTable : _SetEventhandlerInTable,   // Zuweisung des onclick-Eventhandlers, kann auch mehrmals für verschiedene Tabellen aufgerufen werden
        ToggleViewState : _ToggleViewState,                 // Eventhandler der onclick-Events
        FirstCharOnSubCategories : _firstCharOnSubCategories,   // Erstes Zeichen bei Unterkategorien
        FirstCharOnSubCatAlternate : _firstCharOnSubCatAlternate,   // alternatives erstes Zeichen bei Unterkategorien
        FistCharOnSubLinks : _fistCharOnSubLinks,           // Erstes Zeichen bei SubLinks
        Init : _Init                                        // Initialisierung - wenn erforderlich
    }
    })();
// Aufruf der Initialisierung (könnte hier auch unterbleiben)
klapper.Init();
