/*
  LISTDEMO.C 
    A demonstration program which allows the user, through a dialog box,
    to append, insert, and delete strings from a listbox.
*/

#include <stdio.h>
#include "window.h"
#include "keys.h"

#define ID_START      99

#define ID_STRING     100
#define ID_POS        101
#define ID_FRAME      102
#define ID_APPEND     103
#define ID_INSERT     104
#define ID_DELETE     105
#define ID_LISTBOX    106


int  (pascal *OldMainWinProc)();
extern int pascal MainWndProc();
HWND hMain;


main(argc, argv)
  int  argc;
  char **argv;
{
  EVENT  event;
  HWND   hMenu, hPop;

  /*
    Initialize the window system - this *must* be done once in every appl
  */
  WinInit();
  /*
    Create the main window and set the main window procedure
  */
  hMain = WinCreate(NULLHWND, 0, 0, 24, 79, "ListBox Demo", 0x17,
 			          	 (WIN_HAS_BORDER), NORMAL_CLASS, 0);
  OldMainWinProc = WinSetWinProc(hMain, MainWndProc);

  /*
    Create the menu bar and the single item - the DEMO START choice
  */
  hMenu = CreateMenu(hMain);
  hPop = CreateMenu(hMenu);
  ChangeMenu(hPop,  0, "~Start", ID_START,  MF_APPEND);
  ChangeMenu(hMenu, 0, "~Demo",  hPop,      MF_POPUP | MF_APPEND);
  SetMenu(hMain, hMenu);

  /*
    Show the window
  */
  WinDraw(hMain);
  SetFocus(hMain);

  /*
    Main message loop
  */
  for (;;)
  {
    GetMessage(&event);
    TranslateAccelerator(&event);
    DispatchMessage(&event);
  }
}

/*
  MainWndProc - window procedure for the main window
*/
pascal MainWndProc(hWnd, message, wParam, lParam)
  HWND hWnd;
  WORD message;
  WORD wParam;
  DWORD lParam;
{
  switch (message)
  {
    case WM_COMMAND    :
      /*
        See if the user chose the START item from the DEMO menubar item
      */
      if (wParam == ID_START)
        DoDialog();
      break;

    case WM_QUIT       :
      /* End the dialog editor */
      VidClearScreen(0x07);
      exit(0);

    default :
      /* Call the default window procedure for the main window */
      return DefWinProc(hWnd, message, wParam, lParam);
  }

  return FALSE;
}


DoDialog()
{
  HDLG   hDlg;
  extern BOOL pascal DialogProc();

  /*
    Create the dialog box and the associated controls
  */
  hDlg = DialogCreate(hMain, 3,10,20,70, "Listbox Dialog", 0x31, 0x0000,
                      DialogProc, 0);
  DialogAddItem(hDlg, EditCreate(hDlg, 5, 12, 7, 37, "Enter String", 0x31,
 			          	 (WIN_HAS_BORDER), ID_STRING));
  DialogAddItem(hDlg, EditCreate(hDlg, 10, 12, 12, 22, "Position", 0x31,
 			          	 (WIN_HAS_BORDER), ID_POS));
  DialogAddItem(hDlg, StaticCreate(hDlg, 10,25,18,39, "Operation", 0x31, 
                   STATIC_FRAME, ID_FRAME));
  DialogAddItem(hDlg, RadioButtonCreate(hDlg, 12,27, "Append",
                   0x31,0,ID_APPEND));
  DialogAddItem(hDlg, RadioButtonCreate(hDlg, 14,27, "Insert",
                   0x31,0,ID_INSERT));
  DialogAddItem(hDlg, RadioButtonCreate(hDlg, 16,27, "Delete",
                   0x31,0,ID_DELETE));
  DialogAddItem(hDlg, ListBoxCreate(hDlg, 5,42,15,57, "Strings",
                   0x31, LBS_STANDARD, ID_LISTBOX));
  DialogAddItem(hDlg, PushButtonCreate(hDlg,18,42,"OK",0x31,0,IDOK));
  DialogAddItem(hDlg, PushButtonCreate(hDlg,18,49,"QUIT",0x31,0,IDCANCEL));

  /*
    Let the dialog box do its thing
  */
  DialogBox(hDlg);
}


BOOL pascal DialogProc(hDlg, message, wParam, lParam)
  HWND hDlg;
  WORD message;
  WORD wParam;
  DWORD lParam;
{
  char szString[80];
  char szPos[30];
  int  iPos;
  int  operation;
  int  iSel;
  static char szItemText[80];
  static int  nMovedItem = - 1;

  switch (message)
  {
    case WM_CHAR :
      if (wParam == ALT_M && GetDlgItem(hDlg, ID_LISTBOX) == GetFocus())
      {
        if (nMovedItem < 0)
        {
          nMovedItem = SendDlgItemMessage(hDlg,ID_LISTBOX,LB_GETCURSEL,0,0L);
          SendDlgItemMessage(hDlg, ID_LISTBOX, LB_GETTEXT,
                             nMovedItem, (DWORD) (char far *) szItemText);
        }
        else
          nMovedItem = -1;
        return TRUE;
      }
      break;

    case WM_COMMAND    :
      switch (wParam)
      {
      	case IDOK      :
          /*
            The user pressed the OK button. We want to get the string
            that is to be inserted as well as the position.
          */
          GetDialogText(hDlg, ID_STRING, (LPSTR) szString, sizeof(szString));
          GetDialogInt(hDlg, ID_POS, &iPos);

          /*
            Determine the operation to perform
          */
          operation = 0;
          if (IsDialogButtonChecked(hDlg, ID_APPEND))
            operation = LB_ADDSTRING;
          else if (IsDialogButtonChecked(hDlg, ID_INSERT))
            operation = LB_INSERTSTRING;
          else if (IsDialogButtonChecked(hDlg, ID_DELETE))
            operation = LB_DELETESTRING;

          if (operation)
            SendDlgItemMessage(hDlg, ID_LISTBOX, operation, iPos,
                                      (DWORD) (char far *) szString);
          break;

        case IDCANCEL  :
          /*
             If the user pressed the QUIT button, then send a WM_QUIT
             message to all the window procs
          */
          PostQuitMessage(0);
          EndDialog(hDlg, 0);
          break;

        case ID_APPEND :
        case ID_DELETE :
        case ID_INSERT :
          /*
            The user pressed a radio button. Enable this one and disable
            the others
          */
          CheckRadioButton(hDlg, ID_APPEND, ID_DELETE, wParam);
          break;

        case ID_LISTBOX :
          switch (HIWORD(lParam))
          {
          	case LBN_SELCHANGE :
              if (nMovedItem < 0)
                return FALSE;
              iSel = SendDlgItemMessage(hDlg,ID_LISTBOX,LB_GETCURSEL,0,0L);
              SendDlgItemMessage(hDlg,ID_LISTBOX,LB_DELETESTRING,nMovedItem,0L);
              SendDlgItemMessage(hDlg,ID_LISTBOX,LB_INSERTSTRING,iSel,
                                 (DWORD) (char far *) szItemText);
              nMovedItem = iSel;
              break;
          }
          return FALSE;
      }

      return TRUE;
  }

  return FALSE;
}
