/*
 * Copyright (c) 1999-2000 Eric Williams.
 *
 * 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
 */

/*
 * One might call this a Commdlg test jig.  Its sole function in life
 * is to call the Commdlg Common Dialogs.  The results of a call to
 * File Open or File Save are printed in the upper left corner;
 * Font adjusts the font of the printout, and Color adjusts the color
 * of the background.
 */

/*
 * Ideally it would also do event logging and be a bit less stupid
 * about displaying the results of the various requesters.  But hey,
 * it's only a first step. :-)
 */

#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include <windows.h>
#include <commdlg.h>
#include <stdio.h>
#include <string.h>
#include "cmdlgtst.h"

#include <wine/debug.h>

WINE_DEFAULT_DEBUG_CHANNEL(cmdlgtst);

/*
 * This structure is to set up flag / control associations for the custom
 * requesters.  The ft_id is the id for the control (usually generated
 * by the system) and the ft_bit is the flag bit which goes into the
 * settings longword for the various Commdlg structures.  It is assumed
 * that all flags fit in an unsigned long and that all bits are in fact
 * one bit.
 */

/*
 * The array of entries is terminated by {IDOK, 0}; the assumption is that
 * IDOK would never be associated with a dialogbox control (since it's
 * usually the ID of the OK button}.
 */

struct FlagTableEntry {
	int ft_id;
	ULONG ft_bit;
};

#define EXPORT

static const char menuName[]   = "CmdlgtstMenu";
static const char className[]  = "CmdlgtstClass";
static const char windowName[] = "Common Dialog Test";

/*
 * global hInstance variable.  This makes the code non-threadable,
 * but wotthehell; this is Win32 anyway!  (Though it does work
 * under Win16, if one doesn't run more than one copy at a time.)
 */

static HINSTANCE g_hInstance;

/*
 * global CommDlg data structures for modals.  These are placed here
 * so that the custom dialog boxes can get at them.
 */

static PAGESETUPDLG psd;
static PRINTDLG pd;
static COLORREF cc_cr[16];
static CHOOSECOLOR cc;
static LOGFONT cf_lf;
static CHOOSEFONT cf;
static const char ofn_filepat[] = "All Files (*.*)\0*.*\0Only Text Files (*.txt)\0*.txt\0";
static char ofn_result[1024];
static char ofn_titleresult[128];
static OPENFILENAME ofn;

/* Stuff for find and replace.  These are modeless, so I have to put them here. */

static HWND findDialogBox = 0;
static UINT findMessageId = 0;

static FINDREPLACE frS;
static char fromstring[1024], tostring[1024];

/* Stuff for the drawing of the window(s).  I put them here for convenience. */

static COLORREF fgColor = RGB(0, 0, 0); /* not settable */
static COLORREF bgColor = RGB(255, 255, 255); /* COLOR dialog */
static COLORREF txtColor = RGB(0, 0, 0); /* settable if one enables CF_EFFECTS */

/* Utility routines. */

static void nyi(HWND hWnd)
{
	/* "Hi there!  I'm not yet implemented!" */
	MessageBox(hWnd, "Not yet implemented!", "NYI", MB_ICONEXCLAMATION | MB_OK);
}

#if 0
static UINT CALLBACK dummyfnHook(HWND hWnd, UINT msg, UINT wParam, UINT lParam)
{
	/*
	 * If the user specifies something that needs an awfully stupid hook function,
	 * this is the one to use.  It's a no-op, and says "I didn't do anything."
	 */

	(void) hWnd;
	(void) msg;
	(void) wParam;
	(void) lParam;

	WINE_TRACE("dummyfnhook\n"); /* visible under Wine, but Windows probably won't see it! */

	return 0;
}
#endif

/*
 * Initialization code.  This code simply shoves in predefined
 * data into the COMMDLG data structures; in the future, I might use
 * a series of loadable resources, or static initializers; of course,
 * if Microsoft decides to change the field ordering, I'd be screwed.
 */

static void mwi_Print(HWND hWnd)
{
	pd.lStructSize = sizeof(PRINTDLG);
	pd.hwndOwner = hWnd;
	pd.hDevMode = 0;
	pd.hDevNames = 0;
	pd.hDC = 0;
	pd.Flags = 0;
	pd.nMinPage = 1;
	pd.nMaxPage = 100;
	pd.hInstance = g_hInstance;
	pd.lCustData = 0;
	pd.lpfnPrintHook = 0;
	pd.lpfnSetupHook = 0;
	pd.lpPrintTemplateName = 0;
	pd.lpSetupTemplateName = 0;
	pd.hPrintTemplate = 0;
	pd.hSetupTemplate = 0;
}

static void mwi_PageSetup(HWND hWnd)
{
	ZeroMemory(&psd, sizeof(PAGESETUPDLG));
	psd.lStructSize = sizeof(PAGESETUPDLG);
	psd.hwndOwner = hWnd;
	
}

