/*
 * 'Wine' MessageBox function handling
 *
 * Copyright 1993 Martin Ayotte
 */

static char Copyright[] = "Copyright Martin Ayotte, 1993";

#define DEBUG_MSGBOX

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include "prototypes.h"
#include "heap.h"
#include "win.h"
#include "texts.h"
 
/*
 * Defaults for button-texts
 */

ButtonTexts ButtonText = {
  "&Yes",    'Y',
  "&No",     'N',
  "&Ok",     'O',
  "&Cancel", 'C',
  "&Abort",  'A',
  "&Retry",  'R',
  "&Ignore", 'I'
};

extern HINSTANCE hSysRes;
extern HBITMAP hUpArrow;

typedef struct tagMSGBOX {
    LPSTR	Title;
    LPSTR	Str;
    WORD	wType;
    WORD	wRetVal;
    BOOL	ActiveFlg;
    HWND	hWndYes;
    HWND	hWndNo;
    HWND	hWndCancel;
    HICON	hIcon;
    RECT	rectIcon;
    RECT	rectStr;
} MSGBOX;
typedef MSGBOX FAR* LPMSGBOX;

LONG SystemMessageBoxProc(HWND hwnd, WORD message, WORD wParam, LONG lParam);

/**************************************************************************
 *			MessageBox  [USER.1]
 */

int MessageBox(HWND hWnd, LPSTR str, LPSTR title, WORD type)
{
	HWND    	hDlg, hWndOld;
	WND	    	*wndPtr;
	WNDCLASS  	wndClass;
	MSG	    	msg;
    LPMSGBOX 	lpmb;
	DWORD		dwStyle;
	HINSTANCE	hInst;
	int			nRet;

	if (title == NULL)
		title = "Error";
	wndPtr = WIN_FindWndPtr(hWnd);
	if (wndPtr == NULL) {
		hInst = hSysRes;
#ifdef DEBUG_MSGBOX
		printf("MessageBox(NULL, %08X='%s', %08X='%s', %04X)\n", 
									str, str, title, title, type);
#endif
		}
	else {
		hInst = wndPtr->hInstance;
#ifdef DEBUG_MSGBOX
		printf("MessageBox(%04X, %08X='%s', %08X='%s', %04X)\n", 
							hWnd, str, str, title, title, type);
#endif
		}
    lpmb = (LPMSGBOX) malloc(sizeof(MSGBOX));
	memset(lpmb, 0, sizeof(MSGBOX));
/*	lpmb->Title = title;*/
	lpmb->Title = (LPSTR) malloc(strlen(title) + 1);
	strcpy(lpmb->Title, title);
/*	lpmb->Str = str;*/
	if (str && *str)
	{
		lpmb->Str = (LPSTR) malloc(strlen(str) + 1);
		strcpy(lpmb->Str, str);
	}
	else
	{
		lpmb->Str = (LPSTR) malloc(8);
		strcpy(lpmb->Str, "Message");
	}
	lpmb->wType = type;
	lpmb->ActiveFlg = TRUE;
	wndClass.style           = CS_HREDRAW | CS_VREDRAW ;
	wndClass.lpfnWndProc     = (WNDPROC)SystemMessageBoxProc;
	wndClass.cbClsExtra      = 0;
	wndClass.cbWndExtra      = 0;
	wndClass.hInstance       = hInst;
	wndClass.hIcon           = (HICON)NULL;
	wndClass.hCursor         = LoadCursor((HANDLE)NULL, IDC_ARROW); 
	wndClass.hbrBackground   = GetStockObject(WHITE_BRUSH);
	wndClass.lpszMenuName    = NULL;
	wndClass.lpszClassName   = "MESSAGEBOX";
#ifdef DEBUG_MSGBOX
	printf( "MessageBox // before RegisterClass, '%s' '%s' !\n", str, title);
#endif
	if (!RegisterClass(&wndClass)) {
		printf("Unable to Register class 'MESSAGEBOX' !\n");
		if (lpmb != NULL) free(lpmb);
		return 0;
		}
	dwStyle = WS_POPUP | WS_DLGFRAME | WS_VISIBLE;
	if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) == 0) dwStyle |= WS_CAPTION;
	hWndOld = GetFocus();
	hDlg = CreateWindow("MESSAGEBOX", lpmb->Title, dwStyle, 100, 150, 400, 160,
				(HWND)NULL, (HMENU)NULL, hInst, (LPSTR)lpmb);
	if (hDlg == 0) {
		printf("Unable to create 'MESSAGEBOX' window !\n");
		if (lpmb != NULL) free(lpmb);
		return 0;
		}
