/*
 * Copyright (c) 1999, 2000 Kungliga Tekniska Högskolan
 * (Royal Institute of Technology, Stockholm, Sweden).
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sysdep.h>

RCSID("$Id: win32_driver.c,v 1.1 2000/02/18 12:14:31 lha Exp $");

/*
 * The Win32 driver:
 *
 * The problem with this driver is that each message in created
 * a new thread, this effectively limits number of messages to
 * 4K, since this is the limit of threads in one process.
 *
 * This can be fixed, but I haven't bothered yet.
 */

#ifdef WITH_WIN32

#include <windows.h>

static int
getmaxwitdh (const char *msg, int *x, int *y)
{
    int i = 0;
    *x = 1;
    *y = 1;
    while (*msg) {
	switch (*msg) {
	case '\n':
	case '\r':
	    (*y)++;
	    if (*x < i)
		*x = i;
	    i = 0;
	    break;
	default:
	    i++;
	    break;
	}
	msg++;
    }
    if (*x < i)
	*x = i;
    return i;
}

HINSTANCE globalhInstance;

char *lzAppName = "zwgc";

LRESULT CALLBACK
WndProc (HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
    HDC		hdc;	/* A device context used for drawing */
    int	cx, cy;

    /* XXX should really use GetWindowLongPtr */
    char *msg = (char *) GetWindowLong (hwnd, 0);

    switch (nMsg) {
    case WM_CREATE: {
	TEXTMETRIC	tm;	
	CREATESTRUCT	*cs = (CREATESTRUCT *) lParam;

	/* First we use the system fixed font size to choose
	 * a nice button size. */

	if (cs == NULL) {
	    msg = "no CREATESTRUCT";
	} else {
	    msg = (char *) cs->lpCreateParams;
	    if (msg == 0)
		msg = "no msg, strange";
	    else
		SetWindowLong (hwnd, 0, (long) msg);
	    
	}
	getmaxwitdh(msg, &cx, &cy);
	

	hdc = GetDC (hwnd);
	SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
	GetTextMetrics (hdc, &tm);
	cx *= tm.tmAveCharWidth;
	cy *= (tm.tmHeight + tm.tmExternalLeading);

	ReleaseDC (hwnd, hdc);
	SetWindowPos (hwnd, HWND_TOP, 0, 0, cx, cy, SWP_NOMOVE);

	return 0;
    }
    case WM_DESTROY:
 	free (msg);
	PostQuitMessage (0);
	return 0;
    case WM_LBUTTONUP:
	PostMessage (hwnd, WM_DESTROY, 0, 0);
	return 0;
    case WM_RBUTTONUP:
	/* copy marked to clipboard */
	break;
    case WM_PAINT: {
	PAINTSTRUCT	ps;
	RECT		rc;
	
	hdc = BeginPaint (hwnd, &ps);
	GetClientRect (hwnd, &rc);
	
	DrawText (hdc, msg, -1, &rc,
		  DT_CENTER | DT_VCENTER);
	
	EndPaint (hwnd, &ps);
	return 0;
    }
    }
    return DefWindowProc (hwnd, nMsg, wParam, lParam);
}

static DWORD
windows_worker (LPVOID text)
{
    HWND hWnd;
    MSG msg;

    hWnd = CreateWindow (lzAppName, "zgram", WS_BORDER|WS_CAPTION,
			 10, 10, 0, 0,
			 NULL, NULL, globalhInstance, text);
    if (hWnd == NULL) {
	MessageBox (NULL, "lessen", "lessen", MB_OK);
    } else {
	ShowWindow (hWnd, SW_SHOW);
	UpdateWindow (hWnd);
    }

    while (GetMessage (&msg, NULL, 0, 0)) {
	TranslateMessage (&msg);
	DispatchMessage (&msg);
    }
    ExitThread (0);
}

int
windows_init(void)
{
    HANDLE hMod;
    WNDCLASS wc;

    globalhInstance = GetModuleHandleA(0);

    wc.style		= CS_HREDRAW | CS_VREDRAW;
    wc.lpszClassName	= lzAppName;
    wc.lpfnWndProc	= (WNDPROC) WndProc;
    wc.cbClsExtra	= 0;
    wc.cbWndExtra	= 4;
    wc.hInstance	= globalhInstance;
    wc.hIcon		= LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor		= LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName	= NULL;

    RegisterClass (&wc);

    return 0;
}

char *
windows_driver(string input)
{
    string processed_input = tty_filter(input, 0);
    DWORD threadid;

    CreateThread (NULL, 0, windows_worker, processed_input , 0, &threadid);

    return(NULL);
}

#endif /* WITH_WIN32 */
