/*
 * '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 "heap.h"
#include "library.h"
#include "win.h"
#include "texts.h"
#include "stddebug.h"
/* #define DEBUG_MSGBOX */
#include "debug.h"


/*
 * Defaults for button-texts
 */

ButtonTexts ButtonText = {    /* FIXME: Norwegian Translation missing */
#if #LANG(De)
  "&Ja",     'J',
  "&Nein",   'N',
  "&Ok",     'O',
  "&Abbruch",'A',
  "&Abbruch",'A',
  "&Wiederholen", 'W',
  "&Ignorieren", 'I'
#else
  "&Yes",    'Y',
  "&No",     'N',
  "&Ok",     'O',
  "&Cancel", 'C',
  "&Abort",  'A',
  "&Retry",  'R',
  "&Ignore", 'I'
#endif
};

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, str='%s', title='%s', %04X)\n", 
			str, title, type);
		}
	else {
		hInst = wndPtr->hInstance;
		dprintf_msgbox(stddeb,"MessageBox(%04X, str='%s', title='%s', %04X)\n", 
			hWnd, str, 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);
}