#ifdef DEBUG_MSGBOX
	printf( "MessageBox // before Msg Loop !\n");
#endif
	while(TRUE) {
		if (!lpmb->ActiveFlg) break;
		if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break;
		TranslateMessage(&msg);
		if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) != 0 &&
			msg.hwnd != hDlg) {
			switch(msg.message) {
				case WM_KEYDOWN:
				case WM_LBUTTONDOWN:
				case WM_MBUTTONDOWN:
				case WM_RBUTTONDOWN:
					MessageBeep(0);
					break;
				}
			}
		DispatchMessage(&msg);
		}
	SetFocus(hWndOld);
	nRet = lpmb->wRetVal;
	if (lpmb != NULL) free(lpmb);
	if (!UnregisterClass("MESSAGEBOX", hInst)) return 0;
#ifdef DEBUG_MSGBOX
	printf( "MessageBox return %04X !\n", nRet);
#endif
	return(nRet);
}


LPMSGBOX MsgBoxGetStorageHeader(HWND hwnd)
{
    WND  *wndPtr;
    LPMSGBOX lpmb;
    wndPtr = WIN_FindWndPtr(hwnd);
    if (wndPtr == 0) {
    	printf("Bad Window handle on MessageBox !\n");
    	return 0;
    	}
    lpmb = *((LPMSGBOX *)&wndPtr->wExtra[1]);
    return lpmb;
}




LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam)
{
	WND	    	*wndPtr;
	CREATESTRUCT *createStruct;
	PAINTSTRUCT	ps;
	HDC			hDC;
	DWORD		OldTextColor;
	RECT		rect;
	LPMSGBOX	lpmb;
	BITMAP		bm;
	HBITMAP		hBitMap;
	HDC			hMemDC;
	HICON		hIcon;
	HINSTANCE	hInst2;
	int			x;
	switch(message) {
	case WM_CREATE:
#ifdef DEBUG_MSGBOX
		printf("MessageBox WM_CREATE hWnd=%04X !\n", hWnd);
#endif
		wndPtr = WIN_FindWndPtr(hWnd);
		createStruct = (CREATESTRUCT *)lParam;
		lpmb = (LPMSGBOX)createStruct->lpCreateParams;
		if (lpmb == NULL) break;
		*((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmb;
#ifdef DEBUG_MSGBOX
		printf("MessageBox WM_CREATE title='%s' str='%s' !\n", 
									lpmb->Title, lpmb->Str);
#endif
		GetClientRect(hWnd, &rect);
		CopyRect(&lpmb->rectStr, &rect);
		lpmb->rectStr.bottom -= 32;
		switch(lpmb->wType & MB_TYPEMASK) {
		case MB_OK :
		        lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Ok.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 - 30, rect.bottom - 25, 
				60, 18, hWnd, IDOK, wndPtr->hInstance, 0L);
			break;
		case MB_OKCANCEL :
			lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Ok.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 - 65, rect.bottom - 25, 
				60, 18, hWnd, IDOK, wndPtr->hInstance, 0L);
			lpmb->hWndCancel = CreateWindow("BUTTON", ButtonText.Cancel.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 + 5, rect.bottom - 25, 
				60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L);
			break;
		case MB_ABORTRETRYIGNORE :
			lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Retry.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 - 100, rect.bottom - 25, 
				60, 18, hWnd, IDRETRY, wndPtr->hInstance, 0L);
			lpmb->hWndNo = CreateWindow("BUTTON", ButtonText.Ignore.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 - 30, rect.bottom - 25, 
				60, 18, hWnd, IDIGNORE, wndPtr->hInstance, 0L);
			lpmb->hWndCancel = CreateWindow("BUTTON", ButtonText.Abort.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 + 40, rect.bottom - 25, 
				60, 18, hWnd, IDABORT, wndPtr->hInstance, 0L);
			break;
		case MB_YESNO :
			lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Yes.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 - 65, rect.bottom - 25, 
				60, 18, hWnd, IDYES, wndPtr->hInstance, 0L);
			lpmb->hWndNo = CreateWindow("BUTTON", ButtonText.No.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 + 5, rect.bottom - 25, 
				60, 18, hWnd, IDNO, wndPtr->hInstance, 0L);
			break;
		case MB_YESNOCANCEL :
			lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Yes.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 - 100, rect.bottom - 25, 
				60, 18, hWnd, IDYES, wndPtr->hInstance, 0L);
			lpmb->hWndNo = CreateWindow("BUTTON", ButtonText.No.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 - 30, rect.bottom - 25, 
				60, 18, hWnd, IDNO, wndPtr->hInstance, 0L);
			lpmb->hWndCancel = CreateWindow("BUTTON", ButtonText.Cancel.Label,
				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
				rect.right / 2 + 40, rect.bottom - 25, 
				60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L);
			break;
		}
	    switch(lpmb->wType & MB_ICONMASK) {
		case MB_ICONEXCLAMATION:
			printf("MsgBox LoadIcon Exclamation !\n");
			lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION);
			break;
		case MB_ICONQUESTION:
			printf("MsgBox LoadIcon Question !\n");
			lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_QUESTION);
			break;
		case MB_ICONASTERISK:
			printf("MsgBox LoadIcon Asterisk !\n");
			lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_ASTERISK);
			break;
		case MB_ICONHAND:
			printf("MsgBox LoadIcon Hand !\n");
			lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_HAND);
			break;
			}
	    if (lpmb->hIcon != (HICON)NULL) {
			SetRect(&lpmb->rectIcon, 16,
			lpmb->rectStr.bottom / 2 - 16, 48,
			lpmb->rectStr.bottom / 2 + 16);
			lpmb->rectStr.left += 64;
			}
	    break;
	case WM_SHOWWINDOW:
