/*
 * Zentrale Klasse für die Flughafen-Mehrfachauswahl
 * 
 * @author Wolfgang Merkens <wm@traveltainment.de>
 * @copyright  2010 Traveltainment AG
 */ 

// Konstruktor
function TTAirportMultiChoice(thisName) { 
    this.oApCus                 = new Object(); // kundenspez. AFH der Strecke
    this.aApAreas               = new Array(); // kundenspez. Unterteilungen der AFH
    this.aApGroups              = new Array(); // kundenspez. AFH-Gruppen
    this.oApGroupsDLC           = {};          // DLCs der kundenspez. AFH-Gruppen     
    this.selectedGroups         = [];          // Aktuell selektierte Gruppen     
    this.minChoice              = 0; // min. Anzahl ausgewählter AFH
    this.maxChoice              = 30; // max. Anzahl ausgewählter AFH
    this.aSelDlc                = new Array(); // temp. Array mit selektierten DLC        
    this.controlType            = 'checkbox'; // ('graphic') Formular mit checkbox oder mit Grafik?
    this.mouseMoveEffects       = false; // Mouseover-/Mouseout - Effekte ein/aus
    this.mapObj                 = null; // Instanz des Kartenobjekts
    this.isMap                  = false; // mit/ohne Karte 
    this.callbackMouseClick     = '';  // callback-Funktion Mausklick
    this.callbackSubmit         = ''; // callback-Funktion Daten senden
    this.callbackClearAll       = ''; // callback-Funktion: alles deaktivieren
    this.callbackDisplayAirport = ''; // callback-Funktion: HTML-Ausgabe eines AFH
    this.callbackRangeAlert     = ''; // callback-Funktion: Ausgabe bei AFH-Bandbreite-Fehler
    this.callbackGetLabel       = ''; // callback-Funktion: Label
    this.transferClick          = new Object(); // Übergabe-Objekt für callbackMouseClick 
    this.dataField              = 'abflughafen';
    this.abflughafen            = null;
    this.refresh                = null;
    this.name                   = 'ttMultiAirport';
    if (typeof(thisName) == 'string' && thisName != '') {
        this.name = thisName;
    }      
}

// init
TTAirportMultiChoice.prototype.init = function (sourceAp) {
    // sourceAirports: AFH-Array/-Objekt der Strecke
    if (sourceAp != null && typeof(sourceAp) == 'object') {
        // wenn this.oApCus noch nicht definiert... 
        if (!this.oApCus.length || this.oApCus.length < 1) {            
            // wenn Elemente klassisch als string, dann erst json kodieren
            if (typeof(sourceAp[0]) == 'string' && sourceAp[0].indexOf(';') > 0) {                 
                var tmpObj;
                var tmpArr  = [];                 
                var jsonTxt = '[';
                for (var i = 0; i < sourceAp.length; i++) {
                   tmpArr   = sourceAp[i].split(';');
                   jsonTxt += '{"label":"' + tmpArr[0] + '","dlc":"' + tmpArr[1] + '"},';
                }
                jsonTxt     = jsonTxt.replace(/,$/,'');
                jsonTxt    += ']';     
                tmpObj      = eval('(' + jsonTxt + ')');
                this.oApCus = tmpObj;                 
            } else {
                this.oApCus = sourceAp;
            }              
        }          
    }         
    // Formularelement "abflughafen"
    this.abflughafen = document.getElementById(this.dataField);
    if (this.abflughafen == null) {
        this.abflughafen = document.getElementsByName(this.dataField)[0];
    } 
    // ist "abflughafen" in opener?    
    if (this.abflughafen == null && typeof(opener.document) == 'object') {
        this.abflughafen = opener.document.getElementById(this.dataField);
        if (this.abflughafen == null) {
            this.abflughafen = opener.document.getElementsByName(this.dataField)[0];
        }
    }

    // Formularelement "refresh"
    this.refresh = document.getElementById('refresh');
    if (this.refresh == null) {
        this.refresh = document.getElementsByName('refresh')[0];
    } 
    if (typeof this.refresh == 'undefined' || this.refresh == null) {
        // ist "refresh" in opener?
        try {
            if (opener != null && typeof(opener.document) == 'object') {
                this.refresh = opener.document.getElementById('refresh');
                if (this.refresh == null) {
                    this.refresh = opener.document.getElementsByName('refresh')[0];
                }
            }
        } catch(ex) {
            this.refresh = null;
        }
    }    
    
    // Karte initiieren
    if (this.isMap && typeof(this.mapObj) == 'object' && typeof(TTMapForAirportMultiChoice) == 'function') {
        this.mapObj.init();
    }     
    // Startwerte setzen    
    this.setAirportValues();     
    // label aus this.oApCus in die areas setzen
    if (this.aApAreas.length > 0) {
        // Objekt: areas
        for (var ar = 0; ar < this.aApAreas.length; ar ++) {
            // Objekt: AFH der area
            for (var j = 0; j < this.aApAreas[ar].length; j ++) {                 
                // area-objekt mit main-objekt vergleichen                
                for (var m = 0; m < this.oApCus.length; m ++) {                     
                    if (this.aApAreas[ar][j].dlc == this.oApCus[m].dlc) {
                        this.aApAreas[ar][j].label = this.oApCus[m].label;                        
                        break;
                    }                      
                }                 
            }             
        }
    }     
}

