/*
 * COMMDLG - Print Dialog
 *
 * Copyright 1994 Martin Ayotte
 * Copyright 1996 Albrecht Kleine
 * Copyright 1999 Klaas van Gend
 * Copyright 2000 Huw D M Davies
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "wine/wingdi16.h"
#include "winuser.h"
#include "wine/winuser16.h"
#include "commdlg.h"
#include "dlgs.h"
#include "wine/debug.h"
#include "cderr.h"
#include "winspool.h"
#include "cdlg16.h"

WINE_DEFAULT_DEBUG_CHANNEL(commdlg);

static void global_handle_to_16( HGLOBAL16 *h16, HGLOBAL handle )
{
    DWORD size;
    HGLOBAL16 ret;

    if (!handle) return;
    size = GlobalSize( handle );
    if (*h16) ret = GlobalReAlloc16( GMEM_MOVEABLE, *h16, size );
    else ret = GlobalAlloc16( GMEM_MOVEABLE, size );
    if (ret)
    {
        void *src = GlobalLock( handle );
        void *dst = GlobalLock16( ret );
        memcpy( dst, src, size );
        GlobalUnlock( handle );
        GlobalUnlock16( ret );
        *h16 = ret;
    }
}

static HGLOBAL global_handle_from_16( HGLOBAL16 handle )
{
    DWORD size;
    HGLOBAL ret;

    if (!handle) return 0;
    size = GlobalSize16( handle );
    if ((ret = GlobalAlloc( GMEM_MOVEABLE, size )))
    {
        void *src = GlobalLock16( handle );
        void *dst = GlobalLock( ret );
        memcpy( dst, src, size );
        GlobalUnlock16( handle );
        GlobalUnlock( ret );
    }
    return ret;
}

/**********************************************************************
 *
 *      16 bit commdlg
 */

/***********************************************************************
 *           PrintDlg   (COMMDLG.20)
 *
 *  Displays the PRINT dialog box, which enables the user to specify
 *  specific properties of the print job.
 *
 * RETURNS
 *  nonzero if the user pressed the OK button
 *  zero    if the user cancelled the window or an error occurred
 *
 * BUGS
 *  * calls up to the 32-bit versions of the Dialogs, which look different
 *  * Customizing is *not* implemented.
 */

BOOL16 WINAPI PrintDlg16( LPPRINTDLG16 lppd )
{
    PRINTDLGA pd32;
    BOOL ret;

    pd32.lStructSize = sizeof(pd32);
    pd32.Flags       = lppd->Flags & ~(PD_ENABLEPRINTTEMPLATE | PD_ENABLEPRINTTEMPLATEHANDLE |
                                       PD_ENABLESETUPTEMPLATE | PD_ENABLESETUPTEMPLATEHANDLE |
                                       PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK);
    pd32.hwndOwner   = HWND_32(lppd->hwndOwner);
    pd32.hDevMode    = global_handle_from_16( lppd->hDevMode );
    pd32.hDevNames   = global_handle_from_16( lppd->hDevNames );
    pd32.nFromPage   = lppd->nFromPage;
    pd32.nToPage     = lppd->nToPage;
    pd32.nMinPage    = lppd->nMinPage;
    pd32.nMaxPage    = lppd->nMaxPage;
    pd32.nCopies     = lppd->nCopies;

    if (lppd->Flags & (PD_ENABLEPRINTTEMPLATE | PD_ENABLEPRINTTEMPLATEHANDLE |
                       PD_ENABLESETUPTEMPLATE | PD_ENABLESETUPTEMPLATEHANDLE))
        FIXME( "custom templates no longer supported, using default\n" );
    if (lppd->Flags & PD_ENABLEPRINTHOOK)
        FIXME( "custom print hook %p no longer supported\n", lppd->lpfnPrintHook );
    if (lppd->Flags & PD_ENABLESETUPHOOK)
        FIXME( "custom setup hook %p no longer supported\n", lppd->lpfnSetupHook );

    if ((ret = PrintDlgA( &pd32 )))
    {
        lppd->hDC = HDC_16( pd32.hDC );
        global_handle_to_16( &lppd->hDevNames, pd32.hDevNames );
        global_handle_to_16( &lppd->hDevMode, pd32.hDevMode );

        lppd->nFromPage   = pd32.nFromPage;
        lppd->nToPage     = pd32.nToPage;
        lppd->nMinPage    = pd32.nMinPage;
        lppd->nMaxPage    = pd32.nMaxPage;
        lppd->nCopies     = pd32.nCopies;
    }
    GlobalFree( pd32.hDevNames );
    GlobalFree( pd32.hDevMode );
    return ret;
}

/***********************************************************************
 *           PrintDlgProc   (COMMDLG.21)
 */
BOOL16 CALLBACK PrintDlgProc16(HWND16 hDlg16, UINT16 uMsg, WPARAM16 wParam, LPARAM lParam)
{
    FIXME( "%04x %04x %04x %08lx: stub\n", hDlg16, uMsg, wParam, lParam );
    return FALSE;
}

/***********************************************************************
 *           PrintSetupDlgProc   (COMMDLG.22)
 */
BOOL16 CALLBACK PrintSetupDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam,
				   LPARAM lParam)
{
  HWND hWnd = HWND_32(hWnd16);
  switch (wMsg)
    {
    case WM_INITDIALOG:
      TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
      ShowWindow(hWnd, SW_SHOWNORMAL);
      return (TRUE);
    case WM_COMMAND:
      switch (wParam) {
      case IDOK:
	EndDialog(hWnd, TRUE);
	return(TRUE);
      case IDCANCEL:
	EndDialog(hWnd, FALSE);
	return(TRUE);
      }
      return(FALSE);
    }
  return FALSE;
}