#ifdef DEBUG_MSGBOX
		printf("MessageBox WM_SHOWWINDOW hWnd=%04X !\n", hWnd);
#endif
		if (!(wParam == 0 && lParam == 0L)) {
			InvalidateRect(hWnd, NULL, TRUE);
			}
	    break;
	case WM_PAINT:
#ifdef DEBUG_MSGBOX
		printf("MessageBox WM_PAINT hWnd=%04X !\n", hWnd);
#endif
		lpmb = MsgBoxGetStorageHeader(hWnd);
		if (lpmb == NULL) break;
		if (!lpmb->ActiveFlg) break;
		hDC = BeginPaint(hWnd, &ps);
		if (hDC == 0) {
			printf("MessageBox WM_PAINT // BeginPaint returned BAD hDC !\n");
			break;
			}
		GetClientRect(hWnd, &rect);
		FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH));
		CopyRect(&rect, &lpmb->rectStr);
		OldTextColor = SetTextColor(hDC, 0x00000000);
		if (lpmb->hIcon) 
			DrawIcon(hDC, lpmb->rectIcon.left,
				lpmb->rectIcon.top, lpmb->hIcon);
		DrawText(hDC, lpmb->Str, -1, &rect, 
			DT_CALCRECT | DT_CENTER | DT_WORDBREAK);
		rect.top = lpmb->rectStr.bottom / 2 - rect.bottom / 2;
		rect.bottom = lpmb->rectStr.bottom / 2 + rect.bottom / 2;
		DrawText(hDC, lpmb->Str, -1, &rect, DT_CENTER | DT_WORDBREAK);
		SetTextColor(hDC, OldTextColor);
		EndPaint(hWnd, &ps);
#ifdef DEBUG_MSGBOX
		printf("MessageBox End of WM_PAINT !\n");
#endif
		break;
	case WM_DESTROY:
#ifdef DEBUG_MSGBOX
	    printf("MessageBox WM_DESTROY !\n");
#endif
	    ReleaseCapture();
	    lpmb = MsgBoxGetStorageHeader(hWnd);
		if (lpmb == NULL) break;
	    if (lpmb->hIcon) DestroyIcon(lpmb->hIcon);
	    if (lpmb->hWndYes) DestroyWindow(lpmb->hWndYes);
	    if (lpmb->hWndNo) DestroyWindow(lpmb->hWndNo);
	    if (lpmb->hWndCancel) DestroyWindow(lpmb->hWndCancel);
#ifdef DEBUG_MSGBOX
	    printf("MessageBox WM_DESTROY end !\n");
#endif
	    lpmb->ActiveFlg = FALSE;
	    break;
	case WM_COMMAND:
	    lpmb = MsgBoxGetStorageHeader(hWnd);
		if (lpmb == NULL) break;
	    if (wParam < IDOK || wParam > IDNO) return(0);
	    lpmb->wRetVal = wParam;
#ifdef DEBUG_MSGBOX
	    printf("MessageBox sending WM_CLOSE !\n");
#endif
	    PostMessage(hWnd, WM_CLOSE, 0, 0L);
	    break;
	case WM_CHAR:
	    lpmb = MsgBoxGetStorageHeader(hWnd);
