/*
 *  SAMPLE.C
 *
 *  This module contains the WinMain, WndProc, and initialization functions
 *  for SAMPLE.EXE
 *
 *  Copyright (C) 1991 by Daytris.  All rights reserved.
 */

#include <windows.h>
#include <stdio.h>
#include "dbmgr.h"
#include "sampledb.h"
#include "sample.h"


/************************************************
 * Function Declarations
 ************************************************/

int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,
    int nCmdShow);
BOOL InitApplication( HANDLE hInstance);
HWND InitInstance( HANDLE hInstance, short nCmdShow);
static BOOL InitDatabase( HWND hParentWnd);
long FAR PASCAL WndProc( HWND hWnd, unsigned uMessage, WORD wParam,
    LONG lParam);
static void InitMainWindow( HWND hWnd);


/************************************************
 * Local Data
 ************************************************/

static char szAppName[] = "Sample";         /* Class name */


/************************************************
 * Global Data
 ************************************************/

HANDLE hInst;                               /* Instance handle */
HANDLE hDb;                                 /* Database handle */
HWND hWndClientLB;                          /* Client listbox handle */
SETUP setup;                                /* Setup record */
BOOL bSortByNumber = TRUE;                  /* Client listbox sort seq */


/***************************************************************************
 * Function : WinMain
 *
 * Purpose  : This function is the entry function for SAMPLE.EXE.
 *
 * Returns  : FALSE - error in initialization
 *            MSG.wParam
 ***************************************************************************/
int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,
    int nCmdShow)
    {
    HANDLE hWnd;
    MSG msg;

    if( ! hPrevInstance)
        {
        if( ! InitApplication( hInstance))
            return FALSE;
        }

    if( ! (hWnd = InitInstance( hInstance, nCmdShow)) )
        return FALSE;

    /* Initialize the database */
    if( ! InitDatabase( hWnd))
        return FALSE;

    /* Load the client listbox */
    LoadClientListBox( hWnd);

    while( GetMessage( &msg, NULL, NULL, NULL))
        {
        TranslateMessage( &msg);
        DispatchMessage( &msg);
        }

    return msg.wParam;
    }


/***************************************************************************
 * Function : InitApplication
 *
 * Purpose  : This function registers the SAMPLE class.
 *
 * Returns  : RegisterClass return value
 ***************************************************************************/
BOOL InitApplication( HANDLE hInstance)
    {
    WNDCLASS wc;

    wc.style            = NULL;
    wc.lpfnWndProc      = WndProc;
    wc.cbClsExtra       = 0;
    wc.cbWndExtra       = DLGWINDOWEXTRA;
    wc.hInstance        = hInstance;
    wc.hIcon            = LoadIcon( NULL, IDI_APPLICATION);
    wc.hCursor          = LoadCursor( NULL, IDC_ARROW);
    wc.hbrBackground    = GetStockObject( WHITE_BRUSH);
    wc.lpszMenuName     = (LPSTR)"SAMPLE";
    wc.lpszClassName    = (LPSTR)szAppName;

    return( RegisterClass( &wc));
    }


/***************************************************************************
 * Function : InitInstance
 *
 * Purpose  : The function initializes the instance creating a main
 *            window.
 *
 * Returns  : >0   - window handle
 *            NULL - window not created
 ***************************************************************************/
HWND InitInstance( HANDLE hInstance, short nCmdShow)
    {
    HWND hWnd;

    /* Save the instance handle globally */
    hInst = hInstance;

    /* Create the main window */
    hWnd = CreateWindow( szAppName,
        "CDB Sample Program (Client List)",
        WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU |
            WS_MINIMIZEBOX | WS_THICKFRAME,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);
    if( ! hWnd)
        return NULL;

    /* Display the window */
    ShowWindow( hWnd, nCmdShow);
    UpdateWindow( hWnd);

    return hWnd;
    }


/***************************************************************************
 * Function : InitDatabase
 *
 * Purpose  : This function opens SAMPLEDB.DBD and retrieves the setup
 *            record.  If no setup record exists, one is created.  Only
 *            one setup record is used in SAMPLE.EXE.
 *
 * Returns  : TRUE  - database initialized
 *            FALSE - database not initialized
 ***************************************************************************/
static BOOL InitDatabase( HWND hParentWnd)
    {
    DWORD dwStatus;

    /* Open the sample database.  Use the current directory for database
       file creation and retrieval */
    if( dwStatus = DbOpen( hParentWnd, ".\\", "sampledb.dbd", &hDb))
        {
        DbError( hParentWnd, dwStatus, __FILE__, __LINE__);
        return FALSE;
        }

    /* Get the setup record.  If it does not exist, create one. */
    dwStatus = XDbRecordGetFirst( hDb, "setup", "lNextClientNbr", &setup,
        sizeof( SETUP));
    if( dwStatus == E_NOTFOUND)
        {
        /* Starting client number is 1000.  Add record. */
        setup.lNextClientNbr = 1000L;
        dwStatus = XDbRecordAdd( hDb, "setup", &setup, sizeof( SETUP));
        }
    if( dwStatus)
        {
        DbError( hParentWnd, dwStatus, __FILE__, __LINE__);
        DbClose( hDb);
        return FALSE;
        }

    /* Flush the setup record to disk */
    DbFlush( hDb);

    return TRUE;
    }


