/*
 *        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 "wine.h"
#include "task.h"
#include "stddebug.h"
/* #define DEBUG_TASK */
/* #undef DEBUG_TASK */
#include "debug.h"


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

/**********************************************************************
 *				GetCurrentTask	[KERNEL.36]
 */
HTASK GetCurrentTask()
{
	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()
{
	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, lpEnumFunc, 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);
#ifdef WINELIB
		bRet = (*lpEnumFunc)(hWnd, lParam); 
#else
		bRet = CallBack16(lpEnumFunc, 2, 0, (int)hWnd, 2, (int)lParam);
#endif
		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 %08X\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;
}
