/*
 *  SLISTBOX.C
 *
 *  This module contains listbox functions for SAMPLE.EXE.
 *
 *  Copyright (C) 1991 by Daytris.  All rights reserved.
 */

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef ZORTECH
#include <memory.h>
#endif
#include "dbmgr.h"
#include "sampledb.h"
#include "sample.h"


/************************************************
 * Local Data
 ************************************************/


/************************************************
 * Function Declarations
 ************************************************/

BOOL LoadClientListBox( HWND hWnd);
BOOL AddToClientListBox( HWND hWnd, CLIENT *pClient);
BOOL DeleteFromClientListBox( HWND hWnd, short nIndex);
BOOL LoadAddressListBox( HWND hWnd);
BOOL AddToAddressListBox( HWND hWnd, ADDRESS FAR *lpAddress);
BOOL DeleteFromAddressListBox( HWND hWnd, short nIndex);
HANDLE GetAddressHandle( HWND hWnd, short nIndex);


/***************************************************************************
 * Function : LoadClientListBox
 *
 * Purpose  : This function retrieves all client records from the
 *            database and adds them to the client listbox.
 *
 * Returns  : TRUE  - load ok
 *            FALSE - load not ok
 ***************************************************************************/
BOOL LoadClientListBox( HWND hWnd)
    {
    BOOL bFirstTime = TRUE;
    DWORD dwStatus;
    char szSortField[32];
    CLIENT client;

    /* Reinitialize the listbox */
    SendMessage( hWndClientLB, LB_RESETCONTENT, 0, 0L);

    /* Set key field string for search */
    if( bSortByNumber)
        strcpy( szSortField, "lClientNbr");
    else
        strcpy( szSortField, "szName");

    while( 1)
        {
        /* Get the client record */
        if( bFirstTime)
            {
            bFirstTime = FALSE;
            dwStatus = XDbRecordGetFirst( hDb, "client", szSortField,
                &client, sizeof( CLIENT));
            }
        else
            {
            dwStatus = XDbRecordGetNext( hDb, "client", szSortField,
                &client, sizeof( CLIENT));
            }

        /* Check for errors */
        if( dwStatus == E_NOTFOUND || dwStatus == E_NONEXT)
            break;
        if( dwStatus)
            {
            DbError( hWnd, dwStatus, __FILE__, __LINE__);
            return FALSE;
            }

        /* Add client to list box */
        if( ! AddToClientListBox( hWnd, &client))
            return FALSE;
        }

    return TRUE;
    }


/***************************************************************************
 * Function : AddToClientListBox
 *
 * Purpose  : This function adds a client record to the listbox.
 *
 * Returns  : TRUE  - add ok
 *            FALSE - add not ok
 ***************************************************************************/
BOOL AddToClientListBox( HWND hWnd, CLIENT *pClient)
    {
    char szBuffer[64];

    if( bSortByNumber)
        sprintf( szBuffer, "%ld   %s", pClient->lClientNbr,
            pClient->szName);
    else
        sprintf( szBuffer, "%-30.30s   %ld", pClient->szName,
            pClient->lClientNbr);

    if( SendMessage( hWndClientLB, LB_ADDSTRING, NULL,
        (LONG)(LPSTR)szBuffer) == LB_ERR)
        {
        MessageBox( hWnd, "Error SendMessage / LB_ADDSTRING", "Fatal Error",
            MB_OK | MB_ICONEXCLAMATION);
        return FALSE;
        }
    return TRUE;
    }


/***************************************************************************
 * Function : DeleteFromClientListBox
 *
 * Purpose  : This function deletes a string from the client listbox.
 *
 * Returns  : TRUE  - delete ok
 *            FALSE - delete not ok
 ***************************************************************************/
BOOL DeleteFromClientListBox( HWND hWnd, short nIndex)
    {
    if( SendMessage( hWndClientLB, LB_DELETESTRING, nIndex, 0L) == LB_ERR)
        {
        return FALSE;
        }
    return TRUE;
    }


/***************************************************************************
 * Function : LoadAddressListBox
 *
 * Purpose  : This function retrieves all member address records of
 *            a selected client and adds them to the address listbox.
 *            The address listbox contains a tab field that is not
 *            in a visible area of the listbox.  The handle to the
 *            address record is stored in this field in ASCII.
 *
 * Returns  : TRUE  - load ok
 *            FALSE - load not ok
 ***************************************************************************/
