Operation IParser.Parse(string[] lines)
        {
            Operation         operation = new Operation();
            OperationResource last      = new OperationResource();

            lines = Utilities.Trim(lines);
            CurrentSection section      = CurrentSection.AHeader;
            bool           keywordsOnly = true;

            for (int i = 0; i < lines.Length; i++)
            {
                try
                {
                    string line = lines[i];
                    if (line.Length == 0)
                    {
                        continue;
                    }
                    if (GetSection(line.Trim(), ref section, ref keywordsOnly))
                    {
                        continue;
                    }

                    string msg    = line;
                    string prefix = "";

                    // Make the keyword check - or not (depends on the section we are in; see above)
                    string keyword = "";
                    if (keywordsOnly)
                    {
                        if (!ParserUtility.StartsWithKeyword(line, _keywords, out keyword))
                        {
                            continue;
                        }

                        int x = line.IndexOf(':');
                        if (x == -1)
                        {
                            // If there is no colon found (may happen occasionally) then simply remove the length of the keyword from the beginning
                            prefix = keyword;
                            msg    = line.Remove(0, prefix.Length).Trim();
                        }
                        else
                        {
                            prefix = line.Substring(0, x);
                            msg    = line.Substring(x + 1).Trim();
                        }
                        prefix = prefix.Trim().ToUpperInvariant();
                    }

                    // Parse each section
                    switch (section)
                    {
                    case CurrentSection.AHeader:
                    {
                        switch (prefix)
                        {
                        case "EINSATZNUMMER":
                            operation.OperationNumber = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.BMitteiler:
                        operation.Messenger = line.Remove(0, keyword.Length).Trim();
                        break;

                    case CurrentSection.CEinsatzort:
                    {
                        switch (prefix)
                        {
                        case "STRAßE":
                        {
                            string street, streetNumber, appendix;
                            ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix);
                            operation.CustomData["Einsatzort Zusatz"] = appendix;
                            operation.Einsatzort.Street       = street;
                            operation.Einsatzort.StreetNumber = streetNumber;
                        }
                        break;

                        case "ORT":
                        {
                            Match zip = Regex.Match(msg, @"[0-9]{5}");
                            if (zip.Success)
                            {
                                operation.Einsatzort.ZipCode = zip.Value;
                                operation.Einsatzort.City    = msg.Replace(zip.Value, "").Trim();
                            }
                            else
                            {
                                operation.Einsatzort.City = msg;
                            }
                            break;
                        }

                        case "GEMEINDE":
                        {
                            operation.CustomData.Add("GEMEINDE", msg);
                        }
                        break;

                        case "OBJEKT":
                            if (msg.Contains("EPN:"))
                            {
                                operation.Einsatzort.Property = ParserUtility.GetTextBetween(line, null, "EPN");
                                operation.OperationPlan       = ParserUtility.GetTextBetween(line, "EPN");
                            }
                            else
                            {
                                operation.Einsatzort.Property = msg;
                            }
                            break;

                        case "KREUZUNG":
                            operation.Einsatzort.Intersection = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.DEinsatzgrund:
                    {
                        switch (prefix)
                        {
                        case "SCHLAGW.":
                            operation.Keywords.Keyword = msg;
                            break;

                        case "STICHWORT":
                            operation.Keywords.EmergencyKeyword = msg;
                            break;

                        case "PRIO.":
                            operation.Priority = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.EEinsatzmittel:
                    {
                        switch (prefix)
                        {
                        case "NAME":
                            last.FullName = msg;
                            break;

                        case "ALARMIERT":
                            last.Timestamp = ParserUtility.TryGetTimestampFromMessage(msg, DateTime.Now).ToString();
                            break;

                        case "GEF. GERÄT":
                            // Only add to requested equipment if there is some text,
                            // otherwise the whole vehicle is the requested equipment
                            if (!string.IsNullOrWhiteSpace(msg))
                            {
                                last.RequestedEquipment.Add(msg);
                            }

                            operation.Resources.Add(last);
                            last = new OperationResource();
                            break;
                        }
                    }
                    break;

                    case CurrentSection.FBemerkung:
                    {
                        // Append with newline at the end in case that the message spans more than one line
                        operation.Comment = operation.Comment.AppendLine(msg);
                    }
                    break;

                    case CurrentSection.GFooter:
                        // The footer can be ignored completely.
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message);
                }
            }
            return(operation);
        }
Exemple #2
0
        Operation IParser.Parse(string[] lines)
        {
            Operation         operation = new Operation();
            OperationResource last      = new OperationResource();

            lines = Utilities.Trim(lines);
            CurrentSection section      = CurrentSection.AHeader;
            bool           keywordsOnly = true;

            for (int i = 0; i < lines.Length; i++)
            {
                try
                {
                    string line = lines[i];
                    if (line.Length == 0)
                    {
                        continue;
                    }
                    if (GetSection(line.Trim(), ref section, ref keywordsOnly))
                    {
                        continue;
                    }

                    string msg    = line;
                    string prefix = "";

                    // Make the keyword check - or not (depends on the section we are in; see above)
                    string keyword = "";
                    if (keywordsOnly)
                    {
                        if (!ParserUtility.StartsWithKeyword(line, _keywords, out keyword))
                        {
                            continue;
                        }

                        int x = line.IndexOf(':');
                        if (x == -1)
                        {
                            // If there is no colon found (may happen occasionally) then simply remove the length of the keyword from the beginning
                            prefix = keyword;
                            msg    = line.Remove(0, prefix.Length).Trim();
                        }
                        else
                        {
                            prefix = line.Substring(0, x);
                            msg    = line.Substring(x + 1).Trim();
                        }
                        prefix = prefix.Trim().ToUpperInvariant();
                    }

                    // Parse each section
                    switch (section)
                    {
                    case CurrentSection.AHeader:
                    {
                        switch (prefix)
                        {
                        case "EINSATZ-NR.":
                            operation.OperationNumber = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.BMitteiler:
                        operation.Messenger = msg;
                        break;

                    case CurrentSection.CEinsatzort:
                    {
                        switch (prefix)
                        {
                        case "STRAßE":
                        {
                            string street, streetNumber, appendix;
                            ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix);
                            operation.CustomData["Einsatzort Zusatz"] = appendix;
                            operation.Einsatzort.Street       = street;
                            operation.Einsatzort.StreetNumber = streetNumber;
                        }
                        break;

                        case "ORTSTEIL":
                        {
                            operation.Einsatzort.City = msg;
                            // The City-text often contains a dash after which the administrative city appears multiple times (like "City A - City A City A").
                            // However we can (at least with google maps) omit this information without problems!
                            int dashIndex = msg.IndexOf('-');
                            if (dashIndex != -1)
                            {
                                // Ignore everything after the dash
                                operation.Einsatzort.City = operation.Einsatzort.City.Substring(0, dashIndex);
                            }
                        }
                        break;

                        case "OBJEKT":
                            operation.Einsatzort.Property = msg;
                            break;

                        case "KREUZUNG":
                            operation.Einsatzort.Intersection = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.DEinsatzgrund:
                    {
                        switch (prefix)
                        {
                        case "SCHLAGW.":
                            operation.Keywords.Keyword = msg;
                            break;

                        case "STICHWORT":
                            operation.Keywords.EmergencyKeyword = msg;
                            break;

                        case "PRIORITÄT":
                            operation.Priority = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.EEinsatzmittel:
                    {
                        switch (prefix)
                        {
                        case "NAME":
                            last.FullName = msg;
                            break;

                        case "ALARMIERT":
                            msg            = ParserUtility.GetTextBetween(msg, null, "AUS");
                            last.Timestamp = ParserUtility.TryGetTimestampFromMessage(msg, DateTime.Now).ToString();
                            break;

                        case "GEF. GERÄT":
                            // Only add to requested equipment if there is some text,
                            // otherwise the whole vehicle is the requested equipment
                            if (!string.IsNullOrWhiteSpace(msg))
                            {
                                last.RequestedEquipment.Add(msg);
                            }

                            operation.Resources.Add(last);
                            last = new OperationResource();
                            break;
                        }
                    }
                    break;

                    case CurrentSection.FBemerkung:
                    {
                        // Append with newline at the end in case that the message spans more than one line
                        operation.Picture += msg + Environment.NewLine;
                    }
                    break;

                    case CurrentSection.GHinweis:
                    {
                        // Append with newline at the end in case that the message spans more than one line
                        operation.Comment = operation.Comment.AppendLine(msg);
                    }
                    break;

                    case CurrentSection.HFooter:
                        // The footer can be ignored completely.
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message);
                }
            }
            return(operation);
        }
        Operation IParser.Parse(string[] lines)
        {
            Operation         operation = new Operation();
            OperationResource last      = new OperationResource();

            lines = Utilities.Trim(lines);
            CurrentSection   section = CurrentSection.AHeader;
            bool             keywordsOnly = true;
            double           geoX = 0, geoY = 0;
            NumberFormatInfo nfi = new NumberFormatInfo {
                NumberDecimalSeparator = "."
            };

            for (int i = 0; i < lines.Length; i++)
            {
                try
                {
                    string line = lines[i];
                    if (line.Length == 0)
                    {
                        continue;
                    }
                    if (GetSection(line.Trim(), ref section, ref keywordsOnly))
                    {
                        continue;
                    }

                    string msg    = line;
                    string prefix = "";

                    // Make the keyword check - or not (depends on the section we are in; see above)
                    string keyword = "";
                    if (keywordsOnly)
                    {
                        if (!ParserUtility.StartsWithKeyword(line, _keywords, out keyword))
                        {
                            continue;
                        }

                        int x = line.IndexOf(':');
                        if (x == -1)
                        {
                            // If there is no colon found (may happen occasionally) then simply remove the length of the keyword from the beginning
                            prefix = keyword;
                            msg    = line.Remove(0, prefix.Length).Trim();
                        }
                        else
                        {
                            prefix = line.Substring(0, x);
                            msg    = line.Substring(x + 1).Trim();
                        }
                        prefix = prefix.Trim().ToUpperInvariant();
                    }

                    // Parse each section
                    switch (section)
                    {
                    case CurrentSection.AHeader:
                    {
                        switch (prefix)
                        {
                        case "EINSATZNUMMER":
                            operation.OperationNumber = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.CKoordinaten:
                        switch (prefix)
                        {
                        case "X":
                            geoX = double.Parse(msg, nfi);
                            break;

                        case "Y":
                            geoY = double.Parse(msg, nfi);
                            var geo = GeographicCoords.FromGaussKrueger(geoX, geoY);
                            operation.Einsatzort.GeoLatitude  = geo.Latitude;
                            operation.Einsatzort.GeoLongitude = geo.Longitude;
                            break;
                        }
                        break;

                    case CurrentSection.BMitteiler:
                        switch (prefix)
                        {
                        case "NAME":
                            operation.Messenger = msg;
                            break;

                        case "RUFNUMMER":
                            operation.Messenger = operation.Messenger.AppendLine(string.Format("Nr.: {0}", msg));
                            break;
                        }
                        break;

                    case CurrentSection.DEinsatzort:
                    {
                        switch (prefix)
                        {
                        case "STRAßE":
                            operation.Einsatzort.Street = msg;
                            break;

                        case "HAUS-NR.":
                            operation.Einsatzort.StreetNumber = msg;
                            break;

                        case "ORT":
                        {
                            operation.Einsatzort.ZipCode = ParserUtility.ReadZipCodeFromCity(msg);
                            if (!string.IsNullOrWhiteSpace(operation.Einsatzort.ZipCode))
                            {
                                operation.Einsatzort.City = msg.Replace(operation.Einsatzort.ZipCode, "").Trim();
                            }
                            else
                            {
                                operation.Einsatzort.City = msg;
                            }
                            // The City-text often contains a dash after which the administrative city appears multiple times (like "City A - City A City A").
                            // However we can (at least with google maps) omit this information without problems!
                            int dashIndex = operation.Einsatzort.City.IndexOf('-');
                            if (dashIndex != -1)
                            {
                                // Ignore everything after the dash
                                operation.Einsatzort.City = operation.Einsatzort.City.Substring(0, dashIndex);
                            }
                        }
                        break;

                        case "OBJEKT":
                            operation.Einsatzort.Property = msg;
                            break;

                        case "STATION":
                            operation.CustomData["Einsatzort Station"] = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.EZielort:
                    {
                        switch (prefix)
                        {
                        case "STRAßE":
                            operation.Zielort.Street = msg;
                            break;

                        case "HAUS-NR.":
                            operation.Zielort.StreetNumber = msg;
                            break;

                        case "ORT":
                            operation.Zielort.ZipCode = ParserUtility.ReadZipCodeFromCity(msg);
                            if (!string.IsNullOrWhiteSpace(operation.Zielort.ZipCode))
                            {
                                operation.Zielort.City = msg.Replace(operation.Zielort.ZipCode, "").Trim();
                            }
                            else
                            {
                                operation.Zielort.City = msg;
                            }
                            break;

                        case "OBJEKT":
                            operation.Zielort.Property = msg;
                            break;

                        case "STATION":
                            operation.CustomData["Zielort Station"] = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.FEinsatzgrund:
                    {
                        switch (prefix)
                        {
                        case "SCHLAGW.":
                            operation.Keywords.Keyword = msg;
                            break;

                        case "STICHWORT":
                            operation.Keywords.EmergencyKeyword = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.HEinsatzmittel:
                    {
                        switch (prefix)
                        {
                        case "NAME":
                            last.FullName = msg;
                            break;

                        case "GERÄT":
                            // Only add to requested equipment if there is some text,
                            // otherwise the whole vehicle is the requested equipment
                            if (!string.IsNullOrWhiteSpace(msg))
                            {
                                last.RequestedEquipment.Add(msg);
                            }
                            break;

                        case "ALARMIERT":
                            last.Timestamp = ParserUtility.TryGetTimestampFromMessage(msg, DateTime.Now).ToString();
                            operation.Resources.Add(last);
                            last = new OperationResource();
                            break;
                        }
                    }
                    break;

                    case CurrentSection.GBemerkungen:
                    {
                        operation.Picture = operation.Picture.AppendLine(msg);
                    }
                    break;

                    case CurrentSection.ZFooter:
                        // The footer can be ignored completely.
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message);
                }
            }
            return(operation);
        }
Exemple #4
0
        Operation IParser.Parse(string[] lines)
        {
            Operation         operation = new Operation();
            OperationResource last      = new OperationResource();

            lines = Utilities.Trim(lines);

            CurrentSection section      = CurrentSection.AHeader;
            bool           keywordsOnly = true;

            for (int i = 0; i < lines.Length; i++)
            {
                try
                {
                    string line = lines[i];
                    if (line.Length == 0)
                    {
                        continue;
                    }

                    operation.Timestamp = ParserUtility.ReadFaxTimestamp(line, operation.Timestamp);

                    if (GetSection(line.Trim(), ref section, ref keywordsOnly))
                    {
                        continue;
                    }

                    string msg    = line;
                    string prefix = "";

                    string keyword = null;
                    if (keywordsOnly)
                    {
                        if (!ParserUtility.StartsWithKeyword(line, Keywords, out keyword))
                        {
                            continue;
                        }

                        int x = line.IndexOf(':');
                        if (x == -1)
                        {
                            prefix = keyword;
                            msg    = line.Remove(0, prefix.Length).Trim();
                        }
                        else
                        {
                            prefix = line.Substring(0, x);
                            msg    = line.Substring(x + 1).Trim();
                        }

                        prefix = prefix.Trim().ToUpperInvariant();
                    }

                    switch (section)
                    {
                    case CurrentSection.AHeader:
                    {
                        switch (prefix)
                        {
                        case "ABSENDER":
                            operation.CustomData["Absender"] = msg;
                            break;

                        case "TERMIN":
                            operation.CustomData["Termin"] = msg;
                            break;

                        case "EINSATZNUMMER":
                            operation.OperationNumber = msg;
                            break;

                        default:
                            break;
                        }
                    }
                    break;

                    case CurrentSection.BMitteiler:
                    {
                        // This switch would not be necessary in this section (there is only "Name")...
                        switch (prefix)
                        {
                        case "NAME":
                            operation.Messenger = msg;
                            break;

                        default:
                            break;
                        }
                    }
                    break;

                    case CurrentSection.CEinsatzort:
                    {
                        switch (prefix)
                        {
                        case "STRAßE":
                        {
                            string street, streetNumber, appendix;

                            ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix);
                            operation.CustomData["Einsatzort Zusatz"] = appendix;
                            operation.Einsatzort.Street       = street;
                            operation.Einsatzort.StreetNumber = streetNumber;
                        }
                        break;

                        case "ORT":
                        {
                            operation.Einsatzort.ZipCode = ParserUtility.ReadZipCodeFromCity(msg);
                            if (string.IsNullOrWhiteSpace(operation.Einsatzort.ZipCode))
                            {
                                Logger.Instance.LogFormat(LogType.Warning, this, "Could not find a zip code for city '{0}'. Route planning may fail or yield wrong results!", operation.Einsatzort.City);
                            }

                            operation.Einsatzort.City = msg.Remove(0, operation.Einsatzort.ZipCode.Length).Trim();

                            // The City-text often contains a dash after which the administrative city appears multiple times (like "City A - City A City A").
                            // However we can (at least with google maps) omit this information without problems!
                            int dashIndex = operation.Einsatzort.City.IndexOf(" - ");
                            if (dashIndex != -1)
                            {
                                // Ignore everything after the dash
                                operation.Einsatzort.City = operation.Einsatzort.City.Substring(0, dashIndex);
                            }
                        }
                        break;

                        case "OBJEKT":
                            operation.Einsatzort.Property = msg;
                            break;

                        case "PLANNUMMER":
                            operation.CustomData["Einsatzort Plannummer"] = msg;
                            break;

                        case "STATION":
                            operation.CustomData["Einsatzort Station"] = msg;
                            break;

                        default:
                            break;
                        }
                    }
                    break;

                    case CurrentSection.DZielort:
                    {
                        switch (prefix)
                        {
                        case "STRAßE":
                        {
                            string street, streetNumber, appendix;

                            ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix);
                            operation.CustomData["Zielort Zusatz"] = appendix;
                            operation.Zielort.Street       = street;
                            operation.Zielort.StreetNumber = streetNumber;
                        }
                        break;

                        case "ORT":
                        {
                            string plz = ParserUtility.ReadZipCodeFromCity(msg);
                            operation.Zielort.ZipCode = plz;
                            operation.Zielort.City    = msg.Remove(0, plz.Length).Trim();
                        }
                        break;

                        case "OBJEKT":
                            operation.Zielort.Property = msg;
                            break;

                        case "STATION":
                            operation.CustomData["Zielort Station"] = msg;
                            break;

                        default:
                            break;
                        }
                    }
                    break;

                    case CurrentSection.EEinsatzgrund:
                    {
                        switch (prefix)
                        {
                        case "SCHLAGW.":
                            operation.Keywords.Keyword = msg;
                            break;

                        case "STICHWORT B":
                            operation.Keywords.B = msg;
                            break;

                        case "STICHWORT R":
                            operation.Keywords.R = msg;
                            break;

                        case "STICHWORT S":
                            operation.Keywords.S = msg;
                            break;

                        case "STICHWORT T":
                            operation.Keywords.T = msg;
                            break;

                        case "PRIO.":
                            operation.Priority = msg;
                            break;

                        default:
                            break;
                        }
                    }
                    break;

                    case CurrentSection.FEinsatzmittel:
                    {
                        if (line.StartsWith("EINSATZMITTEL", StringComparison.CurrentCultureIgnoreCase))
                        {
                            msg           = ParserUtility.GetMessageText(line, "EINSATZMITTEL");
                            last.FullName = msg;
                        }
                        else if (line.StartsWith("ALARMIERT", StringComparison.CurrentCultureIgnoreCase) && !string.IsNullOrEmpty(msg))
                        {
                            msg = ParserUtility.GetMessageText(line, "Alarmiert");

                            DateTime dt = ParserUtility.TryGetTimestampFromMessage(msg, operation.Timestamp);
                            last.Timestamp = dt.ToString();
                        }
                        else if (line.StartsWith("GEFORDERTE AUSSTATTUNG", StringComparison.CurrentCultureIgnoreCase))
                        {
                            msg = ParserUtility.GetMessageText(line, "Geforderte Ausstattung");

                            if (!string.IsNullOrWhiteSpace(msg))
                            {
                                last.RequestedEquipment.Add(msg);
                            }

                            operation.Resources.Add(last);
                            last = new OperationResource();
                        }
                    }
                    break;

                    case CurrentSection.GBemerkung:
                    {
                        operation.Comment = operation.Comment += msg + "\n";
                    }
                    break;

                    case CurrentSection.HFooter:
                        // The footer can be ignored completely.
                        break;

                    default:
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message);
                }
            }

            operation.Comment = ParserUtility.RemoveTrailingNewline(operation.Comment);

            return(operation);
        }
Exemple #5
0
        Operation IParser.Parse(string[] lines)
        {
            Operation         operation = new Operation();
            OperationResource last      = new OperationResource();

            lines = Utilities.Trim(lines);

            CurrentSection section      = CurrentSection.AHeader;
            bool           keywordsOnly = true;

            InnerSection innerSection = InnerSection.AStraße;

            for (int i = 0; i < lines.Length - 5; i++)
            {
                try
                {
                    string line = lines[i];
                    if (line.Length == 0)
                    {
                        continue;
                    }

                    // Try to parse the header and extract date and time if possible
                    operation.Timestamp = ParserUtility.ReadFaxTimestamp(line, operation.Timestamp);


                    if (GetSection(line.Trim(), ref section, ref keywordsOnly))
                    {
                        continue;
                    }

                    string msg    = line;
                    string prefix = "";

                    // Make the keyword check - or not (depends on the section we are in; see above)
                    if (keywordsOnly)
                    {
                        string keyword;
                        if (!ParserUtility.StartsWithKeyword(line, Keywords, out keyword))
                        {
                            continue;
                        }

                        int x = line.IndexOf(':');
                        int y = line.IndexOf('=');
                        if (x == -1 && y == -1)
                        {
                            // If there is no colon found (may happen occasionally) then simply remove the length of the keyword from the beginning
                            prefix = keyword;
                            msg    = line.Remove(0, prefix.Length).Trim();
                        }
                        else if (y != -1 && x == -1 || (y != -1 && x != -1 && y < x))
                        {
                            prefix = line.Substring(0, y);
                            msg    = line.Substring(y + 1).Trim();
                        }
                        else
                        {
                            prefix = line.Substring(0, x);
                            msg    = line.Substring(x + 1).Trim();
                        }

                        prefix = prefix.Trim().ToUpperInvariant();
                    }

                    // Parse each section
                    switch (section)
                    {
                    case CurrentSection.AHeader:
                    {
                        switch (prefix)
                        {
                        case "EINSATZNUMMER":
                            operation.OperationNumber = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.BMitteiler:
                    {
                        // This switch would not be necessary in this section (there is only "Name")...
                        switch (prefix)
                        {
                        case "NAME":
                            operation.Messenger = msg;
                            break;

                        case "RUFNUMMER":
                            operation.Messenger = operation.Messenger.AppendLine(string.Format("Nr.: {0}", msg));
                            break;
                        }
                    }
                    break;

                    case CurrentSection.CEinsatzort:
                    {
                        switch (prefix)
                        {
                        case "STRAßE":
                        {
                            innerSection = InnerSection.AStraße;
                            string street, streetNumber, appendix;
                            ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix);
                            operation.CustomData["Einsatzort Zusatz"] = appendix;
                            operation.Einsatzort.Street       = street;
                            operation.Einsatzort.StreetNumber = streetNumber;
                        }
                        break;

                        case "ORT":
                        {
                            innerSection = InnerSection.BOrt;
                            operation.Einsatzort.ZipCode = ParserUtility.ReadZipCodeFromCity(msg);
                            if (string.IsNullOrWhiteSpace(operation.Einsatzort.ZipCode))
                            {
                                Logger.Instance.LogFormat(LogType.Warning, this, "Could not find a zip code for city '{0}'. Route planning may fail or yield wrong results!", operation.Einsatzort.City);
                            }

                            operation.Einsatzort.City = msg.Remove(0, operation.Einsatzort.ZipCode.Length).Trim();

                            // The City-text often contains a dash after which the administrative city appears multiple times (like "City A - City A City A").
                            // However we can (at least with google maps) omit this information without problems!
                            int dashIndex = operation.Einsatzort.City.IndexOf(" - ");
                            if (dashIndex != -1)
                            {
                                // Ignore everything after the dash
                                operation.Einsatzort.City = operation.Einsatzort.City.Substring(0, dashIndex).Trim();
                            }
                        }
                        break;

                        case "OBJEKT":
                            innerSection = InnerSection.CObjekt;
                            operation.Einsatzort.Property = msg;
                            break;

                        case "STATION":
                            innerSection = InnerSection.DStation;
                            operation.CustomData["Einsatzort Station"] = msg;
                            break;

                        default:
                            switch (innerSection)
                            {
                            case InnerSection.AStraße:
                                //Quite dirty because of Streetnumber. Looking for better solution
                                operation.Einsatzort.Street += msg;
                                break;

                            case InnerSection.BOrt:
                                operation.Einsatzort.City += msg;
                                break;

                            case InnerSection.CObjekt:
                                operation.Einsatzort.Property += msg;
                                break;

                            case InnerSection.DStation:
                                operation.CustomData["Einsatzort Station"] += msg;
                                break;
                            }
                            break;
                        }
                    }
                    break;

                    case CurrentSection.EEinsatzgrund:
                    {
                        switch (prefix)
                        {
                        case "SCHLAGW.":
                            operation.Keywords.Keyword = msg;
                            break;

                        case "STICHWORT":
                            operation.Keywords.EmergencyKeyword = msg;
                            break;

                        case "PRIO.":
                            operation.Priority = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.FEinsatzmittel:
                    {
                        switch (prefix)
                        {
                        case "NAME":
                            last.FullName = msg.Trim();
                            break;

                        case "ALARMIERT":
                            // Only add to requested equipment if there is some text,
                            // otherwise the whole vehicle is the requested equipment
                            if (!string.IsNullOrWhiteSpace(msg))
                            {
                                last.Timestamp = ParserUtility.TryGetTimestampFromMessage(msg, DateTime.Now).ToString();
                            }
                            operation.Resources.Add(last);

                            last = new OperationResource();
                            break;
                        }
                    }
                    break;

                    case CurrentSection.GBemerkung:
                    {
                        // Append with newline at the end in case that the message spans more than one line
                        operation.Comment = operation.Comment.AppendLine(msg);
                    }
                    break;

                    case CurrentSection.HFooter:
                        // The footer can be ignored completely.
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message);
                }
            }
            return(operation);
        }
        Operation IParser.Parse(string[] lines)
        {
            Operation         operation = new Operation();
            OperationResource last      = new OperationResource();

            lines = Utilities.Trim(lines);
            CurrentSection section             = CurrentSection.AHeader;
            bool           keywordsOnly        = true;
            bool           multiLineProperties = false;
            string         keyword             = "";
            string         prefix = "";

            for (int i = 0; i < lines.Length; i++)
            {
                try
                {
                    string line = lines[i];
                    if (line.Length == 0)
                    {
                        continue;
                    }
                    if (GetSection(line.Trim(), ref section, ref keywordsOnly, ref multiLineProperties))
                    {
                        continue;
                    }

                    string msg = line;

                    // Make the keyword check - or not (depends on the section we are in; see above)
                    if (!multiLineProperties)
                    {
                        prefix = "";
                    }
                    if (keywordsOnly)
                    {
                        bool foundKeyword = ParserUtility.StartsWithKeyword(line, _keywords, out keyword);
                        if (!foundKeyword && !multiLineProperties)
                        {
                            continue;
                        }
                        if (foundKeyword)
                        {
                            int x = line.IndexOf(':');
                            if (x == -1)
                            {
                                // If there is no colon found (may happen occasionally) then simply remove the length of the keyword from the beginning
                                prefix = keyword;
                                msg    = line.Remove(0, prefix.Length).Trim();
                            }
                            else
                            {
                                prefix = line.Substring(0, x);
                                msg    = line.Substring(x + 1).Trim();
                            }
                            prefix = prefix.Trim().ToUpperInvariant();
                        }
                    }

                    // Parse each section
                    switch (section)
                    {
                    case CurrentSection.AHeader:
                    {
                        switch (prefix)
                        {
                        case "EINSATZNUMMER":
                            operation.OperationNumber = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.BMitteiler:
                        operation.Messenger = msg;
                        break;

                    case CurrentSection.CEinsatzort:
                    {
                        switch (prefix)
                        {
                        case "STRAßE":
                        {
                            string street, streetNumber, appendix;
                            ParserUtility.AnalyzeStreetLine(msg, out street, out streetNumber, out appendix);
                            operation.CustomData["Einsatzort Zusatz"] = appendix;
                            operation.Einsatzort.Street       = street;
                            operation.Einsatzort.StreetNumber = streetNumber;
                        }
                        break;

                        case "ORT":
                        {
                            operation.Einsatzort.ZipCode = ParserUtility.ReadZipCodeFromCity(msg);
                            if (string.IsNullOrWhiteSpace(operation.Einsatzort.ZipCode))
                            {
                                Logger.Instance.LogFormat(LogType.Warning, this, "Could not find a zip code for city '{0}'. Route planning may fail or yield wrong results!", operation.Einsatzort.City);
                            }

                            operation.Einsatzort.City = msg.Remove(0, operation.Einsatzort.ZipCode.Length).Trim();

                            // The City-text often contains a dash after which the administrative city appears multiple times (like "City A - City A City A").
                            // However we can (at least with google maps) omit this information without problems!
                            int dashIndex = operation.Einsatzort.City.IndexOf(" - ");
                            if (dashIndex != -1)
                            {
                                // Ignore everything after the dash
                                operation.Einsatzort.City = operation.Einsatzort.City.Substring(0, dashIndex).Trim();
                            }
                            break;
                        }

                        case "GEMEINDE":
                        {
                            operation.CustomData.Add("GEMEINDE", msg);
                        }
                        break;

                        case "OBJEKT":
                            if (msg.Contains("EPN:"))
                            {
                                operation.Einsatzort.Property = ParserUtility.GetTextBetween(msg, null, "EPN");
                                operation.OperationPlan       = ParserUtility.GetTextBetween(msg, "EPN");
                            }
                            else
                            {
                                operation.Einsatzort.Property = msg;
                            }
                            break;

                        case "ABSCHNITT":
                        case "KREUZUNG":
                            operation.Einsatzort.Intersection += msg;
                            break;

                        case "KOORDINATE":
                            Regex r       = new Regex(@"\d+");
                            var   matches = r.Matches(line);
                            if (matches.Count == 2)
                            {
                                int geoRechts = Convert.ToInt32(matches[0].Value);
                                int geoHoch   = Convert.ToInt32(matches[1].Value);
                                var geo       = GeographicCoords.FromGaussKrueger(geoRechts, geoHoch);
                                operation.Einsatzort.GeoLatitude  = geo.Latitude;
                                operation.Einsatzort.GeoLongitude = geo.Longitude;
                            }
                            break;
                        }
                    }
                    break;

                    case CurrentSection.DEinsatzgrund:
                    {
                        switch (prefix)
                        {
                        case "SCHLAGW.":
                            operation.Keywords.Keyword = msg;
                            break;

                        case "STICHWORT":
                            operation.Keywords.EmergencyKeyword = msg;
                            break;

                        case "PRIO.":
                            operation.Priority = msg;
                            break;
                        }
                    }
                    break;

                    case CurrentSection.EEinsatzmittel:
                    {
                        switch (prefix)
                        {
                        case "NAME":
                            last.FullName = msg;
                            break;

                        case "GEF. GERÄT":
                            // Only add to requested equipment if there is some text,
                            // otherwise the whole vehicle is the requested equipment
                            if (!string.IsNullOrWhiteSpace(msg))
                            {
                                last.RequestedEquipment.Add(msg);
                            }
                            break;

                        case "ALARMIERT":
                            last.Timestamp = ParserUtility.TryGetTimestampFromMessage(msg, DateTime.Now).ToString();

                            operation.Resources.Add(last);
                            last = new OperationResource();
                            break;
                        }
                    }
                    break;

                    case CurrentSection.FBemerkung:
                    {
                        // Append with newline at the end in case that the message spans more than one line
                        operation.Comment = operation.Comment.AppendLine(msg);
                    }
                    break;

                    case CurrentSection.GFooter:
                        // The footer can be ignored completely.
                        break;
                    }
                }
                catch (Exception ex)
                {
                    Logger.Instance.LogFormat(LogType.Warning, this, "Error while parsing line '{0}'. The error message was: {1}", i, ex.Message);
                }
            }
            return(operation);
        }