#ifndef _COMMANDS_H
#define _COMMANDS_H

#include "Engine.h"

namespace Engine {

class Module;

/** \brief The callback signature for commands */
typedef bool (*command_cb) (std::vector<std::string>);

/** \brief Contains all the facilities to parse/add/execute/... commands
 *
 *	\todo make the command system case insensitive
 *
 *	This system is mainly used for passing instructions to the Model and
 *	modifying it in this way. Commands can be added with a name (string) and a
 *	function (callback). It also contains a CommandQueue to faciliate delayed
 *	execution of commands and also does the parsing of functions passed to it.
 *
 *  Functions that should be callable by the Commands module must have the
 *  following signature:
 *  \code
 *  bool MyFunc_cmd (std::vector<std::string> args);
 *  \endcode
 *	To keep things readable one is advised to add \c _cmd at the end of the
 *	function so that it is clear that this function is meant to be called by
 *	the Commands module.
 *
 *	Scope: Globally visible (since commands must be added)
 *
  */
class Commands : public Module { 
	public:
		/** \brief Adds the function callback as command for the given name*/
		void AddCommand (const std::string &name, command_cb callback);
		/** \brief Executes the given command immediately */
		bool RunCommand (const std::string &command);
		/** \brief Adds the given command to the command queue */
		void QueueCommand (const std::string &command);
		/** \brief Executes the command queue */
		bool QueueExecute ();
		/** \brief When a command fails it sets the error with this function */
		void SetErrorString (const std::string &error_str);
		/** \brief Returns the error string */
		std::string GetErrorString ();

	protected:
		/** \brief Initializes the system */
		virtual int OnInit (int argc, char* argv[]);
		/** \brief Destroys the system (must be called!) */
		virtual void OnDestroy ();
		/** \brief Registers commands relevant to the Command system */
		virtual void OnRegisterCommands ();	

		/** \brief All registered commands are in this map */
		std::map<std::string, command_cb> mCommandsCallbacks;
		/** \brief Queue for the commands */
		std::queue<std::string> mCommandQueue;
		/** \brief Holds the error message of a failed command */
		std::string mErrorString;

	private:
		std::string GetCommandName (const std::string &command);
		std::vector<std::string> ParseArgs (std::string &argument_str);
};

}
#endif // _COMMANDS_H
