public jtbvReceivedMessage(string text, Point cursorLoc, jtbvMessageColor color)
 {
     Uid = (uid_counter++);
     CursorLoc = cursorLoc;
     Text = text;
     ReceiveTime = System.DateTime.Now;
     Color = color;
 }
        public jtbvTTYReader()
        {
            MessageHistory = new ArrayList();

            CurrentMessages = new ArrayList();
            currentMessage = "";
            currentMessageColor = new jtbvMessageColor();
            currentMessageXY = new Point();

            cursor = new Point();
            screen = new jtbvTextRect(80, 25);
        }
        public void ProcessTTY(string recBuf)
        {
            #region VT102 escape code processing
            for (int cnt = 0; cnt < recBuf.Length; cnt++)
            {
                if (((char) recBuf[cnt]) == ESC) // VT102 escape code handling...
                {
                    int parm = 0;
                    ArrayList parmList = new ArrayList();

                    cnt++;
                    if (cnt >= recBuf.Length)
                        break;

                    switch ((char) recBuf[cnt])
                    {
                        case '[':
                            cnt++;
                            if (cnt >= recBuf.Length)
                                break;
                            bool cmdHit = false;
                            for (; (!cmdHit) && (cnt < recBuf.Length); cnt++) // This loop parses VT100 commands for coloring and cursor movement
                            {
                                switch ((char) recBuf[cnt])
                                {
                                    case '0':
                                    case '1':
                                    case '2':
                                    case '3':
                                    case '4':
                                    case '5':
                                    case '6':
                                    case '7':
                                    case '8':
                                    case '9':
                                        parm *= 10;					// Shift the parameter value by base 10
                                        parm += (recBuf[cnt] - 48); // Add the decimal value to the current parameter
                                        break;
                                    case ';': // Next parameter
                                        parmList.Add(parm);
                                        parm = 0;
                                        break;
                                    case 'H': // Move cursor to position
                                        if (parmList.Count == 1)
                                        {
                                            cursor.X = parm - 1;
                                            cursor.Y = ((int) parmList[0]) - 1;
                                            AlertCurrentMessage();
                                        }
                                        else
                                        {
                                            cursor.X = 0;
                                            cursor.Y = 0;
                                            AlertCurrentMessage();
                                        }
                                        parmList.Clear();
                                        parm = 0;
                                        cmdHit = true;
                                        break;
                                    case 'A': // Move cursor up
                                        if (parm == 0)
                                            parm = 1;
                                        cursor.Y -= parm;
                                        AlertCurrentMessage();
                                        parmList.Clear();
                                        parm = 0;
                                        cmdHit = true;
                                        break;
                                    case 'B': // Move cursor down
                                        if (parm == 0)
                                            parm = 1;
                                        cursor.Y += parm;
                                        AlertCurrentMessage();
                                        parmList.Clear();
                                        parm = 0;
                                        cmdHit = true;
                                        break;
                                    case 'C': // Move cursor right
                                        if (parm == 0)
                                            parm = 1;
                                        cursor.X += parm;
                                        AlertCurrentMessage();
                                        parmList.Clear();
                                        parm = 0;
                                        cmdHit = true;
                                        break;
                                    case 'D': // Move cursor left
                                        if (parm == 0)
                                            parm = 1;
                                        cursor.X -= parm;
                                        AlertCurrentMessage();
                                        parmList.Clear();
                                        parm = 0;
                                        cmdHit = true;
                                        break;
                                    case 'J': // Erase screen
                                        if (parm == 2) // complete display...
                                        {
                                            cursor.X = 0;
                                            cursor.Y = 0;

                                            AlertCurrentMessage();
                                            parmList.Clear();
                                            parm = 0;

            //											Screen.Clear();
                                        }
                                        else
                                        {
                                            parmList.Clear();
                                            parm = 0;
                                            Console.WriteLine("Unknown clear request...");
                                        }
                                        cmdHit = true;
                                        break;
                                    case 'K': // Erase to end of current line
                                        string line = Screen.GetLine(Cursor.Y);
                                        line = jtbvUtils.FixedWidth(line, Cursor.X);
                                        Screen.SetLine(Cursor.Y, line);
                                        cmdHit = true;
                                        break;

                                    case 's': // Saved current cursor position
                                        //TODO: Implement cursor save eventually? (Needed? It's part of the ANSI standard, not VT100 or VT102)
                                    case 'u': // Recall previously saved cursor position
                                        //TODO: Implement cursor save eventually? (Needed? It's part of the ANSI standard, not VT100 or VT102)
                                    case 'h': // Coloring
                                    case 'm': // dGameLaunch seems to also use "m" as opposed to just the ansi standard "h". Wierd.
                                        AlertCurrentMessage(); // Before we change the color, we send a new message so as to break messages up according to color
                                        parmList.Add(parm);
                                        foreach (int p in parmList)
                                        {
                                            //Console.WriteLine("Text attribute " + p.ToString());
                                            if (p == 0)
                                                currentMessageColor = new jtbvMessageColor();
                                            else if ((p >= 1) && (p <= 8))
                                                currentMessageColor.Attr = (jtbvTextAttrib) p;
                                            else if ((p >= 30) && (p <= 38))
                                                currentMessageColor.FGColor = (jtbvTextColor) p - 30;
                                            else if ((p >= 40) && (p <= 48))
                                                currentMessageColor.BGColor = (jtbvTextColor) p - 40;
                                            else
                                                Console.WriteLine("Un-understood ANSI coloring option: " + p.ToString());
                                        }
                                        parmList.Clear();
                                        parm = 0;
                                        cmdHit = true;
                                        break;
                                    case '?': // Set various options... not sure how to handle...
                                        break;
                                    case 'r': // not sure what this does...?
                                    case 'l': // not sure what this does...?
                                        cmdHit = true;
                                        break;
                                    case 'd': // Set row???
                                        cursor.X = 0;
                                        cursor.Y = parm - 1;

                                        AlertCurrentMessage();

                                        parmList.Clear();
                                        parm = 0;

                                        cmdHit = true;
                                        break;
                                    default:
                                        Console.WriteLine("Didn't understand telnet code (" + recBuf[cnt].ToString() + ") '" + (char) recBuf[cnt] + "'");
                                        Console.WriteLine("Current cnt = " + cnt.ToString());
                                        jtbvUtils.HexPrint(recBuf);
                                        cmdHit = true;
                                        // Currently, we're in debug mode, and we can't afford to skip this. We need to process this, so throw a fatal exception that halts the program. If we need more debug information to figure out what happened, do a Console.Writeline above.
                                        throw new System.Exception("Didn't understand telnet code (" + recBuf[cnt].ToString() + ") '" + (char) recBuf[cnt] + "'");
                                        break;
                                }
                                if (cmdHit)
                                {
                                    parmList.Clear();
                                    parm = 0;
                                    cnt--;
                                }
                            }
                            break;
                        case '(':
            //										if (((char) recBuf[cnt+1]) == 'B')
            //											Console.WriteLine("Using the United States G1 character set");
            //										else
            //											Console.WriteLine("Using the " + (char) recBuf[cnt+1] + " character set");
                            cnt++;
                            break;
                        case ')':
            //										if (((char) recBuf[cnt+1]) == '0')
            //											Console.WriteLine("Using the G0 special characters and line set");
            //										else
            //											Console.WriteLine("Using the G" + (char) recBuf[cnt+1] + " special characters and line set");
                            cnt++;
                            break;
                        default:
                            Console.WriteLine("Unknown parameter '" + (char) recBuf[cnt] + "'");
                            break;

                    }
                }
                #endregion VT102 escape code processing

                else
                {
                    if (recBuf[cnt] == 0x08) // Backspace character
                    {
                        cursor.X--;
                        AlertCurrentMessage();
                    }
                    else if (recBuf[cnt] == 0x0A) // Carriage return
                    {
                        cursor.X = 0;
                        AlertCurrentMessage();
                    }
                    else if (recBuf[cnt] == 0x0D) // Line feed
                    {
                        cursor.Y++;
                        AlertCurrentMessage();
                    }
                    else if ((recBuf[cnt] >= 32) && (recBuf[cnt] <= 126)) // If it's a normal ASCII character...
                    {
                        currentMessage += (char) recBuf[cnt];
                        Screen.SetString(Cursor.X, Cursor.Y, ((char) recBuf[cnt]).ToString());
                        cursor.X++;
                    }
                }
            }

            if (currentMessage.Length > 0)
                AlertCurrentMessage();
        }