/**************************************************************************
 *  File name  :  main.c
 *
 *  Description:  This application serves as a template than can be
 *		  modified by an application developer.	 The source
 *		  files are organized so that the overhead code, which
 *		  should be in all applications, is located in the same
 *		  files, so that these files do not need to be modified.
 *		  The routines that deal with application-specific code
 *		  are also locatedin their own modules.	 An application
 *		  developer need only change these files in order to
 *		  modify this template for his application.
 *
 *		  This source file contains the following functions:
 *
 *		  main()
 *		  MainWndProc(hwnd, msg, mp1, mp2)
 *		  MessageBox(hwnd idMsg, fsStyle, fBeep)
 *		  MainCommand(mp1, mp2)
 *
 *  Concepts   :  Presentation Manager
 *
 *  API's      :  WinInitialize
 *		  DosBeep
 *		  WinCreateMsgQueue
 *		  WinTerminate
 *		  WinCreateStdWindow
 *		  WinOpenWindowDC
 *		  WinGetMsg
 *		  WinDispatchMsg
 *		  WinPostMsg
 *		  WinLoadMessage
 *		  WinAlarm
 *		  WinMessageBox
 *
 *    Files    :  OS2.H, MAIN.H, HELP.H, XTRN.H
 *
 *  Copyright (C) 1991 IBM Corporation
 *
 *	DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
 *	sample code created by IBM Corporation. This sample code is not
 *	part of any standard or IBM product and is provided to you solely
 *	for  the purpose of assisting you in the development of your
 *	applications.  The code is provided "AS IS", without
 *	warranty of any kind.  IBM shall not be liable for any damages
 *	arising out of your use of the sample code, even if they have been
 *	advised of the possibility of such damages.						       *
 *************************************************************************/

/*
 *  Include files, macros, defined constants, and externs
 */

#define	 INCL_WINHELP

#include <os2.h>
#include "main.h"
#include "help.h"
#include "xtrn.h"


/*
 *  Global variables
 */
HWND hwndMainFrame = NULLHANDLE;    /* handle to the main frame window */
HWND hwndMain;			    /* handle to the main client window */
HDC  hdcMain;			    /* handle to the DC of the client */
HAB  hab;			    /* anchor block for the process */
HMQ  hmq;			    /* handle to the process' message queue */
CHAR szAppName[MAXNAMEL];	    /* buffer for application name string */
CHAR szUntitled[MESSAGELEN];	    /* buffer for "Untitled" string */
BOOL fPrintEnabled;		    /* flag to determine if we can print */
BOOL fHelpEnabled;		    /* flag to determine if help is enabled */

/*
 *  Entry point declarations
 */

/**************************************************************************
 *
 *  Name       : main()
 *
 *  Description: Initializes the PM environment, calls the
 *		 initialization routine, creates the main
 *		 window,  and polls the message queue
 *
 *  Concepts:	 - obtains anchor block handle and creates message
 *		      queue
 *		 - calls the initialization routine
 *		 - creates the main frame window which creates the
 *		      main client window
 *		 - polls the message queue via Get/Dispatch Msg loop
 *		 - upon exiting the loop, exits
 *
 *  API's      :  WinInitialize
 *		  DosBeep
 *		  WinCreateMsgQueue
 *		  WinTerminate
 *		  WinCreateStdWindow
 *		  WinOpenWindowDC
 *		  WinGetMsg
 *		  WinDispatchMsg
 *
 *  Parameters :  [none]
 *
 *  Return     :  0 - if successful execution completed
 *		  1 - if error
 *
 *************************************************************************/