// Werte der Abflughäfen setzen
TTAirportMultiChoice.prototype.setAirportValues = function() {      
    var actValAp = this.abflughafen.value;  
    if (actValAp != '-1' && actValAp != '-1,' && actValAp != '') {
        this.aSelDlc = actValAp.split(',');
        
        // AFH-IDs -> DLCs
        for (var i = 0; i < this.aSelDlc.length; i++) {
            this.aSelDlc[i] = this.transformId(this.aSelDlc[i]);
        }
    } else {
        this.aSelDlc = new Array();
    }

    // Werte für Karte
    if (this.isMap && typeof(this.mapObj) == 'object' && typeof(TTMapForAirportMultiChoice) == 'function') {
        this.mapObj.setArraySelectedAirports(this.aSelDlc);
    } 
}

// Selektierte DLC in Feld "abflughafen" schreiben
TTAirportMultiChoice.prototype.submitValues = function() { 
    if (this.aSelDlc.length > 1) {
        this.aSelDlc.sort();
    }    
    // Übergabe an def. Callback-Funktion
    if (this.callbackSubmit != '') {        
        eval(this.callbackSubmit + '(this.aSelDlc)');         
    } else {
        if (this.aSelDlc.length > 0) {            
            this.abflughafen.value = this.aSelDlc.join(',');
        } else {
            this.abflughafen.value = '-1';
        } 
    }
    // Change-Field setzen
    if (this.refresh != null) {
        this.refresh.value = '1';
    }
}

// HTML-Ausgabe: AFH in div schreiben
TTAirportMultiChoice.prototype.printAirports = function(obj) {
    // obj.div: id der Ziel-Div-Box; obj.id: Attribut "id" des Area-Objekts; obj.col: max.Anzahl Spalten; obj.range: Anzahl AFH pro Spalte (optional)
    if (typeof(obj) == 'object') {
        if (typeof(obj.div) == 'string' && obj.div != '') {
            var oAp = null;
            // Area?
            if (typeof(obj.id) == 'string' && obj.id != '') {
                // Erste Area mit obj.id als ID finden
                for (var ar = 0; ar < this.aApAreas.length; ar++) {
                    if (this.aApAreas[ar][0].id == obj.id) {
                        oAp = this.aApAreas[ar];
                        break;
                    }
                }
            } else {
                oAp = this.oApCus;
            } 
            if (oAp != null) {
                this.outputAirportsToBox(oAp, obj);               
            }   
        }    
    }
}

