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

// Reconstructed version of BlackAwps' backwards headers, +credits

#ifndef _ILUAOBJECT_H

#define _ILUAOBJECT_H

#include "tier1/utlvector.h"

#include "oubhack_iluainterface.h"
#include "oubhack_types.h"

class ILuaObject;

struct LuaKeyValue
{
	ILuaObject* pKey;
	ILuaObject* pValue;
};

typedef CUtlVector<LuaKeyValue> CUtlLuaVector;

#define FOR_LOOP( vecName, iteratorName ) for ( int iteratorName = 0; iteratorName < vecName->Count(); iteratorName++ )

using namespace GarrysMod::Lua;

class ILuaObject
{
public:
	ILuaObject( ILuaInterface* lua );
	ILuaObject( ILuaInterface* lua, int iRef );
	ILuaObject( ILuaInterface* lua, ILuaObject* obj );
	~ILuaObject( void );

	void			Set( ILuaObject* obj );
	void			SetNil();
	void			SetFromStack( int i );
	
	void			UnReference();
	void			SafeUnReference();
	int				GetReference();

	int				GetType();
	const char*		GetTypeName();

	const char*		GetString( unsigned int* iLen = NULL );
	int				GetInt();
	double			GetDouble();
	float			GetFloat();
	bool			GetBool();
	void*			GetUserData();

	CUtlLuaVector*	GetMembers();
	
	void			SetMember( const char* name );
	void			SetMember( const char* name, ILuaObject* obj );
	void			SetMember( const char* name, double d );
	void			SetMember( const char* name, bool b );
	void			SetMember( const char* name, const char* s, unsigned int iLen = 0 );
	void			SetMember( const char* name, void* f );
	
	void			SetMember( double dKey );
	void			SetMember( double dKey, ILuaObject* obj );
	void			SetMember( double dKey, double d );
	void			SetMember( double dKey, bool b );
	void			SetMember( double dKey, const char* s, unsigned int iLen = 0 );
	void			SetMember( double dKey, void* f );

	void			SetMember( float fKey );
	void			SetMember( float fKey, ILuaObject* obj );
	void			SetMember( float fKey, double d );
	void			SetMember( float fKey, bool b );
	void			SetMember( float fKey, const char* s, unsigned int iLen = 0 );
	void			SetMember( float fKey, void* f );

	void			SetMember( int iKey );
	void			SetMember( int iKey, ILuaObject* obj );
	void			SetMember( int iKey, double d );
	void			SetMember( int iKey, bool b );
	void			SetMember( int iKey, const char* s, unsigned int iLen = 0 );
	void			SetMember( int iKey, void* f );

	ILuaObject*		GetMember( const char* name );
	ILuaObject*		GetMember( double dKey );
	ILuaObject*		GetMember( float fKey );
	ILuaObject*		GetMember( int iKey );
	ILuaObject*		GetMember( ILuaObject* oKey );

	bool			GetMemberBool( const char* name, bool b = true );
	int				GetMemberInt( const char* name, int i = 0 );
	float			GetMemberFloat( const char* name, float f = 0.0f );
	double			GetMemberDouble( const char* name, double d = 0 );
	const char*		GetMemberStr( const char* name, const char* s = "", unsigned int* iLen = NULL );
	void*			GetMemberUserData( const char* name, void* = NULL );
	
	void			SetMemberUserDataLite( const char* name, void* pData );
	void*			GetMemberUserDataLite( const char* name, void* u = NULL );

	void			SetUserData( void* obj, unsigned char type );
	
	bool			isType( int iType );
	bool			isNil();
	bool			isTable();
	bool			isString();
	bool			isNumber();
	bool			isFunction();
	bool			isUserData();

	void			Push();

	ILuaInterface* m_pLua;
	int m_iRef;
};

#endif