using System;
using System.Windows.Forms;

/// <summary>
/// Reusable parser class for processing alarm signals.
/// 
/// Author: Sean Handley
/// Version: 2007-09-29
/// </summary>
public static class AlarmParser
{
    //add extra alarm data members here as required
    private enum AlarmDataMembers { VideoServerNumber, AlarmID };

    public static int GetVideoServerNumber(String AlarmSignal)
    {
        return parse(AlarmSignal, (int)AlarmDataMembers.VideoServerNumber);
    }

    public static int GetAlarmID(String AlarmSignal)
    {
        return parse(AlarmSignal, (int)AlarmDataMembers.AlarmID);
    }

    private static int parse(String AlarmSignal, int AlarmDataMember)
    {
        String input = AlarmSignal;
        //determine message format A or B
        //A = "[The alarm id from video server number ][X][ is ][Y][.]"
        //B = "[Alarm id ][Y][ received from video server number ][X][.]"

        //tokens:
        const String A = "The alarm id from video server number ";
        int B = 0;
        const String C = " is ";
        int D = 0;
        const String E = ".";
        const String F = "Alarm id ";
        const String G = " received from video server number ";

        //valid expression = ABCDE / FDGBE

        //tokenise

        //check string length - minimum valid length is 45 chars
        if (input.Length < 45)
        {
            throw new Exception("Alarm signal message is incomplete.");
        }

        //check for A or F and consume if present
        try
        {
            input.Substring(0, A.Length).Equals(A);
        }
        catch
        {
            throw new Exception("Malformed alarm signal at start of message.");
        }

        if (input.Substring(0, A.Length).Equals(A))
        {
            //expression is type 1 (ABCDE)

            //consume A
            try
            {
                input = input.Substring(A.Length, input.Length - A.Length);
            }
            catch
            {
                throw new Exception("Malformed alarm signal at start of message.");
            }
            //---

            //next expected token is B (integer of any length)
            try
            {
                String sB = "";
                while (IsNumeric(input.Substring(0, 1)))
                {
                    sB += input.Substring(0, 1);
                    //consume a char
                    input = input.Substring(1, input.Length - 1);
                }
                B = Convert.ToInt32(sB);
            }
            catch
            {
                throw new Exception("Invalid Video Server Number.");
            }
            //---

            //next expected is C
            try
            {
                if (input.Substring(0, C.Length).Equals(C))
                {
                    //consume C
                    input = input.Substring(C.Length, input.Length - C.Length);
                }
            }
            catch
            {
                throw new Exception("Malformed alarm message discovered after \n'" + A + B + "'");
            }
            //---

            //next expected is D
            try
            {
                String sD = "";
                while (IsNumeric(input.Substring(0, 1)) && input.Length > 0)
                {
                    sD += input.Substring(0, 1);
                    //consume a char
                    input = input.Substring(1, input.Length - 1);
                }
                D = Convert.ToInt32(sD);
            }
            catch
            {
                throw new Exception("Invalid Alarm ID.");
            }
            //---

            //next expected is E
            try{
                if (input.Substring(0, E.Length).Equals(E))
                {
                    //consume E
                    input = input.Substring(E.Length, input.Length - E.Length);
                }
            }
            catch
            {
                throw new Exception("Message must end with a '.'");
            }
            //---

        }
        else if (input.Substring(0, F.Length).Equals(F))
        {
            //expression is type 2 (FDGBE)

            //consume F
            try
            {
                input = input.Substring(F.Length, input.Length - F.Length);
            }
            catch
            {
                throw new Exception("Malformed alarm signal at start of message.");
            }
            //---

            //next expected is D
            try
            {
                String sD = "";
                while (IsNumeric(input.Substring(0, 1)))
                {
                    sD += input.Substring(0, 1);
                    //consume a char
                    input = input.Substring(1, input.Length - 1);
                }
                D = Convert.ToInt32(sD);
            }
            catch
            {
                throw new Exception("Invalid Alarm ID.");
            }
            //---

            try
            {
                //next expected is G
                if (input.Substring(0, G.Length).Equals(G))
                {
                    //consume G
                    input = input.Substring(G.Length, input.Length - G.Length);
                }
            }
            catch
            {
                throw new Exception("Malformed alarm message discovered after \n'" + F + D + "'");
            }
            //---

            //next expected token is B (integer of any length)
            try
            {
                String sB = "";
                while (IsNumeric(input.Substring(0, 1)))
                {
                    sB += input.Substring(0, 1);
                    //consume a char
                    input = input.Substring(1, input.Length - 1);
                }
                B = Convert.ToInt32(sB);
            }
            catch
            {
                throw new Exception("Invalid Video Server Number.");
            }
            //---

            //next expected is E
            try
            {
                if (input.Substring(0, E.Length).Equals(E))
                {
                    //consume E
                    input = input.Substring(E.Length, input.Length - E.Length);
                }
            }
            catch
            {
                throw new Exception("Message must end with a '.'");
            }
            //---

        }
        else
        {
            throw new Exception("Unexpected message format.");
        }


        //input should now be empty
        if (input.Length > 0)
        {
            throw new Exception("Alarm signal contains unexpected data at the end.");
        }

        //determine token to be returned
        switch (AlarmDataMember)
        {
            case (int)AlarmDataMembers.VideoServerNumber:
                return B;
            case (int)AlarmDataMembers.AlarmID:
                return D;
            default:
                throw new Exception();
        };
    }

    private static bool IsNumeric(string val)
    {
        try
        {
            Convert.ToInt32(val);
            return true;
        }
        catch
        {
            return false;
        }
    }
}