static void mwi_Color(HWND hWnd)
{
	int i;

	/* there's probably an init call for this, somewhere. */

	for(i=0;i<16;i++)
		cc_cr[i] = RGB(0,0,0);

	cc.lStructSize = sizeof(CHOOSECOLOR);
	cc.hwndOwner = hWnd;
	cc.hInstance = (HWND)g_hInstance; /* Should be an HINSTANCE but MS made a typo */
	cc.rgbResult = RGB(0,0,0);
	cc.lpCustColors = cc_cr;
	cc.Flags = 0;
	cc.lCustData = 0;
	cc.lpfnHook = 0;
	cc.lpTemplateName = 0;
}

static void mwi_Font(HWND hWnd)
{
	cf.lStructSize = sizeof(CHOOSEFONT);
	cf.hwndOwner = hWnd;
	cf.hDC = 0;
	cf.lpLogFont = &cf_lf;
	cf.Flags = CF_SCREENFONTS; /* something's needed for display; otherwise it craps out with an error */
	cf.rgbColors = RGB(0,0,0);  /* what is *this* doing here?? */
	cf.lCustData = 0;
	cf.lpfnHook = 0;
	cf.lpTemplateName = 0;
	cf.hInstance = g_hInstance;
	cf.lpszStyle = 0;
	cf.nFontType = 0;
	cf.nSizeMin = 8;
	cf.nSizeMax = 72;

	cf_lf.lfHeight = -18; /* this can be positive or negative, but negative is usually used. */
}

static void mwi_File(HWND hWnd)
{
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = hWnd;
	ofn.hInstance = g_hInstance;
	ofn.lpstrFilter = ofn_filepat;
	ofn.lpstrCustomFilter = 0;
	ofn.nMaxCustFilter = 0;
	ofn.nFilterIndex = 0;
	ofn.lpstrFile = ofn_result;
	ofn.nMaxFile = sizeof(ofn_result);
	ofn.lpstrFileTitle = ofn_titleresult;
	ofn.nMaxFileTitle = sizeof(ofn_titleresult);
	ofn.lpstrInitialDir = 0;
	ofn.lpstrTitle = "Open File";
	ofn.Flags = 0;
	ofn.nFileOffset = 0;
	ofn.nFileExtension = 0;
	ofn.lpstrDefExt = "*";
	ofn.lCustData = 0;
	ofn.lpfnHook = 0;
	ofn.lpTemplateName = 0;

	ofn_result[0] = '\0';
}

static void mwi_FindReplace(HWND hWnd)
{
	frS.lStructSize = sizeof(FINDREPLACE);
	frS.hwndOwner = hWnd;
	frS.hInstance = g_hInstance;
	frS.Flags = FR_DOWN;
	frS.lpstrFindWhat = fromstring;
	frS.lpstrReplaceWith = tostring;
	frS.wFindWhatLen = sizeof(fromstring);
	frS.wReplaceWithLen = sizeof(tostring);
	frS.lCustData = 0;
	frS.lpfnHook = 0;
	frS.lpTemplateName = 0;

	fromstring[0] = '\0';
	tostring[0] = '\0';
	findMessageId = RegisterWindowMessage(FINDMSGSTRING);
}

static void mwi_InitAll(HWND hWnd)
{
	mwi_Print(hWnd);
	mwi_Font(hWnd);
	mwi_Color(hWnd);
	mwi_File(hWnd);
	mwi_FindReplace(hWnd);
	mwi_PageSetup(hWnd);
}

/*
 * Various configurations for the window.  Ideally, this
 * would be stored with the window itself, but then, this
 * isn't the brightest of apps.  Wouldn't be hard to set up,
 * though -- one of the neater functions of Windows, but if
 * someone decides to load the windows themselves from resources,
 * there might be a problem.
 */

static void paintMainWindow(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	RECT rect;
	HPEN pen;
	HFONT font;
	HBRUSH brush;

	(void) iMessage;
	(void) wParam;
	(void) lParam;

	/* Commence painting! */

	BeginPaint(hWnd, &ps);
	GetClientRect(hWnd, &rect);

	pen = SelectObject(ps.hdc, CreatePen(0, 0, fgColor));
	brush = SelectObject(ps.hdc, CreateSolidBrush(bgColor));
	font = SelectObject(ps.hdc, CreateFontIndirect(&cf_lf));

	/*
	 * Ideally, we'd only need to draw the exposed bit.
	 * But something in BeginPaint is screwing up the rectangle.
	 * Either that, or Windows is drawing it wrong.  AARGH!
	 * Rectangle(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom);
         */
	Rectangle(ps.hdc, rect.left, rect.top, rect.right, rect.bottom);

	/* now draw a couple of lines, just for giggles. */

	MoveToEx(ps.hdc, rect.left, rect.top, NULL);
	LineTo(ps.hdc, rect.right, rect.bottom);
	MoveToEx(ps.hdc, rect.left, rect.bottom, NULL);
	LineTo(ps.hdc, rect.right, rect.top);

	/* draw some text */

	SetTextAlign(ps.hdc, TA_CENTER|TA_BASELINE);
	SetTextColor(ps.hdc, txtColor);
	TextOut(ps.hdc, (rect.left+rect.right)/2, (rect.top+rect.bottom)/2, "Common Dialog Test Page", 23);

	SetTextAlign(ps.hdc, TA_LEFT|TA_TOP);
	TextOut(ps.hdc, rect.left+10, rect.top+10, ofn_result, strlen(ofn_result));
	TextOut(ps.hdc, rect.left+10, rect.top-cf_lf.lfHeight+10, ofn_titleresult, strlen(ofn_titleresult));

	/*
	 * set the HDC back to the old pen and brush,
	 * and delete the newly created objects.
	 */

	pen = SelectObject(ps.hdc, pen);
	DeleteObject(pen);
	brush = SelectObject(ps.hdc, brush);
	DeleteObject(brush);
	font = SelectObject(ps.hdc, font);
	DeleteObject(font);

	EndPaint(hWnd, &ps);
}