int main(VOID)
{
   QMSG qmsg;	       /* message structure */
   ULONG flCtlData;    /* frame control data */

   hab = WinInitialize(0);

   if(NULLHANDLE == hab)
   {
      DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
      return(RETURN_ERROR);
   }

   hmq = WinCreateMsgQueue(hab, 0);

   if(NULLHANDLE == hmq)
   {
      DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
      WinTerminate(hab);
      return(RETURN_ERROR);
   }

   if(!Init())
   {
      MessageBox(HWND_DESKTOP,
		 IDMSG_INITFAILED,
		 MB_OK | MB_ERROR,
		 TRUE);
      return(RETURN_ERROR);
   }

   /* NOTE:  clean up from here is handled by the DosExitList processing */


   /* create the main window */
   flCtlData = FCF_STANDARD;

   hwndMainFrame = WinCreateStdWindow(HWND_DESKTOP,
				      WS_VISIBLE,
				      &flCtlData,
				      (PSZ)szAppName,
				      (PSZ)NULL,
				      WS_VISIBLE,
				      (HMODULE)NULL,
				      IDR_MAIN,
				      (PHWND)&hwndMain);

   if(NULLHANDLE == hwndMainFrame)
   {
       MessageBox(HWND_DESKTOP,
		  IDMSG_MAINWINCREATEFAILED,
		  MB_OK | MB_ERROR,
		  TRUE);
       return(RETURN_ERROR);
   }

   hdcMain = WinOpenWindowDC(hwndMain);

   InitHelp();

   /* Get/Dispatch Message loop */
   while(WinGetMsg(hab, (PQMSG)&qmsg, (HWND)NULL, (ULONG)NULL, (ULONG)NULL))
       WinDispatchMsg(hab, (PQMSG)&qmsg);

   /* destroy the help instance */
   DestroyHelpInstance();

#ifdef BACKGROUND_THREAD
    /* see main.h for comment on using a background thread */
   DestroyBackgroundThread();
#endif

   return(RETURN_SUCCESS);
}   /* End of main   */


/**************************************************************************
 *
 *  Name       : MainWndProc(hwnd, msg, mp1, mp2)
 *
 *  Description:  Processes the messages sent to the main client
 *		  window.  This routine processes the basic
 *		  messages all client windows should process
 *		  and passes all others onto UserWndProc where
 *		  the developer can process any others.
 *
 *  Concepts:	  Called for each message placed in the main
 *		  window's message queue
 *
 *		  A switch statement branches to the routines to be
 *		  performed for each message processed.	 Any messages
 *		  not specifically process are passed to the user's
 *		  message processing procedure UserWndProc().
 *
 *  API's      :  WinPostMsg
 *
 *  Parameters :  hwnd = window handle
 *		  msg  = message i.d.
 *		  mp1  = first message parameter
 *		  mp2  = second message parameter
 *
 *  Return     :  value is determined by each message
 *
 *************************************************************************/
MRESULT EXPENTRY MainWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
   switch(msg)
   {
   case WM_CREATE:
      return(InitMainWindow(hwnd, mp1, mp2));
      break;

   case WM_PAINT:
       MainPaint(hwnd);
       break;

   case WM_COMMAND:
       MainCommand(mp1, mp2);
       break;

   case WM_INITMENU:
       InitMenu(mp1, mp2);
       break;

   case HM_QUERY_KEYS_HELP:
       return (MRESULT)PANEL_HELPKEYS;	 /* return id of key help panel */
       break;

   case TM_THREADINITFAILED:
       /*  The message is received if the background thread
	*  initialization fails.
	*  A message box is displayed and the application is
	*  terminated.
	*/
       MessageBox(HWND_DESKTOP,
		  IDMSG_INITFAILED,
		  MB_OK | MB_ERROR,
		  TRUE);

       WinPostMsg(hwnd, WM_CLOSE, NULL, NULL);
       break;

   /*
    *	   Any messages not processed are passed on
    *	   to the user's window proc.  It is
    *	   responsible for passing any messages it
    *	   doesn't handle onto WinDefWindowProc()
    */

   default:
      return UserWndProc(hwnd, msg, mp1, mp2);
      break;

   }
   return (MRESULT)NULL;  /* all window procedures return 0 as a default */
}   /* End of MainWndProc   */

