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

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


#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"
#include "stddebug.h"
/* #define DEBUG_MSGBOX */
/* #undef  DEBUG_MSGBOX */ 
#include "debug.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;
		dprintf_msgbox(stddeb,"MessageBox(NULL, %08X='%s', %08X='%s', %04X)\n", 
									str, str, title, title, type);
		}
	else {
		hInst = wndPtr->hInstance;
		dprintf_msgbox(stddeb,"MessageBox(%04X, %08X='%s', %08X='%s', %04X)\n", 
							hWnd, str, str, title, title, type);
		}
    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";
	dprintf_msgbox(stddeb, "MessageBox // before RegisterClass, '%s' '%s' !\n", str, title);
	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;
		}
	dprintf_msgbox(stddeb, "MessageBox // before Msg Loop !\n");
	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;
	dprintf_msgbox(stddeb, "MessageBox return %04X !\n", nRet);
	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;

	switch(message) {
	case WM_CREATE:
		dprintf_msgbox(stddeb, "MessageBox WM_CREATE hWnd=%04X !\n", hWnd);
		wndPtr = WIN_FindWndPtr(hWnd);
		createStruct = (CREATESTRUCT *)lParam;
		lpmb = (LPMSGBOX)createStruct->lpCreateParams;
		if (lpmb == NULL) break;
		*((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmb;
		dprintf_msgbox(stddeb, "MessageBox WM_CREATE title='%s' str='%s' !\n", 
									lpmb->Title, lpmb->Str);
		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:
		dprintf_msgbox(stddeb, "MessageBox WM_SHOWWINDOW hWnd=%04X !\n", hWnd);
		if (!(wParam == 0 && lParam == 0L)) {
			InvalidateRect(hWnd, NULL, TRUE);
			}
	    break;
	case WM_PAINT:
		dprintf_msgbox(stddeb, "MessageBox WM_PAINT hWnd=%04X !\n", hWnd);
		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_LEFT | DT_VCENTER | 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_LEFT | DT_VCENTER | DT_WORDBREAK);
		SetTextColor(hDC, OldTextColor);
		EndPaint(hWnd, &ps);
		dprintf_msgbox(stddeb, "MessageBox End of WM_PAINT !\n");
		break;
	case WM_DESTROY:
	    dprintf_msgbox(stddeb, "MessageBox WM_DESTROY !\n");
	    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);
	    dprintf_msgbox(stddeb, "MessageBox WM_DESTROY end !\n");
	    lpmb->ActiveFlg = FALSE;
	    break;
	case WM_COMMAND:
	    lpmb = MsgBoxGetStorageHeader(hWnd);
		if (lpmb == NULL) break;
	    if (wParam < IDOK || wParam > IDNO) return(0);
	    lpmb->wRetVal = wParam;
	    dprintf_msgbox(stddeb, "MessageBox sending WM_CLOSE !\n");
	    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;
    RECT 	rect;
    BITMAP	bm;
    OFSTRUCT	ofstruct;
    HBITMAP     hbmpOld;
    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);
	hbmpOld = SelectObject(hMemDC, hBitMap);
	GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
	BitBlt(hDC, rect.left, rect.top, bm.bmWidth, bm.bmHeight, 
					hMemDC, 0, 0, SRCCOPY);
        SelectObject( hMemDC, hbmpOld );
	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:
                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);
}