/***************************************************************************
 * Function : WndProc
 *
 * Purpose  : This function is the window procedure for SAMPLE.EXE
 *
 * Returns  : 0L - message processed by function
 *            DefWndProc value
 ***************************************************************************/
long FAR PASCAL WndProc( HWND hWnd, unsigned uMessage, WORD wParam,
    LONG lParam)
    {
    HANDLE hMenu;

    switch( uMessage)
        {
        case WM_CREATE:
            InitMainWindow( hWnd);
            return 0L;

        case WM_SETFOCUS:
            SetFocus( hWndClientLB);
            return 0L;

        case WM_COMMAND:
            switch( wParam)
                {
                case IDC_CLIENT_LISTBOX:
                    if( HIWORD( lParam) == LBN_DBLCLK)
                        SendMessage( hWnd, WM_COMMAND, IDM_UPDATE, 0L);
                    break;

                case IDM_ADD:
                    AddClientDlg( hWnd);
                    break;

                case IDM_UPDATE:
                    UpdateClientDlg( hWnd);
                    break;

                case IDM_DELETE:
                    DeleteClientDlg( hWnd);
                    break;

                case IDM_SORT_BY_NUMBER:
                    if( bSortByNumber)
                        break;
                    hMenu = GetMenu( hWnd);
                    CheckMenuItem( hMenu, IDM_SORT_BY_NAME, MF_UNCHECKED);
                    CheckMenuItem( hMenu, IDM_SORT_BY_NUMBER, MF_CHECKED);
                    bSortByNumber = TRUE;
                    LoadClientListBox( hWnd);
                    break;

                case IDM_SORT_BY_NAME:
                    if( ! bSortByNumber)
                        break;
                    hMenu = GetMenu( hWnd);
                    CheckMenuItem( hMenu, IDM_SORT_BY_NUMBER, MF_UNCHECKED);
                    CheckMenuItem( hMenu, IDM_SORT_BY_NAME, MF_CHECKED);
                    bSortByNumber = FALSE;
                    LoadClientListBox( hWnd);
                    break;

                case IDM_ABOUT:
                    AboutDlg( hWnd);
                    break;

                case IDM_EXIT:
                    PostMessage( hWnd, WM_DESTROY, 0, 0L);
                    break;
                }
            return 0L;

        case WM_DESTROY:
            {
            DWORD dwStatus;

            if( dwStatus = DbClose( hDb))
                DbError( hWnd, dwStatus, __FILE__, __LINE__);
            PostQuitMessage( 0);
            return 0L;
            }
        }

    return( DefWindowProc( hWnd, uMessage, wParam, lParam));
    }


/***************************************************************************
 * Function : InitMainWindow
 *
 * Purpose  : This function sizes the main window and creates a client
 *            listbox window.
 *
 * Returns  : n/a
 ***************************************************************************/
static void InitMainWindow( HWND hWnd)
    {
    short xChar, yChar;
    HDC hDC;
    TEXTMETRIC tm;
    RECT rect;

    /* Get the default window parameters */
    hDC = GetDC( hWnd);
    GetTextMetrics( hDC, &tm);
    ReleaseDC( hWnd, hDC);
    GetWindowRect( hWnd, &rect);
    xChar = tm.tmAveCharWidth;
    yChar = tm.tmHeight + tm.tmExternalLeading;

    /* Size the window */
    MoveWindow( hWnd,
        rect.left,
        rect.top,
        xChar * WINDOW_WIDTH + (GetSystemMetrics( SM_CXFRAME) * 2),
        (yChar * (LISTBOX_Y + 1)) + (tm.tmHeight * LISTBOX_LENGTH) +
            GetSystemMetrics( SM_CYCAPTION) + GetSystemMetrics( SM_CYMENU),
        FALSE);

    /* Create the listbox */
    GetClientRect( hWnd, &rect);
    hWndClientLB = CreateWindow( "listbox",
        NULL,
        WS_CHILD | WS_VISIBLE | LBS_STANDARD,
        rect.left + (xChar * LISTBOX_X),
        rect.top + (yChar * LISTBOX_Y),
        xChar * LISTBOX_WIDTH,
        tm.tmHeight * LISTBOX_LENGTH,
        hWnd,
        IDC_CLIENT_LISTBOX,
        hInst,
        NULL);

    /* Set listbox font to fixed size */
    SendMessage( hWndClientLB, WM_SETFONT, GetStockObject( SYSTEM_FIXED_FONT),
        0L);
    }
