#include "help.h"
#include "../exceptions/exceptions.h"

#include <algorithm>

using namespace std;

const char* file_cmd_help="help.xml";
HelpLoader::t_cmdhelp HelpLoader::cmdHelp;
string HelpLoader::overview="\n";
bool HelpLoader::enabled=false;


ostream& CommandHelpArgument::print(ostream& o) const
{
	o<<name<<" - "<<desc<<endl;
	return o;
}

ostream& CommandHelp::print(ostream& o) const
{
	o<<"Command : "<<name<<endl;
	o<<"Description : "<<desc<<endl;
	o<<"Usage : "<<usage<<endl;
	for(t_args::const_iterator it=args.begin();it!=args.end();it++)
        o<<*it;
	return o;
}

void HelpLoader::loadCommandHelp()
{
	cmdHelp.clear();
	TiXmlDocument doc(file_cmd_help);
	if (!doc.LoadFile())
	{
		string s="Loading of file ";
		s.append(file_cmd_help);
		s.append(" failed : ");
		s.append(doc.ErrorDesc());
		throw new ExceptionIO(file_cmd_help,true);
	}
	if (doc.FirstChild())
	{
		for(TiXmlNode* node=doc.FirstChild()->FirstChild();node;node=node->NextSibling())
		{
			if (node->Type()==TiXmlNode::ELEMENT)
			{
				TiXmlElement *e=node->ToElement();
				if (!strcmp(e->Value(),"command"))
				{
					string name=e->Attribute("name");
					string usage=e->Attribute("usage");
					string desc=e->Attribute("desc");
					string shortDesc=e->Attribute("shortDesc");
					CommandHelp::t_args lst;
					for(TiXmlNode* arg=node->FirstChild();arg;arg=arg->NextSibling())
					{
						if (arg->Type()==TiXmlNode::ELEMENT)
						{
							TiXmlElement *eArg=arg->ToElement();
							if (!strcmp(eArg->Value(),"arg"))
							{
								string argName=eArg->Attribute("name");
								string argDesc=eArg->Attribute("desc");
								lst.push_back(CommandHelpArgument(argName,argDesc));
							}
						}
					}
					cmdHelp.push_back(CommandHelp(name,usage,desc,shortDesc,lst));
				}
				if (!strcmp(e->Value(),"overview"))
				{
					overview=e->FirstChild()->Value();
				}
			}
		} 
	}
	sort(cmdHelp.begin(),cmdHelp.end());
	enabled=true;
}

const CommandHelp& HelpLoader::getCommandHelp(const string& cmdName)
{
	for(t_cmdhelp::const_iterator it=cmdHelp.begin();it!=cmdHelp.end();it++)
	{
        if ((*it)==cmdName) return *it;
	}
	throw new Exception("HelpLoader","No such command %s.",cmdName.c_str());
}

void HelpLoader::getAllCommands(ostream& o)
{
	o<<overview;
	for(t_cmdhelp::const_iterator it=cmdHelp.begin();it!=cmdHelp.end();it++)
	{
		string name=(*it).getName();
		int length=name.length();
		if (length<20) 
			for(int i=0;i<20-length;i++)
				name.push_back(' ');
		o<<name<<" "<<(*it).getShortDescr()<<endl;
	}
	o<<endl;
}