#ifdef WINCIT
#include "ctdl.h"

#define NUMERRORS 30
#define NUMTRAP 30

static char errors[NUMERRORS][80];
static int nextError;
static HWND hwndError;

static char traps[NUMTRAP][80];
static int nextTrap;
static HWND hwndTrap;

static char msgWindow[80];
static char msgCap[80];
static HWND hwndMsg;

long FAR PASCAL errorWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
	{
	static int /*ecx,*/ ecy, ecxChar, ecyChar;

	switch (message)
		{
		case WM_CREATE:
			{
			TEXTMETRIC tm;
			HDC hdc = GetDC(hwnd);

			GetTextMetrics(hdc, &tm);
			ecxChar = tm.tmAveCharWidth;
			ecyChar = tm.tmHeight + tm.tmExternalLeading;

			ReleaseDC(hwnd, hdc);

			return (0);
			}

		case WM_SIZE:
			{
			ecy = HIWORD(lParam);
//			ecx = LOWORD(lParam);
			return (0);
			}

		case WM_PAINT:
			{
			int lines, wow, te;
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);

			wow = max(ecy - ecyChar / 2, 0);
			lines = wow / ecyChar;

			te = max(0, nextError - lines);

			for (lines = 0; te < nextError; te++, lines++)
				{
				TextOut(hdc, ecxChar, ecyChar * (1 + lines) - ecyChar / 2,
					errors[te], strlen(errors[te]));
				}

			EndPaint(hwnd, &ps);
			return (0);
			}

		case WM_DESTROY:
			{
			hwndError = NULL;
			return (0);
			}
		}
	return (DefWindowProc(hwnd, message, wParam, lParam));
	}

long FAR PASCAL trapWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
	{
	static int /*tcx,*/ tcy, tcxChar, tcyChar;

	switch (message)
		{
		case WM_CREATE:
			{
			TEXTMETRIC tm;
			HDC hdc = GetDC(hwnd);

			GetTextMetrics(hdc, &tm);
			tcxChar = tm.tmAveCharWidth;
			tcyChar = tm.tmHeight + tm.tmExternalLeading;

			ReleaseDC(hwnd, hdc);

			return (0);
			}

		case WM_SIZE:
			{
			tcy = HIWORD(lParam);
//			ecx = LOWORD(lParam);
			return (0);
			}

		case WM_PAINT:
			{
			int lines, wow, te;
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);

			wow = max(tcy - tcyChar / 2, 0);
			lines = wow / tcyChar;

			te = max(0, nextTrap - lines);

			for (lines = 0; te < nextTrap; te++, lines++)
				{
				TextOut(hdc, tcxChar, tcyChar * (1 + lines) - tcyChar / 2,
					traps[te], strlen(traps[te]));
				}

			EndPaint(hwnd, &ps);
			return (0);
			}

		case WM_DESTROY:
			{
			hwndTrap = NULL;
			return (0);
			}
		}
	return (DefWindowProc(hwnd, message, wParam, lParam));
	}

long FAR PASCAL msgWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
	{
	switch (message)
		{
		case WM_PAINT:
			{
			RECT r;
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);

			GetClientRect(hwnd, &r);

			DrawText(hdc, msgWindow, -1, &r, DT_SINGLELINE | DT_CENTER |
					DT_VCENTER);

			EndPaint(hwnd, &ps);
			return (0);
			}

		case WM_DESTROY:
			{
			hwndMsg = NULL;
			return (0);
			}
		}

	return (DefWindowProc(hwnd, message, wParam, lParam));
	}

void cdecl msgCaption(const char *fmt, ...)
	{
	if (fmt && hwndMsg)
		{
		va_list ap;

		va_start(ap, fmt);
		vsprintf(msgCap, fmt, ap);
		va_end(ap);

		if (hwndMsg)
			{
			SetWindowText(hwndMsg, msgCap);
			}
		}
	}