// HTML-Ausgabe der einzelnen AFH-Objekte 
TTAirportMultiChoice.prototype.outputAirportsToBox = function(oAp, obj) {     
    var nrStart = 0; // index Spalten-Start
    var nrEnd   = 0; // index Spalten-Ende
    var breakIt = false;       
    // Spalten durchlaufen
    for (var col = 1; col <= obj.col; col ++) {          
        var strHtml = '';
        // range berechnen? (wenn keine angegeben)
        if (typeof(obj.range) == 'undefined') {
            var nrInCol  = Math.ceil((oAp.length / obj.col));
        } else {            
            var nrInCol = obj.range[(col - 1)];
        }
        nrInCol = parseInt(nrInCol);
        nrEnd  += nrInCol;           
        // Ausgabe der einzelnen Flughäfen pro Spalte
        for (var i = nrStart; i < nrEnd; i ++) {             
            if (i >= oAp.length || !oAp[i]) {
                breakIt = true;
                break;
            }

            // gibts ne kundenspezifische Ausgabe-Funktion?
            if (this.callbackDisplayAirport != '') {
                eval(this.callbackDisplayAirport + '(oAp[i],this.aSelDlc)');         
            } else {
                // AFH-Gruppe?
                var arrAfh     = oAp[i].dlc.split(',');
                var isAfhGroup = arrAfh.length > 1;
                
                // Airport aktiv?
                if (isAfhGroup) {
                    isActAp = this.aSelDlc.length > 0 && this.areInArray(arrAfh, this.aSelDlc);
                } else {
                    isActAp = this.aSelDlc.length > 0 && this.isInArray(oAp[i].dlc, this.aSelDlc);
                }
                
                // zusätzliche Styles?
                var addStyleRow   = '';
                var addStyleLabel = '';
                if (typeof(obj.cssRow) == 'string' && obj.cssRow != '') {
                    addStyleRow = ' style="' + obj.cssRow + '"';
                }
                if (typeof(obj.cssLabel) == 'string' && obj.cssLabel != '') {
                    addStyleLabel = ' style="' + obj.cssLabel + '"';
                }
                
                // Gruppe/Einzel
                var rowId = isAfhGroup ? oAp[i].id + '' + i : oAp[i].dlc;

                // grafische Element-Darstellung
                if (this.controlType == 'graphic') {
                    var theLabelStyle = 'ttAirportLabel';
                    var theRowStyle   = 'ttAirportRow';
                    if (isActAp) {
                        theLabelStyle = 'ttAirportLabelClick';
                        theRowStyle   = 'ttAirportRowClick';
                    }                              
                    strHtml += '<div id="ttAirport_' + rowId + '" class="' + theRowStyle + '"' + addStyleRow + ' dlc="' + oAp[i].dlc + '" onclick="' + this.name + '.mouseAction(\'click\',this,\'1\')"';
                    if (this.mouseMoveEffects) {
                        strHtml += ' onmouseover="' + this.name + '.mouseAction(\'over\',this,\'1\')" onmouseout="' + this.name + '.mouseAction(\'out\',this,\'1\')"';
                    }
                    strHtml += '>';                             
                    strHtml += '<div class="' + theLabelStyle + '"'+addStyleLabel+'>' + this.getLabel(oAp[i].label) + '</div>';             
                    strHtml += '</div>';
                } else if (this.controlType == 'checkbox') {                             
                    // Darstellung: checkbox
                    var isChecked     = '';
                    var theRowStyle   = 'ttAirportRow';
                    var theLabelStyle = 'ttAirportLabel';                     
                    if (isActAp) {
                        isChecked     = ' checked="checked"';
                        theRowStyle   = 'ttAirportRowClick';
                        theLabelStyle = 'ttAirportLabelClick';                         
                    }
                    strHtml += '<div id="ttAirport_' + rowId + '" class="' + theRowStyle + '"' + addStyleRow + ' dlc="' + oAp[i].dlc + '"';                            
                    if (this.mouseMoveEffects) {
                        strHtml += ' onmouseover="if(' + this.name + '.isMouseLeaveOrEnter(event,this)) { ' + this.name + '.mouseAction(\'over\',this,\'1\') }" onmouseout="if(' + this.name + '.isMouseLeaveOrEnter(event,this)) { ' + this.name + '.mouseAction(\'out\',this,\'1\') }"';
                    }
                    strHtml += '>';
                    strHtml += '<input type="checkbox" class="ttAirportInput" name="ttMultiAirportCheckbox" id="ttMultiAirportCheckbox_' + rowId + '" value="' + oAp[i].dlc + '" onclick="' + this.name + '.mouseAction(\'click\',this,\'1\')" dlc="' + oAp[i].dlc + '"' + isChecked + '>';
                    strHtml += '<label for="ttMultiAirportCheckbox_' + rowId + '" class="' + theLabelStyle + '">' + this.getLabel(oAp[i].label) + '</label>';
                    strHtml += '</div>';
                }
            }                      
        } // for (var i = nrStart; i < nrEnd; i ++)             
        nrStart = nrEnd;         
        if (strHtml != '') {
            var inDiv = String(obj.div + col);
            var inElem = null;
            inElem = document.getElementById(inDiv);
            if (inElem == null) {
                inElem = parent.document.getElementById(inDiv);
            }
            if (inElem != null) {
                inElem.innerHTML = strHtml;
            }             
        }          
        if (breakIt) {
            break;
        }         
    } // for (var col = 1; col <= obj.col; col ++)    
}