/*
 * This function simply returns an error indication.  Naturally,
 * I do not (yet) see an elegant method by which one can convert
 * the CDERR_xxx return values into something resembling usable text;
 * consult cderr.h to see what was returned.
 */

static void mw_checkError(HWND hWnd, BOOL explicitcancel)
{
	DWORD errval = CommDlgExtendedError();
	if(errval) {
		char errbuf[80];

		sprintf(errbuf, "CommDlgExtendedError(): error code %d (0x%x)", errval, errval);
		MessageBox(hWnd, errbuf, "Error", MB_ICONEXCLAMATION | MB_OK);
	}
	else {
		if(explicitcancel) MessageBox(hWnd, "Nope, user canceled it.", "No", MB_OK);
	}
}

/*
 * The actual dialog function calls.  These merely wrap the Commdlg
 * calls, and do something (not so) intelligent with the result.
 * Ideally, the main window would refresh and take into account the
 * various values specified in the dialog.
 */

static void mw_ColorSetup(HWND hWnd)
{
	if(ChooseColor(&cc)) {
		RECT rect;

		GetClientRect(hWnd, &rect);
		InvalidateRect(hWnd, &rect, FALSE);
		bgColor = cc.rgbResult;
	}
	else mw_checkError(hWnd, FALSE);
}

static void mw_FontSetup(HWND hWnd)
{
	if(ChooseFont(&cf)) {
		RECT rect;
		GetClientRect(hWnd, &rect);
		InvalidateRect(hWnd, &rect, FALSE);
		txtColor = cf.rgbColors;
	}
	else mw_checkError(hWnd, FALSE);
}

static void mw_FindSetup(HWND hWnd)
{
	if(findDialogBox == 0) {
		findDialogBox = FindText(&frS);
		if(findDialogBox==0) mw_checkError(hWnd,TRUE);
	}
}

static void mw_ReplaceSetup(HWND hWnd)
{
	if(findDialogBox == 0) {
		findDialogBox = ReplaceText(&frS);
		if(findDialogBox==0) mw_checkError(hWnd,TRUE);
	}
}

static void mw_OpenSetup(HWND hWnd)
{
	if(GetOpenFileName(&ofn)) {
		RECT rect;
		GetClientRect(hWnd, &rect);
		InvalidateRect(hWnd, &rect, FALSE);
	}
	else mw_checkError(hWnd,FALSE);
}

static void mw_SaveSetup(HWND hWnd)
{
	if(GetSaveFileName(&ofn)) {
		RECT rect;
		GetClientRect(hWnd, &rect);
		InvalidateRect(hWnd, &rect, FALSE);
	}
	else mw_checkError(hWnd,FALSE);
}

/*
 * Can't find documentation in Borland for this one.  Does it
 * exist at all, or is it merely a subdialog of Print?
 */

static void mw_PSetupSetup(HWND hWnd)
{
	nyi(hWnd);
}

static void mw_PrintSetup(HWND hWnd)
{
	if(PrintDlg(&pd)) {
		/*
		 * the following are suggested in the Borland documentation,
		 * but aren't that useful until WinE starts to actually
		 * function with respect to printing.
		 */

#if 0
		Escape(tmp.hDC, STARTDOC, 8, "Test-Doc", NULL);
#endif

	 /* Print text and rectangle */

#if 0
		TextOut(tmp.hDC, 50, 50, "Common Dialog Test Page", 23);

		Rectangle(tmp.hDC, 50, 90, 625, 105);
		Escape(tmp.hDC, NEWFRAME, 0, NULL, NULL);
		Escape(tmp.hDC, ENDDOC, 0, NULL, NULL);
	 	DeleteDC(tmp.hDC);
#endif
		 if (pd.hDevMode != 0)
			 GlobalFree(pd.hDevMode);
		 if (pd.hDevNames != 0)
			 GlobalFree(pd.hDevNames);

		 pd.hDevMode = 0;
		 pd.hDevNames = 0;

		 MessageBox(hWnd, "Success.", "Yes", MB_OK);
	}
	else mw_checkError(hWnd,TRUE);
}

#define OF(fn, fi, fl)  \
		if(dm->dmFields & fl){ \
			WINE_TRACE("        %s  =%hd\n", (fn), dm->fi); \
		} else \
			WINE_TRACE("        %s NOT SET!\n", fn);


