/*
 *        Tasks functions
 *
static char Copyright[] = "Copyright  Martin Ayotte, 1994";
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include "windows.h"
#include "callback.h"
#include "task.h"
#include "stddebug.h"
#include "debug.h"

static LPWINETASKENTRY lpTaskList = NULL;
static int nTaskCount = 0;

/**********************************************************************
 *				GetCurrentTask	[KERNEL.36]
 */
HTASK GetCurrentTask(void)
{
	LPWINETASKENTRY lpTask = lpTaskList;
	int pid = getpid();
	dprintf_task(stddeb,"GetCurrentTask() // unix_pid=%08X !\n", pid);
	if (lpTask == NULL) return 0;
	while (TRUE) {
		if (lpTask->unix_pid == pid) break;
		if (lpTask->lpNextTask == NULL) return 0;
		lpTask = lpTask->lpNextTask;
		}
	dprintf_task(stddeb,"GetCurrentTask() returned hTask=%04X !\n", lpTask->te.hTask);
	return lpTask->te.hTask;
}


/**********************************************************************
 *				GetNumTasks	[KERNEL.152]
 */
WORD GetNumTasks(void)
{
	dprintf_task(stddeb,"GetNumTasks() returned %d !\n", nTaskCount);
	return nTaskCount;
}


/**********************************************************************
 *				GetWindowTask	[USER.224]
 */
HTASK GetWindowTask(HWND hWnd)
{
	HWND 	*wptr;
	int		count;
	LPWINETASKENTRY lpTask = lpTaskList;
	dprintf_task(stddeb,"GetWindowTask(%04X) !\n", hWnd);
	while (lpTask != NULL) {
		wptr = lpTask->lpWndList;
		if (wptr != NULL) {
			count = 0;
			while (++count < MAXWIN_PER_TASK) {
				dprintf_task(stddeb,"GetWindowTask // searching %04X %04X !\n",
										lpTask->te.hTask, *(wptr));
				if (*(wptr) == hWnd) {
					dprintf_task(stddeb,"GetWindowTask(%04X) found hTask=%04X !\n", 
												hWnd, lpTask->te.hTask);
					return lpTask->te.hTask;
					}
				wptr++;
				}
			}
		lpTask = lpTask->lpNextTask;
		}
	return 0;
}


/**********************************************************************
 *				EnumTaskWindows	[USER.225]
 */
BOOL EnumTaskWindows(HANDLE hTask, FARPROC lpEnumFunc, LONG lParam)
{
	HWND 	*wptr, hWnd;
	BOOL	bRet;
	int		count = 0;
	LPWINETASKENTRY lpTask = lpTaskList;
	dprintf_task(stddeb,"EnumTaskWindows(%04X, %08X, %08X) !\n", hTask, 
		(unsigned int) lpEnumFunc, (unsigned int) lParam);
	while (TRUE) {
		if (lpTask->te.hTask == hTask) break;
		if (lpTask == NULL) {
			dprintf_task(stddeb,"EnumTaskWindows // hTask=%04X not found !\n", hTask);
			return FALSE;
			}
		lpTask = lpTask->lpNextTask;
		}
	dprintf_task(stddeb,"EnumTaskWindows // found hTask=%04X !\n", hTask);
	wptr = lpTask->lpWndList;
	if (wptr == NULL) return FALSE;
	if (lpEnumFunc == NULL)	return FALSE;
	while ((hWnd = *(wptr++)) != 0) {
		if (++count >= MAXWIN_PER_TASK) return FALSE;
		dprintf_task(stddeb,"EnumTaskWindows // hWnd=%04X count=%d !\n", hWnd, count);
                bRet = CallEnumTaskWndProc( lpEnumFunc, hWnd, lParam );
		if (bRet == 0) break;
		}
	return TRUE;
}


/**********************************************************************
 *				CreateNewTask		[internal]
 */