// Mausaktionen bei click, over und out
TTAirportMultiChoice.prototype.mouseAction = function (action, obj, callback) {
    // zusätzliche callback-Funktion aufrufen?   
    var setCallback = false;     
    if (typeof(callback) != 'undefined' && callback == '1') {
        setCallback = true;
    }           
    // mouseAction wird durch Mausaktion der IconMap aufgerufen
    var mapElem = null;
    if (typeof(obj) == 'string' && obj != '' && this.isMap && typeof(this.mapObj) == 'object') {
        mapElem = document.getElementById(obj);
        if (mapElem != null) {
            var mapDlc  = mapElem.getAttribute('dlc', 0);
            if (mapDlc != '') {
                if (action == 'click' && this.controlType == 'checkbox') {
                    var obj = document.getElementById('ttMultiAirportCheckbox_' + mapDlc);
                } else {
                    var obj = document.getElementById('ttAirport_' + mapDlc);
                } 
                setCallback = true;                
            }
        }         
    } 
    // Aktionen
    if (obj != null && typeof(obj) == 'object') {         
        var objDlc = obj.getAttribute('dlc', 0);
        var arrDLC = objDlc.split(',');

        if (action == 'over') {
            var isOver = false;
            if (obj.className != 'ttAirportRowClick') {
                this.toggleState(obj, 'ttAirportRowHover', 'ttAirportLabel', 'ttAirportLabelHover');
                isOver = true;
            }

            // Mausaktion für Gruppe
            if (isOver && arrDLC.length > 1) {
                for (var i = 0; i < arrDLC.length; i++) {
                    var rObj = document.getElementById('ttAirport_' + arrDLC[i]);
                    if (rObj && rObj.className != 'ttAirportRowClick') {
                        this.toggleState(rObj, 'ttAirportRowHover', 'ttAirportLabel', 'ttAirportLabelHover');
                    }

                    // Karte
                    if (this.isMap && typeof(this.mapObj) == 'object') {
                        var mapElem = document.getElementById('ttMapAirport_' + arrDLC[i]);
                        if (mapElem != null) {
                            this.mapObj.mouseAction(action, mapElem);
                        }
                    }
                }
            }
            
            // Mausaktion für Karte
            if (isOver && this.isMap && typeof(this.mapObj) == 'object' && mapElem == null) {
                var mapElem = document.getElementById('ttMapAirport_' + objDlc);
                if (mapElem != null) {
                    this.mapObj.mouseAction(action, mapElem);
                }
            }             

        } else if (action == 'out') {
            var isOut = false;
            if (obj.className != 'ttAirportRowClick') {
                this.toggleState(obj, 'ttAirportRow', 'ttAirportLabelHover', 'ttAirportLabel');
                isOut = true;
            }
            
            // Mausaktion für Gruppe
            if (isOut && arrDLC.length > 1) {
                for (var i = 0; i < arrDLC.length; i++) {
                    var rObj = document.getElementById('ttAirport_' + arrDLC[i]);
                    if (rObj && rObj.className != 'ttAirportRowClick') {
                        this.toggleState(rObj, 'ttAirportRow', 'ttAirportLabelHover', 'ttAirportLabel');
                    }

                    // Karte
                    if (this.isMap && typeof(this.mapObj) == 'object') {
                        var mapElem = document.getElementById('ttMapAirport_' + arrDLC[i]);
                        if (mapElem != null) {
                            this.mapObj.mouseAction(action, mapElem);
                        }
                    }
                }
            }
            // Mausaktion für Karte
            if (isOut && this.isMap && typeof(this.mapObj) == 'object' && mapElem == null) {
                var mapElem = document.getElementById('ttMapAirport_' + objDlc);
                if (mapElem != null) {
                    this.mapObj.mouseAction(action, mapElem);
                }
            }             

        } else if (action == 'click') {
            var isClick = false;
            // Sammelt hinzuzufügende bzw. zu entfernende DLCs
            var handle  = [];
            
            // DLC entfernen oder hinzufügen?
            if (arrDLC.length > 1) {
                // Gruppe
                var clickType  = this.areInArray(arrDLC, this.aSelDlc) ? 'minus' : 'plus';
                var dontHandle = [];
                
                if (clickType == 'minus') {
                    // Schnittmengen mit anderen selektierten Gruppen nicht abwählen!
                    dontHandle = this.getDlcIntersection(arrDLC, obj.id.split('_')[1]); 
                }
                
                // Selektierte / Neue prüfen
                for (var i = 0; i < arrDLC.length; i++) {
                    if (this.isInArray(arrDLC[i], this.aSelDlc)) {
                        if (clickType == 'minus' && !this.isInArray(arrDLC[i], dontHandle)) {
                            handle[handle.length] = arrDLC[i];
                        }
                    } else if (clickType == 'plus') {
                        handle[handle.length] = arrDLC[i];
                    }
                }
                var delta = clickType == 'plus' ? handle.length : -1 * handle.length;
            } else {
                // Einzel-DLC
                var clickType = this.isInArray(objDlc, this.aSelDlc) ? 'minus' : 'plus';
                var delta = clickType == 'plus' ? 1 : -1;
                handle[0] = objDlc;
            }
            
            // Bandbreite selektierter Flughäfen gültig?
            if (this.isValidRange(delta)) {
                for (var i = 0; i < handle.length; i++) {
                    if (clickType == 'plus') {
                        // hinzufügen
                        this.aSelDlc.push(handle[i]);
                    } else {
                        // löschen
                        this.deleteFromArray(handle[i], this.aSelDlc);
                    }
                }
                
                if (this.controlType == 'graphic') {                     
                    if (clickType == 'plus') {
                        this.toggleState(obj, 'ttAirportRowClick', 'ttAirportLabel', 'ttAirportLabelClick');

                        for (var i = 0; i < handle.length; i++) {
                            var rObj = document.getElementById('ttAirport_' + handle[i]);
                            if (rObj) {
                                this.toggleState(rObj, 'ttAirportRowClick', 'ttAirportLabel', 'ttAirportLabelClick');
                            }
                            // Karte
                            if (this.isMap && typeof(this.mapObj) == 'object') {
                                var mapElem = document.getElementById('ttMapAirport_' + handle[i]);
                                if (mapElem != null) {
                                    this.mapObj.mouseAction('active', mapElem);
                                }
                            }                            
                        }
                    } else {
                        this.toggleState(obj, 'ttAirportRowHover', 'ttAirportLabelClick', 'ttAirportLabelHover');

                        for (var i = 0; i < handle.length; i++) {
                            var rObj = document.getElementById('ttAirport_' + handle[i]);
                            if (rObj) {
                                this.toggleState(rObj, 'ttAirportRow', 'ttAirportLabelClick', 'ttAirportLabel');
                            }
                            // Karte
                            if (this.isMap && typeof(this.mapObj) == 'object') {
                                var mapElem = document.getElementById('ttMapAirport_' + handle[i]);
                                if (mapElem != null) {
                                    this.mapObj.mouseAction('normal', mapElem);
                                }
                            }                            
                        }
                    }
                    isClick = true;
                } else if (this.controlType == 'checkbox') { 
                    var parentObj = obj.parentNode;
                    if (clickType == 'plus') {
                        this.toggleState(parentObj, 'ttAirportRowClick', 'ttAirportLabel', 'ttAirportLabelClick', obj, true);

                        for (var i = 0; i < handle.length; i++) {
                            var rObj = document.getElementById('ttAirport_' + handle[i]);
                            var cObj = document.getElementById('ttMultiAirportCheckbox_' + handle[i]);
                            if (rObj && cObj) {
                                this.toggleState(rObj, 'ttAirportRowClick', 'ttAirportLabel', 'ttAirportLabelClick', cObj, true);
                            }
                            // Karte
                            if (this.isMap && typeof(this.mapObj) == 'object') {
                                var mapElem = document.getElementById('ttMapAirport_' + handle[i]);
                                if (mapElem != null) {
                                    this.mapObj.mouseAction('active', mapElem);
                                }
                            }                            
                        }
                    } else {
                        this.toggleState(parentObj, 'ttAirportRowHover', 'ttAirportLabelClick', 'ttAirportLabelHover', obj, false);

                        for (var i = 0; i < handle.length; i++) {
                            var rObj = document.getElementById('ttAirport_' + handle[i]);
                            var cObj = document.getElementById('ttMultiAirportCheckbox_' + handle[i]);
                            if (rObj && cObj) {
                                this.toggleState(rObj, 'ttAirportRow', 'ttAirportLabelClick', 'ttAirportLabel', cObj, false);
                            }
                            // Karte
                            if (this.isMap && typeof(this.mapObj) == 'object') {
                                var mapElem = document.getElementById('ttMapAirport_' + handle[i]);
                                if (mapElem != null) {
                                    this.mapObj.mouseAction('normal', mapElem);
                                }
                            }                            
                        }
                    }                     
                    isClick = true;
                    
                }
                // Gruppen selektieren / abwählen ?
                this.updateGroups();

                // Mausaktion für Karte
                if (isClick && this.isMap && typeof(this.mapObj) == 'object' && mapElem == null) {
                    var mapElem = document.getElementById('ttMapAirport_' + objDlc);
                    if (mapElem != null) {
                        this.mapObj.mouseAction(action, mapElem);
                    }
                }
                // Übergabe an def. Callback-Funktion
                if (isClick && setCallback && this.callbackMouseClick != '') {                    
                    this.transferClick.clickType   = clickType;
                    this.transferClick.controlType = this.controlType;                    
                    this.transferClick.actObj      = obj;
                    eval(this.callbackMouseClick + '(this.transferClick)');
                }
            } else {
                // Außerhalb gültiger Bandbreite selektierter Flughäfen
                // wenn zuerst Karte geklickt wurde...
                if (this.isMap && typeof(this.mapObj) == 'object' && mapElem != null) {                     
                    this.mapObj.mouseAction('normal', mapElem);
                }
                // Feedback
                if (this.callbackRangeAlert != '') {
                    eval(this.callbackRangeAlert + '(clickType,this.minChoice,this.maxChoice)');         
                } else {                
                    if (clickType == 'plus') {
                        alert('Max. Anzahl Flughäfen: ' + this.maxChoice);
                    } else {
                        alert('Min. Anzahl Flughäfen: ' + this.minChoice);
                    }
                }
            }             
        }        
    }
}

