/*!
	ManagedInterfaceMacro.h - マネージャインタフェース用マクロ

	DEFINE_MANAGED_INTERFACE_IMPLEMENT
	DEFINE_MANAGED_INTERFACE_ACCESS
	上記を定義して繰り返しインクルードされる
*/


//	宣言を解除しておく
#undef START_MANAGED_INTERFACE_DEFINE
#undef END_MANAGED_INTERFACE_DEFINE
#undef DEFINE_INTERFACE_METHOD_ARG0
#undef DEFINE_INTERFACE_METHOD_ARG1
#undef DEFINE_INTERFACE_METHOD_ARG2
#undef DEFINE_INTERFACE_METHOD_ARG3
#undef DEFINE_INTERFACE_METHOD_ARG4
#undef DEFINE_INTERFACE_METHOD_ARG0_VOID
#undef DEFINE_INTERFACE_METHOD_ARG1_VOID
#undef DEFINE_INTERFACE_METHOD_ARG2_VOID
#undef DEFINE_INTERFACE_METHOD_ARG3_VOID
#undef DEFINE_INTERFACE_METHOD_ARG4_VOID


/*!
	DEFINE_MANAGED_INTERFACE_IMPLEMENT を定義した場合

	インプリメント用のマクロが定義される
*/
#ifdef DEFINE_MANAGED_INTERFACE_IMPLEMENT
	#include "ManagedInterfaceImplement.h"

	/////////////////////////////////////////////////////////////////////////////////////////////
	//	インタフェース宣言
	/////////////////////////////////////////////////////////////////////////////////////////////
	#define	START_MANAGED_INTERFACE_DEFINE(className) \
		class className##Implement : public CManagedInterfaceImplement, public className { \
		public: virtual ~className##Implement(){}; \
		virtual int Dispatch(CString funcName, CManagedInterfaceImplementArgStack args, int checkFunctionExist) { 

	#define	END_MANAGED_INTERFACE_DEFINE() return(-1); } };

	/////////////////////////////////////////////////////////////////////////////////////////////
	//	戻り値有りのメソッド宣言
	/////////////////////////////////////////////////////////////////////////////////////////////
	#define DEFINE_INTERFACE_METHOD_ARG0(ret, func)	\
		if(funcName == #func) { if(!checkFunctionExist) args[0] = func(); return(0); }

	#define DEFINE_INTERFACE_METHOD_ARG1(ret, func, arg1_t, artg1_n)	\
		if(funcName == #func) { if(!checkFunctionExist) args[0] = func(args[1]); return(0); }

	#define DEFINE_INTERFACE_METHOD_ARG2(ret, func, arg1_t, arg1_n, arg2_t, arg2_n)	\
		if(funcName == #func) { if(!checkFunctionExist) args[0] = func(args[1], args[2]); return(0); }

	#define DEFINE_INTERFACE_METHOD_ARG3(ret, func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n)	\
		if(funcName == #func) { if(!checkFunctionExist) args[0] = func(args[1], args[2], args[3]); return(0); }

	#define DEFINE_INTERFACE_METHOD_ARG4(ret, func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n, arg4_t, arg4_n)	\
		if(funcName == #func) { if(!checkFunctionExist)  args[0] = func(args[1], args[2], args[3], args[4]); return(0); }


	/////////////////////////////////////////////////////////////////////////////////////////////
	//	戻り値無しのメソッド宣言
	/////////////////////////////////////////////////////////////////////////////////////////////
	#define DEFINE_INTERFACE_METHOD_ARG0_VOID(func)	\
		if(funcName == #func) { if(!checkFunctionExist) func(); return(0); }

	#define DEFINE_INTERFACE_METHOD_ARG1_VOID(func, arg1_t, artg1_n)	\
		if(funcName == #func) { if(!checkFunctionExist) func(args[1]); return(0); }

	#define DEFINE_INTERFACE_METHOD_ARG2_VOID(func, arg1_t, arg1_n, arg2_t, arg2_n)	\
		if(funcName == #func) { if(!checkFunctionExist) func(args[1], args[2]); return(0); }

	#define DEFINE_INTERFACE_METHOD_ARG3_VOID(func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n)	\
		if(funcName == #func) { if(!checkFunctionExist) func(args[1], args[2], args[3]); return(0); }

	#define DEFINE_INTERFACE_METHOD_ARG4_VOID(func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n, arg4_t, arg4_n)	\
		if(funcName == #func) { if(!checkFunctionExist) func(args[1], args[2], args[3], args[4]); return(0); }

#endif


/*!
	DEFINE_MANAGED_INTERFACE_ACCESS を定義した場合

	アクセス用のマクロが定義される
*/
#ifdef DEFINE_MANAGED_INTERFACE_ACCESS
	#include "ManagedInterfaceAccess.h"
	#include "ManagedInterfaceAccessArgStack.h"

	/////////////////////////////////////////////////////////////////////////////////////////////
	//	インタフェース宣言
	/////////////////////////////////////////////////////////////////////////////////////////////
	#define	START_MANAGED_INTERFACE_DEFINE(className) \
		class className##Access : public CManagedInterfaceAccess { \
		public: MANAGED_INTERFACE_COMMON_CONSTRUCTOR(className##Access);

	#define	END_MANAGED_INTERFACE_DEFINE() };


	/////////////////////////////////////////////////////////////////////////////////////////////
	//	戻り値有りのメソッド宣言
	/////////////////////////////////////////////////////////////////////////////////////////////
	#define DEFINE_INTERFACE_METHOD_ARG0(ret, func)	\
	ret func() \
	{ ret retVal; CManagedInterfaceAccessArgStack args; args.AddArg(&retVal); Invoke(#func, args); return retVal; };

	#define DEFINE_INTERFACE_METHOD_ARG1(ret, func, arg1_t, artg1_n)	\
	ret func(arg1_t arg1_n) \
	{ ret retVal; CManagedInterfaceAccessArgStack args; args.AddArg(&retVal);  args.AddArg(arg1_n); Invoke(#func, args);  return retVal; };

	#define DEFINE_INTERFACE_METHOD_ARG2(ret, func, arg1_t, arg1_n, arg2_t, arg2_n)	\
	ret func(arg1_t arg1_n, arg2_t arg2_n) \
	{ ret retVal; CManagedInterfaceAccessArgStack args; args.AddArg(&retVal);  args.AddArg(arg1_n);  args.AddArg(arg2_n); Invoke(#func, args);  return retVal; };

	#define DEFINE_INTERFACE_METHOD_ARG3(ret, func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n)	\
	ret func(arg1_t arg1_n, arg2_t arg2_n, arg3_t arg3_n) \
	{ ret retVal; CManagedInterfaceAccessArgStack args; args.AddArg(&retVal);  args.AddArg(arg1_n);  args.AddArg(arg2_n); args.AddArg(arg3_n); Invoke(#func, args);  return retVal; };

	#define DEFINE_INTERFACE_METHOD_ARG4(ret, func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n, arg4_t, arg4_n)	\
	ret func(arg1_t arg1_n, arg2_t arg2_n, arg3_t arg3_n, arg4_t arg4_n) \
	{ ret retVal; CManagedInterfaceAccessArgStack args; args.AddArg(&retVal);  args.AddArg(arg1_n);  args.AddArg(arg2_n); args.AddArg(arg3_n); args.AddArg(arg4_n); Invoke(#func, args);  return retVal; };


	/////////////////////////////////////////////////////////////////////////////////////////////
	//	戻り値無しのメソッド宣言
	/////////////////////////////////////////////////////////////////////////////////////////////
	#define DEFINE_INTERFACE_METHOD_ARG0_VOID(func)	\
	void func() \
	{ CManagedInterfaceAccessArgStack args; args.AddEmptyArg(); Invoke(#func, args); };

	#define DEFINE_INTERFACE_METHOD_ARG1_VOID(func, arg1_t, arg1_n)	\
	void func(arg1_t arg1_n) \
	{ CManagedInterfaceAccessArgStack args; args.AddEmptyArg(); args.AddArg(arg1_n); Invoke(#func, args); };

	#define DEFINE_INTERFACE_METHOD_ARG2_VOID(func, arg1_t, arg1_n, arg2_t, arg2_n)	\
	void func(arg1_t arg1_n, arg2_t arg2_n) \
	{ CManagedInterfaceAccessArgStack args; args.AddEmptyArg(); args.AddArg(arg1_n);  args.AddArg(arg2_n); Invoke(#func, args); };

	#define DEFINE_INTERFACE_METHOD_ARG3_VOID(func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n)	\
	void func(arg1_t arg1_n, arg2_t arg2_n, arg3_t arg3_n) \
	{ CManagedInterfaceAccessArgStack args; args.AddEmptyArg();  args.AddArg(arg1_n);  args.AddArg(arg2_n); args.AddArg(arg3_n); Invoke(#func, args); };

	#define DEFINE_INTERFACE_METHOD_ARG4_VOID(func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n, arg4_t, arg4_n)	\
	void func(arg1_t arg1_n, arg2_t arg2_n, arg3_t arg3_n, arg4_t arg4_n) \
	{ CManagedInterfaceAccessArgStack args; args.AddEmptyArg();  args.AddArg(arg1_n);  args.AddArg(arg2_n); args.AddArg(arg3_n); args.AddArg(arg4_n); Invoke(#func, args); };
#endif


/*!
	DEFINE_MANAGED_INTERFACE_IMPLEMENT, DEFINE_MANAGED_INTERFACE_ACCESS 共に未定義

	基本クラス定義用マクロが定義される
*/
#ifndef DEFINE_MANAGED_INTERFACE_IMPLEMENT
#ifndef DEFINE_MANAGED_INTERFACE_ACCESS

	/////////////////////////////////////////////////////////////////////////////////////////////
	//	インタフェース宣言
	/////////////////////////////////////////////////////////////////////////////////////////////
	#define	START_MANAGED_INTERFACE_DEFINE(className) class className { public:
	#define	END_MANAGED_INTERFACE_DEFINE() };


	/////////////////////////////////////////////////////////////////////////////////////////////
	//	戻り値有りのメソッド宣言
	/////////////////////////////////////////////////////////////////////////////////////////////
	#define DEFINE_INTERFACE_METHOD_ARG0(ret, func)	\
			virtual ret func() = 0;

	#define DEFINE_INTERFACE_METHOD_ARG1(ret, func, arg1_t, arg1_n)	\
			virtual ret func(arg1_t arg1_n) = 0;

	#define DEFINE_INTERFACE_METHOD_ARG2(ret, func, arg1_t, arg1_n, arg2_t, arg2_n)	\
			virtual ret func(arg1_t arg1_n, arg2_t arg2_n) = 0;

	#define DEFINE_INTERFACE_METHOD_ARG3(ret, func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n)	\
			virtual ret func(arg1_t arg1_n, arg2_t arg2_n, arg3_t arg3_n) = 0;

	#define DEFINE_INTERFACE_METHOD_ARG4(ret, func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n, arg4_t, arg4_n)	\
			virtual ret func(arg1_t arg1_n, arg2_t arg2_n, arg3_t arg3_n, arg4_t arg4_n) = 0;


	/////////////////////////////////////////////////////////////////////////////////////////////
	//	戻り値無しのメソッド宣言
	/////////////////////////////////////////////////////////////////////////////////////////////
	#define DEFINE_INTERFACE_METHOD_ARG0_VOID(func)	\
			virtual void func() = 0;

	#define DEFINE_INTERFACE_METHOD_ARG1_VOID(func, arg1_t, arg1_n)	\
			virtual void func(arg1_t arg1_n) = 0;

	#define DEFINE_INTERFACE_METHOD_ARG2_VOID(func, arg1_t, arg1_n, arg2_t, arg2_n)	\
			virtual void func(arg1_t arg1_n, arg2_t arg2_n) = 0;

	#define DEFINE_INTERFACE_METHOD_ARG3_VOID(func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n)	\
			virtual void func(arg1_t arg1_n, arg2_t arg2_n, arg3_t arg3_n) = 0;

	#define DEFINE_INTERFACE_METHOD_ARG4_VOID(func, arg1_t, arg1_n, arg2_t, arg2_n, arg3_t, arg3_n, arg4_t, arg4_n)	\
			virtual void func(arg1_t arg1_n, arg2_t arg2_n, arg3_t arg3_n, arg4_t arg4_n) = 0;
#endif
#endif
