/*
 * SHLWAPI message box functions
 *
 * Copyright 2004 Jon Griffiths
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#define COM_NO_WINDOWS_H
#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "shlwapi.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "resource.h"


WINE_DEFAULT_DEBUG_CHANNEL(shell);

extern HINSTANCE shlwapi_hInstance; /* in shlwapi_main.c */

static const WCHAR szDontShowKey[] = { 'S','o','f','t','w','a','r','e','\\',
  'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
  'E','x','p','l','o','r','e','r','\\','D','o','n','t','S','h','o','w',
  'M','e','T','h','i','s','D','i','a','l','o','g','A','g','a','i','n','\0'
};

INT_PTR WINAPI SHMessageBoxCheckExW(HWND,HINSTANCE,LPCWSTR,DLGPROC,LPARAM,INT_PTR,LPCWSTR);
INT_PTR WINAPI SHMessageBoxCheckW(HWND,LPCWSTR,LPCWSTR,DWORD,INT_PTR,LPCWSTR);

/* Data held by each general message boxes */
typedef struct tagDLGDATAEX
{
  DLGPROC dlgProc;   /* User supplied DlgProc */
  LPARAM  lParam;    /* User supplied LPARAM for dlgProc */
  LPCWSTR lpszId;    /* Name of reg key holding whether to skip */
} DLGDATAEX;

/* Dialogue procedure for general message boxes */
static INT_PTR CALLBACK SHDlgProcEx(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  DLGDATAEX *d = (DLGDATAEX *)GetWindowLongW(hDlg, DWL_USER);

  TRACE("(%p,%u,%d,%ld) data %p\n", hDlg, uMsg, wParam, lParam, d);

  switch (uMsg)
  {
  case WM_INITDIALOG:
  {
    /* FIXME: Not sure where native stores its lParam */
    SetWindowLongW(hDlg, DWL_USER, lParam);
    d = (DLGDATAEX *)lParam;
    TRACE("WM_INITDIALOG: %p, %s,%p,%p\n", hDlg, debugstr_w(d->lpszId),
          d->dlgProc, (void*)d->lParam);
    if (d->dlgProc)
      return d->dlgProc(hDlg, uMsg, wParam, d->lParam);
    return TRUE;
  }

  case WM_COMMAND:
    switch (LOWORD(wParam))
    {
      case IDYES:
        wParam = MAKELONG(IDOK, HIWORD(wParam));
        /* Fall through ... */
      case IDNO:
        if (LOWORD(wParam) == IDNO)
          wParam = MAKELONG(IDCANCEL, HIWORD(wParam));
        /* Fall through ... */
      case IDOK:
      case IDCANCEL:

        TRACE("WM_COMMAND: id=%s data=%p\n",
              LOWORD(wParam) == IDOK ? "IDOK" : "IDCANCEL", d);

        if (SendMessageW(GetDlgItem(hDlg, IDC_ERR_DONT_SHOW), BM_GETCHECK, 0L, 0L))
        {
          DWORD dwZero = 0;

          /* The user clicked 'don't show again', so set the key */
          SHRegSetUSValueW(szDontShowKey, d->lpszId, REG_DWORD, &dwZero,
                           sizeof(dwZero), SHREGSET_DEFAULT);
        }
        if (!d->dlgProc || !d->dlgProc(hDlg, uMsg, wParam, lParam))
          EndDialog(hDlg, wParam);
        return TRUE;
    }
    break;

  default:
    break;
  }

  if (d && d->dlgProc)
    return d->dlgProc(hDlg, uMsg, wParam, lParam);
  return FALSE;
}

/*************************************************************************
 * @ [SHLWAPI.291]
 *
 * Pop up a 'Don't show this message again' dialogue box.
 *
 * PARAMS
 *  hWnd     [I] Window to be the dialogues' parent
 *  hInst    [I] Instance of the module holding the dialogue resource
 *  lpszName [I] Resource Id of the dialogue resource
 *  dlgProc  [I] Dialog procedure, or NULL for default handling
 *  lParam   [I] LPARAM to pass to dlgProc
 *  iRet     [I] Value to return if dialogue is not shown
 *  lpszId   [I] Name of registry subkey which determines whether to show the dialog
 *
 * RETURNS
 *  Success: The value returned from the dialogue procedure.
 *  Failure: iRet, if the dialogue resource could not be loaded or the dialogue
 *           should not be shown.
 *
 * NOTES
 *  Both lpszName and lpszId must be less than MAX_PATH in length.
 */
INT_PTR WINAPI SHMessageBoxCheckExA(HWND hWnd, HINSTANCE hInst, LPCSTR lpszName,
                                    DLGPROC dlgProc, LPARAM lParam, INT_PTR iRet,
                                    LPCSTR lpszId)
{
  WCHAR szNameBuff[MAX_PATH], szIdBuff[MAX_PATH];
  LPCWSTR szName = szNameBuff;

  if (HIWORD(lpszName))
    MultiByteToWideChar(CP_ACP, 0, lpszName, -1, szNameBuff, MAX_PATH);
  else
    szName = (LPCWSTR)lpszName; /* Resource Id or NULL */

  MultiByteToWideChar(CP_ACP, 0, lpszId, -1, szIdBuff, MAX_PATH);

  return SHMessageBoxCheckExW(hWnd, hInst, szName, dlgProc, lParam, iRet, szIdBuff);
}

