/*
 * CiderPress
 * Copyright (C) 2007 by faddenSoft, LLC.  All Rights Reserved.
 * See the file LICENSE for distribution terms.
 */
/*
 * Trivial implementation of a modeless dialog box.
 */
#ifndef __MODELESS__
#define __MODELESS__

/*
 * This class must be allocated on the heap, and destroyed by calling
 * DestroyWindow().  Do not delete the object or call EndDialog().
 *
 * To use, call Create(dialogID, pParentWnd).  Make sure "visible" is set to
 * "true" in the dialog properties.
 *
 * For "progress" dialogs: immediately before creating the window with Create,
 * disable the main window with EnableWindow(FALSE).  That prevents it from
 * getting user input.  When you're done, re-enable it with
 * EnableWindow(TRUE), and then DestroyWindow on this object.  (If you do it
 * the other way, some other window will get focus, and you have to use
 * SetActiveWindow() to get it back... but that causes a UI flash.)  This
 * behavior is now implemented in ExclusiveModelessDialog.
 */
class ModelessDialog : public CDialog {
public:
	ModelessDialog(void) : fOkayToDelete(false) {}
	virtual ~ModelessDialog(void) { ASSERT(fOkayToDelete); }

	/*
	 * OK button clicked.  Must override to prevent standard EndDialog
	 * behavior.
	 */
	virtual void OnOK(void) {
		if (UpdateData() != FALSE)		// try the DDX/DDV stuff, if any
			DestroyWindow();
	}
	/*
	 * ESC key hit or Cancel button clicked.  Must override to prevent
	 * standard EndDialog behavior.
	 */
	virtual void OnCancel(void) {
		DestroyWindow();
	}

protected:
	void PostNcDestroy(void) {
		// this may not arrive immediately
		fOkayToDelete = true;
		delete this;
	}

private:
	bool fOkayToDelete;		// sanity check
};


/*
 * Variant of ModelessDialog that handles enabling and disabling the parent
 * window.
 */
class ExclusiveModelessDialog : public ModelessDialog {
public:
	ExclusiveModelessDialog(void) : fpParentWnd(nil) {}
	virtual ~ExclusiveModelessDialog(void) {};

	/* disable the parent window before we're created */
	BOOL Create(int dialogID, CWnd* pParentWnd = NULL) {
		ASSERT(pParentWnd != nil);		// else what's the point?
		if (pParentWnd != nil) {
			fpParentWnd = pParentWnd;
			fpParentWnd->EnableWindow(FALSE);
		}
		return ModelessDialog::Create(dialogID, pParentWnd);
	}

	/* enable the parent window before we're destroyed */
	virtual BOOL DestroyWindow(void) {
		if (fpParentWnd != nil)
			fpParentWnd->EnableWindow(TRUE);
		return ModelessDialog::DestroyWindow();
	}

private:
	CWnd*	fpParentWnd;
};

/*
	From DLGCORE.CPP line 516:

	// disable parent (before creating dialog)
	HWND hWndParent = PreModal();	// ATM: finds parent of modal dlg
	AfxUnhookWindowCreate();
	BOOL bEnableParent = FALSE;
	if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
	{
		::EnableWindow(hWndParent, FALSE);
		bEnableParent = TRUE;
	}

[...]

  	if (bEnableParent)
		::EnableWindow(hWndParent, TRUE);
	if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
		::SetActiveWindow(hWndParent);

	// destroy modal window
	DestroyWindow();
	PostModal();

*/

#endif /*__MODELESS__*/