// Hole vollen Namen zu einem DLC / AFH-ID
TTAirportMultiChoice.prototype.getNameForDlc = function(dlc) {     
    var ret = '';
    dlc = this.transformId(dlc);
    if (typeof(dlc) == 'string' && dlc != '') {
        for (var i = 0; i < this.oApCus.length; i ++) {
            if (dlc == this.oApCus[i].dlc) {
                ret = this.oApCus[i].label;
                break;
            }
        }
    }     
    return ret;
}

// Deaktiviere alle selektierten AFH
TTAirportMultiChoice.prototype.clearAll = function() {
    for (var i = 0; i < this.aSelDlc.length; i ++) {
        if (this.controlType == 'graphic') {
            var clearObj = document.getElementById('ttAirport_' + this.aSelDlc[i]);
        } else {
            var clearObj = document.getElementById('ttMultiAirportCheckbox_' + this.aSelDlc[i]);
        }

        if (this.controlType == 'graphic') {
            this.toggleState(clearObj, 'ttAirportRow', 'ttAirportLabelClick', 'ttAirportLabel');
        } else if (this.controlType == 'checkbox') {
            this.toggleState(clearObj.parentNode, 'ttAirportRow', 'ttAirportLabelClick', 'ttAirportLabel', clearObj, false);
        }
        // Mausaktion für Karte
        if (this.isMap && typeof(this.mapObj) == 'object') {
            var mapElem = document.getElementById('ttMapAirport_' + this.aSelDlc[i]);
            if (mapElem != null) {
                this.mapObj.mouseAction('normal', mapElem);
            }
        }
    }

    this.aSelDlc = new Array();
    
    // Gruppen abwählen
    this.updateGroups();

    // Aufruf der def. Callback-Funktion
    if (this.callbackClearAll != '') {               
        eval(this.callbackClearAll + '()');         
    }          
}