static void mw_PageSetup(HWND hWnd)
{
	DEVMODEA *dm;
	DEVNAMES *dn;
	CHAR      tmplnm[30] = "PAGESETUPDLGORD_CSTM";
	
	if(psd.Flags & PSD_ENABLEPAGESETUPTEMPLATE)
		psd.lpPageSetupTemplateName = tmplnm;
	psd.hInstance = g_hInstance;
	
	if(PageSetupDlg(&psd)){
		dm = GlobalLock(psd.hDevMode);
		if(dm) {
			WINE_TRACE("dm != NULL\nDEVMODEA struct:\n");
			WINE_TRACE("    dmDeviceName    ='%s'\n", 	dm->dmDeviceName);
			WINE_TRACE("    dmSpecVersion   =%#x\n",	dm->dmSpecVersion);
			WINE_TRACE("    dmDriverVersion =%#x\n",	dm->dmDriverVersion);
			WINE_TRACE("    dmSize          =%#x\n", 	dm->dmSize);	
			WINE_TRACE("    dmDriverExtra   =%#x\n",	dm->dmDriverExtra);
			WINE_TRACE("    dmFields        =%#x\n", 	dm->dmFields);
			OF("dmOrientation",	u1.s1.dmOrientation,	DM_ORIENTATION)
			OF("dmPaperSize",	u1.s1.dmPaperSize,	DM_PAPERSIZE);
			OF("dmPaperLength",	u1.s1.dmPaperLength,	DM_PAPERLENGTH);
			OF("dmPaperWidth",	u1.s1.dmPaperWidth,	DM_PAPERWIDTH);
			OF("dmScale",		u1.s1.dmScale,	DM_SCALE);
			OF("dmCopies",		u1.s1.dmCopies,	DM_COPIES);
			OF("dmDefaultSource",	u1.s1.dmDefaultSource,DM_DEFAULTSOURCE);
			OF("dmPrintQuality",	u1.s1.dmPrintQuality,	DM_PRINTQUALITY);
			if(dm->dmFields &	DM_POSITION)
				WINE_TRACE("        dmPosition(%d, %d)\n", dm->u1.s2.dmPosition.x, dm->u1.s2.dmPosition.y);
			else
				WINE_TRACE("        dmPosition NOT SET!\n");
			OF("dmColor",		dmColor,	DM_COLOR);
			OF("dmDuplex",		dmDuplex,	DM_DUPLEX);
			OF("dmYResolution",	dmYResolution,	DM_YRESOLUTION);
			OF("dmTTOption",	dmTTOption,	DM_TTOPTION);
			OF("dmCollate",		dmCollate,	DM_COLLATE);
			if(dm->dmFields & DM_FORMNAME)
				WINE_TRACE("        dmFormName = '%s'\n", dm->dmFormName);
			else 
				WINE_TRACE("        dmFormName NOT SET!\n");
			if(dm->dmFields & DM_ICMMETHOD)
				WINE_TRACE("        dmICMMethod = %#x\n", dm->dmICMMethod);
			else
				WINE_TRACE("        dmICMMethod NOT SET!\n");
			
			GlobalUnlock(psd.hDevMode);
		}
		else
			WINE_TRACE("dm == NULL\n");
	
		WINE_TRACE("\nPAGESETUPDLG struct\n");
		WINE_TRACE("    ptPaperSize(%d, %d)\n", psd.ptPaperSize.x, psd.ptPaperSize.y);
		WINE_TRACE("    rtMargin(%d, %d, %d, %d)\n",
			psd.rtMargin.left, psd.rtMargin.top, psd.rtMargin.right, psd.rtMargin.bottom);
	
		WINE_TRACE("\nDEVNAMES struct\n");
		dn = GlobalLock(psd.hDevNames);
		if(dn){
			WINE_TRACE("    wDriverOffset='%s'\n", ((char*)dn+dn->wDriverOffset));
			WINE_TRACE("    wDeviceOffset='%s'\n", ((char*)dn+dn->wDeviceOffset));
			WINE_TRACE("    wOutputOffset='%s'\n", ((char*)dn+dn->wOutputOffset));
			WINE_TRACE("    wDefault     ='%s'\n", ((char*)dn+dn->wDefault));
			GlobalUnlock(psd.hDevNames);
		}else
			WINE_TRACE(" dn == NULL!\n");		
		WINE_TRACE("End.\n");

		if (psd.hDevMode != NULL)
			GlobalFree(psd.hDevMode);
		if (psd.hDevNames != NULL)
			GlobalFree(psd.hDevNames);
		if (psd.hPageSetupTemplate != NULL)
			GlobalFree(psd.hPageSetupTemplate);

		psd.hDevMode  = NULL;
		psd.hDevNames = NULL;
		psd.hPageSetupTemplate = NULL;

		MessageBox(hWnd, "Success.", "Yes", MB_OK);
	} mw_checkError(hWnd, FALSE);
}

/********************************************************************************************************/
/*
 * Some support functions for the custom dialog box handlers.
 * In particular, we have to set things properly, and get the flags back.
 */

