#ifndef PLATFORM_CONFIG_H

#define PLATFORM_CONFIG_H


#define USE_STL	// Determines where STL containers or internal physx foundation SDK containers are used

#ifdef USE_STL

#pragma warning(disable:4530) // disable exception handling warning

#include <vector>
#include <hash_map>
#include <malloc.h>
#include <Windows.h> // For mutex (Critical Section)

#include "foundation/PxSimpleTypes.h"
#include "foundation/PxAssert.h"


namespace physx
{
	namespace shdfnd
	{

		PX_INLINE void * AllocAligned(size_t size,size_t alignment)
		{
			return ::_aligned_malloc(size,alignment);
		}


#define PX_NEW(T) new(#T,__FILE__,__LINE__,sizeof(T)) T
#define PX_ALLOC_ALIGNED(x,y) AllocAligned(x,y)
#define PX_ALLOC(x) AllocAligned(x,16)
#define PX_FREE(x) ::_aligned_free(x)

		class UserAllocated
		{
		public:
			PX_INLINE void* operator new(size_t size,UserAllocated *t)
			{
				PX_FORCE_PARAMETER_REFERENCE(size);
				return t;
			}

			PX_INLINE void* operator new(size_t size,const char *className,const char* fileName, int lineno,size_t classSize)
			{
				PX_FORCE_PARAMETER_REFERENCE(className);
				PX_FORCE_PARAMETER_REFERENCE(fileName);
				PX_FORCE_PARAMETER_REFERENCE(lineno);
				PX_FORCE_PARAMETER_REFERENCE(classSize);
				return PX_ALLOC(size);
			}

			inline void* operator new[](size_t size,const char *className,const char* fileName, int lineno,size_t classSize)
			{
				PX_FORCE_PARAMETER_REFERENCE(className);
				PX_FORCE_PARAMETER_REFERENCE(fileName);
				PX_FORCE_PARAMETER_REFERENCE(lineno);
				PX_FORCE_PARAMETER_REFERENCE(classSize);
				return PX_ALLOC(size);
			}

			inline void  operator delete(void* p,UserAllocated *t)
			{
				PX_FORCE_PARAMETER_REFERENCE(p);
				PX_FORCE_PARAMETER_REFERENCE(t);
				PX_ALWAYS_ASSERT(); // should never be executed
			}

			inline void  operator delete(void* p)
			{
				PX_FREE(p);
			}

			inline void  operator delete[](void* p)
			{
				PX_FREE(p);
			}

			inline void  operator delete(void *p,const char *className,const char* fileName, int line,size_t classSize)
			{
				PX_FORCE_PARAMETER_REFERENCE(className);
				PX_FORCE_PARAMETER_REFERENCE(fileName);
				PX_FORCE_PARAMETER_REFERENCE(line);
				PX_FORCE_PARAMETER_REFERENCE(classSize);
				PX_FREE(p);
			}

			inline void  operator delete[](void *p,const char *className,const char* fileName, int line,size_t classSize)
			{
				PX_FORCE_PARAMETER_REFERENCE(className);
				PX_FORCE_PARAMETER_REFERENCE(fileName);
				PX_FORCE_PARAMETER_REFERENCE(line);
				PX_FORCE_PARAMETER_REFERENCE(classSize);
				PX_FREE(p);
			}


		};


		class Mutex
		{
		public:
			Mutex(void)
			{
				InitializeCriticalSection(&m_Mutex);
			}

			~Mutex(void)
			{
				DeleteCriticalSection(&m_Mutex);
			}

			void lock(void)
			{
				EnterCriticalSection(&m_Mutex);
			}

			bool tryLock(void)
			{
				bool bRet = false;
				//assert(("TryEnterCriticalSection seems to not work on XP???", 0));
				bRet = TryEnterCriticalSection(&m_Mutex) ? true : false;
				return bRet;
			}

			void unlock(void)
			{
				LeaveCriticalSection(&m_Mutex);
			}

		private:
			CRITICAL_SECTION m_Mutex;
		};



	} // end of shdfnd namespace

#define ArrayContainer std::vector
#define HashContainer stdext::hash_map

} // end of physx namespace





#else

#include "PsUserAllocated.h"
#include "PsArray.h"
#include "PsMutex.h"
#include "PsHashMap.h"
#include "PsInlineArray.h"

#define ArrayContainer physx::shdfnd::Array
#define HashContainer physx::shdfnd::HashMap

#endif

#endif