void cdecl msgDisp(const char *fmt, ...)
	{
	if (fmt)
		{
		int i;
		va_list ap;

		va_start(ap, fmt);
		vsprintf(msgWindow, fmt, ap);
		va_end(ap);

		stripansi(msgWindow);
		
		for (i = 0; msgWindow[i]; i++)
			{
			if (msgWindow[i] < 32)
				{
				msgWindow[i] = 32;
				}
			}

		if (!hwndMsg)
			{
			int h, w;
			TEXTMETRIC tm;
			HDC hdc;

			hwndMsg = CreateWindow("Citadel Message",
					msgCap[0] ? msgCap : "Citadel Message Window",
					WS_BORDER, CW_USEDEFAULT, CW_USEDEFAULT,
					CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

			hdc = GetDC(hwndMsg);

			GetTextMetrics(hdc, &tm);

			w = tm.tmAveCharWidth * (strlen(msgWindow) + 5) +
					2 * GetSystemMetrics(SM_CXBORDER);
			h = tm.tmHeight + tm.tmExternalLeading +
					GetSystemMetrics(SM_CYCAPTION) +
					2 * GetSystemMetrics(SM_CYBORDER);

			ReleaseDC(hwndMsg, hdc);

			MoveWindow(hwndMsg, (GetSystemMetrics(SM_CXSCREEN) - w) / 2,
					(GetSystemMetrics(SM_CYSCREEN) - h) / 2, w, h, TRUE);

			ShowWindow(hwndMsg, SW_SHOW);
			UpdateWindow(hwndMsg);
			}
		else 
			{
			int h, w;
			TEXTMETRIC tm;
			HDC hdc;

			hdc = GetDC(hwndMsg);

			GetTextMetrics(hdc, &tm);

			w = tm.tmAveCharWidth * (strlen(msgWindow) + 5) +
					2 * GetSystemMetrics(SM_CXBORDER);
			h = tm.tmHeight + tm.tmExternalLeading +
					GetSystemMetrics(SM_CYCAPTION) +
					2 * GetSystemMetrics(SM_CYBORDER);

			ReleaseDC(hwndMsg, hdc);

			MoveWindow(hwndMsg, (GetSystemMetrics(SM_CXSCREEN) - w) / 2,
					(GetSystemMetrics(SM_CYSCREEN) - h) / 2, w, h, TRUE);
			}

		InvalidateRect(hwndMsg, NULL, TRUE);
		}
	else
		{
		if (hwndMsg)
			{
			if (DestroyWindow(hwndMsg))
				{
				hwndMsg = FALSE;
				}
			}
		}

	letWindowsMultitask();
	}

void cdecl errorDisp(const char *fmt, ...)
	{
	int i;
	va_list ap;

	if (fmt)
		{
		if (nextError == NUMERRORS)
			{
			for (i = 1; i < NUMERRORS; i++)
				{
				strcpy(errors[i-1], errors[i]);
				}

			nextError--;
			}

		va_start(ap, fmt);
		vsprintf(errors[nextError], fmt, ap);
		va_end(ap);

		stripansi(errors[nextError]);
		
		for (i = 0; errors[nextError][i]; i++)
			{
			if (errors[nextError][i] < 32)
				{
				errors[nextError][i] = 32;
				}
			}

		nextError++;
		}

	if (!hwndError)
		{
		hwndError = CreateWindow("Citadel Error", "Citadel Error Log",
				WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
				CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

		ShowWindow(hwndError, SW_SHOWMINNOACTIVE);
		}
	else 
		{
		InvalidateRect(hwndError, NULL, TRUE);
		}

	if (!fmt)
		{
		ShowWindow(hwndError, IsIconic(hwndError) ? SW_RESTORE : SW_SHOW);
		SetFocus(hwndError);
		}

	UpdateWindow(hwndError);
	}

void cdecl trapDisp(const char *fmt, ...)
	{
	int i;
	va_list ap;

	if (fmt)
		{
		char tbuf[3];

		if (nextTrap == NUMTRAP)
			{
			for (i = 1; i < NUMTRAP; i++)
				{
				strcpy(traps[i-1], traps[i]);
				}
			nextTrap--;
			}

		va_start(ap, fmt);
		vsprintf(traps[nextTrap], fmt, ap);
		va_end(ap);

		stripansi(traps[nextTrap]);
		
		for (i = 0; traps[nextTrap][i]; i++)
			{
			if (traps[nextTrap][i] < 32)
				{
				traps[nextTrap][i] = 32;
				}
			}

		citWinReOpen(&trapfl);
		citWrite(traps[nextTrap], strlen(traps[nextTrap]), 1, trapfl);
		tbuf[0] = '\r'; tbuf[1] = '\n'; tbuf[2] = 0;
		citWrite(tbuf, 2, 1, trapfl);
		citWinCloseTmp(&trapfl);

		nextTrap++;
		}

	if (!hwndTrap)
		{
		hwndTrap = CreateWindow("Citadel Trap", "Citadel Trap Log",
				WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
				CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
		}
	else 
		{
		InvalidateRect(hwndTrap, NULL, TRUE);
		}

	if (!fmt)
		{
		ShowWindow(hwndTrap, IsIconic(hwndTrap) ? SW_RESTORE : SW_SHOW);
		SetFocus(hwndTrap);
		}

	UpdateWindow(hwndTrap);
	}
#endif