/*
 * Copyright (c) 2003-2007 Rony Shapiro <ronys@users.sourceforge.net>.
 * All rights reserved. Use of the code is allowed under the
 * Artistic License 2.0 terms, as specified in the LICENSE file
 * distributed with this code, or available from
 * http://www.opensource.org/licenses/artistic-license-2.0.php
 */

/*
 * GeneralMsgBox.h
 *
 * Defines a extended Message Box class with fancy features as:
 * - HTML Format support via CRichEditCtrlExtn.
 * - Customizable buttons
 * - Customizable icon
 *
 * This is a cut down version of TcxMsgBox by Thales P. Carvalho but then
 * significantly enhanced to support text with HTML formatting and links
 * instead of a RTF string by using a CRichEditCtrlExtn control.
 * See www.codeproject.com for the original code
*/

#pragma once

#include "RichEditCtrlExtn.h"

/////////////////////////////////////////////////////////////////////////////
// CGeneralMsgBox

class CGeneralMsgBox : private CDialog
{
// Basic
public:

// Constructor
  CGeneralMsgBox(CWnd* pParentWnd = NULL);

// Destructor
  virtual ~CGeneralMsgBox();

// Execute
  int DoModal();

// Buttons operations
  void AddButton(UINT uIDC, LPCTSTR pszText,
                 BOOL bIsDefault = FALSE,
                 BOOL bIsEscape = FALSE);
  void AddButton(UINT uIDC, UINT uIdText = (UINT)-1,
                 BOOL bIsDefault = FALSE,
                 BOOL bIsEscape = FALSE);

// Title operations
  void SetTitle(LPCTSTR pszTitle);
  void SetTitle(UINT uIdTitle);

// Message operations
  BOOL SetMsg(UINT uMsgId);
  BOOL SetMsg(LPCTSTR pszMsg);

// Icon operations
  void SetIcon(HICON hIcon);
  void SetIcon(UINT uIcon);
  void SetStandardIcon(LPCTSTR pszIconName);
  void SetStandardIcon(UINT uIcon);

// Metric enumerators (see SetMetric and GetMetric)
  enum {CX_LEFT_BORDER, CX_RIGHT_BORDER,
        CY_TOP_BORDER, CY_BOTTOM_BORDER,
        CX_ICON_MSG_SPACE, CY_BTNS_MSG_SPACE,
        CX_BTN_BORDER, CY_BTN_BORDER,
        CX_BTNS_SPACE, CX_MIN_BTN,
        NUM_OF_METRICS
  };

// Set a metric (in dialog units)
  void SetMetric(int iMetric, int xy);

// Get a metric (in dialog units)
  int GetMetric(int iMetric);

private:
// Graphical attributes
  int m_aMetrics[NUM_OF_METRICS];  // basic metrics (dialog units)
  CSize m_dimMsg;                  // message dimension (pixels)
  CSize m_dimBtn;                  // button dimension (pixels)
  CSize m_dimIcon;                 // icon dimension (pixels)

// Dialog unit base: dimensions used in d.u. <-> pixel conversion
  enum {CX_DLGUNIT_BASE = 1000, CY_DLGUNIT_BASE = 1000};

// Pixel dimensions of the dialog unit base
  CSize m_dimDlgUnit;

// Controls' attributes
  UINT m_uDefCmdId;            // default command ID: <Return>
  UINT m_uEscCmdId;            // escape command ID: <ESC> or box close
  CStatic m_stIconCtrl;        // the icon control
  CRichEditCtrlExtn m_edCtrl;  // the RTF control

// Button's attributes
  struct BTNDATA {
    UINT uIDC;                    // button ID
    CString strBtn;               // button Text
  };

  CArray<BTNDATA,const BTNDATA&> m_aBtns;   // buttons' attributes

// Message attributes
  HICON m_hIcon;                   // icon handle
  CString m_strMsg;                // the message
  CString m_strTitle;              // the title

// Overrides
  virtual BOOL OnInitDialog();
  virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
  virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
  virtual BOOL PreTranslateMessage(MSG* pMsg);

// Utility - creating the nested controls
  void CreateRtfCtrl();
  void CreateBtns();
  void CreateIcon();

  void UpdateLayout();

  int FromDlgX(int x);
  int FromDlgY(int y);
};

/////////////////////////////////////////////////////////////////////////////
// CGeneralMsgBox - inlined member functions

inline void CGeneralMsgBox::SetTitle(LPCTSTR pszTitle)
   { m_strTitle = pszTitle; }

inline void CGeneralMsgBox::SetTitle(UINT uIdTitle)
   { VERIFY(m_strTitle.LoadString(uIdTitle)); }

inline void CGeneralMsgBox::SetMetric(int iMetric, int nValue)
   {  ASSERT(0 <= iMetric && iMetric < NUM_OF_METRICS);
      m_aMetrics[iMetric] = nValue; }

inline int CGeneralMsgBox::GetMetric(int iMetric)
   {  ASSERT(0 <= iMetric && iMetric < NUM_OF_METRICS);
      return m_aMetrics[iMetric]; }
