/* * * * * * * * * * * * * * * * 
 * 	 ______     __  __     ______     __  __     ______     ______     __  __    
 *	/\  __ \   /\ \/\ \   /\  == \   /\ \_\ \   /\  __ \   /\  ___\   /\ \/ /    
 *	\ \ \/\ \  \ \ \_\ \  \ \  __<   \ \  __ \  \ \  __ \  \ \ \____  \ \  _"-.  
 *	 \ \_____\  \ \_____\  \ \_____\  \ \_\ \_\  \ \_\ \_\  \ \_____\  \ \_\ \_\ 
 *	  \/_____/   \/_____/   \/_____/   \/_/\/_/   \/_/\/_/   \/_____/   \/_/\/_/ 
 *
 *  - Version : 3L
 *  - By Oubliette
 * * * * * * * * * * * * * * * */

#ifndef _LUA_INTERFACE

#define _LUA_INTERFACE

//#include "oubhack_iluaobject.h"
#include "main.h"

class ILuaObject;

#define LUA_FUNCTION( _function_ ) int _function_( lua_State* L )

struct lua_State;

struct UserData
{
	void*			data;
	unsigned char	type;
};

// ======================= TYPEDEFS ======================= //

typedef bool		( __thiscall* RunStringFn )				( void*, const char*, const char*, const char*, bool, bool );
typedef bool		( __thiscall* RunStringExFn )			( void*, const char*, const char*, const char*, bool, bool, bool );
typedef void		( __thiscall* MsgFn )					( void*, const char* );
typedef void*		( __thiscall* NewGlobalTableFn )		( void*, const char* );
typedef void*		( __thiscall* SetFieldFn )				( void*, int, const char* );
typedef void*		( __thiscall* GetFieldFn )				( void*, int, const char* );
typedef const char*	( __thiscall* GetStringFn )				( void*, int, unsigned int* );
typedef double		( __thiscall* GetNumberFn )				( void*, int );
typedef bool		( __thiscall* GetBoolFn )				( void*, int );
typedef void*		( __thiscall* GetCFunctionFn )			( void*, int );
typedef void*		( __thiscall* GetUserdataFn )			( void*, int );
typedef ILuaObject*	( __thiscall* GetReturnFn )				( void*, int );
typedef const char*	( __thiscall* CallInternalGetStringFn )	( void*, int );


typedef void*		( __thiscall* CallFn )					( void*, int, int );
typedef void*		( __thiscall* PCallFn )					( void*, int, int, int );

typedef bool		( __thiscall* IsServerFn )				( void* );
typedef bool		( __thiscall* IsClientFn )				( void* );

typedef void*		( __thiscall* PushStringFn )			( void*, const char*, unsigned int* );
typedef void*		( __thiscall* PushNumberFn )			( void*, double );
typedef void*		( __thiscall* PushBoolFn )				( void*, bool );
typedef void*		( __thiscall* PushCFunctionFn )			( void*, void* );
typedef void*		( __thiscall* PushCClosureFn )			( void*, void*, int );
typedef void*		( __thiscall* PushUserdataFn )			( void*, void* );
typedef void*		( __thiscall* PushFn )					( void*, int );
typedef void*		( __thiscall* PushLongFn )				( void*, long );
typedef void*		( __thiscall* PushNilFn )				( void* );
typedef void*		( __thiscall* PushLuaFunctionFn )		( void*, void* );

typedef void*		( __thiscall* ReferencePushFn )			( void*, int );
typedef int			( __thiscall* ReferenceCreateFn )		( void* );
typedef void*		( __thiscall* ReferenceFreeFn )			( void*, int );

typedef int			( __thiscall* GetTypeFn )				( void*, int );
typedef const char*	( __thiscall* GetTypeNameFn )			( void*, int );

typedef void*		( __thiscall* NextFn )					( void*, int );

typedef void*		( __thiscall* PopFn )					( void*, int );

typedef void*		( __thiscall* SetTableFn )				( void*, int );
typedef void*		( __thiscall* GetTableFn )				( void*, int );
typedef bool		( __thiscall* IsTypeFn )				( void*, int, int );
typedef void*		( __thiscall* CheckTypeFn )				( void*, int, int );

typedef void*		( __thiscall* CreateTableFn )			( void* );

typedef lua_State*	( __thiscall* GetLuaStateFn )			( void* );

