
class LuaScriptManager //this is a completly new coding style for me
{
public:	
	
	class LuaScript : public ScriptImpClass
	{
		
		void Created(GameObject *obj);
		void Destroyed(GameObject *obj);
		void Killed(GameObject *obj,GameObject *shooter);
		void Damaged(GameObject *obj,GameObject *damager,float damage);
		void Custom(GameObject *obj,int message,int param,GameObject *sender);
		void Enemy_Seen(GameObject *obj,GameObject *seen);
		void Action_Complete(GameObject *obj,int action,ActionCompleteReason reason);
		void Timer_Expired(GameObject *obj,int number);
		void Animation_Complete(GameObject *obj,const char *anim);
		void Poked(GameObject *obj,GameObject *poker);
		void Entered(GameObject *obj,GameObject *enter);
		void Exited(GameObject *obj,GameObject *exit);
	};
	struct Script
	{
		ScriptRegistrant<LuaScript> *scriptreg;
		lua_State *lua;
		int uRef;
		char Name[256];
		char Param[256];
	};
	
	static Script *Scripts[256];
	static ScriptImpClass *Get_Script(GameObject *obj, int scriptID);
	static bool Report_Errors(lua_State *L, int status);
	static void RegisterScriptFunctions(lua_State *L);

	static int Lua_DestroyScript_Wrap(lua_State *L);
	static int Lua_Get_Float_Parameter_Wrap(lua_State *L);
	static int Lua_Get_Int_Parameter_Wrap(lua_State *L);
	static int Lua_Get_String_Parameter_Wrap(lua_State *L);
	static int Lua_Start_Timer_Wrap(lua_State *L);

	

	static void Load();
	static int Register_Script(lua_State *L);
	static void Lua_DestroyScript(GameObject *obj, int scriptID);
	static float Lua_Get_Float_Parameter(GameObject *obj, int scriptID, const char *Name);
	static int Lua_Get_Int_Parameter(GameObject *obj, int scriptID, const char *Name);
	static const char *Lua_Get_String_Parameter(GameObject *obj, int scriptID, const char *Name);
	static void Lua_Start_Timer(GameObject *obj, int scriptID, float Time, int Number);
	static void Cleanup();
};

class LuaManager
{
	
	static lua_State *Lua[256];
public:
	static void Load();
	static void ShowBanner();
	static void LoadLua(const char *LuaFile);
	static void Cleanup();
	static void Call_Load();
	static void Call_Unload();
	static void Call_Host_Hook(int ID, int Type, const char *Msg);
	static void Call_Player_Join_Hook(int ID, const char *Nick);
	static void Call_Player_Leave_Hook(int ID);
	static void Call_Level_Loaded_Hook();
	static void Call_GameOver_Hook();
	static void Call_Console_Output_Hook(const char *Output);
	static void Call_Version_Hook(int ID, float Ver);
	static void Call_DDE_Hook(const char *DDEStr);

	static void Call_Serial_Hook(int ID, const char *Serial);
	static void Call_LoadingE_Hook(int ID, bool Loaded);
	static bool Call_Damage_Hook(int ID, int Damager, int Target, float Damage, unsigned int Warhead);
	static bool Call_Chat_Hook(int ID, int Type, WideStringClass &Message, int Target);
	static void Call_Ping_Hook(int ID, int Ping);
	static bool Call_Suicide_Hook(int ID);
	static bool Call_Radio_Hook(int Team, int PlayerId, int a, int RadioId, int b);
	static void Call_Think_Hook();

	static bool Report_Errors(lua_State *L, int status);
	static void Purchase_Hook(BaseControllerClass *base, GameObject *purchaser, unsigned int cost, unsigned int preset,unsigned int purchaseret,const char *data);
	static void Call_Object_Hook(void *data, GameObject *obj);
	static void CallInvoke(const char *Function, const char *Arg);
	static void CallHostCallback(const char *Data, const char *Host);
	static void Reload_All();

	static bool Reload_Flag;

};

class LuaSocketManager
{
	static TCPSocket *Sockets[64];
	static int Upload_State;
	static int Upload_Error;

	struct UploadIfo
	{
		char Host[256];
		int Port;
		char LocalFile[256];
		char RemoteFile[256];
		char Username[256];
		char Password[256];
	};

public:
	static void Load();
	static void Cleanup();

	static int Connect(const char *IP, int port);
	static int Server(const char *IP, int port);
	static int Accept(int Socket);
	static int Recv(int Socket, char *Data, int Length);
	static int Send(int Socket, const char *Data);
	static int Is_DataAvaliable(int Socket);
	static int Is_ClientWaiting(int Socket);
	static void Disconnect(int Socket);	
	static int Lua_Connect_Wrap(lua_State *L);
	static int Lua_Server_Wrap(lua_State *L);
	static int Lua_Accept_Wrap(lua_State *L);
	static int Lua_Send_Wrap(lua_State *L);
	static int Lua_Recv_Wrap(lua_State *L);
	static int Lua_DataAvaliable_Wrap(lua_State *L);
	static int Lua_ClientWaiting_Wrap(lua_State *L);
	static int Lua_Disconnect_Wrap(lua_State *L);
	static void Register(lua_State *L);
	static DWORD __stdcall Upload(void *x);
	static int Lua_Upload(lua_State *L);
	static int Lua_Check_Upload(lua_State *L);
	static int Lua_Check_Upload_Error(lua_State *L);
	
};


#define lua_boxpointer(L,u) \
	(*(void **)(lua_newuserdata(L, sizeof(void *))) = (u))

#define lua_unboxpointer(L,i)	(*(void **)(lua_touserdata(L, i)))