#ifndef _HELP_H_

#include "../tinyxml/tinyxml.h"

#include <string>
#include <ostream>
#include <list>
#include <vector>

using namespace std;

/**
 * \brief Represent help on command argument.
 * 
 * \date 01-29-2006
 *
 * \author Onrej Svejdar
 *
 * \todo 
 *
 * \bug 
 *
 */
class CommandHelpArgument
{
	string name;
	string desc;
	ostream& print(ostream& o) const;
public:
	/**
	 * \brief ctor
	 * \param name name of argument
	 * \param desc argument description
	 */
	inline CommandHelpArgument(const string& name,const string& desc):name(name),desc(desc) {}
	inline CommandHelpArgument& operator=(const CommandHelpArgument& arg)
	{
		name=arg.name;
		desc=arg.desc;
	}
	friend ostream& operator<<(ostream& o,const CommandHelpArgument& arg)
	{
		return arg.print(o);
	}
};

/**
 * \brief Represent help on command.
 * 
 * \date 01-29-2006
 *
 * \author admin
 *
 * \todo 
 *
 * \bug 
 *
 */
class CommandHelp
{
public:
	typedef list<CommandHelpArgument> t_args;
private:
	string name;
	string usage;
	string shortDesc;
	string desc;
	t_args args;
	ostream& print(ostream& o) const;
public:
	/**
	 * \brief ctor
	 * \param name name of command 
	 * \param usage typical usage of command
	 * \param desc  command description
	 * \param shortDesc command short description (for help list)
	 * \param args arguments help
	 * \return 
	 */
	inline CommandHelp(const string& name,const string& usage,const string& desc,const string& shortDesc,const t_args& args):name(name),usage(usage),desc(desc),shortDesc(shortDesc),args(args) {}
	inline CommandHelp& operator=(const CommandHelp& cmd)
	{
		name=cmd.name;
		usage=cmd.usage;
		desc=cmd.desc;
		args=cmd.args;
		shortDesc=cmd.shortDesc;
		return *this;
	}
	inline bool operator==(const string& name) const
	{
		return this->name==name;
	}

	/**
	 * \brief return name of command
	 * \return name of command
	 */
	inline const string& getName() const
	{
		return name;
	}

	/**
	 * \brief return short description of command (will be used in helps list)
	 * \return short description
	 */
	inline const string& getShortDescr() const
	{
		return shortDesc;
	}

	/**
	 * \brief return typical usage of command
	 * \return typical usage
	 */
	inline const string& getUsage() const
	{
		return usage;
	}

	inline bool operator<(const CommandHelp& cmd) const
	{
		return this->name<cmd.name;
	}
	friend ostream& operator<<(ostream& o,const CommandHelp& cmd)
	{
		return cmd.print(o);
	}
};

/**
 * \brief Support for "helps" command.
 * 
 * \date 01-29-2006
 *
 * \author admin
 *
 * \todo 
 *
 * \bug 
 *
 */
class HelpLoader
{
public:
	typedef vector<CommandHelp> t_cmdhelp;
private:
	static bool enabled;
	static string overview;
	static t_cmdhelp cmdHelp;
public:
	/**
	 * \brief load help from file
	 */
	static void loadCommandHelp();
	
	/**
	 * \brief return help on specific command
	 * \param cmdName name of command
	 */
	static const CommandHelp& getCommandHelp(const string& cmdName);

	/**
	 * \brief Writes overall help into the output stream.
	 * \param o output stream 
	 */
	static void getAllCommands(ostream& o);
	
	
	/**
	 * \brief Return true if help is enabled (help file was found and loaded).
	 * \return true if help is enabled.
	 */
	static bool isHelpEnabled()
	{
		return enabled;
	}
};

#endif/*_HELP_H_*/
