#ifndef _USE_RGE_

#ifndef _RUTYPE_BASE_H_
#define _RUTYPE_BASE_H_

#ifndef NULL
	#define NULL 0
#endif

#define WIN32_LEAN_AND_MEAN

#include <assert.h>
#include <windows.h>
#include <mmsystem.h>
#include <objbase.h>
#include <xmmintrin.h>

// Library includes
#pragma comment(lib, "winmm.lib")

#pragma unmanaged

#pragma warning(disable : 4793)														// Disable native code generation warnings
#pragma warning(disable : 4949)														// Disable #pragma unmanaged only having effect with CLR on warnings (god this is an amazingly retarded warning)
#pragma warning(disable : 4996)														// Disable deprecated warnings

// ************************************************************************************************************************************************************

typedef signed __int32		INT;
typedef signed __int8		INT8;
typedef signed __int16		INT16;
typedef signed __int32		INT32;
typedef signed __int64		INT64;
typedef unsigned __int32	UINT;
typedef unsigned __int8		UINT8;
typedef unsigned __int16	UINT16;
typedef unsigned __int32	UINT32;
typedef unsigned __int64	UINT64;
typedef unsigned __int8		BYTE;
typedef unsigned __int16	WORD;
typedef unsigned long		DWORD;
typedef float				REAL;

// ************************************************************************************************************************************************************

/*!
	IRuReferenceCounted
	Note - this is terrible for interfaces! What if we inherit two interfaces which both inherit this? UGLY!
	@author Ceranos
	@version Initial
*/
class IRuReferenceCounted
{
protected:
	INT32					m_refCount;												// Reference count

public:
							IRuReferenceCounted();									// Initial reference count is always 1
	virtual					~IRuReferenceCounted();									// Default destructor

	INT32					AddRef();												// Increment reference count
	INT32					Release();												// Decrement reference count
	INT32					GetRefCount() const;									// Retrieve reference count
};

// ************************************************************************************************************************************************************

class CRuRTTI
{
protected:
	const char*			m_typeName;
	const CRuRTTI*		m_baseType;

public:
					CRuRTTI(const char *typeName, const CRuRTTI *baseType);

	// Type queries
	const char*		GetTypeName() const;
	BOOL			IsSubClassOf(const CRuRTTI &type) const;
	BOOL			operator==(const CRuRTTI &type) const;
	BOOL			operator!=(const CRuRTTI &type) const;

protected:
	// Prevent copying
					CRuRTTI(const CRuRTTI &obj);
	CRuRTTI&		operator=(const CRuRTTI & obj);
};

#define ruRTTI_DECLARE													\
	public:																\
		virtual const CRuRTTI&		GetType() const { return Type; }	\
		static const CRuRTTI		Type;

#define ruRTTI_DEFINE_ROOTCLASS(name)									\
	const CRuRTTI name::Type(#name, NULL);

#define ruRTTI_DEFINE_SUBCLASS(name, parent)							\
	const CRuRTTI name::Type(#name, &parent::Type);

// ************************************************************************************************************************************************************

#pragma pack(1)

struct CDXT1Block
{
	UINT16			m_color0;
	UINT16			m_color1;
	UINT32			m_block;
};

#pragma pack()

// ************************************************************************************************************************************************************

inline IRuReferenceCounted::IRuReferenceCounted()
:	m_refCount(1)
{
}

inline IRuReferenceCounted::~IRuReferenceCounted()
{
}

inline INT32 IRuReferenceCounted::AddRef()
{
    // Increment reference count
    ++m_refCount;

    // Return reference count
    return m_refCount;
}

inline INT32 IRuReferenceCounted::Release()
{
    // Decrement reference count
    --m_refCount;

    // Automatically delete the reference counted resource
    if(m_refCount <= 0)
    {
        delete this;
        return 0;
    }

    return m_refCount;
}

inline INT32 IRuReferenceCounted::GetRefCount() const
{
    return m_refCount;
}

// ************************************************************************************************************************************************************

inline CRuRTTI::CRuRTTI(const char *typeName, const CRuRTTI *baseType)
:	m_typeName(typeName),
m_baseType(baseType)
{
}

inline const char *CRuRTTI::GetTypeName() const
{
    return m_typeName;
}

inline BOOL CRuRTTI::IsSubClassOf(const CRuRTTI &type) const
{
    const CRuRTTI *curType = this;

    while(curType != NULL)
    {
        if(curType == &type)
            return TRUE;

        curType = curType->m_baseType;
    }

    return FALSE;
}

inline BOOL CRuRTTI::operator==(const CRuRTTI &type) const
{
    return (this == &type);
}

inline BOOL CRuRTTI::operator!=(const CRuRTTI &type) const
{
    return (this != &type);
}

// ************************************************************************************************************************************************************

#pragma managed

#endif

#endif