// (c) 2002 Manuel Heras, modified by S.Schlobach

function add_output(text)
{
 document.encoded.decreport.value = document.encoded.decreport.value + text;
}

function is_num_digit(ch)
{
    return ( (ch == '0') || (ch == '1') || (ch == '2') || (ch == '3') ||
             (ch == '4') || (ch == '5') || (ch == '6') || (ch == '7') ||
             (ch == '8') || (ch == '9') );
}

function is_alphabetic_char(ch)
{
    return ( (ch >= 'A') && (ch <= 'Z') );
}

function decode_token(token)
{
    // Check auf Windstille
    if(token == "00000KT")
    {
        add_output("Wind ...........: windstill\n");
        return;
    }

    // Check auf Wind
    // alt, nur mit IE kompatibel: var reWindKT  = /^(\d{3}|VRB)(\d{2,3})(G\d{2,3})?(KT|MPS|KMH)$/;
    // Wind: dddss(s){Gss(s)}KT -- ddd is true direction, ss(s) speed in knots

    var reWindKT  = /^(\d{3}|VRB)(\d{2,3})(((G\d{2,3})(KT|MPS|KMH))|(KT|MPS|KMH))$/;
    if(reWindKT.test(token))
    {
        var myArray = reWindKT.exec(token);
        if ((myArray[3]=="KT")||(myArray[3]=="KMH")||(myArray[3]=="MPS")) {myArray[4]=myArray[3]; myArray[3]=""}
        else
          {
          var windunit = myArray[3].search(/KT/); if(windunit != -1) myArray[4] = "KT";
          var windunit = myArray[3].search(/KMH/); if(windunit != -1) myArray[4] = "KMH";
          var windunit = myArray[3].search(/MPS/); if(windunit != -1) myArray[4] = "MPS";
          windunit = -1;
          };
        var units = myArray[4];
        add_output("Wind ...........: ");
        if(myArray[1]=="VRB")
          add_output("umlaufend");
        else
          add_output("aus " + myArray[1] + "°");
        add_output(" mit " + parseInt(myArray[2],10));
        if(units=="KT") add_output(" kt");
        else if(units=="KMH") add_output(" km/h");
        else if(units=="MPS") add_output(" m/s");
        if(myArray[3] != "")
        {
            add_output(", in Böen bis maximal " + parseInt(myArray[3].substr(1,myArray[3].length),10));
            if(units=="KT") add_output(" kt");
            else if(units=="KMH") add_output(" km/h");
            else if(units=="MPS") add_output(" m/s");
        }

        add_output("\n");  return;
    }


    // Check if token is "variable wind direction"
    var reVariableWind = /^(\d{3})V(\d{3})$/;
    if(reVariableWind.test(token))
    {
        // Variable wind direction: aaaVbbb, aaa and bbb are directions in clockwise order
        add_output("                  Wind schwankt zwischen "+token.substr(0,3)+"° und "+token.substr(4,3)+"°\n");
        return;
    }


    // Check if token is visibility
    var reVis = /^(\d{4})(N|S)?(E|W)?$/;
    if(reVis.test(token))
    {
        var myArray = reVis.exec(token);

        if (sichtflag < 0.5) {add_output("Sicht ..........: ");}
        if (sichtflag > 0.5) {add_output("                  ");}
        sichtflag = sichtflag + 1;

        if(myArray[1]=="9999")
          add_output("10 km oder mehr");
        else if (myArray[1]=="0000")
          add_output("weniger als 50 m");
        else
          add_output(parseInt(myArray[1],10) + " m");

        var dir = "";
        if(typeof myArray[2] != "undefined")
        {
          dir=dir + myArray[2];
        }
        if(typeof myArray[3] != "undefined")
        {
          dir=dir + myArray[3];
        }
        if(dir != "")
        {
          add_output(" in Richtung ");
          if(dir=="N") add_output("Nord");
          else if(dir=="NE") add_output("Nordost");
          else if(dir=="E") add_output("Ost");
          else if(dir=="SE") add_output("Südost");
          else if(dir=="S") add_output("Süd");
          else if(dir=="SW") add_output("Südwest");
          else if(dir=="W") add_output("West");
          else if(dir=="NW") add_output("Nordwest");
        }
        add_output("\n"); return;
    }


    // Check if token is QNH indication in mmHg or hPa
    var reQNHhPa = /Q\d{4}/;
    if(reQNHhPa.test(token))
    {
        // QNH token: Qpppp -- pppp is pressure in hPa
        add_output("QNH ............: ");
        add_output(parseInt(token.substr(1,4),10) + " hPa");
        add_output("\n");  return;
    }


    // Check if token is runway visual range (RVR) indication
    // original: var reRVR = /^R(\d{2})(R|C|L)?\/(M|P)?(\d{4})(V\d{4})?(U|D|N)?$/;
    var reRVR = /^R(\d{2})(R|C|L)?\/(M|P)?(\d{4})(V)?(\d{4})?(U|D|N)?$/;
    if(reRVR.test(token))
    {
        var myArray = reRVR.exec(token);
        add_output("                  Pistensicht auf RWY ");
        add_output(myArray[1]);
        if(typeof myArray[2] != "undefined")
        {
          if(myArray[2]=="L") add_output("L");
          else if(myArray[2]=="R") add_output("R");
          else if(myArray[2]=="C") add_output(" Mitte");
        }
        add_output(" ist ");
        if(typeof myArray[5] != "undefined")
        {
            // Variable range
            if(myArray[5]=="V") add_output("variabel \n");
            if(myArray[3]=="P") add_output("mehr als ");
            else if(myArray[3]=="M") add_output("kleiner als ");
            if(myArray[5]=="V") add_output("                  von minimal ");
            add_output(myArray[4]);
            add_output(" m");
            if(myArray[5]=="V") add_output(" bis maximal "+myArray[6].substr(0,myArray[6].length)+" m");
        }
        else
        {
          // Single value
          if( (typeof myArray[3] != "undefined") &&
              (typeof myArray[4] != "undefined")    )
          {
            if(myArray[3]=="P") add_output("more than ");
            else if(myArray[3]=="M") add_output("less than ");
            add_output(myArray[4]);
            add_output(" meters");
          }
        }
        if( (myArray.length > 5) && (typeof myArray[6] != "undefined") )
        {
          if(myArray[7]=="U") add_output(",\n                  Tendenz steigend (Verbesserung)");
          if(myArray[7]=="D") add_output(",\n                  Tendenz fallend (Verschlechterung)");
          else if(myArray[7]=="N") add_output(",\n                  keine ausgeprägte Tendenz");
        }
        add_output("\n");
        return;
    }


    // Check if token is CAVOK
    if(token == "CAVOK")
    {
        add_output("\n                  CAVOK Bedingungen (Sicht 10 km oder mehr, keine Wolken\n                  unter 5000 ft über Grund bzw. unterhalb der höchsten\n                  Sektormindesthöhe, keine Cb und keine signifikanten\n                  Wettererscheinungen am Flughafen oder der näheren Umgebung)\n\n");
        return;
    }


    // Check if token is NOSIG
    var reNOSIG  = /(^NOSIG$|^NOSIG\r)/;
    if(reNOSIG.test(token))
    {
        add_output("\n                  keine wesentliche Änderung erwartet\n");
        return;
    }


    // Check if token is a present weather code - The regular expression is a bit
    // long, because several precipitation types can be joined in a token, and I
    // don't see a better way to get all the codes.
    var reWX = /^(\-|\+)?(VC)?(MI|BC|BL|SH|TS|FZ|PR)?(DZ|RA|SN|SG|IC|PL|GR|GS)?(DZ|RA|SN|SG|IC|PL|GR|GS)?(DZ|RA|SN|SG|IC|PL|GR|GS)?(DZ|RA|SN|SG|IC|PL|GR|GS)?(DZ|RA|SN|SG|IC|PL|GR|GS|BR|FG|FU|VA|DU|SA|HZ|PO|SQ|FC|SS|DS)$/;
    if(reWX.test(token))
    {
        if (wetterflag < 0.5) {add_output("Wetter .........: ");}
        if (wetterflag > 0.5) {add_output("                  ");}
        wetterflag = wetterflag + 1;
        var myArray = reWX.exec(token);
        for(var i=1;i<myArray.length; i++)
        {
            if(myArray[i] == "-") add_output("leicht ");
            if(myArray[i] == "+") add_output("stark ");
            if(myArray[i] == "VC") add_output("in der Nähe, ");
            if(myArray[i] == "MI") add_output("flach ");
            if(myArray[i] == "BC") add_output("Schwaden ");
            if(myArray[i] == "SH") add_output("Schauer ");
            if(myArray[i] == "TS") add_output("Gewitter ");
            if(myArray[i] == "FZ") add_output("gefrierend ");
            if(myArray[i] == "PR") add_output("partiell ");
            if(myArray[i] == "DZ") add_output("Sprühregen ");
            if(myArray[i] == "RA") add_output("Regen ");
            if(myArray[i] == "SN") add_output("Schnee ");
            if(myArray[i] == "SG") add_output("Schneegriesel ");
            if(myArray[i] == "IC") add_output("Eisnadeln ");
            if(myArray[i] == "PL") add_output("Eiskörner ");
            if(myArray[i] == "GR") add_output("Hagel ");
            if(myArray[i] == "GS") add_output("Graupel ");
            if(myArray[i] == "BR") add_output("feuchter Dunst ");
            if(myArray[i] == "FG") add_output("Nebel ");
            if(myArray[i] == "FU") add_output("Rauch ");
            if(myArray[i] == "VA") add_output("Vulkanasche ");
            if(myArray[i] == "DU") add_output("verbreitet Staub ");
            if(myArray[i] == "SA") add_output("Sand ");
            if(myArray[i] == "HZ") add_output("trockener Dunst ");
            if(myArray[i] == "PO") add_output("Staub-/Sandwirbel ");
            if(myArray[i] == "SQ") add_output("markante Böen ");
            if(myArray[i] == "FC") add_output("Tornado/Wasserhose ");
            if(myArray[i] == "SS") add_output("Sandsturm ");
            if(myArray[i] == "DS") add_output("Staubsturm ");
        }
        add_output("\n");  return;
    }


    // Check if token is recent weather observation
    var reREWX = /^RE(\-|\+)?(VC)?(MI|BC|BL|SH|TS|FZ|PR)?(DZ|RA|SN|SG|IC|PL|GR|GS)?(DZ|RA|SN|SG|IC|PL|GR|GS)?(DZ|RA|SN|SG|IC|PL|GR|GS)?(DZ|RA|SN|SG|IC|PL|GR|GS)?(DZ|RA|SN|SG|IC|PL|GR|GS|BR|FG|FU|VA|DU|SA|HZ|PO|SQ|FC|SS|DS)?$/;
    if(reREWX.test(token))
    {
        add_output("\n                  Seit der letzten Beobachtung wurden die folgenden\n                  Wettererscheinungen beobachtet: ");
        var myArray = reREWX.exec(token);
        for(var i=1;i<myArray.length; i++)
        {
            if(myArray[i] == "-") add_output("leicht ");
            if(myArray[i] == "+") add_output("stark ");
            if(myArray[i] == "VC") add_output("in der Nähe, ");
            if(myArray[i] == "MI") add_output("flach ");
            if(myArray[i] == "BC") add_output("Schwaden ");
            if(myArray[i] == "SH") add_output("Schauer ");
            if(myArray[i] == "TS") add_output("Gewitter ");
            if(myArray[i] == "FZ") add_output("gefrierend ");
            if(myArray[i] == "PR") add_output("partiell ");
            if(myArray[i] == "DZ") add_output("Sprühregen ");
            if(myArray[i] == "RA") add_output("Regen ");
            if(myArray[i] == "SN") add_output("Schnee ");
            if(myArray[i] == "SG") add_output("Schneegriesel ");
            if(myArray[i] == "IC") add_output("Eisnadeln ");
            if(myArray[i] == "PL") add_output("Eiskörner ");
            if(myArray[i] == "GR") add_output("Hagel ");
            if(myArray[i] == "GS") add_output("Graupel ");
            if(myArray[i] == "BR") add_output("feuchter Dunst ");
            if(myArray[i] == "FG") add_output("Nebel ");
            if(myArray[i] == "FU") add_output("Rauch ");
            if(myArray[i] == "VA") add_output("Vulkanasche ");
            if(myArray[i] == "DU") add_output("verbreitet Staub ");
            if(myArray[i] == "SA") add_output("Sand ");
            if(myArray[i] == "HZ") add_output("trockener Dunst ");
            if(myArray[i] == "PO") add_output("Staub-/Sandwirbel ");
            if(myArray[i] == "SQ") add_output("markante Böen ");
            if(myArray[i] == "FC") add_output("Tornado/Wasserhose ");
            if(myArray[i] == "SS") add_output("Sandsturm ");
            if(myArray[i] == "DS") add_output("Staubsturm ");
        }
        add_output("\n\n"); return;
    }


    // Check if token is temperature / dewpoint pair
    var reTempDew = /^(M?\d\d|\/\/)\/(M?\d\d)?$/;
    if(reTempDew.test(token))
    {
        var myArray = reTempDew.exec(token);

        if(myArray[1].charAt(0)=='M')
          add_output("Temperatur .....: -" + myArray[1].substr(1,2) + "°C\n");
        else
          add_output("Temperatur .....: " + myArray[1].substr(0,2) + "°C\n");

        if(myArray[2]!="")
        {
          if(myArray[2].charAt(0)=='M')
            add_output("Taupunkt .......: -" + myArray[2].substr(1,2) + "°C\n");
          else
            add_output("Taupunkt .......: " + myArray[2].substr(0,2) + "°C\n");
        }

        return;
    }


    // Check if token is "sky clear" indication
    if(token=="SKC")
    {
        add_output("                  wolkenlos\n");
        return;
    }


    // Check if token is "vertical visibility" indication
    var reVV = /^VV(\d{3}|\/{3})$/;
    if(reVV.test(token))
    {
        // VVddd -- ddd is vertical distance, or /// if unspecified
        var myArray = reVV.exec(token);
        add_output("Vertikalsicht ..: ");
        if(myArray[1] == "///")
          add_output("nicht angebbar\n");
        else
          add_output(100*parseInt(myArray[1],10) + " ft\n");

        return;
    }


    // Check if token is cloud indication
    var reCloud = /^(FEW|SCT|BKN|OVC)(\d{3})(CB|TCU)?$/;
    if(reCloud.test(token))
    {
        // Clouds: aaadddkk -- aaa indicates amount of sky covered, ddd distance over
        //                     aerodrome level, and kk the type of cloud.
        var myArray = reCloud.exec(token);

        if (wolkenflag < 0.5) {add_output("Wolken .........: ");}
        if (wolkenflag > 0.5) {add_output("                  ");}
        wolkenflag = wolkenflag + 1;

        if(myArray[1] == "FEW") add_output("1/8 - 2/8");
        else if(myArray[1] == "SCT") add_output("3/8 - 4/8");
        else if(myArray[1] == "BKN") add_output("5/8 - 7/8");
        else if(myArray[1] == "OVC") add_output("bedeckt (8/8)");

        add_output(" in " + (100*parseInt(myArray[2],10)) + " ft über Flugplatzniveau");

        if(myArray[3] == "CB") add_output("\n                  Cumulonimbus");
        else if(myArray[3] == "TCU") add_output("\n                  hochaufgetürmter Cumulus vertikal > 10000 ft");

        add_output("\n"); return;
    }


    // Check if token is part of a wind-shear indication
    var reRWY = /^RWY(\d{2})(L|C|R)?$/;
    if(token=="WS")       { add_output("Windscherung ...: "); return; }
    else if(token=="ALL") { add_output("auf allen "); return; }
    else if(token=="RWY") { add_output("Runways\n"); return; }
    else if (reRWY.test(token))
    {
        var myArray = reRWY.exec(token);
        add_output("auf RWY "+myArray[1]);
        if(myArray[2]=="L")      add_output("L");
        else if(myArray[2]=="C") add_output(" Mitte");
        else if(myArray[2]=="R") add_output("R");
        add_output("\n");
        return;
    }


    // Check if token is no-significant-weather indication
    if(token=="NSW")
    {
        add_output("\n                  keine signifikanten Wettererscheinungen derzeit beobachtet\n");
        return;
    }


    // Check if token is no-significant-clouds indication
    if(token=="NSC")
    {
        add_output("No significant clouds are observed below 5000 feet or below the minimum sector altitude (whichever is higher)\n");
        return;
    }


    // Check if token is part of trend indication
    if(token=="BECMG")
    {
        wetterflag = 0; sichtflag = 0; wolkenflag = 0;
        add_output("\n                  Die folgenden Wettererscheinungen werden erwartet:\n");
        return;
    }
    if(token=="TEMPO")
    {
        wetterflag = 0; sichtflag = 0; wolkenflag = 0;
        add_output("\n                  vorübergehende zeitweilige Änderung von Wetterelementen:\n");
        return;
    }
    var reFM = /^FM(\d{2})(\d{2})Z?$/;
    if(reFM.test(token))
    {
        var myArray = reFM.exec(token);
        add_output("                  von "+myArray[1]+":"+myArray[2]+" UTC an:\n\n");
        return;
    }
    var reTL = /^TL(\d{2})(\d{2})Z?$/;
    if(reTL.test(token))
    {
        var myArray = reTL.exec(token);
        add_output("                  bis "+myArray[1]+":"+myArray[2]+" UTC, ");
        return;
    }
    var reAT = /^AT(\d{2})(\d{2})Z?$/;
    if(reAT.test(token))
    {
        var myArray = reAT.exec(token);
        add_output("um "+myArray[1]+":"+myArray[2]+" UTC, ");
        return;
    }


    // Check if item is runway state group
    //var reRSG = /^(\d\d)(\d|C|\/)(\d|L|\/)(\d\d|RD|\/)(\d\d)$/;
      var reRSG = /^(\d\d)(\d|C|\/)(\d|L|\/)(\d\d|RD|\W\W)(\d\d|\W\W)$/;
    if(reRSG.test(token))
    {
        var myArray = reRSG.exec(token);

        if (pistenzustandflag < 0.5) {add_output("Pistenzustand...: ");}
        if (pistenzustandflag > 0.5) {add_output("                  ");}
        pistenzustandflag = pistenzustandflag + 1;

        // Runway designator (first 2 digits)
        var r = parseInt(myArray[1],10);
        if(r < 50) add_output("RWY " + myArray[1] + " (oder "+myArray[1]+"L): ");
        else if(r <= 59) add_output("RWY 0" + (r-50) + "R: ");
        else if(r < 88) add_output("RWY " + (r-50) + "R: ");
        else if(r == 88) add_output("alle Pisten: ");

        // Check if "CLRD" occurs in digits 3-6
        if(token.substr(2,4)=="CLRD") add_output("clear, ");
        else
        {
          // Runway deposits (third digit)
          if(myArray[2]=="0") add_output("trocken und frei von Ablagerungen, ");
          else if(myArray[2]=="1") add_output("feucht, ");
          else if(myArray[2]=="2") add_output("naß oder Wasserpfützen, ");
          else if(myArray[2]=="3") add_output("Raureif oder Reif, ");
          else if(myArray[2]=="4") add_output("trockener Schnee, ");
          else if(myArray[2]=="5") add_output("nasser Schnee, ");
          else if(myArray[2]=="6") add_output("Schneematsch, ");
          else if(myArray[2]=="7") add_output("Eis, ");
          else if(myArray[2]=="8") add_output("zusammengepreßter oder gewalzter Schnee, ");
          else if(myArray[2]=="9") add_output("festgefrorene Radspuren, ");
          else if(myArray[2]=="/") add_output("Art der Ablagerung nicht gemeldet, ");

          // Extent of runway contamination (fourth digit)
          if(myArray[3]=="1") add_output("weniger als 10% bedeckt, ");
          else if(myArray[3]=="2") add_output("11% bis 25% bedeckt, ");
          else if(myArray[3]=="5") add_output("26% bis 50% bedeckt, ");
          else if(myArray[3]=="9") add_output("51% bis 100% bedeckt, ");
          else if(myArray[3]=="/") add_output("keine Angaben zur Ausdehnung, ");

          // Depth of deposit (fifth and sixth digits)
          if(myArray[4]=="//") add_output("\n                  Höhe der Ablagerungen betrieblich nicht signifikant oder\n                  nicht meßbar, ");
          else
          {
              var d = parseInt(myArray[4],10);
              if(d == 0) add_output("Ablagerungen weniger als 1 mm, ");
              else if ((d >  0) && (d < 91)) add_output("\n                  Ablagerungen sind "+d+" mm hoch, ");
              else if (d == 92) add_output("\n                  Ablagerungen sind 10 cm hoch, ");
              else if (d == 93) add_output("\n                  Ablagerungen sind 15 cm hoch, ");
              else if (d == 94) add_output("\n                  Ablagerungen sind 20 cm hoch, ");
              else if (d == 95) add_output("\n                  Ablagerungen sind 25 cm hoch, ");
              else if (d == 96) add_output("\n                  Ablagerungen sind 30 cm hoch, ");
              else if (d == 97) add_output("\n                  Ablagerungen sind 35 cm hoch, ");
              else if (d == 98) add_output("\n                  Ablagerungen sind 40 cm oder höher, ");
              else if (d == 99) add_output("\n                  Piste(n) nicht benutzbar wegen Schnee, Schneematsch, Eis,\n                  starker Verwehungen oder Räumung der Piste, ohne Höhenangabe\n");
          }
        }

        // Friction coefficient or braking action (seventh and eighth digit)
        if(myArray[5]=="//") add_output("\n                  Bremswirkung und Reibungskoeffizient nicht festgestellt,\n                  da Piste(n) nicht in Betrieb");
        else
        {
            var b = parseInt(myArray[5],10);
            if(b<91) add_output("Reibungskoeffizient 0,"+myArray[5]);
            else
            {
                 if(b == 91) add_output("schlechte Bremswirkung");
                 else if(b == 92) add_output("schlechte bis mittelmäßige Bremswirkung");
                 else if(b == 93) add_output("mittelmäßige Bremswirkung");
                 else if(b == 94) add_output("mittelmäßig bis gute Bremswirkung");
                 else if(b == 95) add_output("gute Bremswirkung");
                 else if(b == 99) add_output("\n                  Bremswirkung und Reibungskoeffizient unzuverlässig bzw.\n                  nicht meßbar");
            }
        }
        add_output("\n"); return;
    }

    if(token=="SNOCLO")
    {
        add_output("Aerodrome is closed due to snow on runways\n");
        return;
    }

    // Check if item is sea status indication
    reSea = /^W(M)?(\d\d)\/S(\d)/;
    if(reSea.test(token))
    {
        var myArray = reSea.exec(token);
        add_output("Sea surface temperature: ");
        if(myArray[1]=="M")
            add_output("-");
        add_output(parseInt(myArray[2],10) + " degrees Celsius\n");

        add_output("Sea waves have height: ");
        if(myArray[3]=="0") add_output("0 m (calm)\n");
        else if(myArray[3]=="1") add_output("0-0,1 m\n");
        else if(myArray[3]=="2") add_output("0,1-0,5 m\n");
        else if(myArray[3]=="3") add_output("0,5-1,25 m\n");
        else if(myArray[3]=="4") add_output("1,25-2,5 m\n");
        else if(myArray[3]=="5") add_output("2,5-4 m\n");
        else if(myArray[3]=="6") add_output("4-6 m\n");
        else if(myArray[3]=="7") add_output("6-9 m\n");
        else if(myArray[3]=="8") add_output("9-14 m\n");
        else if(myArray[3]=="9") add_output("more than 14 m (huge!)\n");
        return;
    }
}