/*************************************************************************
 * @ [SHLWAPI.292]
 *
 * Unicode version of SHMessageBoxCheckExW.
 */
INT_PTR WINAPI SHMessageBoxCheckExW(HWND hWnd, HINSTANCE hInst, LPCWSTR lpszName,
                                    DLGPROC dlgProc, LPARAM lParam, INT_PTR iRet, LPCWSTR lpszId)
{
  DLGDATAEX d;

  if (!SHRegGetBoolUSValueW(szDontShowKey, lpszId, FALSE, TRUE))
    return iRet;

  d.dlgProc = dlgProc;
  d.lParam = lParam;
  d.lpszId = lpszId;
  return DialogBoxParamW(hInst, (LPCWSTR)lpszName, hWnd, SHDlgProcEx, (LPARAM)&d);
}

/* Data held by each shlwapi message box */
typedef struct tagDLGDATA
{
  LPCWSTR lpszTitle; /* User supplied message title */
  LPCWSTR lpszText;  /* User supplied message text */
  DWORD   dwType;    /* Message box type */
} DLGDATA;

/* Dialogue procedure for shlwapi message boxes */
static INT_PTR CALLBACK SHDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  TRACE("(%p,%u,%d,%ld)\n", hDlg, uMsg, wParam, lParam);

  switch (uMsg)
  {
  case WM_INITDIALOG:
  {
    DLGDATA *d = (DLGDATA *)lParam;
    TRACE("WM_INITDIALOG: %p, %s,%s,%ld\n", hDlg, debugstr_w(d->lpszTitle),
          debugstr_w(d->lpszText), d->dwType);

    SetWindowTextW(hDlg, d->lpszTitle);
    SetWindowTextW(GetDlgItem(hDlg, IDS_ERR_USER_MSG), d->lpszText);

    /* Set buttons according to dwType */
    switch (d->dwType)
    {
    case 0:
      ShowWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);
      /* FIXME: Move OK button to position of the Cancel button (cosmetic) */
    case 1:
      ShowWindow(GetDlgItem(hDlg, IDYES), FALSE);
      ShowWindow(GetDlgItem(hDlg, IDNO), FALSE);
      break;
    default:
      ShowWindow(GetDlgItem(hDlg, IDOK), FALSE);
      ShowWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);
      break;
    }
    return TRUE;
  }
  default:
    break;
  }
  return FALSE;
}

/*************************************************************************
 * @ [SHLWAPI.185]
 *
 * Pop up a 'Don't show this message again' dialogue box.
 *
 * PARAMS
 *  hWnd      [I] Window to be the dialogues' parent
 *  lpszText  [I] Text of the message to show
 *  lpszTitle [I] Title of the dialogue box
 *  dwType    [I] Type of dialogue buttons (See below)
 *  iRet      [I] Value to return if dialogue is not shown
 *  lpszId    [I] Name of registry subkey which determines whether to show the dialog
 *
 * RETURNS
 *  Success: The value returned from the dialogue procedure (e.g. IDOK).
 *  Failure: iRet, if the default dialogue resource could not be loaded or the
 *           dialogue should not be shown.
 *
 * NOTES
 *  - Both lpszTitle and lpszId must be less than MAX_PATH in length.
 *  - Possible values for dwType are:
 *| Value     Buttons
 *| -----     -------
 *|   0       OK
 *|   1       OK/Cancel
 *|   2       Yes/No
 */
INT_PTR WINAPI SHMessageBoxCheckA(HWND hWnd, LPCSTR lpszText, LPCSTR lpszTitle,
                                  DWORD dwType, INT_PTR iRet, LPCSTR lpszId)
{
  WCHAR szTitleBuff[MAX_PATH], szIdBuff[MAX_PATH];
  WCHAR *szTextBuff = NULL;
  int iLen;
  INT_PTR iRetVal;

  if (lpszTitle)
    MultiByteToWideChar(CP_ACP, 0, lpszTitle, -1, szTitleBuff, MAX_PATH);

  if (lpszText)
  {
    iLen = MultiByteToWideChar(CP_ACP, 0, lpszText, -1, NULL, 0);
    szTextBuff = HeapAlloc(GetProcessHeap(), 0, iLen * sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, lpszText, -1, szTextBuff, iLen);
  }

  MultiByteToWideChar(CP_ACP, 0, lpszId, -1, szIdBuff, MAX_PATH);

  iRetVal = SHMessageBoxCheckW(hWnd, szTextBuff, lpszTitle ? szTitleBuff : NULL,
                               dwType, iRet, szIdBuff);
  if (szTextBuff)
    HeapFree(GetProcessHeap(), 0, szTextBuff);
  return iRetVal;
}

/*************************************************************************
 * @ [SHLWAPI.191]
 *
 * Unicode version of SHMessageBoxCheckA.
 */
INT_PTR WINAPI SHMessageBoxCheckW(HWND hWnd, LPCWSTR lpszText, LPCWSTR lpszTitle,
                                  DWORD dwType, INT_PTR iRet, LPCWSTR lpszId)
{
  DLGDATA d;

  d.lpszTitle = lpszTitle;
  d.lpszText = lpszText;
  d.dwType = dwType;

  return SHMessageBoxCheckExW(hWnd, shlwapi_hInstance, (LPCWSTR)IDD_ERR_DIALOG,
                               SHDlgProc, (LPARAM)&d, iRet, lpszId);
}
