public static colorstring operator +(colorstring one, colorstring two)
        {
            colorstring result = new colorstring();

            foreach (colorstringpart s in one.strings)
            {
                result.strings.Add(s);
            }
            foreach (colorstringpart s in two.strings)
            {
                result.strings.Add(s);
            }
            return(result);
        }
 public static void Write(int r, int c, colorstring cs, int left_border, int width, int bottom_border)
 {
     if (cs.Length() > 0)
     {
         int row = r;
         int col = c;
         foreach (colorstringpart s1 in cs.strings)
         {
             colorstringpart s               = new colorstringpart(s1.s, s1.color, s1.bgcolor);
             colorstringpart wrapped         = new colorstringpart("", defaultcolor);
             bool            carriage_return = false;
             int             available_space = (left_border + width) - col;
             if (row == H - 1)
             {
                 --available_space;                         //this prevents Parabola from printing to the bottom right corner, which would scroll the screen.
             }
             colorchar cch;
             cch.color   = s.color;
             cch.bgcolor = s.bgcolor;
             if (ForegroundColor != s.color)
             {
                 ForegroundColor = s.color;
             }
             if (BackgroundColor != s.bgcolor)
             {
                 BackgroundColor = s.bgcolor;
             }
             string print_string           = s.s;
             int    i                      = 0;
             bool   changed                = false;
             bool   last_char_was_NL_or_CR = false;
             foreach (char ch in s.s)
             {
                 if (ch == '\r' || ch == '\n')
                 {
                     print_string = s.s.Substring(0, i);
                     wrapped.s    = s.s.Substring(i + 1);
                     if (wrapped.s.Length == 0)
                     {
                         last_char_was_NL_or_CR = true;
                     }
                     wrapped.bgcolor = s.bgcolor;
                     wrapped.color   = s.color;
                     if (ch == '\r')
                     {
                         carriage_return = true;
                     }
                     break;
                 }
                 else
                 {
                     if (i >= available_space)
                     {
                         if (wordwrap)
                         {
                             wrapped.s       = s.s.Substring(i);
                             wrapped.bgcolor = s.bgcolor;
                             wrapped.color   = s.color;
                         }
                         print_string = s.s.Substring(0, i);
                         break;
                     }
                     else
                     {
                         cch.c = ch;
                         if (!memory[row, col + i].Equals(cch))
                         {
                             memory[row, col + i] = cch;
                             changed = true;
                         }
                         ++i;
                     }
                 }
             }
             if (changed)
             {
                 Console.SetCursorPosition(col, row);
                 Console.Write(print_string);
             }
             col += print_string.Length;
             if (wrapped.s.Length > 0)
             {
                 if (carriage_return)
                 {
                     Write(row, left_border, wrapped, left_border, width, bottom_border);
                     col = left_border + wrapped.s.Length;
                 }
                 else
                 {
                     if (row < bottom_border)
                     {
                         ++row;
                         Write(row, left_border, wrapped, left_border, width, bottom_border);
                         col = left_border + wrapped.s.Length;
                     }
                 }
             }
             else
             {
                 if (last_char_was_NL_or_CR)
                 {
                     if (carriage_return)
                     {
                         col = left_border;
                     }
                     else
                     {
                         if (row < bottom_border)
                         {
                             ++row;
                             col = left_border;
                         }
                     }
                 }
             }
             if (col >= left_border + width)
             {
                 if (wordwrap)
                 {
                     ++row;
                     col = left_border;
                     if (row > bottom_border)
                     {
                         break;
                     }
                 }
                 else
                 {
                     break;
                 }
             }
         }
     }
 }
 public void Write(int r, int c, colorstring cs)
 {
     Screen.Write(row + r, col + c, cs, col, W, (row + H) - 1);
 }
 public static void Write(int r, int c, colorstring cs)
 {
     Write(r, c, cs, 0, W, H - 1);
 }