/*
 * Message boxes
 *
 * Copyright 1995 Bernd Schmidt
 */

#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
#include <stdio.h>
#include "windows.h"
#include "dlgs.h"
#include "heap.h"
#include "module.h"
#include "win.h"
#include "resource.h"
#include "task.h"

typedef struct
{
    LPCSTR title;
    LPCSTR text;
    UINT32 type;
} MSGBOX, *LPMSGBOX;


/**************************************************************************
 *           MSGBOX_DlgProc
 *
 * Dialog procedure for message boxes.
 */
static LRESULT MSGBOX_DlgProc( HWND32 hwnd, UINT32 message,
                               WPARAM32 wParam, LPARAM lParam )
{
  LPMSGBOX lpmb;
  RECT32 rect, textrect;
  HWND32 hItem;
  HDC32 hdc;
  LRESULT lRet;
  int i, buttons, bwidth, bheight, theight, wwidth, bpos;
  int borheight, iheight, tiheight;
  
  switch(message) {
   case WM_INITDIALOG:
    lpmb = (LPMSGBOX)lParam;
    if (lpmb->title) SetWindowText32A(hwnd, lpmb->title);
    SetWindowText32A(GetDlgItem32(hwnd, 100), lpmb->text);
    /* Hide not selected buttons */
    switch(lpmb->type & MB_TYPEMASK) {
     case MB_OK:
      ShowWindow32(GetDlgItem32(hwnd, 2), SW_HIDE);
      /* fall through */
     case MB_OKCANCEL:
      ShowWindow32(GetDlgItem32(hwnd, 3), SW_HIDE);
      ShowWindow32(GetDlgItem32(hwnd, 4), SW_HIDE);
      ShowWindow32(GetDlgItem32(hwnd, 5), SW_HIDE);
      ShowWindow32(GetDlgItem32(hwnd, 6), SW_HIDE);
      ShowWindow32(GetDlgItem32(hwnd, 7), SW_HIDE);
      break;
     case MB_ABORTRETRYIGNORE:
      ShowWindow32(GetDlgItem32(hwnd, 1), SW_HIDE);
      ShowWindow32(GetDlgItem32(hwnd, 2), SW_HIDE);
      ShowWindow32(GetDlgItem32(hwnd, 6), SW_HIDE);
      ShowWindow32(GetDlgItem32(hwnd, 7), SW_HIDE);
      break;
     case MB_YESNO:
      ShowWindow32(GetDlgItem32(hwnd, 2), SW_HIDE);
      /* fall through */
     case MB_YESNOCANCEL:
      ShowWindow32(GetDlgItem32(hwnd, 1), SW_HIDE);
      ShowWindow32(GetDlgItem32(hwnd, 3), SW_HIDE);
      ShowWindow32(GetDlgItem32(hwnd, 4), SW_HIDE);
      ShowWindow32(GetDlgItem32(hwnd, 5), SW_HIDE);
      break;
    }
    /* Set the icon */
    switch(lpmb->type & MB_ICONMASK) {
     case MB_ICONEXCLAMATION:
      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
                           (WPARAM16)LoadIcon16(0, IDI_EXCLAMATION), 0);
      break;
     case MB_ICONQUESTION:
      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
                           (WPARAM16)LoadIcon16(0, IDI_QUESTION), 0);
      break;
     case MB_ICONASTERISK:
      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
                           (WPARAM16)LoadIcon16(0, IDI_ASTERISK), 0);
      break;
     case MB_ICONHAND:
     default:
      SendDlgItemMessage16(hwnd, stc1, STM_SETICON, 
                           (WPARAM16)LoadIcon16(0, IDI_HAND), 0);
      break;
    }
    
    /* Position everything */
    GetWindowRect32(hwnd, &rect);
    borheight = rect.bottom - rect.top;
    wwidth = rect.right - rect.left;
    GetClientRect32(hwnd, &rect);
    borheight -= rect.bottom - rect.top;

    /* Get the icon height */
    GetWindowRect32(GetDlgItem32(hwnd, 1088), &rect);
    iheight = rect.bottom - rect.top;
    
    /* Get the number of visible buttons and their width */
    GetWindowRect32(GetDlgItem32(hwnd, 2), &rect);
    bheight = rect.bottom - rect.top;
    bwidth = rect.left;
    GetWindowRect32(GetDlgItem32(hwnd, 1), &rect);
    bwidth -= rect.left;
    for (buttons = 0, i = 1; i < 8; i++)
    {
      hItem = GetDlgItem32(hwnd, i);
      if (GetWindowLong32A(hItem, GWL_STYLE) & WS_VISIBLE) buttons++;
    }
    
    /* Get the text size */
    hItem = GetDlgItem32(hwnd, 100);
    GetWindowRect32(hItem, &textrect);
    MapWindowPoints32(0, hwnd, (LPPOINT32)&textrect, 2);
    
    GetClientRect32(hItem, &rect);
    hdc = GetDC32(hItem);
    lRet = DrawText32A( hdc, lpmb->text, -1, &rect,
                        DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_CALCRECT);
    theight = rect.bottom  - rect.top;
    tiheight = 16 + MAX(iheight, theight);
    ReleaseDC32(hItem, hdc);
    
    /* Position the text */
    SetWindowPos32(hItem, 0, textrect.left, (tiheight - theight) / 2, 
		   rect.right - rect.left, theight,
		   SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
    
    /* Position the icon */
    hItem = GetDlgItem32(hwnd, 1088);
    GetWindowRect32(hItem, &rect);
    MapWindowPoints32(0, hwnd, (LPPOINT32)&rect, 2);
    SetWindowPos32(hItem, 0, rect.left, (tiheight - iheight) / 2, 0, 0,
		   SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
    
    /* Resize the window */
    SetWindowPos32(hwnd, 0, 0, 0, wwidth, 8 + tiheight + bheight + borheight,
		   SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
    
    /* Position the buttons */
    bpos = (wwidth - bwidth * buttons) / 2;
    GetWindowRect32(GetDlgItem32(hwnd, 1), &rect);
    for (buttons = i = 0; i < 7; i++) {
      /* some arithmetic to get the right order for YesNoCancel windows */
      hItem = GetDlgItem32(hwnd, (i + 5) % 7 + 1);
      if (GetWindowLong32A(hItem, GWL_STYLE) & WS_VISIBLE) {
	if (buttons++ == ((lpmb->type & MB_DEFMASK) >> 8)) {
	  SetFocus32(hItem);
	  SendMessage32A( hItem, BM_SETSTYLE32, BS_DEFPUSHBUTTON, TRUE );
	}
	SetWindowPos32(hItem, 0, bpos, tiheight, 0, 0,
		       SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW);
	bpos += bwidth;
      }
    }
    return 0;
    break;
    
   case WM_COMMAND:
    switch (wParam)
    {
     case IDOK:
     case IDCANCEL:
     case IDABORT:
     case IDRETRY:
     case IDIGNORE:
     case IDYES:
     case IDNO:
      EndDialog(hwnd, wParam);
      break;
    }
    break;
  }
  return 0;
}


/**************************************************************************
 *           MessageBox16   (USER.1)
 */
INT16 MessageBox16( HWND16 hwnd, LPCSTR text, LPCSTR title, UINT16 type )
{
    return MessageBox32A( hwnd, text, title, type );
}


/**************************************************************************
 *           MessageBox32A   (USER32.390)
 */
INT32 MessageBox32A( HWND32 hWnd, LPCSTR text, LPCSTR title, UINT32 type )
{
    MSGBOX mbox;

    if (!text) text="<WINE-NULL>";
    if (!title) title="<WINE-NULL>";
    mbox.title = title;
    mbox.text  = text;
    mbox.type  = type;
    return DialogBoxIndirectParam32A( WIN_GetWindowInstance(hWnd),
                                      SYSRES_GetResPtr( SYSRES_DIALOG_MSGBOX ),
                                      hWnd, MSGBOX_DlgProc, (LPARAM)&mbox );
}


/**************************************************************************
 *           MessageBox32W   (USER32.395)
 */
INT32 MessageBox32W( HWND32 hwnd, LPCWSTR text, LPCWSTR title, UINT32 type )
{
    LPSTR titleA = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
    LPSTR textA  = HEAP_strdupWtoA( GetProcessHeap(), 0, text );
    INT32 ret = MessageBox32A( hwnd, textA, titleA, type );
    HeapFree( GetProcessHeap(), 0, titleA );
    HeapFree( GetProcessHeap(), 0, textA );
    return ret;
}


/**************************************************************************
 *           MessageBoxEx32A   (USER32.391)
 */
INT32
MessageBoxEx32A(HWND32 hWnd,LPCSTR text,LPCSTR title,UINT32 type,WORD langid) {
    /* ignore language id for now */
    return MessageBox32A(hWnd,text,title,type);
}

/**************************************************************************
 *           MessageBoxEx32W   (USER32.392)
 */
INT32
MessageBoxEx32W(HWND32 hWnd,LPCWSTR text,LPCWSTR title,UINT32 type,WORD langid)
{
    /* ignore language id for now */
    return MessageBox32W(hWnd,text,title,type);
}


/**************************************************************************
 *           FatalAppExit16   (KERNEL.137)
 */
void FatalAppExit16( UINT16 action, LPCSTR str )
{
    FatalAppExit32A( action, str );
}


/**************************************************************************
 *           FatalAppExit32A   (KERNEL32.108)
 */
void FatalAppExit32A( UINT32 action, LPCSTR str )
{
    MessageBox32A( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
    TASK_KillCurrentTask(0);
}


/**************************************************************************
 *           FatalAppExit32W   (KERNEL32.109)
 */
void FatalAppExit32W( UINT32 action, LPCWSTR str )
{
    MessageBox32W( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
    TASK_KillCurrentTask(0);
}