static void mwcd_SetFlags(HWND hWnd, struct FlagTableEntry *table, DWORD flags)
{
	int i;

	for(i=0; table[i].ft_id != IDOK; i++)
	{
		CheckDlgButton(hWnd, table[i].ft_id,(table[i].ft_bit & flags) ? 1 : 0);
	}
}

static DWORD mwcd_GetFlags(HWND hWnd, struct FlagTableEntry * table)
{
	int i;
	ULONG l = 0;

	for(i=0; table[i].ft_id != IDOK; i++)
	{
		if(IsDlgButtonChecked(hWnd, table[i].ft_id) == 1)
			l |= table[i].ft_bit;
	}

	return l;
}

/*
 * These functions are the custom dialog box handlers.
 * The division of labor may be a tad peculiar; in particular,
 * the flag tables should probably be in the main functions,
 * not the handlers.  I'll fix that later; this works as of right now.
 */

static INT_PTR mwcd_Setup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
					 struct FlagTableEntry * table, DWORD* flags)
{
	(void) lParam;

	switch(uMsg)
	{
		case WM_INITDIALOG:
			/* Set the controls properly. */

			mwcd_SetFlags(hWnd, table, *flags);

			return TRUE; /* I would return FALSE if I explicitly called SetFocus(). */
				     /* As usual, Windows is weird. */

		case WM_COMMAND:
			switch(wParam) {
				case IDOK:
					*flags = mwcd_GetFlags(hWnd, table);
					EndDialog(hWnd,1);
					break;

				case IDCANCEL:
					EndDialog(hWnd,0);
					break;

				case CM_R_HELP:
					break; /* help?  We don't need no steenkin help! */

				default:
					break; /* eat the message */
			}
			return TRUE;

		default:
			return FALSE; /* since I don't process this particular message */
	}
}

static INT_PTR CALLBACK mwcd_ColorSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static struct FlagTableEntry flagTable[] = {
		{I_CC_RGBINIT, CC_RGBINIT},
		{I_CC_SHOWHELP, CC_SHOWHELP},
		{I_CC_PREVENTFULLOPEN, CC_PREVENTFULLOPEN},
		{I_CC_FULLOPEN, CC_FULLOPEN},
		{I_CC_ENABLETEMPLATEHANDLE, CC_ENABLETEMPLATEHANDLE},
		{I_CC_ENABLETEMPLATE, CC_ENABLETEMPLATE},
		{I_CC_ENABLEHOOK, CC_ENABLEHOOK},
		{IDOK, 0},
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cc.Flags);
}

static INT_PTR CALLBACK mwcd_FontSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static struct FlagTableEntry flagTable[] = {
		{I_CF_APPLY, CF_APPLY},
		{I_CF_ANSIONLY, CF_ANSIONLY},
		{I_CF_BOTH, CF_BOTH},
		{I_CF_TTONLY, CF_TTONLY},
		{I_CF_EFFECTS, CF_EFFECTS},
		{I_CF_ENABLEHOOK, CF_ENABLEHOOK},
		{I_CF_ENABLETEMPLATE, CF_ENABLETEMPLATE},
		{I_CF_ENABLETEMPLATEHANDLE, CF_ENABLETEMPLATEHANDLE},
		{I_CF_FIXEDPITCHONLY, CF_FIXEDPITCHONLY},
		{I_CF_INITTOLOGFONTSTRUCT, CF_INITTOLOGFONTSTRUCT},
		{I_CF_LIMITSIZE, CF_LIMITSIZE},
		{I_CF_NOFACESEL, CF_NOFACESEL},
		{I_CF_USESTYLE, CF_USESTYLE},
		{I_CF_WYSIWYG, CF_WYSIWYG},
		{I_CF_SHOWHELP, CF_SHOWHELP},
		{I_CF_SCREENFONTS, CF_SCREENFONTS},
		{I_CF_SCALABLEONLY, CF_SCALABLEONLY},
		{I_CF_PRINTERFONTS, CF_PRINTERFONTS},
		{I_CF_NOVECTORFONTS, CF_NOVECTORFONTS},
		{I_CF_NOSTYLESEL, CF_NOSTYLESEL},
		{I_CF_NOSIZESEL, CF_NOSIZESEL},
		{I_CF_NOOEMFONTS, CF_NOOEMFONTS},
		{IDOK, 0},
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &cf.Flags);
}

static INT_PTR CALLBACK mwcd_FindSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	static struct FlagTableEntry flagTable[] = {
		{I_FR_DIALOGTERM, FR_DIALOGTERM},
		{I_FR_DOWN, FR_DOWN},
		{I_FR_ENABLEHOOK, FR_ENABLEHOOK},
		{I_FR_ENABLETEMPLATE, FR_ENABLETEMPLATE},
		{I_FR_ENABLETEMPLATEHANDLE, FR_ENABLETEMPLATEHANDLE},
		{I_FR_FINDNEXT, FR_FINDNEXT},
		{I_FR_HIDEMATCHCASE, FR_HIDEMATCHCASE},
		{I_FR_HIDEWHOLEWORD, FR_HIDEWHOLEWORD},
		{I_FR_HIDEUPDOWN, FR_HIDEUPDOWN},
		{I_FR_MATCHCASE, FR_MATCHCASE},
		{I_FR_NOMATCHCASE, FR_NOMATCHCASE},
		{I_FR_NOUPDOWN, FR_NOUPDOWN},
		{I_FR_NOWHOLEWORD, FR_NOWHOLEWORD},
		{I_FR_REPLACE, FR_REPLACE},
		{I_FR_REPLACEALL, FR_REPLACEALL},
		{I_FR_SHOWHELP, FR_SHOWHELP},
		{I_FR_WHOLEWORD, FR_WHOLEWORD},
		{IDOK, 0},
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &frS.Flags);
}

