#include "thread.h"
#include <windows.h>


Thread::Thread(int priority) 
: _priority(priority), _canRun(true), _isPaused(false), _isSuspended(true), _handle(NULL)
{
	_handle = CreateThread(NULL, 0, Thread::entry, this, CREATE_SUSPENDED, &_id);
    SetThreadPriority(_handle, _priority);
}

Thread::~Thread()
{
	if (_handle != NULL)
		CloseHandle(_handle);
}

void Thread::start()
{
    if ((_handle != NULL) && (_isSuspended)) {
		_isSuspended = false;
        ResumeThread(_handle);
    }
}

void Thread::join(unsigned long timeout)
{
	if (_handle != NULL)
		WaitForSingleObject(_handle, timeout);
}

void Thread::pause()
{
	_isPaused = true;
}

void Thread::unpause()
{
	_isPaused = false;
}


void Thread::stop()
{
	_canRun = false;
}


void Thread::suspend()
{
    if ((_handle != NULL) && (!_isSuspended)) {
        _isSuspended = true;
		SuspendThread(_handle);
    }
}

void Thread::resume()
{
    if ((_handle != NULL) && (_isSuspended)) {
		_isSuspended = false;
        ResumeThread(_handle);
    }
}

void Thread::kill()
{
    if (_handle != NULL) {
	    TerminateThread(_handle, 0);
	    CloseHandle(_handle);
	    _handle = NULL;
    }
}

int Thread::getPriority()
{
    return _priority;
}

void Thread::setPriority(int priority)
{
    if (_handle != NULL) {
        _priority = priority;
        SetThreadPriority(_handle, _priority);
    }
}

unsigned long Thread::entry(void* p) {
	(*((Thread*)p))();
	return 0;
}

bool Thread::canRun()
{
	return _canRun;
}

bool Thread::isPaused()
{
	return _isPaused;
}

void Thread::beginBackgroundMode()
{
    if (_handle != NULL)
        SetThreadPriority(_handle, THREAD_MODE_BACKGROUND_BEGIN);
}

void Thread::endBackgroundMode()
{
    if (_handle != NULL)
        SetThreadPriority(_handle, THREAD_MODE_BACKGROUND_END);
}