// A utility class representing output to the console.
// Provides a Print() function that will both call MyGridProgram.Echo()
// and also output to the Programmable Block's LCD.

using Sandbox.ModAPI.Ingame;
using System.Collections.Generic;
using System.Text;
using VRage.Game.ModAPI.Ingame.Utilities;

namespace IngameScript
{
    partial class Program
    {
        public interface IConsole
        {
            void Print(string text);
            void PrintLower(string text);
        }

        public class Console : IConsole
        {
            private MyGridProgram _program;
            private int _maxLines;
            private List<string> _buffer;

            private const int DefaultMaxLines = 10;

            public Console(MyGridProgram program, MyIni ini)
            {
                _program = program;
                _buffer = new List<string>();

                // Check the PB's custom data for a maxlines directive.
                ini.TryParse(program.Me.CustomData);
                _maxLines = ini.Get("console", "maxLines").ToInt32(DefaultMaxLines);
            }

            public PrefixedConsole CreatePrefixedConsole(string prefix)
            {
                return new PrefixedConsole(this, prefix);
            }

            public void Print(string text)
            {
                _program.Echo(text);
                _program.Me.GetSurface(0).WriteText(writeToBuffer(text));
            }

            // Text written with this method goes to the lower screen / keyboard,
            // with no buffering.
            public void PrintLower(string text)
            {
                _program.Me.GetSurface(1).WriteText(text);
            }

            // Adds the text to the buffer, trims the top if necessary, and builds a printable
            // string.
            private string writeToBuffer(string text)
            {
                _buffer.Add(text);
                if (_buffer.Count > _maxLines) _buffer.RemoveAt(0);
                StringBuilder result = new StringBuilder("", 800);
                foreach (string line in _buffer) result.AppendLine(line);
                return result.ToString();
            }
        }

        // This class is necessary because we need to keep a *single* buffer
        // to write to. So we can ask the primary Console for a prefixer.
        public class PrefixedConsole : IConsole
        {
            private IConsole _console;
            private string _prefix;

            public PrefixedConsole(IConsole console, string prefix)
            {
                _console = console;
                _prefix = prefix + ": ";
            }

            public void Print(string text)
            {
                _console.Print(_prefix + text);
            }

            // sub-consoles can't print to the ephemeral display
            public void PrintLower(string text) { }
        }
    }
}