// ======================= INDICES ======================= //


#define INDEX_LUAINTERFACE_RUNSTRING			88
#define INDEX_LUAINTERFACE_RUNSTRINGEX			106
#define INDEX_LUAINTERFACE_MSG					96		
#define INDEX_LUAINTERFACE_NEWGLOBALTABLE		64
#define INDEX_LUAINTERFACE_PUSHSTRING			29
#define INDEX_LUAINTERFACE_PUSHNUMBER			30
#define INDEX_LUAINTERFACE_PUSHBOOL				31
#define INDEX_LUAINTERFACE_PUSHCFUNCTION		32
#define INDEX_LUAINTERFACE_PUSHCCLOSURE			33
#define INDEX_LUAINTERFACE_PUSHUSERDATA			34
#define INDEX_LUAINTERFACE_PUSH					1
#define INDEX_LUAINTERFACE_PUSHLONG				82
#define INDEX_LUAINTERFACE_PUSHNIL				28
#define INDEX_LUAINTERFACE_PUSHLUAFUNCTION		55
#define INDEX_LUAINTERFACE_GETFIELD				4
#define INDEX_LUAINTERFACE_SETFIELD				5
#define INDEX_LUAINTERFACE_GETSTRING			23
#define INDEX_LUAINTERFACE_GETNUMBER			24
#define INDEX_LUAINTERFACE_GETBOOL				25
#define INDEX_LUAINTERFACE_GETCFUNCTION			26
#define INDEX_LUAINTERFACE_GETUSERDATA			27
#define INDEX_LUAINTERFACE_GETRETURN			69
#define INDEX_LUAINTERFACE_CALLINTERNALGETSTRING 61
#define INDEX_LUAINTERFACE_CALL					10
#define INDEX_LUAINTERFACE_PCALL				11
#define INDEX_LUAINTERFACE_ISSERVER				71
#define INDEX_LUAINTERFACE_ISCLIENT				72
#define INDEX_LUAINTERFACE_REFERENCEPUSH		37
#define INDEX_LUAINTERFACE_REFERENCECREATE		35
#define INDEX_LUAINTERFACE_REFERENCEFREE		36
#define INDEX_LUAINTERFACE_GETTYPE				40
#define INDEX_LUAINTERFACE_GETTYPENAME			41
#define INDEX_LUAINTERFACE_NEXT					16
#define INDEX_LUAINTERFACE_POP					2
#define INDEX_LUAINTERFACE_SETTABLE				7
#define INDEX_LUAINTERFACE_GETTABLE				3
#define INDEX_LUAINTERFACE_ISTYPE				39
#define INDEX_LUAINTERFACE_CHECKTYPE			19
#define INDEX_LUAINTERFACE_CREATETABLE			6
#define INDEX_LUAINTERFACE_GETLUASTATE			49

