#pragma once

#include "ParamList.h"

#define FUNC_EndOfList	L"EndOfList"

typedef BOOL (*TYPE_FUNC)(CParamList*);

struct TableFuncEntry
{
	CString		szFuncName;		// function name
	TYPE_FUNC	pFunc;			// function pointer
	CParamList* pParamList;		// function parameters
};

class CFuncList
{
public:
	CFuncList(void);
	~CFuncList(void);

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Add function to list.  Duplicate functions are allowed.
	///
	///	\param	[IN] szFunction:	
	///			Function to add
	///
	///	\return	TRUE if function successfully added to list, FALSE otherwise			
	///
	///////////////////////////////////////////////////////////////////////////////
	BOOL Add(CString szType, CString szFunction, CParamList* pParams = NULL);

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Remove all functions from list
	///
	///	\return	TRUE if all functions successfully removed from list, FALSE otherwise			
	///
	///////////////////////////////////////////////////////////////////////////////
	BOOL RemoveAll(void);

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Find function in list
	///
	///	\param	[IN] szFunction:	
	///			Function to search for
	///
	///	\return	TRUE function is in list, FALSE otherwise			
	///
	///////////////////////////////////////////////////////////////////////////////
	BOOL Find(CString szFunction);

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Get function name at specified index
	///
	///	\param	[IN] nIndex
	///			Index of function
	/// 
	/// \param	[OUT] pszType
	///			Type of function
	///
	///	\return	Function at specified index.  NULL string if empty.		
	///
	///////////////////////////////////////////////////////////////////////////////
	CString GetFunctionName(UINT nIndex, CString* pszType = NULL);

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Get total number of functions in list
	///
	///	\return	Total number of functions in list			
	///
	///////////////////////////////////////////////////////////////////////////////
	int GetCount(void);

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Copy functions to specified list
	/// 
	/// \param	[OUT] pFuncList
	///			Copy functions to this list
	///
	///	\return	TRUE if functions successfully copied, FALSE otherwise		
	///
	///////////////////////////////////////////////////////////////////////////////
	BOOL Copy(CFuncList* pFuncList);

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Retrieve the list of parameters for the specified function 
	/// TODO: Need to add support for duplicate function names.  Currently acts on
	/// the first match.
	/// 
	/// \param	[IN] szFunction
	///			Name of function of interest
	/// 
	/// \param	[OUT] sFuncParams
	///			List of parameters for the specified function
	///
	///	\return	TRUE if list of parameters successfully retrieved, FALSE otherwise		
	///
	///////////////////////////////////////////////////////////////////////////////
	BOOL GetFuncParams(CString szFunction, CParamList &sFuncParams);

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Save the list of parameters for the specified function.  
	/// TODO: Need to add support for duplicate function names.  Currently acts on
	/// the first match.
	/// 
	/// \param	[IN] szFunction
	///			Name of function of interest
	/// 
	/// \param	[IN] pFuncParams
	///			List of parameters to save for the specified function
	///
	///	\return	TRUE if list of parameters successfully saved, FALSE otherwise		
	///
	///////////////////////////////////////////////////////////////////////////////
	BOOL SetFuncParams(CString szFunction, CParamList* pFuncParams);

protected:

	///////////////////////////////////////////////////////////////////////////////
	///
	///	Each function in the list contains the function name and a list of
	/// parameters for that function.
	/// 
	/// \param	szName
	///			Name of function
	/// 
	/// \param	sParams
	///			Parameters associated with the function
	///
	///////////////////////////////////////////////////////////////////////////////
	typedef struct STRUCT_Function
	{
		CString szType;
		CString szName;
		CParamList sParams;
	};

	// List of functions
	CList <STRUCT_Function, STRUCT_Function&> m_FuncList;
};
