// DWBS ------------------------------------------------------------------ DWBS
//
// PLATFORM		: ALL
// PRODUCT		: BIT_DEMON
// VISIBILITY	: PUBLIC
//
// DWBS ------------------------------------------------------------------ DWBS

#include <bdCore/bdCore.h>

#include <bdCore/bdMemory/bdDefaultMemory.h>

#define BD_LOG_LEVEL "core"

bdBool bdCore::m_initialized = false;

// Check the size of the fixed width types
//BD_COMPILE_ASSERT( sizeof(bdChar8)		== 1, bdChar8_is_unexpected_size);
//BD_COMPILE_ASSERT( sizeof(bdUChar8)		== 1, bdUChar8_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdByte8) == 1, bdByte8_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdUByte8) == 1, bdUByte8_is_unexpected_size);
//BD_COMPILE_ASSERT( sizeof(bdWChar16)	== 2, bdWChar16_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdInt16)		== 2, bdInt16_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdUInt16)		== 2, bdUInt16_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdInt32)		== 4, bdInt32_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdUInt32)		== 4, bdUInt32_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdInt64)		== 8, bdInt64_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdUInt64)		== 8, bdUInt64_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdLong32)		== 4, bdLong32_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdULong32)	== 4, bdULong32_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdLong64)		== 8, bdLong64_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdULong64)	== 8, bdULong64_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdFloat32)	== 4, bdFloat32_is_unexpected_size);
BD_COMPILE_ASSERT( sizeof(bdFloat64)	== 8, bdFloat64_is_unexpected_size);

void BD_CALL bdCore::init(const bdBool defaultMemoryFunctions)
{
	if(!m_initialized)
	{
		if(defaultMemoryFunctions)
		{
			// Setup the memory manager
			bdMemory::setAllocateFunc(bdDefaultMemory::allocate);
			bdMemory::setAlignedAllocateFunc(bdDefaultMemory::alignedAllocate);
			
			bdMemory::setDeallocateFunc(bdDefaultMemory::deallocate);
			bdMemory::setAlignedDeallocateFunc(bdDefaultMemory::alignedDeallocate);

			bdMemory::setReallocateFunc(bdDefaultMemory::reallocate);
			bdMemory::setAlignedReallocateFunc(bdDefaultMemory::alignedReallocate);
		}

		m_initialized = true;	
	}
	else
	{
		BD_WARN(BD_LOG_LEVEL, "init() has been called twice without an intermediate quit()");
	}
}

void BD_CALL bdCore::quit()
{
	if(m_initialized)
	{

		bdSingletonRegistry::getInstance()->cleanUp();

#if defined (BD_MALLOC_MEMORY) || defined (BD_DEBUG_MEMORY)
		bdDefaultMemory::leakCheck();
#endif // (BD_MALLOC_MEMORY) || defined (BD_DEBUG_MEMORY)

		/// Test facilitation.
		/// In order to check that bdCore::init() is working we must set these pointers
		/// to BD_NULL so that they can be seen to change if init and quit are called repeatedly.
		/// Set these pointers to null so that we can call init -> quit -> init sensibly.
		bdMemory::setAllocateFunc(BD_NULL);
		bdMemory::setAlignedAllocateFunc(BD_NULL);
		
		bdMemory::setDeallocateFunc(BD_NULL);
		bdMemory::setAlignedDeallocateFunc(BD_NULL);

		bdMemory::setReallocateFunc(BD_NULL);
		bdMemory::setAlignedReallocateFunc(BD_NULL);

		m_initialized = false;
	}
	else
	{	
		BD_WARN(BD_LOG_LEVEL, "quit() has been called twice without an intermediate init()");
	}
}

bdCore::bdCore()
{

}
