// ============================================================================
// config.c -- dialog procedure and support functions for the "Configure..."
// dialog box.
// ============================================================================


#include <windows.h>
#include <commdlg.h>
#include "resgauge.h"


// ============================================================================
// > > > > > > > > > > > > > > >  code  begins  < < < < < < < < < < < < < < < <
// ============================================================================
// Processes messages for the "Configure..." dialog box.
// ----------------------------------------------------------------------------
BOOL
CALLBACK
ConfigDlgProc(
HWND              hDlg,   // window handle of the dialog
UINT              msg,    // message type
WPARAM            wParam, // 16 bits of information
LPARAM            lParam) // 32 additional bits of information
{
    static CONFIG Sconfig;

    BOOL          fReturn;

    fReturn = FALSE;
    switch ( msg )
    {
        case WM_INITDIALOG:
            // make a local copy of the global configuration data
            Sconfig = GcfgCur;
            // initialize the configuration dialog
            InitConfigDlg(hDlg);
            // tell DefDlgProc() that this message was handled
            fReturn = TRUE;
            break;

        // private message to reset the edit control
        case WM_REVERT:
            SetDlgItemInt(hDlg, IDD_PERCENT, GcfgCur.wThreshold, FALSE);
            break;

        case WM_COMMAND:
            fReturn = ConfigCommand(hDlg, &Sconfig, wParam, lParam);
            break;
    }

    return(fReturn);
} // ConfigDlgProc


// ----------------------------------------------------------------------------
// Initializes the configuration dialog.
// ----------------------------------------------------------------------------
void
FAR
PASCAL
InitConfigDlg(
HWND      hDlg) // window handle of the dialog
{
    int   i;
    HFONT hFont;
    WORD  wTmp;

    // center the dialog
    CenterDialog(hDlg);

    // set the font of the text boxes
    hFont = GetStockObject(ANSI_VAR_FONT);
    SendDlgItemMessage(hDlg, IDOK, WM_SETFONT, (WPARAM) hFont, FALSE);
    SendDlgItemMessage(hDlg, IDCANCEL, WM_SETFONT, (WPARAM) hFont, FALSE);
    for ( i = IDD_USER; i <= LAST_CONFIG; ++i )
        SendDlgItemMessage(hDlg, i, WM_SETFONT, (WPARAM) hFont, FALSE);

    // set the "Monitor" radio buttons
    if ( GcfgCur.wMonitor == MONITOR_GDI )
        wTmp = IDD_GDI;
    else if ( GcfgCur.wMonitor == MONITOR_USER )
        wTmp = IDD_USER;
    else
        wTmp = IDD_BOTH;
    CheckRadioButton(hDlg, IDD_USER, IDD_BOTH, wTmp);

    // set the "Alarm" radio buttons
    if ( GcfgCur.wAlarmType == ALARM_FLASH )
        wTmp = IDD_FLASH;
    else
        wTmp = IDD_BEEP;
    CheckRadioButton(hDlg, IDD_BEEP, IDD_FLASH, wTmp);

    // load the edit control with the threshold value
    SetDlgItemInt(hDlg, IDD_PERCENT, GcfgCur.wThreshold, FALSE);

    // limit the edit control to 2 characters
    SendDlgItemMessage(hDlg, IDD_PERCENT, EM_LIMITTEXT, 2, 0L);

    // enable or disable the alarm controls
    EnableAlarmControls(hDlg, GcfgCur.fAlarmEnabled);
} // InitConfigDlg