// Check der min. und max. AFH-Anzahl
TTAirportMultiChoice.prototype.isValidRange = function(delta) {
    var newLength = this.aSelDlc.length + delta;
    return newLength <= this.maxChoice && newLength >= this.minChoice;
}

// AFH-IDs -> DLCs
TTAirportMultiChoice.prototype.transformId = function(dlcOrId) {
    if (typeof TTAFH_ID2DLC[dlcOrId] != 'undefined') {
        return TTAFH_ID2DLC[dlcOrId];
    } else {
        return dlcOrId;
    }
}

TTAirportMultiChoice.prototype.getLabel = function(label) {
    if (this.callbackGetLabel != '') {
        return eval(this.callbackGetLabel + '(label)');         
    }
    return label;
}

/**
 * Schaltet den Status der einzelnen Abflughäfen-Container um.
 * @param {Object} obj               AFH-Container Element
 * @param {Object} objNewClassName   Zu setzende CSS-Klasse des AFH-Container Elements
 * @param {Object} childOldClassName Alter Name der CSS-Klasse des Label-Elements, oder null wenn Label nicht verändert werden soll.
 * @param {Object} childNewClassName Neuer Name der CSS-Klasse des Label-Elements, oder null wenn Label nicht verändert werden soll.
 * @param {Object} checkboxObj       Checkbox-Element, oder null wenn nicht gesetzt werden soll (graphic)
 * @param {Object} checkboxChecked   Neuer Checkbox-State, oder null wenn nicht gesetzt werden soll (graphic)
 */
TTAirportMultiChoice.prototype.toggleState = function(obj, objNewClassName, childOldClassName, childNewClassName, checkboxObj, checkboxChecked) {
    obj.className = objNewClassName;
    if (typeof checkboxObj != 'undefined' && checkboxObj != null && typeof checkboxChecked != 'undefined') {
        checkboxObj.checked = checkboxChecked ? true : false;
    }
    if (typeof childOldClassName != 'undefined' && childOldClassName != null && typeof childNewClassName != 'undefined' && childNewClassName != null) {
        var childObj = this.getFirstChildByClassName(obj, childOldClassName);
        if (childObj != null) {
            childObj.className = childNewClassName;
        }
    }
}
/*
TTAirportMultiChoice.prototype.mapAction = function(mapElemId, action) {
    var mapElem = document.getElementById(mapElemId);
    if (mapElem != null) {
        this.mapObj.mouseAction(action, mapElem);
    }
}*/

/**
 * Gruppen-Selektion aktualisieren anhand interem aSelDlc-Array
 */
TTAirportMultiChoice.prototype.updateGroups = function() {
    for (var i = 0; i < this.aApGroups.length; i++) {
        var elem   = document.getElementById('ttAirport_' + this.aApGroups[i]);
        var arrDLC = this.oApGroupsDLC[this.aApGroups[i]];
        if (this.areInArray(arrDLC, this.aSelDlc)) {
            if (elem.className != 'ttAirportRowClick') {
                // Gruppe auswählen (graphic/checkbox)
                elem.className = 'ttAirportRowClick';
                var childObj   = this.getFirstChildByClassName(elem, 'ttAirportLabel');
                if (childObj != null) {
                    childObj.className = 'ttAirportLabelClick';
                }
                if (this.controlType == 'checkbox') {
                    document.getElementById('ttMultiAirportCheckbox_' + this.aApGroups[i]).checked = true;
                }
            }
        } else {
            if (elem.className == 'ttAirportRowClick') {
                // Gruppe abwählen (graphic/checkbox)
                elem.className = 'ttAirportRow';
                var childObj   = this.getFirstChildByClassName(elem, 'ttAirportLabelClick');
                if (childObj != null) {
                    childObj.className = 'ttAirportLabel';
                }
                if (this.controlType == 'checkbox') {
                    document.getElementById('ttMultiAirportCheckbox_' + this.aApGroups[i]).checked = false;
                }
            }
        }
    }
}

