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

namespace IngameScript
{
    partial class Program
    {
        // We don't really do anything with the modes other than Loading right now,
        // but they are nice for consistency.
        // TODO: we could have displays that print the current mode...
        public enum DockMode
        {
            Loading,
            Unloading,
            Off,
        }

        public class Dock
        {
            public string Id { get; private set; }
            public DockMode Mode { get; private set; } = DockMode.Off;

            public bool Functional
            {
                get
                {
                    return _ports.Count > 0 && _inputSorter != null && _outputSorter != null;
                }
            }

            private IMyTextSurface _display;
            private IMyConveyorSorter _inputSorter;
            private IMyConveyorSorter _outputSorter;
            private List<IMyShipConnector> _ports = new List<IMyShipConnector>();
            private bool _wasDocked = false; // Records whether a ship was docked last time we checked for one.
            private IConsole _console;

            public Dock(string id, IConsole console)
            {
                Id = id;
                _console = new PrefixedConsole(console, id);
            }

            // Check and update the state of the Dock.
            // In particular, this checks whether a ship has undocked since our last check,
            // and if so it turns off the loading/unloading mechanism and releases the lock.
            public void Update()
            {
                bool isDocked = false;
                foreach (IMyShipConnector port in _ports)
                {
                    if (port.IsConnected)
                    {
                        isDocked = true;
                        break;
                    }
                }

                if (_wasDocked && !isDocked) Reset();

                _wasDocked = isDocked;
            }

            public void UpdateDisplay()
            {
                if (_display == null) return;
                switch (Mode)
                {
                    case DockMode.Loading:
                        _display.WriteText("Ready to load cargo");
                        break;
                    case DockMode.Unloading:
                        _display.WriteText("Unloading Cargo");
                        break;
                    case DockMode.Off:
                        _display.WriteText("Standby Mode");
                        break;
                }
            }

            public void StartLoading()
            {
                _console.Print("Loading mode.");
                Mode = DockMode.Loading;
                _outputSorter.Enabled = false;
                _inputSorter.Enabled = true;
                UpdateDisplay();
            }

            public void StartUnloading()
            {
                _console.Print("Unloading mode.");
                Mode = DockMode.Unloading;
                _inputSorter.Enabled = false;
                _outputSorter.Enabled = true;
                UpdateDisplay();
            }

            public void Reset()
            {
                _console.Print("Disabling conveyors.");
                Mode = DockMode.Off;
                _inputSorter.Enabled = false;
                _outputSorter.Enabled = false;
                UpdateDisplay();
            }

            public void AddBlock(IMyTerminalBlock block, MyIni ini)
            {
                if (block is IMyConveyorSorter)
                {
                    string direction = ini.Get("dockLoader", "direction").ToString();
                    switch (direction)
                    {
                        case "input":
                            _inputSorter = block as IMyConveyorSorter;
                            _inputSorter.Enabled = false;
                            break;
                        case "output":
                            _outputSorter = block as IMyConveyorSorter;
                            _outputSorter.Enabled = false;
                            break;
                        default:
                            _console.Print($"Invalid direction for '{block.CustomName}'");
                            break;
                    }
                }
                else if (block is IMyShipConnector)
                {
                    _ports.Add(block as IMyShipConnector);
                }
                else if (block is IMyTextSurfaceProvider)
                {
                    // for now we'll just assume the first display, since that meets our most popular use case
                    _display = ((IMyTextSurfaceProvider)block).GetSurface(0);
                    _display.ContentType = ContentType.TEXT_AND_IMAGE;
                    _display.WriteText("Standby Mode");
                }
                else
                {
                    _console.Print($"Can't add block '{block.CustomName}'");
                }
            }
        }
    }
}