/*
#define INDEX_LUAINTERFACE_PUSH				1
#define INDEX_LUAINTERFACE_POP					2
#define INDEX_LUAINTERFACE_GETTABLE			3
#define INDEX_LUAINTERFACE_GETFIELD			4
#define INDEX_LUAINTERFACE_SETFIELD			5
#define INDEX_LUAINTERFACE_CREATETABLE			6
#define INDEX_LUAINTERFACE_SETTABLE			7
#define INDEX_LUAINTERFACE_SETMETATABLE		8
#define INDEX_LUAINTERFACE_GETMETATABLE		9
#define INDEX_LUAINTERFACE_CALL				10
#define INDEX_LUAINTERFACE_PCALL				11
#define INDEX_LUAINTERFACE_EQUAL				12
#define INDEX_LUAINTERFACE_RAWEQUAL			13
#define INDEX_LUAINTERFACE_INSERT				14
#define INDEX_LUAINTERFACE_REMOVE				15
#define INDEX_LUAINTERFACE_NEXT				16
#define INDEX_LUAINTERFACE_NEWUSERDATA			17
#define INDEX_LUAINTERFACE_THROWERROR			18
#define INDEX_LUAINTERFACE_CHECKTYPE			20
#define INDEX_LUAINTERFACE_ARGERROR			20
#define INDEX_LUAINTERFACE_RAWGET				21
#define INDEX_LUAINTERFACE_RAWSET				22
#define INDEX_LUAINTERFACE_GETSTRING			23
#define INDEX_LUAINTERFACE_GETNUMBER			24
#define INDEX_LUAINTERFACE_GETBOOL				25
#define INDEX_LUAINTERFACE_GETCFUNCTION		26
#define INDEX_LUAINTERFACE_GETUSERDATA			27
#define INDEX_LUAINTERFACE_PUSHNIL				29
#define INDEX_LUAINTERFACE_PUSHSTRING			29
#define INDEX_LUAINTERFACE_PUSHNUMBER			30
#define INDEX_LUAINTERFACE_PUSHBOOL			31
#define INDEX_LUAINTERFACE_PUSHCFUNCTION		32
#define INDEX_LUAINTERFACE_PUSHCCLOSURE		33
#define INDEX_LUAINTERFACE_PUSHUSERDATA		34
#define INDEX_LUAINTERFACE_REFERENCECREATE		35
#define INDEX_LUAINTERFACE_REFERENCEFREE		36
#define INDEX_LUAINTERFACE_REFERENCEPUSH		37
#define INDEX_LUAINTERFACE_PUSHSPECIAL			38
#define INDEX_LUAINTERFACE_ISTYPE				39
#define INDEX_LUAINTERFACE_GETTYPE				40
#define INDEX_LUAINTERFACE_GETTYPENAME			41
#define INDEX_LUAINTERFACE_CREATEMETATABLETYPE	42
#define INDEX_LUAINTERFACE_CHECKSTRING			43
#define INDEX_LUAINTERFACE_CHECKNUMBER			44
#define INDEX_LUAINTERFACE_OBJLEN				45
#define INDEX_LUAINTERFACE_INIT				47
#define INDEX_LUAINTERFACE_SHUTDOWN			48
#define INDEX_LUAINTERFACE_CYCLE				49
#define INDEX_LUAINTERFACE_GETLUASTATE			50
#define INDEX_LUAINTERFACE_GLOBAL				51
#define INDEX_LUAINTERFACE_GETOBJECT			52
#define INDEX_LUAINTERFACE_DELETE_ME_5437		53
#define INDEX_LUAINTERFACE__DELETE_ME2466		54
#define INDEX_LUAINTERFACE_PUSHLUAOBJECT		55
#define INDEX_LUAINTERFACE_PUSHLUAFUNCTION		56
#define INDEX_LUAINTERFACE_LUAERROR			57
#define INDEX_LUAINTERFACE_TYPEERROR			58
#define INDEX_LUAINTERFACE_CALLINTERNAL		59
#define INDEX_LUAINTERFACE_CALLINTERNALNORETURNS 60
#define INDEX_LUAINTERFACE_CALLINTERNALGETBOOL	61
#define INDEX_LUAINTERFACE_CALLINTERNALGETSTRING 62
#define INDEX_LUAINTERFACE_CALLINTERNALGET		63
#define INDEX_LUAINTERFACE__DELETE_ME			64
#define INDEX_LUAINTERFACE_NEWGLOBALTABLE		65
#define INDEX_LUAINTERFACE_NEWTEMPORARYOBJECT	66
#define INDEX_LUAINTERFACE_ISUSERDATA			67
#define INDEX_LUAINTERFACE_GETMETATABLEOBJECT	69
#define INDEX_LUAINTERFACE_GETRETURN			70
#define INDEX_LUAINTERFACE_ISSERVER			71
#define INDEX_LUAINTERFACE_ISCLIENT			72
#define INDEX_LUAINTERFACE_ISDEDICATEDSERVER	73
#define INDEX_LUAINTERFACE_DESTROYOBJECT		74
#define INDEX_LUAINTERFACE_CREATEOBJECT		75
#define INDEX_LUAINTERFACE_SETMEMBER			76
#define INDEX_LUAINTERFACE_GETNEWTABLE			77
#define INDEX_LUAINTERFACE_SETISSERVER			82
#define INDEX_LUAINTERFACE_PUSHLONG			83
#define INDEX_LUAINTERFACE_GETFLAGS			84
#define INDEX_LUAINTERFACE_FINDONOBJECTSMETATABLE	85
#define INDEX_LUAINTERFACE_FINDOBJECTONTABLE	86
#define INDEX_LUAINTERFACE_SETMEMBERFAST		87
#define INDEX_LUAINTERFACE_RUNSTRING			88
#define INDEX_LUAINTERFACE_ISEQUAL				89
#define INDEX_LUAINTERFACE_ERROR				90
#define INDEX_LUAINTERFACE_GETSTRINGORERROR	91
#define INDEX_LUAINTERFACE_RUNLUAMODULE		92
#define INDEX_LUAINTERFACE_FINDANDRUNSCRIPT	93
#define INDEX_LUAINTERFACE_SETPATHID			94
#define INDEX_LUAINTERFACE_GETPATHID			95
#define INDEX_LUAINTERFACE_ERRORNOHALT			96
#define INDEX_LUAINTERFACE_MSG					97
#define INDEX_LUAINTERFACE_PUSHPATH			98
#define INDEX_LUAINTERFACE_POPPATH				99
#define INDEX_LUAINTERFACE_GETPATH				100
#define INDEX_LUAINTERFACE_GETCOLOR			101
#define INDEX_LUAINTERFACE_PUSHCOLOR			102
#define INDEX_LUAINTERFACE_GETSTACK			103
#define INDEX_LUAINTERFACE_GETINFO				104
#define INDEX_LUAINTERFACE_GETLOCAL			105
#define INDEX_LUAINTERFACE_GETUPVALUE			106
#define INDEX_LUAINTERFACE_RUNSTRINGEX			107
#define INDEX_LUAINTERFACE_DELETE_ME1			108
#define INDEX_LUAINTERFACE_GETDATASTRING		109
#define INDEX_LUAINTERFACE_ERRORFROMLUA		110
#define INDEX_LUAINTERFACE_GETCURRENTLOCATION	111
#define INDEX_LUAINTERFACE_MSGCOLOUR			112
#define INDEX_LUAINTERFACE_SETSTATE			113
#define INDEX_LUAINTERFACE_DELETE_ME2			113
#define INDEX_LUAINTERFACE_GETCURRENTFILE		115
#define INDEX_LUAINTERFACE_COMPILESTRING		116
#define INDEX_LUAINTERFACE_THREADLOCK			116
#define INDEX_LUAINTERFACE_THREADUNLOCK		117
#define INDEX_LUAINTERFACE_CALLFUNCTIONPROTECTED	119
#define INDEX_LUAINTERFACE_REQUIRE				120
#define INDEX_LUAINTERFACE_GETACTUALTYPENAME	121
#define INDEX_LUAINTERFACE_SETUPINFINITELOOPPROTECTION	122
*/