// Hilfsmethode für Mouseaction
TTAirportMultiChoice.prototype.getFirstChildByClassName = function(parentObj, classname) {
    var retObj = null;
    if (parentObj.childNodes != null && classname != '') {
        for (var c = 0; c < parentObj.childNodes.length; c ++) {
            if (parentObj.childNodes[c].className.indexOf(classname) >= 0) {
                retObj = parentObj.childNodes[c];
                break;
            } 
        }
    }
    return retObj;
}

// verhindert unerwünschtes bubbling bei mouseover/-out
TTAirportMultiChoice.prototype.isMouseLeaveOrEnter = function(e, handler) {
    if (!e) { 
        var e = window.event;
    }
    if (e.type != 'mouseout' && e.type != 'mouseover') { 
        return false;
    }
    if (!handler) {
        return false;
    }     
    var reltg = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement;     
    while (reltg && reltg != handler) {
        reltg = reltg.parentNode;
    } 
    return (reltg != handler);
} 

// Element in Array suchen
TTAirportMultiChoice.prototype.isInArray = function(needle, haystack) {
    for (var i = 0; i < haystack.length; i ++) {
        if (haystack[i] === needle) {
            return true;
        }
    }
    return false;
}

// Elemente in Array suchen (nur für primitive Datentypen in needles)
TTAirportMultiChoice.prototype.areInArray = function(needles, haystack) {
    var needleIndex = {};
    var found = 0;
    for (var i = 0; i < needles.length; i++) {
        needleIndex[needles[i]] = 1;
    }
    for (var i = 0; i < haystack.length; i++) {
        if (typeof needleIndex[haystack[i]] != 'undefined') {
            found++;
        }
    }
    return found == needles.length;
} 


// Element in Array suchen
TTAirportMultiChoice.prototype.findInArray = function(needle, haystack) {
    for (var i = 0; i < haystack.length; i ++) {
        if (haystack[i] === needle) {
            return haystack[i];
        }
    }
    return null;
}

TTAirportMultiChoice.prototype.deleteFromArray = function(needle, haystack) {
    for (var i = 0; i < haystack.length; i++) {
        if (needle == haystack[i]) {
            haystack.splice(i, 1);
            return;
        }
    }
}

// AFH-Area definieren
TTAirportMultiChoice.prototype.setNewArea = function(area) {     
    if (area != null && typeof(area) == 'object') {
        this.aApAreas.push(area);
        for (var i = 0; i < area.length; i++) {
            var arrDLC = area[i].dlc.split(',');
            if (arrDLC.length > 1) {
                this.aApGroups.push(area[i].id + '' + i);
                this.oApGroupsDLC[area[i].id + '' + i] = arrDLC;
                //this.aApGroupsDLC[this.aApGroupsDLC.length] = arrDLC;
            }
        }
    }
}

// zusätzliche Funktion, die bei Mausaktionen aufgerufen wird
TTAirportMultiChoice.prototype.setCallbackMouseClick = function(theFunction) {
    if (typeof(theFunction) == 'string' && theFunction != '') {
        this.callbackMouseClick = theFunction;
    }    
}

// Callback-Funktion, die anstelle des Standard-Submit aufgerufen wird
TTAirportMultiChoice.prototype.setCallbackSubmit = function(theFunction) {
    if (typeof(theFunction) == 'string' && theFunction != '') {
        this.callbackSubmit = theFunction;
    }    
}

// Callback-Funktion, die bei einer "ClearAll"-Aktion zusätzlich aufgerufen wird
TTAirportMultiChoice.prototype.setCallbackClearAll = function(theFunction) {
    if (typeof(theFunction) == 'string' && theFunction != '') {
        this.callbackClearAll = theFunction;
    }    
}

// Callback-Funktion, die für die HTML-Ausgabe eines AFH-Elements alternativ zur Defaultausgabe aufgerufen wird
TTAirportMultiChoice.prototype.setCallbackDisplayAirport = function(theFunction) {
    if (typeof(theFunction) == 'string' && theFunction != '') {
        this.callbackDisplayAirport = theFunction;
    }    
}

// Callback-Funktion, die zur Ausgabe einer Fehlermeldung bezüglich AFH-Anzahl alternativ zur Defaultausgabe aufgerufen wird
TTAirportMultiChoice.prototype.setCallbackRangeAlert = function(theFunction) {
    if (typeof(theFunction) == 'string' && theFunction != '') {
        this.callbackRangeAlert = theFunction;
    }    
}

