#pragma once
#include <iostream>
#include <vector>
#include "MPFW_Quake.h"
#include "MPFW_UI.h"
#include <functional>
#include <map>

#define MPFW_ConsoleCommand(x) void x(std::vector<std::string> cmd, MPFW::Console::CommandHandlerResources* ctx, std::string* logStr)

namespace MPFW {
	namespace Console {

		enum OperationMode {
			MPFW = 0,
			QUAKE = 1
		};

		struct CommandHandlerResources {
			Quake::Maps::MapFile* mapQuake;
			OperationMode mode = MPFW;
			UI::UIRenderer* ui;
			std::map<std::string, std::string> cvars;
			bool gameDisabled = false;
		};

		

		struct CommandID {
			OperationMode m;
			std::string n;
		};
		inline bool operator==(const CommandID& left, const CommandID& right) {
			return left.m == right.m && left.n == right.n;
		}

	}
}


namespace std
{
	template<>
	struct hash<MPFW::Console::CommandID>
	{
		typedef MPFW::Console::CommandID argument_type;
		typedef std::size_t result_type;
		result_type operator()(argument_type const& in) const
		{
			std::string t;
			t = in.n + (in.m == MPFW::Console::QUAKE ? "QUAKE" : "MPFW");
			std::hash<std::string> h;

			return h(t);

		}
	};
}


namespace MPFW{
	namespace Console{

		class CommandHandler {
			CommandHandlerResources* chr;
			std::unordered_map<CommandID, std::function<void(std::vector<std::string>,CommandHandlerResources*, std::string*)>> functionMap;
		public:
			
			[[deprecated("Never initialize an empty command handler")]]
			CommandHandler() { throw; }

			CommandHandler(CommandHandlerResources* chr);

			std::vector<std::string> parseCommand(std::string s);

			std::string logStr;
			void Run(std::string command, bool verbose = true);
			void RunScript(std::string path);



			~CommandHandler();
		};
	}
}