#define LUA_GLOBALSINDEX	(-10002)

// ======================= CLASS HEADER ======================= //

class ILuaInterface {
	
protected:

	PDWORD_PTR* base;
	template <typename T> T GetFunction( PDWORD_PTR*, int index );

public:

	PDWORD_PTR* GetBase();

	ILuaInterface( PDWORD_PTR* );   

	bool			RunString( const char*, const char*, const char*, bool, bool );
	bool			RunStringEx( const char*, const char*, const char*, bool, bool, bool );

	void*			CreateTable( void ); 

	//void			Msg( const char* );

	void*			NewGlobalTable( const char* );

	void*			GetField( int, const char* );
	void*			SetField( int, const char* );

	const char*		GetString( int, unsigned int * = NULL );
	double			GetNumber( int i = -1 );
	bool			GetBool( int i = -1  );
	void*			GetCFunction( int i = -1  );
	void*			GetUserdata( int i = -1  );
	ILuaObject*		GetReturn( int i = -1  );

	const char*		CallInternalGetString( int );

	void*			Call( int, int );
	void*			PCall( int, int, int );

	bool			IsServer( void );
	bool			IsClient( void );

	void*			Push( int );
	void*			PushLong( long );
	void*			PushString( const char*, unsigned int* = NULL );
	void*			PushNumber( double );
	void*			PushBool( bool );
	void*			PushCFunction( void* );
	void*			PushCClosure( void*, int  );
	void*			PushUserdata( void* );
	void*			PushNil( void );

	void*			ReferencePush( int );
	int				ReferenceCreate( void );
	void*			ReferenceFree( int );

	int				GetType( int );
	const char*		GetTypeName( int );
	void*			Next( int );
	void*			Pop( int i = -1 );

	void*			SetTable( int );
	void*			GetTable( int );
	bool			IsType( int, int );
	void*			CheckType( int, int );

	ILuaObject*		GetGlobal( const char* );
	ILuaObject*		IGetObject( int i = -1 );

	lua_State*		GetLuaState();

};

#endif