static INT_PTR CALLBACK mwcd_PrintSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static struct FlagTableEntry flagTable[] = {
		{I_PD_ALLPAGES, PD_ALLPAGES},
		{I_PD_COLLATE, PD_COLLATE},
		{I_PD_DISABLEPRINTTOFILE, PD_DISABLEPRINTTOFILE},
		{I_PD_ENABLEPRINTHOOK, PD_ENABLEPRINTHOOK},
		{I_PD_ENABLEPRINTTEMPLATE, PD_ENABLEPRINTTEMPLATE},
		{I_PD_ENABLEPRINTTEMPLATEHANDLE, PD_ENABLEPRINTTEMPLATEHANDLE},
		{I_PD_ENABLESETUPHOOK, PD_ENABLESETUPHOOK},
		{I_PD_ENABLESETUPTEMPLATE, PD_ENABLESETUPTEMPLATE},
		{I_PD_ENABLESETUPTEMPLATEHANDLE, PD_ENABLESETUPTEMPLATEHANDLE},
		{I_PD_HIDEPRINTTOFILE, PD_HIDEPRINTTOFILE},
		{I_PD_NOPAGENUMS, PD_NOPAGENUMS},
		{I_PD_NOSELECTION, PD_NOSELECTION},
		{I_PD_NOWARNING, PD_NOWARNING},
		{I_PD_PAGENUMS, PD_PAGENUMS},
		{I_PD_PRINTSETUP, PD_PRINTSETUP},
		{I_PD_PRINTTOFILE, PD_PRINTTOFILE},
		{I_PD_RETURNDC, PD_RETURNDC},
		{I_PD_RETURNDEFAULT, PD_RETURNDEFAULT},
		{I_PD_RETURNIC, PD_RETURNIC},
		{I_PD_SELECTION, PD_SELECTION},
		{I_PD_SHOWHELP, PD_SHOWHELP},
		{I_PD_USEDEVMODECOPIES, PD_USEDEVMODECOPIES},
		{IDOK, 0},
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &pd.Flags);
}

static INT_PTR CALLBACK mwcd_PageSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static struct FlagTableEntry flagTable[] = {
		{I_PSD_DEFAULTMINMARGINS, 	PSD_DEFAULTMINMARGINS},
		{I_PSD_DISABLEMARGINS,    	PSD_DISABLEMARGINS},
		{I_PSD_DISABLEORIENTATION, 	PSD_DISABLEORIENTATION},
		{I_PSD_DISABLEPAGEPAINTING, 	PSD_DISABLEPAGEPAINTING},
		{I_PSD_DISABLEPAPER, 		PSD_DISABLEPAPER},
		{I_PSD_DISABLEPRINTER, 		PSD_DISABLEPRINTER},
		{I_PSD_ENABLEPAGEPAINTHOOK, 	PSD_ENABLEPAGEPAINTHOOK},
		{I_PSD_ENABLEPAGESETUPHOOK, 	PSD_ENABLEPAGESETUPHOOK},
		{I_PSD_ENABLEPAGESETUPTEMPLATE, PSD_ENABLEPAGESETUPTEMPLATE},
		{I_PSD_ENABLEPAGESETUPTEMPLATEHANDLE, PSD_ENABLEPAGESETUPTEMPLATEHANDLE},
		{I_PSD_INHUNDREDTHSOFMILLIMETERS, PSD_INHUNDREDTHSOFMILLIMETERS},
		{I_PSD_INTHOUSANDTHSOFINCHES, 	PSD_INTHOUSANDTHSOFINCHES},
		{I_PSD_INWININIINTLMEASURE, 	PSD_INWININIINTLMEASURE},
		{I_PSD_MARGINS, 		PSD_MARGINS},
		{I_PSD_MINMARGINS, 		PSD_MINMARGINS},
		{I_PSD_NONETWORKBUTTON, 	PSD_NONETWORKBUTTON},
		{I_PSD_NOWARNING, 		PSD_NOWARNING},
		{I_PSD_RETURNDEFAULT, 		PSD_RETURNDEFAULT},
		{I_PSD_SHOWHELP, 		PSD_SHOWHELP},
		{IDOK, 0}
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &psd.Flags);
}

