using System;
using System.Collections.Generic;
using System.Text;
using FBPLib;

    namespace FBPVerbs
    {
        using System;
        // This component was converted from Java, but has not been tested...  It is
        // retained in case of future need.

        /// <summary>This class is based on a (language) parsing technique called Babel, that I learned in
        /// England many years ago!
        /// This class definitely has an internal state, so all users must create an instance of it.  
        /// *
        /// </summary>

        public class BabelParser
        {
            internal virtual bool MoreInput
            {
                get
                {
                    if (null != currentPacket)
                    {
                        Connection cnxt = (Connection)inport;
                        cnxt._receiver.Drop(currentPacket);
                    }

                    if (null == (currentPacket = inport.Receive()))
                        return false;
                    //   end of file returns false 
                    System.String str = (System.String)currentPacket.Content;
                    int x = str.Length;
                    input = new char[x]; // new char array each time
                    inputIndex = 0;
                    endOfInput = x;

                    int i;
                    int j;
                    i = 0;
                    j = 0;
                    while (i < x)
                    {
                        input[j] = str[i];
                        i++;
                        j++;
                    }
                    // move str into input array
                    return true;
                }

            }
            public virtual System.String OutStr
            {
                get
                {
                    System.String sym = null;
                    if (outputIndex > 0)
                    {
                        try
                        {
                            sym = new String(output, 0, outputIndex);
                        }
                        catch (System.NullReferenceException r)
                        {
                            System.Console.Out.WriteLine("RuntimeException:" + r);

                        }
                        catch (System.IndexOutOfRangeException e)
                        {
                            System.Console.Out.WriteLine("RuntimeException:" + e);

                        }
                        outputIndex = 0;
                    }
                    return sym;
                }

            }

            internal static string copyright = "Copyright 1999, 2000, 2001, 2002, J. Paul Morrison.  At your option, you may copy, " + "distribute, or make derivative works under the terms of the Clarified Artistic License, " + "based on the Everything Development Company's Artistic License.  A document describing " + "this License may be found at http://www.jpaulmorrison.com/fbp/artistic2.htm. " + "THERE IS NO WARRANTY; USE THIS PRODUCT AT YOUR OWN RISK.";


            private char[] input;
            private char[] output;
            private int inputIndex;
            private int outputIndex;
            private int endOfInput;

            private IInputPort inport;
            private Packet currentPacket = null;

            /// <summary> BabelParser constructor.
            /// </summary>
            public BabelParser(IInputPort input)
                : base()
            {
                inputIndex = 0;
                endOfInput = 0; // this will force getMoreInput before first comparison
                outputIndex = 0;
                output = new char[256];
                inport = input;
            }
            /// <summary> Erase output stream
            /// </summary>
            public virtual void eraseOutput()
            {

                outputIndex = 0;

            }
            /// <summary> Get another input Packet - return false if no more
            /// </summary>
            /// <summary> Take output generated by syntax scan, and return as String
            /// Output index is then set back to zero. 
            /// </summary>
            /// <returns>java.lang.String
            /// 
            /// </returns>
            /// <summary> This macro compares against a given character. Scanning is continuous from the end of one
            /// incoming packet to the start of the next one.  End of input results in a false result -
            /// i.e. end of input is considered to not match _any_ test character.
            /// </summary>
            public virtual bool tc(char x)
            {
                while (inputIndex >= endOfInput)
                {
                    if (!MoreInput)
                        return false;
                }
                if (input[inputIndex] != x)
                    return false;
                output[outputIndex] = input[inputIndex];
                outputIndex++;
                inputIndex++;
                return true;
            }
            /// <summary> Same as tc(char), but with modification (must be 'n' or 'o')
            /// ('n' is equivalent to old Babel 'IO' - I- and O-modification)
            /// </summary>
            /// <param name="x">char
            /// </param>
            /// <param name="mod">char
            /// 
            /// </param>

            public virtual bool tc(char x, char mod)
            {

                while (inputIndex >= endOfInput)
                {
                    if (!MoreInput)
                        return false;
                }
                if (input[inputIndex] != x)
                    return false;

                if (mod == 'o')
                    inputIndex++;
                return true;
            }
            /// <summary> This macro compares against a number (figure). Scanning is continuous from the end of one
            /// incoming packet to the start of the next one.  End of input results in a false result.
            /// </summary>
            public virtual bool tf()
            {
                while (inputIndex >= endOfInput)
                {
                    if (!MoreInput)
                        return false;
                }
                if (!System.Char.IsDigit(input[inputIndex]))
                    return false;
                output[outputIndex] = input[inputIndex];
                outputIndex++;
                inputIndex++;
                return true;
            }
            /// <summary> Same as tf(), but with modification (must be 'o' or 'n')
            /// ('n' is equivalent to old Babel 'IO' - I- and O-modification)
            /// </summary>
            /// <param name="mod">char
            /// 
            /// </param>

            public virtual bool tf(char mod)
            {

                while (inputIndex >= endOfInput)
                {
                    if (!MoreInput)
                        return false;
                }
                if (!System.Char.IsDigit(input[inputIndex]))
                    return false;

                if (mod == 'o')
                    inputIndex++;
                return true;
            }
            /// <summary> This macro compares against a letter. Scanning is continuous from the end of one
            /// incoming packet to the start of the next one.  End of input results in a false result.
            /// </summary>
            public virtual bool tl()
            {
                while (inputIndex >= endOfInput)
                {
                    if (!MoreInput)
                        return false;
                }
                if (!System.Char.IsLetter(input[inputIndex]))
                    return false;
                output[outputIndex] = input[inputIndex];
                outputIndex++;
                inputIndex++;
                return true;
            }
            /// <summary> Same as tl(), but with modification (must be 'o' or 'n')
            /// ('n' is equivalent to old Babel 'IO' - I- and O-modification)
            /// </summary>
            /// <param name="mod">char
            /// 
            /// </param>

            public virtual bool tl(char mod)
            {

                while (inputIndex >= endOfInput)
                {
                    if (!MoreInput)
                        return false;
                }
                if (!System.Char.IsLetter(input[inputIndex]))
                    return false;

                if (mod == 'o')
                    inputIndex++;
                return true;
            }
            /// 
            /// <summary> Babel 'universal comparator' - it is always true, unless we are at end of file 
            /// </summary>
            public virtual bool tu()
            {
                while (inputIndex >= endOfInput)
                {
                    if (!MoreInput)
                        return false;
                }

                output[outputIndex] = input[inputIndex];
                outputIndex++;
                inputIndex++;
                return true;

            }
            /// <summary> Same as tu(), but with modification (must be 'o' or 'n')
            /// ('n' is equivalent to old Babel 'IO' - I- and O-modification)
            /// </summary>
            /// <param name="mod">char
            /// 
            /// </param>
            public virtual bool tu(char mod)
            {
                while (inputIndex >= endOfInput)
                {
                    if (!MoreInput)
                        return false;
                }


                if (mod == 'o')
                    inputIndex++;
                return true;
            }
        }

    }

 
