/*
	Copyright 2004-2005 Electronic Arts Inc.
*/

// --- Include guard

#ifndef GAMETALKTHREAD_HPP
#define GAMETALKTHREAD_HPP

// --- Includes

#include "stdio.h"
#include <atlstr.h>
#include <string>

// --- Macros 

using namespace std;

namespace EA
{
namespace GameTalk
{
	// --- Thread class implementation
	class Thread 
	{
	public:

		enum ThreadState 
		{
			THREAD_STOPPED,
			THREAD_RUNNING,
			THREAD_PAUSED,
			THREAD_ENDING,
		};

		Thread();
		Thread(const char *nm);
		~Thread();

		void	setName(const char *nm);
		string	getName() const;
		void	start();
		virtual void run();
		void	sleep(long ms);
		void	suspend();
		void	resume();
		void	stop();

		void	setPriority(int p);

		bool	wait(const char *m, long ms=10000);
		void	release(const char *m);


		// Thread priorities
		static const int P_ABOVE_NORMAL;
		static const int P_BELOW_NORMAL;
		static const int P_HIGHEST;
		static const int P_IDLE;
		static const int P_LOWEST;
		static const int P_NORMAL;
		static const int P_CRITICAL;

	private:
		// low-level thread object
		unsigned long	*m_hThread;
		// name to identify the thread
		string			m_strName;
	protected:
		ThreadState		m_threadState;
	};

	// --- Mutex class implementation
	class Mutex 
	{
	public:
		Mutex();
		Mutex(const char *nm);
		~Mutex();

		void			create(const char *nm);
		unsigned long	*getMutexHandle();
		string			getName();
		void			release();

	private:
		// low-level mutex object
		unsigned long	*m_hMutex;
		// name to identify the mutex
		string			m_strName;
	};

	// --- ThreadException class implementation
	class ThreadException 
	{
	public:
		ThreadException(const char *m);
		string getMessage() const;

	private:
		string msg;
	};

	typedef int ReceiveCallback();

	// --- GameTalkThread class implementation
	class GameTalkThread : public Thread
	{
	public:
		GameTalkThread(const char *nm, int socketId, ReceiveCallback* callback); 
		void destroy();
		void run();

	private:
		WSAEVENT mhEvent;
		Mutex mMutex;
		SOCKET mSocketId;
		ReceiveCallback* mCallback;
	};
} // namespace GameTalk
} // namespace EA


#endif // GAMETALKTHREAD_HPP