// ----------------------------------------------------------------------------
// Handles WM_COMMAND messages to the configuration dialog.
// ----------------------------------------------------------------------------
BOOL
FAR
PASCAL
ConfigCommand(
HWND            hDlg,    // window handle of the dialog
PCONFIG         pConfig, // configuration structure in caller
WPARAM          wParam,  // 16 bits of information
LPARAM          lParam)  // 32 additional bits of information
{
    BOOL        fEnable;
    BOOL        fNoError;
    BOOL        fReturn;
    DWORD FAR * lpdwTmp;
    WORD        wTmp;

    fReturn = FALSE;
    switch ( wParam )
    {
        // monitor the GDI heap
        case IDD_GDI:
            CheckRadioButton(hDlg, IDD_USER, IDD_BOTH, wParam);
            GwFree = 0;
            GcfgCur.wMonitor = MONITOR_GDI;
            break;

        // monitor the USER heap
        case IDD_USER:
            CheckRadioButton(hDlg, IDD_USER, IDD_BOTH, wParam);
            GwFree = 0;
            GcfgCur.wMonitor = MONITOR_USER;
            break;

        // monitor both heaps
        case IDD_BOTH:
            CheckRadioButton(hDlg, IDD_USER, IDD_BOTH, wParam);
            GwFree = 0;
            GcfgCur.wMonitor = MONITOR_BOTH;
            break;

        // edit the gauge color
        case IDD_GAUGE_COLOR:
            if ( GcfgCur.wMonitor == MONITOR_GDI )
                lpdwTmp = &(GcfgCur.dwColorGDI);
            else if ( GcfgCur.wMonitor == MONITOR_USER )
                lpdwTmp = &(GcfgCur.dwColorUser);
            else
                lpdwTmp = &(GcfgCur.dwColorBoth);
            if ( DoColor(hDlg, lpdwTmp) )
                GwFree = 0;
            break;

        // toggle the alarm
        case IDD_ENABLE:
            fEnable = LOWORD(SendDlgItemMessage(hDlg,
                                                wParam,
                                                BM_GETCHECK,
                                                0,
                                                0L));
            GcfgCur.fAlarmEnabled = !fEnable;
            EnableAlarmControls(hDlg, GcfgCur.fAlarmEnabled);
            break;

        // beep for an alarm
        case IDD_BEEP:
            CheckRadioButton(hDlg, IDD_BEEP, IDD_FLASH, wParam);
            GcfgCur.wAlarmType = ALARM_BEEP;
            break;

        // flash for an alarm
        case IDD_FLASH:
            CheckRadioButton(hDlg, IDD_BEEP, IDD_FLASH, wParam);
            GcfgCur.wAlarmType = ALARM_FLASH;
            break;

        // decrement the threshold value
        case IDD_MINUS:
            wTmp = GetDlgItemInt(hDlg, IDD_PERCENT, NULL, FALSE);
            if ( wTmp > 1 )
            {
                --wTmp;
                SetDlgItemInt(hDlg, IDD_PERCENT, wTmp, FALSE);
                GcfgCur.wThreshold = wTmp;
            }
            else
            {
                MessageBeep(0);
            }
            break;

        // check the value entered in the edit control
        case IDD_PERCENT:
            if ( HIWORD(lParam) == EN_CHANGE )
            {
                wTmp = GetDlgItemInt(hDlg,
                                     IDD_PERCENT,
                                     (BOOL FAR *) &fNoError,
                                     FALSE);
                if ( fNoError )
                {
                    GcfgCur.wThreshold = wTmp;
                }
                else
                {
                    MessageBeep(0);
                    PostMessage(hDlg, WM_REVERT, 0, 0L);
                }
            }
            break;

        // increment the threshold value
        case IDD_PLUS:
            wTmp = GetDlgItemInt(hDlg, IDD_PERCENT, NULL, FALSE);
            if ( wTmp < 99 )
            {
                ++wTmp;
                SetDlgItemInt(hDlg, IDD_PERCENT, wTmp, FALSE);
                GcfgCur.wThreshold = wTmp;
            }
            else
            {
                MessageBeep(0);
            }
            break;

        // save and use the current configuration
        case IDOK:
            SaveConfig();
            EndDialog(hDlg, TRUE);
            fReturn = TRUE;
            break;

        // use the current configuration
        case IDD_APPLY:
            EndDialog(hDlg, TRUE);
            fReturn = TRUE;
            break;

        // reset the current configuration to default values
        case IDD_DEFAULT:
            GcfgCur = GcfgDef;
            GwFree = 0;
            InitConfigDlg(hDlg);
            break;

        // restore the original configuration
        case IDCANCEL:
            GcfgCur = *pConfig;
            GwFree = 0;
            EndDialog(hDlg, FALSE);
            fReturn = TRUE;
            break;
    }

    return(fReturn);
} // ConfigCommand


// ----------------------------------------------------------------------------
// Enables or disables all the alarm controls.
// ----------------------------------------------------------------------------
void
FAR
PASCAL
EnableAlarmControls(
HWND    hDlg,    // window handle of the dialog
BOOL    fEnable) // TRUE if the controls are to be enabled
{
    int i;

    SendDlgItemMessage(hDlg, IDD_ENABLE, BM_SETCHECK, fEnable, 0L);
    for ( i = IDD_BEEP; i <= IDD_THRESHOLD; ++i )
        EnableWindow(GetDlgItem(hDlg, i), fEnable);
    for ( i = IDD_MINUS; i <= IDD_PLUS; ++i )
        EnableWindow(GetDlgItem(hDlg, i), fEnable);
} // EnableAlarmControls


// ----------------------------------------------------------------------------
// Wrapper for the common color selection dialog.
// ----------------------------------------------------------------------------
BOOL
FAR
PASCAL
DoColor(
HWND            hWnd,      // window handle
DWORD FAR *     lpdwColor) // color to be modified
{
    int         i;
    BOOL        fReturn;
    CHOOSECOLOR cc;
    COLORREF    aclrCust[16];

    // assume failure
    fReturn = FALSE;

    // set the custom color controls to white
    for ( i = 0; i < 16; ++i )
        aclrCust[i] = RGB(255, 255, 255);

    // initialize the structure members
    cc.lStructSize    = sizeof(CHOOSECOLOR);
    cc.hwndOwner      = hWnd;
    cc.hInstance      = NULL;
    cc.rgbResult      = *lpdwColor;
    cc.lpCustColors   = aclrCust;
    cc.Flags          = CC_RGBINIT | CC_PREVENTFULLOPEN;
    cc.lCustData      = 0;
    cc.lpfnHook       = NULL;
    cc.lpTemplateName = NULL;

    // call the common color selection dialog
    if ( ChooseColor(&cc) )
    {
        *lpdwColor = cc.rgbResult;
        fReturn = TRUE;
    }

    return(fReturn);
} // DoColor


// ===============
// end of config.c
// ===============