// Callback-Funktion, die zur Ausgabe des Labels eines AFH mit dem Label aufgerufen wird
TTAirportMultiChoice.prototype.setCallbackGetLabel = function(theFunction) {
    if (typeof(theFunction) == 'string' && theFunction != '') {
        this.callbackGetLabel = theFunction;
    }    
}

// Name des zu füllenden Datenfelds (standard: "abflughafen")
TTAirportMultiChoice.prototype.setDataField = function(field) {
    if (typeof(field) == 'string' && field != '') {
        this.dataField = field;
    }    
}

// Karte definieren 
TTAirportMultiChoice.prototype.setMap = function(mapExists, mapObj) {
    // mapExists: true/false; mapObj: Objekt der Karte
    if (mapExists != null) {
        if (mapExists == 1 || mapExists == true) {
            this.isMap = true;
            if (typeof(mapObj) == 'object') {
                this.mapObj = mapObj;
            } else {
                this.mapObj = ttMapAirport;
            }             
        } else {
            this.isMap  = false;
            this.mapObj = null;
        }
    }     
}

/**
 * Berechnet die Schnittmenge zwischen arrDLC und den Gruppen, die nicht clickedGroup sind
 * @param {Object} arrDLC       DLCs, die ausgewählt wurden.
 * @param {Object} clickedGroup Gruppe, die angeklickt wurde
 */
TTAirportMultiChoice.prototype.getDlcIntersection = function(arrDLC, clickedGroup) {
    var result = [];
    for (var i in this.oApGroupsDLC) {
        var elem = document.getElementById('ttAirport_' + i);
        // Wenn Gruppe selektiert und nicht die angeklickte Gruppe
        if (elem.className == 'ttAirportRowClick' && i != clickedGroup) {
            // Schnittmenge berechnen 
            var intersection = array_intersect(arrDLC, this.oApGroupsDLC[i]);
            // Zu Ergebnis hinzufügen
            var intersectArr = [];
            for (var j in intersection) {
                intersectArr[intersectArr.length] = intersection[j];
            }
            result = result.concat(intersectArr);
        }
    }
    return result;
}

var ttMultiAirport = new TTAirportMultiChoice();

function array_intersect () {
    // http://kevin.vanzonneveld.net
    // +   original by: Brett Zamir (http://brett-zamir.me)
    // %        note 1: These only output associative arrays (would need to be
    // %        note 1: all numeric and counting from zero to be numeric)
    // *     example 1: $array1 = {'a' : 'green', 0:'red', 1: 'blue'};
    // *     example 1: $array2 = {'b' : 'green', 0:'yellow', 1:'red'};
    // *     example 1: $array3 = ['green', 'red'];
    // *     example 1: $result = array_intersect($array1, $array2, $array3);
    // *     returns 1: {0: 'red', a: 'green'}

    var arr1 = arguments[0], retArr = {};
    var k1 = '', arr = {}, i = 0, k = '';
    
    arr1keys:
    for (k1 in arr1) {
        arrs:
        for (i=1; i < arguments.length; i++) {
            arr = arguments[i];
            for (k in arr) {
                if (arr[k] === arr1[k1]) {
                    if (i === arguments.length-1) {
                        retArr[k1] = arr1[k1];
                    }
                    // If the innermost loop always leads at least once to an equal value, continue the loop until done
                    continue arrs;
                }
            }
            // If it reaches here, it wasn't found in at least one array, so try next value
            continue arr1keys;
        }
    }
    return retArr;
}

// Mapping der AFH-IDs zu DLCs
var TTAFH_ID2DLC = {
    5000: 'NORTH',
    5001: 'SOUTH',
    5002: 'WEST',
    5003: 'EAST',
    0:    'AOC',
    1:    'AMS',
    3:    'MLH',
    141:  'BER',
    4:    'SXF',
    5:    'TXL',
    94:   'BLL',
    8:    'BRE',
    9:    'BRU',
    67:   'CRL',
    10:   'DTM',
    11:   'DRS',
    12:   'DUS',
    73:   'EIN',
    13:   'ENS',
    14:   'ERF',
    15:   'FRA',
    16:   'HHN',
    17:   'FDH',
    18:   'GVA',
    19:   'GRZ',
    81:   'GRQ',
    20:   'HAM',
    21:   'HAJ',
    23:   'INN',
    24:   'FKB',
    27:   'KLU',
    28:   'CGN',
    29:   'LEJ',
    30:   'LNZ',
    31:   'LBC',
    32:   'LGG',
    33:   'LUX',
    34:   'MST',
    90:   'FMM',
    36:   'MUC',
    37:   'FMO',
    49:   'NRN',
    38:   'NUE',
    39:   'PAD',
    40:   'RLG',
    41:   'SCN',
    42:   'SZG',
    43:   'SZW',
    44:   'SXB',
    45:   'STR',
    77:   'WAW',
    46:   'VIE',
    47:   'ZRH',
    48:   'ZQW'
}
