#include <windows.h>
#include "app.h"

/*
 * SndHack, A Windows Sound Hack Utility in
 * Borland C++.  By Jerry Joplin, 1991.  Please
 * modify and improve this code as you see fit.
 *
 * SndHack is a Windows Sound Function Interpreter.  It
 * interprets text as a series of calls to Windows
 * Sound Functions and executes the Sound Functions.
 *
 * Module: main.c
 *
 * Contains: Global data and functions.  WinMain and
 * application wide functions should be located here.
 *
 */

/*********************************************************************/
/* Global data                                                       */
/*********************************************************************/

HWND    hWindow;                      /* handle to class window      */
HANDLE  hInst;                        /* handle to process instance  */
HWND    hEditWindow;                  /* handle to edit window       */
HANDLE  hAccelTable;                  /* handle to accelerator table */
HMENU   hMenu;                        /* handle to menu              */
HANDLE  hNote;                        /* handle to note cursor       */
HANDLE  hHourGlass;                   /* handle to hourglass cursor  */
HANDLE  hText = NULL;                 /* handle to Edit Text buffer  */
HANDLE  hData, hClipData;             /* handles to clip data        */
LPSTR   lpData, lpClipData;           /* pointers to clip data       */

char WindowName[]    = "SndHack";
char ClassName[]     = "SndHack";
char HelpFileName[80];

/* Default sound function settings data structure                    */
SndDef SndState = {
  0,                                  /* open state: 0=closed, 1=open*/
  0,                                  /* numvoices, total voices     */
  S_PERIODVOICE,                      /* source setting              */
  1,                                  /* voice, last voice used      */
  120,                                /* tempo setting               */
  64,                                 /* volume setting              */
  S_NORMAL,                           /* mode setting                */
  0,                                  /* pitch setting               */
  1,                                  /* value of note setting       */
  2,                                  /* length of note setting      */
  0,                                  /* cdots of note setting       */
  1,                                  /* shape of waveform setting   */
  1,                                  /* repeat count setting        */
  0x01000000L,                        /* long frequency setting      */
  0x0100,                             /* frequency setting           */
  0,                                  /* frequency fraction setting  */
  1,                                  /* duration of sound setting   */
  192,                                /* queue size                  */
  0,                                  /* threshold count setting     */
  S_QUEUEEMPTY,                       /* wait state setting          */
};

/*********************************************************************/
/* Local Function Prototypes                                         */
/*********************************************************************/

void OutOfMemory(void);

/*********************************************************************/
/* Local data and structures                                         */
/*********************************************************************/


/*-------------------------------------------------------------------*/
/* Windows main()                                                    */
/*-------------------------------------------------------------------*/

int NEAR PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  HWND  hWnd;
  MSG   msg;

  if (!hPrevInstance) {
    if (!InitApplication(hInstance))
      return FALSE;
  }

  if (!InitInstance(hInstance,cmdShow))
    return FALSE;

  while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
    if (TranslateAccelerator(hWindow, hAccelTable, (LPMSG)&msg) == 0) {
      TranslateMessage((LPMSG)&msg);
      DispatchMessage((LPMSG)&msg);
    }
  }
  return(msg.wParam);
}


/*-------------------------------------------------------------------*/
/* Window message processor                                          */
/*-------------------------------------------------------------------*/

long FAR PASCAL WinProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
  switch (message) {

    case WM_INITMENU:
      if (wParam == GetMenu(hWnd)) {
        if (OpenClipboard(hWnd)) {
          if (IsClipboardFormatAvailable(CF_TEXT)
            || IsClipboardFormatAvailable(CF_OEMTEXT))
            EnableMenuItem(wParam, IDM_PASTE, MF_ENABLED);
          else
            EnableMenuItem(wParam, IDM_PASTE, MF_GRAYED);
          CloseClipboard();
          return(TRUE);
        }
        else                           /* Clipboard is not available */
          return(FALSE);
      }
      return(TRUE);

    case WM_SETFOCUS:
    case WM_SIZE:
      return(EditProc(hWnd, message, wParam, lParam));

    case WM_QUERYENDSESSION:
      return(FileQuerySave(hWnd));

    case WM_CLOSE:
      if (FileQuerySave(hWnd))
        DestroyWindow(hWnd);
      break;

    case WM_DESTROY:
      if (SndState.open) {
        CloseSound();
        SndState.open = 0;
      }
      PostQuitMessage(0);
      break;

    case WM_COMMAND:
      WinMenuCommand(hWnd, wParam);
      break;

    default:
      return(DefWindowProc(hWnd, message, wParam, lParam));
    }

  return(0L);
}