BOOL LoadAddressListBox( HWND hWnd)
    {
    BOOL bFirstTime = TRUE;
    HANDLE hAddress;
    DWORD dwStatus;
    ADDRESS FAR *lpAddress;

    /* Reinitialize the listbox */
    SendMessage( GetDlgItem( hWnd, IDC_ADDR_LISTBOX), LB_RESETCONTENT, 0, 0L);

    while( 1)
        {
        /* Allocate space for the address record */
        if( ! (hAddress = GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE,
            (DWORD)sizeof( ADDRESS))) )
            {
            MessageBox( hWnd, "Out of memory", "Fatal Error",
                MB_ICONEXCLAMATION | MB_OK);
            return FALSE;
            }

        /* Get the first or next set connection.  Owner=client,
           Member=address. */
        if( bFirstTime)
            {
            bFirstTime = FALSE;
            dwStatus = DbSetGetFirst( hDb, "client", "address", hAddress);
            }
        else
            dwStatus = DbSetGetNext( hDb, "client", "address", hAddress);

        /* Check for errors */
        if( dwStatus == E_NOTFOUND || dwStatus == E_NONEXT)
            {
            /* All members retrieved, break */
            GlobalFree( hAddress);
            break;
            }
        if( dwStatus)
            {
            DbError( hWnd, dwStatus, __FILE__, __LINE__);
            return FALSE;
            }

        /* Lock the address and add it to the listbox */
        if( ! (lpAddress = (ADDRESS FAR *)GlobalLock( hAddress)) )
            {
            MessageBox( hWnd, "Memory: GlobalLock", "Fatal Error",
                MB_ICONEXCLAMATION | MB_OK);
            return FALSE;
            }
        if( ! AddToAddressListBox( hWnd, lpAddress))
            {
            GlobalUnlock( hAddress);
            return FALSE;
            }
        GlobalUnlock( hAddress);
        }

    return TRUE;
    }


/***************************************************************************
 * Function : AddToAddressListBox
 *
 * Purpose  : This function adds an address to the address listbox.
 *
 * Returns  : TRUE  - add ok
 *            FALSE - add not ok
 ***************************************************************************/
BOOL AddToAddressListBox( HWND hWnd, ADDRESS FAR *lpAddress)
    {
    HANDLE hAddress;
    LPSTR lpMem;
    char szBuffer[64];

    /* Allocate memory and store Address record */
    if( ! (hAddress = GlobalAlloc( GMEM_MOVEABLE, (DWORD)sizeof( ADDRESS))) )
        {
        MessageBox( hWnd, "Out of memory", "Fatal Error",
            MB_ICONEXCLAMATION | MB_OK);
        return FALSE;
        }
    if( (lpMem = GlobalLock( hAddress)) == NULL)
        {
        MessageBox( hWnd, "Memory: GlobalLock", "Fatal Error",
            MB_ICONEXCLAMATION | MB_OK);
        return FALSE;
        }
    _fmemcpy( lpMem, lpAddress, sizeof( ADDRESS));
    GlobalUnlock( hAddress);

    /* Add the Address to the listbox.  Also store the handle to the ADDRESS
       structure.  It will not be visible in the listbox. */
    wsprintf( szBuffer, "%s\t%u", (LPSTR)lpAddress->szStreet, hAddress);
    if( SendMessage( GetDlgItem( hWnd, IDC_ADDR_LISTBOX), LB_ADDSTRING,
        NULL, (LONG)(LPSTR)szBuffer) == LB_ERR)
        {
        MessageBox( hWnd, "Error SendMessage / LB_ADDSTRING", "Fatal Error",
            MB_ICONEXCLAMATION | MB_OK);
        }

    return TRUE;
    }


/***************************************************************************
 * Function : DeleteFromAddressListBox
 *
 * Purpose  : This function deletes an address from the address listbox.
 *
 * Returns  : TRUE  - delete ok
 *            FALSE - delete not ok
 ***************************************************************************/
BOOL DeleteFromAddressListBox( HWND hWnd, short nIndex)
    {
    /* Get the handle to the address structure and free it */
    if( GlobalFree( GetAddressHandle( hWnd, nIndex)) )
        {
        return FALSE;
        }

    /* Delete the listbox entry */
    if( SendMessage( GetDlgItem( hWnd, IDC_ADDR_LISTBOX), LB_DELETESTRING,
        nIndex, 0L) == LB_ERR)
        {
        return FALSE;
        }

    return TRUE;
    }


/***************************************************************************
 * Function : GetAddressHandle
 *
 * Purpose  : This function retrieves the handle to an address record
 *            of a selected string in the address listbox.
 *
 * Returns  : >0   - handle to address record
 *            NULL - error
 ***************************************************************************/
HANDLE GetAddressHandle( HWND hWnd, short nIndex)
    {
    char szBuffer[64];

    /* Get the handle to the address structure and free it */
    if( SendMessage( GetDlgItem( hWnd, IDC_ADDR_LISTBOX), LB_GETTEXT,
        nIndex, (LONG)(LPSTR)szBuffer) == LB_ERR)
        {
        MessageBox( hWnd, "Error SendMessage / LB_GETTEXT", "Fatal Error",
            MB_ICONEXCLAMATION | MB_OK);
        return NULL;
        }
    return( atoi( strchr( szBuffer, '\t')));
    }
