#pragma once

namespace SystemPack
{
	typedef CArray<CPatch_Symbol*> TPatchParameters;
	typedef CPatch_Symbol* (__cdecl * TPatch_ExecutableFunc) (TPatchParameters&);




	struct ASTAPI TPatch_FuncDescriptor
	{
		CString					 sName;
		TPatch_ExecutableFunc	 pFuncExec;
		TTypeDescriptor*		 pFuncType;
		CArray<TTypeDescriptor*> arrParmTypes;

		TPatch_FuncDescriptor (const CString& name, TPatch_ExecutableFunc func, TTypeDescriptor* types);
		void InsertParameter  (TTypeDescriptor* parm);
	};




	class ASTAPI CPatch_Function : public CObject
	{
		friend class CPatch_Stack;
		static CArray<const TPatch_FuncDescriptor*> arrFuncDescriptors;

	protected:

		CPatch_Function();
		void SetDescriptor(const TPatch_FuncDescriptor* desc);

		COBJECT_CLASS_DELARATE( CPatch_Function );
		virtual void Archive	(CArchiver&) { };
		virtual void Unarchive  (CArchiver&) { };

	public:

		const TPatch_FuncDescriptor*	pDescriptor;
		CArray<CPatch_Symbol*>			arrParameters;

		static	CPatch_Function*		CreateFunction	 (const CString& name);
		static	void					RegisterFunction (const CString& name, TPatch_ExecutableFunc func, TTypeDescriptor* types ...); // name, return type, arguments type
				CString					GetName			 ();
				CString					GetFullName		 ();
				TPatch_ExecutableFunc	GetFunction		 ();
				TTypeDescriptor*		GetType			 ();
				void					PushParameter	 (CPatch_Symbol* sym);
				CPatch_Symbol*			Execute			 ();
				void					CreateParameters (const CString& line);
									   ~CPatch_Function	 ();
	};


}