HANDLE CreateNewTask(HINSTANCE hInst, HTASK hTaskParent)
{
	HANDLE hTask;
	LPWINETASKENTRY lpTask = lpTaskList;
	LPWINETASKENTRY lpNewTask;
	MODULEENTRY module;

	module.dwSize = sizeof(module);
	ModuleFindHandle(&module, hInst);

	if (lpTask != NULL) {
		while (TRUE) {
			if (lpTask->lpNextTask == NULL) break;
			lpTask = lpTask->lpNextTask;
			}
		}
	hTask = GlobalAlloc(GMEM_MOVEABLE, sizeof(WINETASKENTRY));
	lpNewTask = (LPWINETASKENTRY) GlobalLock(hTask);
    	dprintf_task(stddeb,"CreateNewTask entry allocated %p\n", lpNewTask);
	if (lpNewTask == NULL) return 0;
	if (lpTaskList == NULL) {
		lpTaskList = lpNewTask;
		lpNewTask->lpPrevTask = NULL;
		}
	else {
		lpTask->lpNextTask = lpNewTask;
		lpTask->te.hNext = lpNewTask->te.hTask;
		lpNewTask->lpPrevTask = lpTask;
		}
	lpNewTask->lpNextTask = NULL;
	lpNewTask->hIcon = 0;
	lpNewTask->te.dwSize = sizeof(TASKENTRY);
	lpNewTask->te.hModule = 0;
	lpNewTask->te.hInst = hInst;
	lpNewTask->te.hTask = hTask;
	lpNewTask->te.hTaskParent = hTaskParent;
	lpNewTask->te.wSS = 0;
	lpNewTask->te.wSP = 0;
	lpNewTask->te.wStackTop = 0;
	lpNewTask->te.wStackMinimum = 0;
	lpNewTask->te.wStackBottom = 0;
	lpNewTask->te.wcEvents = 0;
	lpNewTask->te.hQueue = 0;
	strcpy(lpNewTask->te.szModule, module.szModule);
	lpNewTask->te.wPSPOffset = 0;
	lpNewTask->unix_pid = getpid();
	lpNewTask->lpWndList = (HWND *) malloc(MAXWIN_PER_TASK * sizeof(HWND));
	if (lpNewTask->lpWndList != NULL) 
		memset((LPSTR)lpNewTask->lpWndList, 0, MAXWIN_PER_TASK * sizeof(HWND));
    	dprintf_task(stddeb,"CreateNewTask // unix_pid=%08X return hTask=%04X\n", 
									lpNewTask->unix_pid, hTask);
	GlobalUnlock(hTask);	
	nTaskCount++;
    return hTask;
}


/**********************************************************************
 *				AddWindowToTask		[internal]
 */
BOOL AddWindowToTask(HTASK hTask, HWND hWnd)
{
	HWND 	*wptr;
	int		count = 0;
	LPWINETASKENTRY lpTask = lpTaskList;
	dprintf_task(stddeb,"AddWindowToTask(%04X, %04X); !\n", hTask, hWnd);
	while (TRUE) {
		if (lpTask->te.hTask == hTask) break;
		if (lpTask == NULL) {
			fprintf(stderr,"AddWindowToTask // hTask=%04X not found !\n", hTask);
			return FALSE;
			}
		lpTask = lpTask->lpNextTask;
		}
	wptr = lpTask->lpWndList;
	if (wptr == NULL) return FALSE;
	while (*(wptr) != 0) {
		if (++count >= MAXWIN_PER_TASK) return FALSE;
		wptr++;
		}
	*wptr = hWnd;
	dprintf_task(stddeb,"AddWindowToTask // window added, count=%d !\n", count);
	return TRUE;
}


/**********************************************************************
 *				RemoveWindowFromTask		[internal]
 */
BOOL RemoveWindowFromTask(HTASK hTask, HWND hWnd)
{
	HWND 	*wptr;
	int		count = 0;
	LPWINETASKENTRY lpTask = lpTaskList;
	dprintf_task(stddeb,"RemoveWindowFromTask (%04X, %04X); !\n", hTask, hWnd);
	while (TRUE) {
		if (lpTask->te.hTask == hTask) break;
		if (lpTask == NULL) {
			fprintf(stderr,"RemoveWindowFromTask // hTask=%04X not found !\n", hTask);
			return FALSE;
			}
		lpTask = lpTask->lpNextTask;
		}
	wptr = lpTask->lpWndList;
	if (wptr == NULL) return FALSE;
	while (*(wptr) != hWnd) {
		if (++count >= MAXWIN_PER_TASK) return FALSE;
		wptr++;
		}
	while (*(wptr) != 0) {
		*(wptr) = *(wptr + 1);
		if (++count >= MAXWIN_PER_TASK) return FALSE;
		wptr++;
		}
	dprintf_task(stddeb,"RemoveWindowFromTask // window removed, count=%d !\n", --count);
	return TRUE;
}

BOOL TaskFirst(LPTASKENTRY lpTask)
{
	dprintf_task(stddeb,"TaskFirst(%8x)\n", (int) lpTask);
	if (lpTaskList) {
		memcpy(lpTask, &lpTaskList->te, lpTask->dwSize);
		return TRUE;
	} else
		return FALSE;
}

BOOL TaskNext(LPTASKENTRY lpTask)
{
	LPWINETASKENTRY list;
	dprintf_task(stddeb,"TaskNext(%8x)\n", (int) lpTask);
	list = lpTaskList;
	while (list) {
		if (list->te.hTask == lpTask->hTask) {
			list = list->lpNextTask;
			if (list) {
				memcpy(lpTask, &list->te, lpTask->dwSize);
				return TRUE;
			} else
				return FALSE;
		}
		list = list->lpNextTask;
	}
	return FALSE;
}

BOOL TaskFindHandle(LPTASKENTRY lpTask, HTASK hTask)
{
	static LPWINETASKENTRY list;
	dprintf_task(stddeb,"TaskFindHandle(%8x,%4x)\n", (int) lpTask, hTask);
	list = lpTaskList;
	while (list) {
		if (list->te.hTask == hTask) {
			list = list->lpNextTask;
			if (list) {
				memcpy(lpTask, &list->te, lpTask->dwSize);
				return TRUE;
			} else
				return FALSE;
		}
		list = list->lpNextTask;
	}
	return FALSE;
}