function metar_decode(text)
{
    document.encoded.decreport.value = "";

    // Join newline-separated pieces...
    var newlineJoined = text.replace(/\n/, " ");

    // An '=' finishes the report
    var equalPosition = newlineJoined.indexOf("=");
    if (equalPosition > -1)
    {
        //alert("End of a METAR report is indicated by '='. We only decode until the first '='!!");
        newlineJoined = newlineJoined.substr(0,equalPosition);
    }


    arrayOfTokens = newlineJoined.split(" ");
    var numToken = 0;

    //Hilfsvariablen für die Darstellung (keine doppelten Stichwörter voranstellen)
    wetterflag = 0;
    sichtflag = 0;
    wolkenflag = 0;
    pistenzustandflag = 0;

    // Check if initial token is non-METAR date
    var reDate = /^\d\d\d\d\/\d\d\/\d\d/;
    if (reDate.test(arrayOfTokens[numToken]))
        numToken++;

    // Check if initial token is non-METAR time
    var reTime = /^\d\d:\d\d/;
    if (reTime.test(arrayOfTokens[numToken]))
        numToken++;

    // Check if initial token indicates type of report
    typeofreport = "";
    if(arrayOfTokens[numToken] == "METAR")
        {
        numToken++;
        document.encoded.typ[0].checked = true;
        typeofreport = "metar";
        }
    else if(arrayOfTokens[numToken] == "TAF")
        {
        numToken++;
        document.encoded.typ[1].checked = true;
        typeofreport = "taf";
        }
    else if(arrayOfTokens[numToken] == "SPECI")
        {
        add_output("Report ist ein SPECIAL report.\n");
        numToken++;
        }

    if (typeofreport == "")
    {
    if (document.encoded.typ[0].checked == true) typeofreport = "metar"
    else if (document.encoded.typ[1].checked == true) typeofreport = "taf"
    else {alert('Bitte entscheiden Sie ob es sich um ein METAR oder ein TAF handelt !  ');
          return;}
    }




    // Parse location token
    if (arrayOfTokens[numToken].length == 4)
    {
        airportname(arrayOfTokens[numToken]);
        add_output("METAR Report für: "+flughafenname+" - " + arrayOfTokens[numToken] + iatacode +"\n");
        numToken++;
    }
    else
    {
        add_output("ungültiger Report: ungültiger Flughafen-ICAO-4-Letter-Code '" + arrayOfTokens[numToken] + "' \n");
        return;
    }


    // Parse date-time token -- we allow time specifications without final 'Z'
    if ( (
           ( (arrayOfTokens[numToken].length == 7) &&
             (arrayOfTokens[numToken].charAt(6) == 'Z') ) ||
           ( arrayOfTokens[numToken].length == 6 )
         ) &&
         is_num_digit(arrayOfTokens[numToken].charAt(0)) &&
         is_num_digit(arrayOfTokens[numToken].charAt(1)) &&
         is_num_digit(arrayOfTokens[numToken].charAt(2)) &&
         is_num_digit(arrayOfTokens[numToken].charAt(3)) &&
         is_num_digit(arrayOfTokens[numToken].charAt(4)) &&
         is_num_digit(arrayOfTokens[numToken].charAt(5))    )
    {
        add_output("Beobachtungszeit: " + arrayOfTokens[numToken].substr(0,2)+".xx.xxxx "+ arrayOfTokens[numToken].substr(2,2) +":" + arrayOfTokens[numToken].substr(4,2) + " Uhr UTC" + "\n");

        if(arrayOfTokens[numToken].length == 6)
            add_output(" (Ungültige Zeitangabe)");

        add_output("\n");
        numToken++;
    }
    else
    {
        add_output("Gegebene Zeit nicht gefunden oder ungültiges Zeitformat!");
        return;
    }


    // Check if "AUTO" or "COR" token comes next.
    if (arrayOfTokens[numToken] == "AUTO")
    {
        add_output("Report is fully automated, with no human intervention or oversight\n");
        numToken++;
    }
    else if (arrayOfTokens[numToken] == "COR")
    {
        add_output("Report is a correction over a METAR or SPECI report\n");
        numToken++;
    }

    // Parse remaining tokens
    for (var i=numToken; i<arrayOfTokens.length; i++)
    {
        if(arrayOfTokens[i].length > 0)
        {
            decode_token(arrayOfTokens[i].toUpperCase());
        }
    }
}

function ejem(text)
{
    alert(text);
}
