/***************************************************************************
 *   Copyright (C) 2003 by Dan Muller                                      *
 *   dan@verliba.cz                                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/
#ifndef NCMDRCCOMMAND_H
#define NCMDRCCOMMAND_H

#include "cpcre.h"

using namespace nUtils;
using std::ostream;
using std::string;

namespace nCmdr {

/**
describes how commmand should be recognized an then how it should be treated

@author Daniel Muller
*/
class cCommand
{
friend class cCmdr;
public:
	/**
		A function calling structure for the commander
	*/
	struct sCmdFunc
	{
		string mIdStr;
		string mParStr;
		cPCRE * mIdRex;
		cPCRE * mParRex;
		ostream *mOS;
		cCommand *mCommand;

		void *mExtra;
		sCmdFunc():mIdRex(NULL), mParRex(NULL), mOS(NULL), mCommand(NULL){}

      // this is an executive function of a command
		virtual bool operator() (void) = 0;
		virtual bool operator() (cPCRE &idrex, cPCRE &parrex, ostream &os, void *extra)
		{
			mIdRex = &idrex;
			mParRex = &parrex;
			mExtra = extra;
			mOS = &os;
			return operator()();
		}

		virtual bool PartFound(int rank)
		{
			return this->mParRex->PartFound(rank);
		}
		
		virtual bool GetParStr(int rank, string &dest)
		{
			if(! this->mParRex->PartFound(rank)) return false;
			this->mParRex->Extract(rank, this->mParStr, dest);
			return true;
		}

		virtual bool GetParInt(int rank, int &dest)
		{
			string tmp;
			if (!GetParStr(rank, tmp)) return false;
			dest = atoi(tmp.data());
			return true;			
		}

		virtual bool GetParLong(int rank, long &dest)
		{
			string tmp;
			if (!GetParStr(rank, tmp)) return false;
			dest = atoi(tmp.data());
			return true;			
		}
		
		virtual bool GetIDStr (int rank, string &dest)
		{
			if(! this->mIdRex->PartFound(rank)) return false;
			this->mIdRex->Extract(rank, this->mIdStr, dest);
			return true;
		}

		int StringToIntFromList(const string &str,const char *stringlist[], const int intlist[], int item_count);
	};

	cCommand(int ID, const char *IdRegex, const char *, sCmdFunc*);
	cCommand();
	~cCommand();
	virtual void Init(int ID, const char *IdRegex, const char *, sCmdFunc*);
	bool TestID(const string &cmd_line);
	bool TestParams();
	bool Execute(ostream &output, void *extrapar);
	virtual void Init(void *){};
	virtual void ListCommands(ostream &os);
	void GetParamSyntax(ostream &os);
	cCmdr *mCmdr;
protected:
	int mID;
	cPCRE mIdentificator;
	cPCRE mParamsParser;
	sCmdFunc *mCmdFunc;
	string mIdStr;
	string mParStr;
	string mIdRegexStr;
	string mParRegexStr;
};

};

#endif
