using SlatedGameToolkit.Framework;
using SlatedGameToolkit.Framework.Logging;
using SlatedGameToolkit.Framework.StateSystem;
using SlatedGameToolkit.Tools.CommandSystem;
using SlatedGameToolkit.Tools.CommandSystem.Interaction;
using SlatedGameToolkit.Tools.Utilities.Playground;

namespace SlatedGameToolkit.Tools.Commands
{
    public class GraphicalPlaygroundCommand : IInvocable
    {
        private readonly string[] invokers = new string[] {"playground"};
        private ConsoleLogListener logListener;
        private bool debugging;

        public bool Execute(IInteractable interactable, string[] args)
        {
            if (args.Length != 1) return false;
            args[0] = args[0].ToLower();
            if (args[0].Equals("start")) {
                if (GameEngine.IsRunning()) {
                    interactable.Tell("Engine is already running!");
                    return true;
                }
                Logger.AddLogListener((logListener = new ConsoleLogListener(interactable as ConsoleInteraction)));
                logListener.Debug = debugging;
                GameEngine.Ignite(new MainState());
                return true;
            } else if (args[0].Equals("stop")) {
                if (!GameEngine.IsRunning()) {
                    interactable.Tell("Engine was never running!");
                    return true;
                }
                Logger.RemoveLogListener(logListener);
                GameEngine.Stop();
                return true;
            } else if (args[0].Equals("status")) {
                interactable.Tell("Running: " + GameEngine.IsRunning());
                interactable.Tell("Target FPS: " + (GameEngine.targetFPS <= 0 ? "Not bounded." : GameEngine.targetFPS.ToString()));
                interactable.Tell("Update Step: " + (GameEngine.UpdatesPerSecond <= 0 ? "Not Locked." : GameEngine.UpdatesPerSecond.ToString()));
                interactable.Tell("Debug logging: " + logListener.Debug);
                return true;
            } else if (args[0].Equals("debug")) {
                debugging = !debugging;
                if (logListener != null) {
                    logListener.Debug = debugging;
                    interactable.Tell("Debug logging: " + logListener.Debug);
                } else {
                    interactable.Tell(string.Format("Debug will be turned {0} when playground is started.", debugging ? "on" : "off"));
                }
                return true;
            }
            return false;
        }

        public string getDescription()
        {
            return "Starts and stops the graphical playground.";
        }

        public string[] GetInvokers()
        {
            return invokers;
        }

        public string getUsage(string arg)
        {
            return "Usage: \"playground [start | stop | status]\" the required argument being whether to start, stop or get the current status of the game engine.";
        }

        public void Dispose()
        {
            GameEngine.Stop();
        }
    }
}