#ifndef DETHREAD_PRIV_HPP
#define DETHREAD_PRIV_HPP

#include "deThread.hpp"
#include "deList.hpp"

#ifdef DESTINY3D_PLATFORM_WIN32
#include <windows.h>

class deThread : public IdeThread {
public:
	deThread(ThreadProc threadProc);
	virtual ~deThread();
	virtual deBoolean Start(void* parameter);
	virtual deBoolean IsRunning();
	virtual u32 GetReturnValue(deBoolean WaitForExit);
	virtual s32 Release();
	void Join(MessageHandler mh);
	void DoMessageJoin(MessageHandler mh);
	void DoWaitJoin();
protected:
private:
	ThreadProc	mThreadProc;
	HANDLE		mThreadHandle;
	DWORD		mThreadId;
};

class deThreadLock : public IdeThreadLock {
public:
	deThreadLock(u32 spinCount);
	virtual ~deThreadLock();
	virtual void Lock();
	virtual void Unlock();
	virtual deBoolean TryLock(u32 waitTimeInMs);
	virtual s32 Release();
private:
	HANDLE		mLockEvent;
	LONG		mThreadId;
	s32			mCount;
	s32			mDepth;
	u32 const	mSpinCount;
	void operator=(const deThreadLock&) {}
};

class deThreadPool : public IdeThreadPool {
public:
	deThreadPool(u32 minStartThreadCount);
	virtual void QueueUserWorkItem(IdeThread::ThreadProc, void* parameter);
	virtual u32 GetAvailableThreadCount();
	virtual u32 GetCurrentThreadCount();
	virtual void RemoveUnusedThreads();
	virtual ~deThreadPool();
	static deThreadPool* mInstance;
private:
	struct ThreadPoolItem {
		IdeThread* thread;
		IdeThread::ThreadProc workerFunction;
		HANDLE workAvailableSignal;
		HANDLE doneSignal;
		void* param;
	};
	typedef deTList<ThreadPoolItem*>::iterator ThreadPoolIterator;
	ThreadPoolItem* GetAvailableThread();
	ThreadPoolItem* CreateNewThread();
	bool IsThreadAvailable(ThreadPoolItem* item);
	void RemoveThread(ThreadPoolItem* item);
	
	deTList<ThreadPoolItem*> mThreads;
	IdeThreadLock* mLock;

	static u32 ThreadPoolWorkerThreadFunc(void* parameter);
};

#elif defined(DESTINY3D_PLATFORM_LINUX)
#error linux threading system not yet implemented
#else
#error unsupported platform configuration
#endif

#endif //DETHREAD_PRIV_HPP