/*          if (wParam >= 'a' || wParam <= 'z') wParam -= 'a' - 'A'; */
		wParam = toupper(wParam);
	    if (wParam == ButtonText.Yes.Hotkey)
                lpmb->wRetVal = IDYES;
            else if (wParam == ButtonText.Ok.Hotkey)
                lpmb->wRetVal = IDOK;
            else if (wParam == ButtonText.Retry.Hotkey)
                lpmb->wRetVal = IDRETRY;
            else if (wParam == ButtonText.Abort.Hotkey)
                lpmb->wRetVal = IDABORT;
            else if (wParam == ButtonText.No.Hotkey)
                lpmb->wRetVal = IDNO;
            else if (wParam == ButtonText.Ignore.Hotkey)
                 lpmb->wRetVal = IDIGNORE;
            else if ((wParam == ButtonText.Ok.Hotkey) || (wParam == VK_ESCAPE))
                lpmb->wRetVal = IDCANCEL;
	    else
		return 0;
		if (lpmb == NULL) break;
		ShowWindow(hWnd, SW_HIDE);
		PostMessage(hWnd, WM_CLOSE, 0, 0L);
		break;
	default:
	    return DefWindowProc(hWnd, message, wParam, lParam );
    }
return(0);
}



/*************************************************************************
 *			"About Wine..." Dialog Box
 */
BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam)
{
    HDC  	hDC;
    HDC		hMemDC;
    PAINTSTRUCT ps;
    int 	OldBackMode;
    HFONT	hOldFont;
    RECT 	rect;
    BITMAP	bm;
    int 	X;
    OFSTRUCT	ofstruct;
    static LPSTR	ptr;
    static char 	str[256];
    static HBITMAP	hBitMap = 0;
    static BOOL		CreditMode;
    static HANDLE	hFile = 0;
    switch (msg) {
    case WM_INITDIALOG:
	CreditMode = FALSE;
	strcpy(str, "WINELOGO");
	hBitMap = LoadBitmap((HINSTANCE)NULL, (LPSTR)str);

	strcpy(str, "LICENSE");
	printf("str = '%s'\n", str);
	hFile = OpenFile((LPSTR)str, &ofstruct, OF_READ);
	ptr = (LPSTR)malloc(2048);
	lseek(hFile, 0L, SEEK_SET);
	_lread(hFile, ptr, 2000L);
	close(hFile);
	return TRUE;
    case WM_PAINT:
	hDC = BeginPaint(hDlg, &ps);
	GetClientRect(hDlg, &rect);
	if (CreditMode) {
	    FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH));
	    InflateRect(&rect, -8, -8);
	    DrawText(hDC, ptr, -1, &rect, DT_LEFT | DT_WORDBREAK);
	    EndPaint(hDlg, &ps);
	    return TRUE;
	    }
	FillRect(hDC, &rect, GetStockObject(GRAY_BRUSH));
	InflateRect(&rect, -3, -3);
	FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
	InflateRect(&rect, -10, -10);
	hMemDC = CreateCompatibleDC(hDC);
	SelectObject(hMemDC, hBitMap);
	GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
	BitBlt(hDC, rect.left, rect.top, bm.bmWidth, bm.bmHeight, 
					hMemDC, 0, 0, SRCCOPY);
	DeleteDC(hMemDC);
	EndPaint(hDlg, &ps);
	return TRUE;
    case WM_COMMAND:
	switch (wParam)
	    {
	    case IDYES:
		if (!CreditMode) {
		    SetWindowPos(hDlg, (HWND)NULL, 0, 0, 640, 480, 
				SWP_NOMOVE | SWP_NOZORDER);
		    }
		else {
		    SetWindowPos(hDlg, (HWND)NULL, 0, 0, 320, 250, 
				SWP_NOMOVE | SWP_NOZORDER);
		    }
		CreditMode = !CreditMode;
		ShowWindow(GetDlgItem(hDlg, IDYES), CreditMode ? SW_HIDE : SW_SHOW);
		ShowWindow(GetDlgItem(hDlg, IDOK), CreditMode ? SW_HIDE : SW_SHOW);
		InvalidateRect(hDlg, (LPRECT)NULL, TRUE);
		UpdateWindow(hDlg);
		return TRUE;
	    case IDCANCEL:
	    case IDOK:
CloseDLG:	if (hBitMap != 0 ) DeleteObject(hBitMap);
		if (ptr != NULL) free(ptr);
		EndDialog(hDlg, TRUE);
		return TRUE;
	    default:
		return TRUE;
	    }
    }
return FALSE;
}


/**************************************************************************
 *			FatalAppExit  [USER.137]
 */

void FatalAppExit(WORD wAction, LPSTR str)
{
MessageBox((HWND)NULL, str, NULL, MB_SYSTEMMODAL | MB_OK);
exit(1);
}