static INT_PTR CALLBACK mwcd_FileSetup(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static struct FlagTableEntry flagTable[] = {
		{I_OFN_ALLOWMULTISELECT, OFN_ALLOWMULTISELECT},
		{I_OFN_CREATEPROMPT, OFN_CREATEPROMPT},
		{I_OFN_ENABLEHOOK, OFN_ENABLEHOOK},
		{I_OFN_ENABLETEMPLATE, OFN_ENABLETEMPLATE},
		{I_OFN_ENABLETEMPLATEHANDLE, OFN_ENABLETEMPLATEHANDLE},
		{I_OFN_EXPLORER, OFN_EXPLORER},
		{I_OFN_EXTENSIONDIFFERENT, OFN_EXTENSIONDIFFERENT},
		{I_OFN_FILEMUSTEXIST, OFN_FILEMUSTEXIST},
		{I_OFN_HIDEREADONLY, OFN_HIDEREADONLY},
		{I_OFN_NOCHANGEDIR, OFN_NOCHANGEDIR},
		{I_OFN_NOREADONLYRETURN, OFN_NOREADONLYRETURN},
		{I_OFN_NOTESTFILECREATE, OFN_NOTESTFILECREATE},
		{I_OFN_NOVALIDATE, OFN_NOVALIDATE},
		{I_OFN_OVERWRITEPROMPT, OFN_OVERWRITEPROMPT},
		{I_OFN_PATHMUSTEXIST, OFN_PATHMUSTEXIST},
		{I_OFN_READONLY, OFN_READONLY},
		{I_OFN_SHAREAWARE, OFN_SHAREAWARE},
		{I_OFN_SHOWHELP, OFN_SHOWHELP},
		{IDOK, 0},
	};

	return mwcd_Setup(hWnd, uMsg, wParam, lParam, flagTable, &ofn.Flags);
}

static INT_PTR CALLBACK mwcd_About(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	(void) wParam;
	(void) lParam;

	switch(uMsg) {
		case WM_INITDIALOG: return TRUE; /* let WINDOWS set the focus. */
		case WM_COMMAND: EndDialog(hWnd, 0); return TRUE; /* it's our OK button. */
		default: return FALSE; /* it's something else, let Windows worry about it */
	}
}

/*
 * These functions call custom dialog boxes (resource-loaded, if I do this right).
 * Right now they don't do a heck of a lot, but at some future time
 * they will muck about with the flags (and be loaded from the flags) of
 * the CommDlg structures initialized by the mwi_xxx() routines.
 */

static void mwc_ColorSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "Color_Flags_Dialog", hWnd, mwcd_ColorSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening Color_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

static void mwc_FontSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "Font_Flags_Dialog", hWnd, mwcd_FontSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening Font_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

static void mwc_FindReplaceSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "Find_Flags_Dialog", hWnd, mwcd_FindSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening Find_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

static void mwc_PrintSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "Print_Flags_Dialog", hWnd, mwcd_PrintSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening Print_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

static void mwc_PageSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "PageSetup_Flags_Dialog", hWnd, mwcd_PageSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening PageSetup_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

static void mwc_FileSetup(HWND hWnd)
{
	int r = DialogBox(g_hInstance, "File_Flags_Dialog", hWnd, mwcd_FileSetup);
	if(r < 0) { MessageBox(hWnd, "Failure opening File_Flags_Dialog box", "Error", MB_ICONASTERISK|MB_OK); }
}

/*
 * Main window message dispatcher.  Here the messages get chewed up
 * and spit out.  Note the ugly hack for the modeless Find/Replace box;
 * this looks like it was bolted on with hexhead screws and is now
 * dangling from Windows like a loose muffler.  Sigh.
 */

