#pragma once

#define ASSERT(a)	if(!(a)) STOP(("Failed assert"));

namespace Gos2 {

class Heap : public GosHeap
{
	TCHAR					m_Name[32];
	DWORD					m_MaximumSize;
	DWORD					m_BytesAllocated;
	Heap *					m_pNextHeap;
	Heap *					m_pPrevHeap;
	CRITICAL_SECTION		m_CriticalSection;

	struct Allocation
	{
		Allocation		*pPrev;
		Allocation		*pNext;
		DWORD			SizeBytes;
		const _TCHAR	*Signature;
		const _TCHAR	*pDescription;
		DWORD			id;
		GosHeap			*pHeap;
	}						m_Anchor;

	static Heap *			s_pFirstHeap;
	static GosHeap *		s_apHeapStack[20];
	static int				s_HeapStackDepth;
	static DWORD			s_NextAllocationId;

public:
	static void				Shutdown();
	virtual void			VerifyEmpty();
	virtual _TCHAR *		Name() { return m_Name; }
	static GosHeap *		Create( _TCHAR *name, DWORD bytesMax );
	static void				PushCurrent( GosHeap *pHeap );
	static void				PopCurrent();
	static GosHeap *		Current();
	virtual void *			Malloc( DWORD sizeBytes, const TCHAR *pDescription );
	static void				Free( void *pData );
	static DWORD			GetID( void *pData );
	virtual DWORD			GetIDLocal( void *pData );
	virtual void			FreeLocal( void *pData );
	virtual					~Heap();
};

} using namespace Gos2;