/*-------------------------------------------------------------------*/
/* Window command processor                                          */
/*-------------------------------------------------------------------*/

void WinMenuCommand(hWnd, id)
HWND hWnd;
int id;
{
  LPSTR lpszText;

  switch (id) {

    /* file menu commands */
    case IDM_NEW:
      FileNew(hWnd);
      break;

    case IDM_OPEN:
      FileOpen(hWnd);
      break;

    case IDM_SAVE:
      FileSave(hWnd);
      break;

    case IDM_SAVEAS:
      FileSaveAs(hWnd);
      break;

    case IDM_EXIT:
      if (FileQuerySave(hWnd))
        DestroyWindow(hWnd);
      break;


    /* edit menu commands */
    case IDM_UNDO:
    case IDM_CLEAR:
    case IDM_CUT:
    case IDM_COPY:
    case IDM_PASTE:
      EditMenuCommand(hWnd,id);
      break;

    /* Paste function menu commands */
    case IDM_CLOSESOUND:
    case IDM_COUNTVOICENOTES:
    case IDM_GETTHRESHOLDEVENT:
    case IDM_GETTHRESHOLDSTATUS:
    case IDM_OPENSOUND:
    case IDM_SETSOUNDNOISE:
    case IDM_SETVOICEACCENT:
    case IDM_SETVOICEENVELOPE:
    case IDM_SETVOICENOTE:
    case IDM_SETVOICEQUEUESIZE:
    case IDM_SETVOICESOUND:
    case IDM_SETVOICETHRESHOLD:
    case IDM_STARTSOUND:
    case IDM_STOPSOUND:
    case IDM_SYNCALLVOICES:
    case IDM_WAITSOUNDSTATE:
      PasteMenuCommand(hWnd,id);
      break;

    /* play menu commands */
    case IDM_PLAY:
      Play();
      break;

    /* help menu commands */
    case IDM_HELP_INDEX:
      WinHelp(hWnd,HelpFileName,HELP_INDEX,0L);
      break;

    case IDM_HELP_FUNCTIONS:
      WinHelp(hWnd,HelpFileName,HELP_KEY,(DWORD)(LPSTR)"Sound Functions");
      break;

    case IDM_HELP_HELP:
      WinHelp(hWnd,"",HELP_HELPONHELP,0L);
      break;

    case IDM_ABOUT:
      GoDialogBox(hInst, "About", hWnd, About);
      break;

    default:
      break;
  }
}

/*-------------------------------------------------------------------*/
/* Create a dialog box and let a callback function handle messages.  */
/*-------------------------------------------------------------------*/

int GoDialogBox(hInstance, lpTemplateName, hWndParent, lpProc)
HANDLE hInstance;
LPSTR lpTemplateName;
HWND hWndParent;
FARPROC lpProc;
{
  int     nResult;
  FARPROC lpDialog;

  lpDialog = MakeProcInstance(lpProc, hInstance);
  nResult = DialogBox(hInstance, lpTemplateName, hWndParent, lpDialog);
  FreeProcInstance(lpDialog);

  return(nResult);
}


/*-------------------------------------------------------------------*/
/* About dialog box callback function.                               */
/*-------------------------------------------------------------------*/

BOOL FAR PASCAL About( hDlg, message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
  if (message == WM_COMMAND) {
    EndDialog( hDlg, TRUE );
    return TRUE;
  }
  else if (message == WM_INITDIALOG) {
    return TRUE;
  }
  else return FALSE;
}


/**********************************************************************/
/* Local functions                                                    */
/**********************************************************************/

void OutOfMemory(void)
{
  MessageBox(
    GetFocus(),
    "Out of Memory",
    NULL,
    MB_ICONHAND | MB_SYSTEMMODAL);
  return;
}