/**************************************************************************
 *
 *  Name       : MessageBox(hwndOwner, nIdMsg, fsStyle, fBeep)
 *
 *  Description:  Displays the message box with the message
 *		  given in idMsg retrieved from the message table
 *		  and using the style flags in fsStyle.
 *
 *  Concepts:	  Called whenever a message box is to be displayed
 *
 *		  - Message string is loaded from the process'
 *		      message table
 *		  - Alarm beep is sounded if desired
 *		  - Message box with the message is displayed
 *		  - WinMessageBox return value is returned
 *
 *  API's      :  WinLoadMessage
 *		  WinAlarm
 *		  WinMessageBox
 *
 *  Parameters :  hwndOwner = window handle of the owner
 *		  nIdMsg    = message i.d.
 *		  fsStyle   = style flags for the message box
 *		  fBeep	    = should an alarm be sounded?
 *
 *  Return     :  return value from WinMessageBox
 *
 *************************************************************************/
ULONG MessageBox(HWND hwndOwner, ULONG idMsg, ULONG fsStyle, BOOL fBeep)
{
   CHAR szText[MESSAGELEN];

   if(!WinLoadMessage(hab,
		     (HMODULE)NULL,
		     idMsg,
		     MESSAGELEN,
		     (PSZ)szText))
   {
      WinAlarm(HWND_DESKTOP, WA_ERROR);
      return MBID_ERROR;
   }

   if(fBeep)
      WinAlarm(HWND_DESKTOP, WA_ERROR);

   return(WinMessageBox(HWND_DESKTOP,
			hwndOwner,
			szText,
			(PSZ)NULL,
			MSGBOXID,
			fsStyle));

}   /* End of MessageBox   */

/**************************************************************************
 *
 *  Name       : MainCommand(mp1, mp2)
 *
 *  Description: Calls the appropriate procedures that deal with
 *		 the selected menu item.
 *
 *  Concepts:	 Routine is called whenever a WM_COMMAND message
 *		 is posted to the main window.
 *
 *		 A switch statement branches on the id of the
 *		 menu item that posted the message and the
 *		 appropriate action for that item is taken.  Any
 *		 menu ids that are not part of the standard menu
 *		 set are passed onto the user defined WM_COMMAND
 *		 processing procedure.
 *
 *  API's      : [none]
 *
 *  Parameters : mp1 = first message parameter
 *		 mp2 = second message parameter
 *
 *  Return     : [none]
 *
 *************************************************************************/
VOID MainCommand(MPARAM mp1, MPARAM mp2)
{
   switch(SHORT1FROMMP(mp1))
   {
   case IDM_FILENEW:
      FileNew(mp2);
      break;

   case IDM_FILEOPEN:
      FileOpen(mp2);
      break;

   case IDM_FILESAVE:
      FileSave(mp2);
      break;

   case IDM_FILESAVEAS:
      FileSaveAs(mp2);
      break;

   case IDM_EDITUNDO:
      EditUndo(mp2);
      break;

   case IDM_EDITCUT:
      EditCut(mp2);
      break;

   case IDM_EDITCOPY:
      EditCopy(mp2);
      break;

   case IDM_EDITPASTE:
      EditPaste(mp2);
      break;

   case IDM_EDITCLEAR:
      EditClear(mp2);
      break;

   case IDM_HELPINDEX:
      HelpIndex();
      break;

   case IDM_HELPGENERAL:
      HelpGeneral();
      break;

   case IDM_HELPUSINGHELP:
      HelpUsingHelp();
      break;

   case IDM_HELPKEYS:
      HelpKeys();
      break;

   case IDM_HELPTUTORIAL:
      HelpTutorial();
      break;

   case IDM_HELPPRODUCTINFO:
      HelpProductInfo();
      break;

   /*
    *	   User command processing routine is called
    *	   here so any ids not processed here can be
    *	   processed.
    */
   default:
      UserCommand(mp1, mp2);
      break;
   }
}   /* End of MainCommand  */
/***************************  End of main.c  ****************************/
