- 001
 - 002
 - 003
 - 004
 - 005
 - 006
 - 007
 - 008
 - 009
 - 010
 - 011
 - 012
 - 013
 - 014
 - 015
 - 016
 - 017
 - 018
 - 019
 - 020
 - 021
 - 022
 - 023
 - 024
 - 025
 - 026
 - 027
 - 028
 - 029
 - 030
 - 031
 - 032
 - 033
 - 034
 - 035
 - 036
 - 037
 - 038
 - 039
 - 040
 - 041
 - 042
 - 043
 - 044
 - 045
 - 046
 - 047
 - 048
 - 049
 - 050
 - 051
 - 052
 - 053
 - 054
 - 055
 - 056
 - 057
 - 058
 - 059
 - 060
 - 061
 - 062
 - 063
 - 064
 - 065
 - 066
 - 067
 - 068
 - 069
 - 070
 - 071
 - 072
 - 073
 - 074
 - 075
 - 076
 - 077
 - 078
 - 079
 - 080
 - 081
 - 082
 - 083
 - 084
 - 085
 - 086
 - 087
 - 088
 - 089
 - 090
 - 091
 - 092
 - 093
 - 094
 - 095
 - 096
 - 097
 - 098
 - 099
 - 100
 
                        class Thread
{
public:
	Thread(const Thread&);
	Thread() : handle(NULL), running(false), finished(false)
	{
		handle = (HANDLE)(_beginthreadex(NULL, 0, &(Thread::threadRun), this, CREATE_SUSPENDED, NULL));
	}
	~Thread()
	{
		if(isRunning()) {
			TerminateThread(handle, 0);
		} 
		CloseHandle(handle);
	}
	void start(void* arg)
	{
		if(isRunning() || isFinished()) {
			throw Exception("Thread is running or finished!");
		} else {
			this->arg = arg;
			ResumeThread(handle);
		}
		
	}
	void pause()
	{
		if(isRunning()) {
			SuspendThread(handle);
		} else {
			throw Exception("Thread is not running or finished!");
		}
	}
	void resume()
	{
		if(!(isRunning())) {
			throw Exception("Thread is finished!");
		} else {
			ResumeThread(handle);
		}
	}
	void stop()
	{
		if(isRunning()) {
			TerminateThread(handle, 0);
			running = false;
			finished = true;
			throw Exception("Thread stopped!");
		} else {
			throw Exception("Thread is not running or finished!");
		}
	}
	void setPriority(ThreadPriority priority)
	{
		if(isFinished()) {
			throw Exception("Thread is finished!");
		} else {
			switch(priority) {
			case ThreadPriorityLow:
				SetThreadPriority(handle, THREAD_PRIORITY_LOWEST);
				break;
			case ThreadPriorityNormal:
				SetThreadPriority(handle, THREAD_PRIORITY_NORMAL);
				break;
			case ThreadPriorityHigh:
				SetThreadPriority(handle, THREAD_PRIORITY_HIGHEST);
				break;
			default:
				throw Exception("Invalid priority!");
				break;
			}
		}
	}
	bool isRunning()
	{
		return (running);
	}
	bool isFinished()
	{
		return (finished);
	}
protected:
	virtual void run(void *arg) = 0;
private:
	static unsigned int __stdcall threadRun(void *arg)
	{
		Thread *thread = static_cast<Thread*>(arg);
		thread->running = true;
		thread->run(thread->arg);
		thread->running = false;
		thread->finished = true;
		_endthreadex(0);
		return (0);
	}
	void *arg;
	HANDLE handle;
	bool running;
	bool finished;
};