///////////////////////////////////////////////////////////////////////////////
/// @file deMemory_priv.hpp
///
/// @brief Destiny3D Memory Manager
///
/// @author Lightning
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Feb 2001
/// @author Lightning
/// @remarks Creation
///
/// @date Oct 2001
/// @author Hootie
/// @remarks Started Conversion to C++
///
/// @date Oct 2002
/// @author Lightning
/// @remarks Scrapped old, started from scratch
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DEMEMORY_PRIV_HPP
#define DEMEMORY_PRIV_HPP

//include the headers
#include "deGlobalTypes.hpp"
#include "Functions/Functions.hpp"
#include "deMemory.hpp"
#include "RedBlackTree.hpp"

//a global header we need
//#include <cstdio>

#ifdef _WIN32
	//need the windows header for memory functions
	#include <windows.h>
#endif

class deMemoryManager : public IdeMemoryManager
{
	public:
		deMemoryManager(char *ConfigFile);
		~deMemoryManager();
		
		///function to see if we initialized properly
		deBoolean IsInitialized();

		//all the functions that are used for overridding
		void * Malloc(unsigned int Size, MallocType Type, const char *File, long Line);
		void Free(void *Ptr, FreeType Type, const char *File, long Line);
		void * MemCpy(void *To, const void *From, unsigned int Size, const char *File, long Line);
		void * MemSet(void *To, int Value, unsigned int Size, const char *File, long Line);

	private:
		//internal structure for alloc info
		typedef struct AllocStruct
		{
			char *							File;
			DWORD							Line;
			IdeMemoryManager::MallocType	AllocType;
		} AllocStruct;
		
		//internal structure storing each real allocation done
		typedef struct RealAllocStruct
		{
			void *						Ptr;
			DWORD						Size;
			struct RealAllocStruct *	Next;
		} RealAllocStruct;

		deBoolean			Initialized;		//did we init correctly
		RedBlackNode *		RootFreeNode;		//root of the free nodes
		RedBlackNode *		RootAllocNode;		//root of the alloc nodes
		RealAllocStruct *	RootRealAllocList;	//root of the real allocations

		//some private functions
		void CheckMemoryLeaks();
		RedBlackNode *AllocRealMem(DWORD *Size);
		void ReleaseAllRealAllocMem();
		void OutputMemLeak(RedBlackNode *LeakAlloc);
};


//some defines that are used in the memory manager internally
#define Round64k(Val) ((Val + 0x0000FFFF) & 0xFFFF0000)
#define Round4(Val) ((Val + 3) & 0xFFFFFFFC)


//if in windows, define the allocations for windows
#ifdef _WIN32

//some inline functions for setting what to use on real allocations and free's
static inline void *RealAlloc(DWORD *Size)
{
	//make sure we are allocating in multiples of 64k
	*Size = Round64k(*Size);

	//now allocate it
	return VirtualAlloc(NULL, *Size, MEM_COMMIT, PAGE_READWRITE);
}

static inline deBoolean RealFree(void *Ptr)
{
	//free the real memory that was allocated
	return VirtualFree(Ptr, 0, MEM_RELEASE);
}

#endif	//_WIN32

#endif