static LRESULT CALLBACK EXPORT mainWindowDispatcher(
	HWND hWnd,
	UINT uMsg,
	WPARAM wParam,
	LPARAM lParam
)
{

	if(uMsg == findMessageId) {
		FINDREPLACE * lpfr = (FINDREPLACE *) lParam;
		if(lpfr->Flags & FR_DIALOGTERM) {
			MessageBox(hWnd, "User closing us down.", "Down", MB_OK);
			findDialogBox = 0;
		}
		else if (lpfr->Flags & FR_FINDNEXT) {
			MessageBox(hWnd, "Finding next occurrence.", "Findnext", MB_OK);
		}
		else if (lpfr->Flags & FR_REPLACE) {
			MessageBox(hWnd, "Replacing next occurrence.", "Replace", MB_OK);
		}
		else if (lpfr->Flags & FR_REPLACEALL) {
			MessageBox(hWnd, "Replacing all occurrences.", "Replace All", MB_OK);
		}
		else {
			MessageBox(hWnd, "Eh?", "Eh?", MB_OK);
		}
		return 1;
	}
	else switch(uMsg) {
	case WM_CREATE:
			/*
			 * this is always the first message... at least as far
			 * as we are concerned.
			 */
		mwi_InitAll(hWnd);
		break;

	case WM_PAINT:
			/* Well, draw something! */
		paintMainWindow(hWnd, uMsg, wParam, lParam);
		break;

	case WM_DESTROY:
			/* Uh oh.  Eject!  Eject!  Eject! */
		PostQuitMessage(0);
		break;

	case WM_COMMAND:
			/* menu or accelerator pressed; do something. */

		switch(wParam) {
		case CM_U_EXIT:
				/* Uh oh.  Eject!  Eject!  Eject! */
			PostQuitMessage(0);
			break;

		/* these actually call the Common Dialogs. */

		case CM_U_COLOR:
			mw_ColorSetup(hWnd); return 1;

		case CM_U_FONT:
			mw_FontSetup(hWnd); return 1;

		case CM_U_FIND:
			mw_FindSetup(hWnd); return 1;

		case CM_U_REPLACE:
			mw_ReplaceSetup(hWnd); return 1;

		case CM_U_OPEN:
			mw_OpenSetup(hWnd); return 1;

		case CM_U_SAVE:
			mw_SaveSetup(hWnd); return 1;

		case CM_U_PSETUP:
			mw_PSetupSetup(hWnd); return 1;

		case CM_U_PRINT:
			mw_PrintSetup(hWnd); return 1;
			
		case CM_U_PAGESETUP:
			mw_PageSetup(hWnd); return 1;
			
		/*
		 * these set up various flags and values in the Common Dialog
		 * data structures, which are currently stored in static memory.
		 * The control dialogs themselves are resources as well.
		 */

		case CM_F_FILE:
			mwc_FileSetup(hWnd); return 1;

		case CM_F_COLOR:
			mwc_ColorSetup(hWnd); return 1;

		case CM_F_FONT:
			mwc_FontSetup(hWnd); return 1;

		case CM_F_FINDREPLACE:
			mwc_FindReplaceSetup(hWnd); return 1;

		case CM_F_PRINT:
			mwc_PrintSetup(hWnd); return 1;

		case CM_F_PAGESETUP: 
			mwc_PageSetup(hWnd); return 1;

		case CM_H_ABOUT:
			DialogBox(g_hInstance, "AboutDialog", hWnd, mwcd_About);
			return 1;
		case CM_H_USAGE:
			DialogBox(g_hInstance, "UsageDialog", hWnd, mwcd_About);
         	/* return value?  *What* return value? */
			return 1;

		default:
			nyi(hWnd); return 1;
		}
		break;

	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}

/* Class registration.  One might call this a Windowsism. */

static int registerMainWindowClass(HINSTANCE hInstance)
{
	WNDCLASS wndClass;

	wndClass.style         = CS_HREDRAW|CS_VREDRAW;
	wndClass.lpfnWndProc   = mainWindowDispatcher;
	wndClass.cbClsExtra    = 0;
	wndClass.cbWndExtra    = 0;
	wndClass.hInstance     = hInstance;
#if 0
	wndClass.hIcon         = LoadIcon(hInstance, "whello");
	wndClass.hCursor       = LoadCursor(hInstance, IDC_ARROW);
#endif
	wndClass.hIcon         = 0;
	wndClass.hCursor       = 0;
	wndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
	wndClass.lpszMenuName  = menuName;
	wndClass.lpszClassName = className;

	return RegisterClass(&wndClass);
}

/*
 * Another Windowsism; this one's not too bad, as it compares
 * favorably with CreateWindow() in X (mucking about with X Visuals
 * can get messy; at least here we don't have to worry about that).
 */

static HWND createMainWindow(HINSTANCE hInstance, int show)
{
	HWND hWnd;

	hWnd = CreateWindow(
		className,  /* classname */
		windowName,  /* windowname/title */
		WS_OVERLAPPEDWINDOW, /* dwStyle */
		0, /* x */
		0, /* y */
		CW_USEDEFAULT, /* width */
		CW_USEDEFAULT, /* height */
		0, /* parent window */
		0, /* menu */
		hInstance, /* instance */
		0          /* passthrough for MDI */
	);

	if(hWnd==0) return 0;

	ShowWindow(hWnd, show);
	UpdateWindow(hWnd);

	return hWnd;
}

static int messageLoop(HINSTANCE hInstance, HWND hWnd)
{
	MSG msg;

	(void) hInstance;
	(void) hWnd;

	while(GetMessage(&msg, 0, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

/*
 * Oh, did we tell you that main() isn't the name of the
 * thing called in a Win16/Win32 app?  And then there are
 * the lack of argument lists, the necessity (at least in Win16)
 * of having to deal with class registration exactly once (as the
 * app may be run again), and some other bizarre holdovers from
 * Windows 3.x days.  But hey, Solitaire still works.
 */

int PASCAL WinMain(
	HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpszCmdLine, int nCmdShow
)
{
	HWND hWnd;

	(void) lpszCmdLine;

	strcpy(ofn_result, "--- not yet set ---");

	if(hPrevInstance==0) {
		if(!registerMainWindowClass(hInstance))
			return -1;
	}

	g_hInstance = hInstance;

	hWnd = createMainWindow(hInstance,nCmdShow);
	if(hWnd == 0)
		return -1;

	return messageLoop(hInstance, hWnd);
}

/* And now the end of the program.  Enjoy. */

/*
 * (c) 1999-2000 Eric Williams.  Rights as specified under the WINE
 * License.  Don't hoard code; share it!
 */
