#include "xthread.h"
#include "xmsgbox.h"
#include "stdio.h"
#include "xexcept.h"

#include <stdlib.h>
#include <process.h>


#ifndef __WATCOMC__
int XThread::threadsRunning = 0;
#else
static int threadsRunning = 0;
#endif


ULONG XThread::Resume()
{
	return DosResumeThread(tid);
}


ULONG XThread::Suspend()
{
	return DosSuspendThread(tid);
}


/*@ XThread::Terminate(void)
@group initiate/terminate a process
@remarks With this method a thread can be terminated. If you
call Terminate() the method QueryForQuit() will not be called.
*/
void XThread::Terminate(void)
{
	XProcess::Terminate();
	threadsRunning -= 1;
	_endthread();
}


void XThread::ThreadEntry(void)
{
	hab = WinInitialize(0);
	queue = WinCreateMsgQueue(hab, 0);
	Init();
	Start();
}


/*@ XThread::XThread(LONG)
@group constructors/destructors
@remarks Contructs a thread. After a thread is constructed, call Run() to make
the thread work. You should override method XThread::Init() where you can construct
windows and so on. Init() is the funcion where you enter the thread and have full controll of it.
To stop the thread call Terminate().
<BR>After you have called XThread::Run() for one or more threads,
you must call XThread::RunThreads() to initialize this threads (only one time
required).<P>
<B>WARNING:</B> donīt try to construct windows in the constructor of XThread or a derived
class of it! 
@parameters: LONG stackSize    size of the stack, default is 128000 KB
*/


// TBO
#ifndef __WATCOMC__
void _Optlink StartUp(void *v)
#else
void StartUp(void *v)
#endif
{
	XThread *t = (XThread *) v;

        // TBO
        #ifndef __WATCOMC__
	XThread :: threadsRunning++;
        #else
        threadsRunning++;
        #endif
	t->ThreadEntry();
	delete t;
}


void XThread::Run()
{
#ifdef __BCPLUSPLUS__
	tid = _beginthread(StartUp(this), stackSize, this);
#else
	tid = _beginthread(StartUp, 0, stackSize, (void *) this);
#endif
}


/*@ XThread::RunThreads(void)
@group initiate/terminate a process
@remarks Call RunThreads if you have constructed one or more threads.
Call RunTreads only one time.
*/
void XThread::RunThreads(void)
{
	while (1)
	{
		TID id = 0;

		DosWaitThread(&id, DCWW_WAIT);
                // TBO
                #ifndef __WATCOMC__
		if (XThread::threadsRunning <= 0)
                #else
                if( threadsRunning <= 0 )
                #endif
			break;
		DosSleep(0);
	}
}

