/*
 * AppTempBuilder Main   (C) 1996 John M Haubrich Jr
 *                           All Rights Under Copyright Reserved
 *
 * Version 1.0
 *
 * Written using SAS/C 6.56
 * Using Magic User Interface (MUI) by Stefan Stuntz
 *
 * By John M. Haubrich, Jr.
 *
 *
 * Version~ Date~~~~~~~ Comments~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * -------  ----        --------
 *             ;
 */

#include "common.h"


/*
 * GLOBAL VARIABLES ---------------------------------
 */
struct MyGlobals  MG;
UBYTE             GL_szFault[256];
UBYTE             GL_szBuf[512];

struct MainWindow       MAIN;
struct WindowsWindow    WINDOWS;

LONG  __stack = 16384;


/*
 * DEFINES ------------------------------------------
 */
#define NUM_ARGS        0
//#define ARG_PUBSCREEN   0


/*
 * LIBRARY VARIABLES ---------------------------------
 */
struct Library       *AslBase       = NULL;
struct DosBase       *DosBase       = NULL;
struct GfxBase       *GfxBase       = NULL;
struct Library       *IconBase      = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Library       *MUIMasterBase = NULL;
struct Library       *UtilityBase   = NULL;
struct Library       *WorkbenchBase = NULL;

#ifdef LATTICE
int CXBRK(void) { return(0); }
void __regargs __chkabort(void) { return; }
#endif

/**
 ** M A I N   P R O G R A M -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 **/
void main(int argc, char *argv[])
{
   ULONG   signals;
   ULONG   ulInputEvent;

   // generic status vars
   LONG    l, lStat;
   UBYTE  *pszStat, *pszStat2;

   struct WindowData *pWdwData;

   BPTR               tmplock;
   struct WBStartup  *WBenchMsg   = NULL;
   struct WBArg      *pWBArg      = NULL;

   // MAKE-SOURCE variables
   UBYTE              szSourceDir[ FMSIZE + 2 ];
   UBYTE              szSourceFile[ FMSIZE + 2 ];
   BPTR               fhi, fho, fhiSave;
   UBYTE              szLineIn[ LINEIN_BUFSIZE ];
   UBYTE             *pBuf;
   LONG               lError;
   UBYTE             *pszStart, *pszEnd, *pszOpener, *pszCloser;
   LONG               lDiskLoopAddr;
   struct WindowData *pCurrWindow;
   ULONG              ulGadgetID = 10000;
   UBYTE              szBuf[256], szBuf2[50];
   UBYTE              szTempleFile[256];
   BPTR               fhTempleW, fhTempleN, fhTempleV;


   MG.running = TRUE;

   //
   // setup variables, read startup params, etc...
   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   JMH_Startup( argc, argv );
   NewList( &MG.WindowList );

   //
   // attempt to create window objects and attach to application parent
   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   if ( fnConstructMainWindow   () == FALSE )   {  JMH_Quit( "Failed to create MAIN window."    );  }
   if ( fnConstructWindowsWindow() == FALSE )   {  JMH_Quit( "Failed to create WINDOWS window." );  }

   //
   // Load application settings; populate global vars
   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   DoMethod( MG.App, MUIM_Application_Load, MUIV_Application_Load_ENV );

   //
   // allocate initial 'window' node (MAIN)
   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   pWdwData = fnSetupMAINWindowNode();
   if ( pWdwData )
   {
      AddTail( &MG.WindowList, (struct Node *)pWdwData );
      DoMethod( WINDOWS.LIS_List, MUIM_List_InsertSingle, pWdwData->szName, MUIV_List_Insert_Bottom );
      set( WINDOWS.LIS_List, MUIA_List_Active, 0L );
   }

   //
   // open main window
   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   fnInitMainWindow();
   fnClearMainWindow();

   //
   // if we're passed a data file, load it
   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   if ( argc > 1 )
   {
      strcpy( MG.szProjectSpec, argv[1] );
      if ( fnOpen( MG.szProjectSpec ) == TRUE )
      {
//         fnRefreshWindows();
      }
   }
   else
   {
      WBenchMsg   = (struct WBStartup *)argv;
      pWBArg      = WBenchMsg->sm_ArgList;

      pWBArg++;   // get first parameter

      if ( pWBArg )
      {
         if ( ( pWBArg->wa_Lock ) && ( *pWBArg->wa_Name ) )
         {
            tmplock = Lock( pWBArg->wa_Name, ACCESS_READ );
            NameFromLock( tmplock, MG.szProjectSpec, FMSIZE );
            if ( fnOpen( MG.szProjectSpec ) == TRUE )
            {
//               fnRefreshWindows();
            }
            UnLock( tmplock );
         }
      }
   }

   //
   // show 'em what it's all 'About'
   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   JMH_About();

   //
   //   MAIN LOOP          MAIN LOOP         MAIN LOOP         MAIN LOOP
   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   while ( MG.running )
   {
      ulInputEvent = DoMethod( MG.App, MUIM_Application_Input, &signals );
      switch ( ulInputEvent )
      {
         case MUIV_Application_ReturnID_Quit:
         case ID_MENU_MAIN_QUIT:
            if ( MUI_Request( MG.App, MG.WIN_MAIN, 0, NULL, "OK|*Cancel",
                              "Are you sure you want to quit?", NULL ) == 1 )
            {
               MG.running = FALSE;
            }
            break;

         // MENUS ---------------------------------------------
         case ID_MENU_MAIN_NEW:
            if ( MUI_Request( MG.App, MG.WIN_MAIN, 0, NULL, "OK|*Cancel",
                              "Are you sure you wish to clear all data?", NULL ) == 1 )
            {
               fnClearMainWindow();
               fnClearWindowsWindow();
               strcpy( szSourceDir, "" );
            }
            break;
         case ID_MENU_MAIN_OPEN:
            if ( JMH_FileReq( MG.WIN_MAIN, "Open File", FALSE, FALSE, MG.szProjectSpec, FMSIZE ) )
            {
               if ( fnOpen( MG.szProjectSpec ) == TRUE )
               {
//                  fnRefreshWindows();
               }
            }
            break;
         case ID_MENU_MAIN_SAVE:
            if ( strcmp( MG.szProjectSpec, "" ) == 0 )
            {
               JMH_FileReq( MG.WIN_MAIN, "Save File", TRUE, FALSE, MG.szProjectSpec, FMSIZE );
            }
            if ( strcmp( MG.szProjectSpec, "" ) )
            {
               fnSave( MG.szProjectSpec );
            }
            break;
         case ID_MENU_MAIN_SAVEAS:
            if ( JMH_FileReq( MG.WIN_MAIN, "Save File", TRUE, FALSE, MG.szProjectSpec, FMSIZE ) )
            {
               fnSave( MG.szProjectSpec );
            }
            break;
         case ID_MENU_MAIN_MAKESOURCE:
//            strcpy( szSourceDir, "" );
            if ( JMH_FileReq( MG.WIN_MAIN, "Save Directory", TRUE, TRUE, szSourceDir, FMSIZE ) )
            {
               set( MG.App, MUIA_Application_Sleep, TRUE );

               pBuf          = NULL;
               lError        = 0L;
               lDiskLoopAddr = 0L;
               pCurrWindow   = (struct WindowData *)MG.WindowList.lh_Head;
               fho           = NULL;
               fhi = Open( "apptemp.dat", MODE_OLDFILE );
               get( MAIN.STR_TEMPLEFILE, MUIA_String_Contents, &pszStat );
               sprintf( szTempleFile, "%s.window", pszStat );
               fhTempleW = Open( szTempleFile, MODE_OLDFILE );
               sprintf( szTempleFile, "%s.notify", pszStat );
               fhTempleN = Open( szTempleFile, MODE_OLDFILE );
               sprintf( szTempleFile, "%s.var", pszStat );
               fhTempleV = Open( szTempleFile, MODE_OLDFILE );
               if ( fhi && fhTempleW && fhTempleN && fhTempleV )
               {
                  while ( 1 )
                  {
                     pBuf = FGets( fhi, szLineIn, sizeof( szLineIn ) );
                     if ( !pBuf )
                     {
                        lError = IoErr();
                        break;
                     }

                     //
                     // detect end of temple file and revert to
                     // apptemp.dat file handle...
                     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     if ( strcmp( szLineIn, "===END===\n" ) == 0 )
                     {
                        fhi = fhiSave;
                        continue;
                     }

                     pszStart = szLineIn;
                     pszEnd = szLineIn + strlen( szLineIn );
                     while ( pszStart < pszEnd )
                     {
                        // Rip '«' and '»' from line
                        pszOpener = strchr( pszStart, '«' );
                        if ( pszOpener )
                        {
                           *pszOpener = 0;
                           if ( fho )  FPuts( fho, pszStart );
                           pszStart = pszOpener + 1;
                           pszCloser = strchr( pszStart, '»' );
                           if ( pszCloser )
                           {
                              //
                              // Handle keywords here...
                              // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                              *pszCloser = 0;
                              if      ( strncmp( pszStart, "FILE:", 5 ) == 0 )
                              {
                                 strcpy( szSourceFile, szSourceDir );
                                 AddPart( szSourceFile, pszStart+5, FMSIZE );
                                 fho = Open( szSourceFile, MODE_NEWFILE );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "ENDFILE" ) == 0 )
                              {
                                 if ( fho )
                                 {
                                    Close( fho );
                                    fho = NULL;
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "APPOWNER" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szAPPOWNER );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "COMPILER" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szCOMPILER );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "VERSNUM" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szVERSNUM );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "YEAR" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szYEAR );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "APPNAME" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szAPPNAME );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "APPBASE" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szAPPBASE );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "APPTITLE" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szAPPTITLE );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "APPVERS" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szAPPVERS );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "APPCOPYR" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szAPPCOPYR );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "APPAUTH" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szAPPAUTH );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "APPDESC" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szAPPDESC );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "HELPFILE" ) == 0 )
                              {
                                 if ( fho )  FPuts( fho, MG.szHELPFILE );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "REXX" ) == 0 )
                              {
                                 pszStart = fnFindEndif( fhi, "«ENDIF»" );
                                 if ( pszStart == NULL )
                                    pszStart = pszEnd;
                              }
                              else if ( strncmp( pszStart, "MENULINE:", 9 ) == 0 )
                              {
                                 lStat = atol( &pszStart[9] );
                                 DoMethod( MAIN.LIS_List, MUIM_List_GetEntry, lStat, &pszStat );
                                 if ( *(pszStat+1) != 'b' )
                                 {
                                    pszStart = pszEnd;
                                 }
                                 else
                                 {
                                    pszStart = pszCloser + 1;
                                 }
                              }
                              else if ( strncmp( pszStart, "MENUIF:", 7 ) == 0 )
                              {
                                 lStat = atol( &pszStart[7] );
                                 DoMethod( MAIN.LIS_List, MUIM_List_GetEntry, lStat, &pszStat );
                                 if ( *(pszStat+1) != 'b' )
                                 {
                                    pszStart = fnFindEndif( fhi, "«ENDIF»" );
                                    if ( pszStart == NULL )
                                       pszStart = pszEnd;
                                 }
                                 else
                                 {
                                    pszStart = pszCloser + 1;
                                 }
                              }
                              else if ( strcmp( pszStart, "FOREACH:WINDOW" ) == 0 )
                              {
                                 ulGadgetID = 10000;
                                 pCurrWindow = (struct WindowData *)MG.WindowList.lh_Head;
                                 lDiskLoopAddr = Seek( fhi, 0, OFFSET_CURRENT );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "ENDEACH" ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    pCurrWindow = (struct WindowData *)( ( (struct Node *)pCurrWindow )->ln_Succ );
                                    if ( ( (struct Node *)pCurrWindow )->ln_Succ )
                                    {
                                       ulGadgetID += 1000;
                                       if ( lDiskLoopAddr != -1L )
                                       {
                                          Seek( fhi, lDiskLoopAddr, OFFSET_BEGINNING );
                                       }
                                    }
                                    else
                                    {
                                       ulGadgetID  = 10000;
                                       pCurrWindow = (struct WindowData *)MG.WindowList.lh_Head;
                                    }
                                 }
                                 else
                                 {
                                    if ( fho )  FPuts( fho, "***** ENDEACH without FOREACH error. *****" );
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "WSN" ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    if ( fho )  FPuts( fho, pCurrWindow->szName );
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "WSI" ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    if ( fho )  FPuts( fho, pCurrWindow->szIdent );
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "WID" ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    if ( fho )
                                    {
                                       sprintf( szBuf2, "%-4.4s", pCurrWindow->szID );
                                       sprintf( szBuf, "'%c','%c','%c','%c'", szBuf2[0], szBuf2[1], szBuf2[2], szBuf2[3] );
                                       FPuts( fho, szBuf );
                                    }
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "WTITLE" ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    if ( fho )  FPuts( fho, pCurrWindow->szTitle );
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "MENUPTR" ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    if ( fho )  FPuts( fho, pCurrWindow->szMenu );
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "APPWDW" ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    if ( fho )  FPuts( fho, pCurrWindow->fAppW ? "TRUE" : "FALSE" );
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "WHELP" ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    if ( fho )  FPuts( fho, pCurrWindow->szWHelp );
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "MHELP" ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    if ( fho )  FPuts( fho, pCurrWindow->szMHelp );
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "WCLOSE" ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    if ( fho )  FPuts( fho, pCurrWindow->szClose );
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strncmp( pszStart, "GADGETID:", 9 ) == 0 )
                              {
                                 if ( pCurrWindow )
                                 {
                                    sprintf( szBuf, "%lu", ulGadgetID + atol( pszStart + 9 ) );
                                    if ( fho )  FPuts( fho, szBuf );
                                 }
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "IF:REXX" ) == 0 )
                              {
                                 get( MAIN.CHE_REXX, MUIA_Selected, &lStat );
                                 if ( !lStat )
                                 {
                                    pszStart = fnFindEndif( fhi, "«ENDIF»" );
                                    if ( pszStart == NULL )
                                       pszStart = pszEnd;
                                 }
                                 else
                                 {
                                    pszStart = pszCloser + 1;
                                 }
                              }
                              else if ( strncmp( pszStart, "IF:", 3 ) == 0 )
                              {
                                 if      ( strcmp( &pszStart[3], "ASL_INCL" ) == 0 )
                                 {
                                    get( MAIN.CHE_AslBase, MUIA_Selected, &lStat );
                                 }
                                 else if ( strcmp( &pszStart[3], "DATATYPES_INCL" ) == 0 )
                                 {
                                    get( MAIN.CHE_DataTypesBase, MUIA_Selected, &lStat );
                                 }
                                 else if ( strcmp( &pszStart[3], "DISKFONT_INCL" ) == 0 )
                                 {
                                    get( MAIN.CHE_DiskfontBase, MUIA_Selected, &lStat );
                                 }
                                 else if ( strcmp( &pszStart[3], "GADTOOLS_INCL" ) == 0 )
                                 {
                                    get( MAIN.CHE_GadToolsBase, MUIA_Selected, &lStat );
                                 }
                                 else if ( strcmp( &pszStart[3], "IFFPARSE_INCL" ) == 0 )
                                 {
                                    get( MAIN.CHE_IFFParseBase, MUIA_Selected, &lStat );
                                 }
                                 else if ( strcmp( &pszStart[3], "LOCALE_INCL" ) == 0 )
                                 {
                                    get( MAIN.CHE_LocaleBase, MUIA_Selected, &lStat );
                                 }
                                 else if ( strcmp( &pszStart[3], "REALTIME_INCL" ) == 0 )
                                 {
                                    get( MAIN.CHE_RealTimeBase, MUIA_Selected, &lStat );
                                 }
                                 else if ( strcmp( &pszStart[3], "WORKBENCH_INCL" ) == 0 )
                                 {
                                    get( MAIN.CHE_WorkbenchBase, MUIA_Selected, &lStat );
                                 }
                                 else
                                 {
                                    // skip this!
                                    if ( fho )  FPuts( fho, "***** UNKNOWN 'IF' TYPE *****" );
                                    lStat = 1;
                                 }
                                 if ( !lStat )
                                 {
                                    pszStart = fnFindEndif( fhi, "«ENDIF»" );
                                    if ( pszStart == NULL )
                                       pszStart = pszEnd;
                                 }
                                 else
                                 {
                                    pszStart = pszCloser + 1;
                                 }
                              }
                              else if ( strcmp( pszStart, "ENDIF" ) == 0 )
                              {
                                 //
                                 // just ignore these!  They're detected by fnFindEndif()
                                 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "ASL_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_AslBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "DATATYPES_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_DataTypesBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "DISKFONT_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_DiskfontBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "DOS_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_DosBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "GADTOOLS_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_GadToolsBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "GFX_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_GfxBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "ICON_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_IconBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "IFFPARSE_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_IFFParseBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "INTUITION_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_IntuitionBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "LOCALE_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_LocaleBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "MUIMASTER_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_MUIMasterBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "REALTIME_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_RealTimeBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "UTILITY_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_UtilityBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "WORKBENCH_VERSION" ) == 0 )
                              {
                                 get( MAIN.INT_WorkbenchBase, MUIA_Numeric_Value, &lStat );
                                 if ( fho )  FPrintf( fho, "%ld", lStat );
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "TEMPLE.WINDOW" ) == 0 )
                              {
//                                 fnCopyTempleUntilEndMarker( fhTempleW, fho );
                                 fhiSave = fhi;
                                 fhi = fhTempleW;
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "TEMPLE.NOTIFY" ) == 0 )
                              {
//                                 fnCopyTempleUntilEndMarker( fhTempleN, fho );
                                 fhiSave = fhi;
                                 fhi = fhTempleN;
                                 pszStart = pszCloser + 1;
                              }
                              else if ( strcmp( pszStart, "TEMPLE.VAR" ) == 0 )
                              {
//                                 fnCopyTempleUntilEndMarker( fhTempleV, fho );
                                 fhiSave = fhi;
                                 fhi = fhTempleV;
                                 pszStart = pszCloser + 1;
                              }
                              else
                              {
                                 if ( fho )  FPuts( fho, "***** UNKNOWN KEYWORD *****" );
                              }
                           }
                           else
                           {
                              // parse error
                              if ( fho )
                              {
                                 FPuts( fho, "[PARSE ERROR: Cannot find matching '»' LINE FOLLOWS:]" );
                                 FPuts( fho, pszStart );
                              }
                              pszStart = pszEnd;
                           }
                        }
                        else
                        {
                           if ( fho )
                           {
                              FPuts( fho, pszStart );
                           }
                           pszStart = pszEnd;
                        }
                     }
                  }

                  //
                  // Report error, if any
                  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  if ( lError )
                  {
                     JMH_Error( "Unable to open apptemp.dat input file.\nSource code was not generated.",
                                MG.WIN_MAIN, FALSE, "apptemp.guide", "errors", 0 );
                     if ( fho )
                     {
                        FPuts( fho, "CRITICAL I/O ERROR ENCOUNTERED.  SOURCE FILE MAY BE INCOMPLETE.\n" );
                     }
                  }

                  //
                  // Close open files
                  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  if ( fho )
                  {
                     Close( fho );
                     fho = NULL;
                  }
                  if ( fhi       )     Close( fhi );
                  if ( fhTempleW )     Close( fhTempleW );
                  if ( fhTempleN )     Close( fhTempleN );
                  if ( fhTempleV )     Close( fhTempleV );
               }
               else
               {
                  JMH_Error( "Unable to open apptemp.dat input file.\nSource code was not generated.",
                             MG.WIN_MAIN, FALSE, "apptemp.guide", "errors", 0 );
                  if ( fhi       )     Close( fhi );
                  if ( fhTempleW )     Close( fhTempleW );
                  if ( fhTempleN )     Close( fhTempleN );
                  if ( fhTempleV )     Close( fhTempleV );
               }

               set( MG.App, MUIA_Application_Sleep, FALSE );
            }
            break;
         case ID_MENU_MAIN_ABOUT:
            JMH_About();
            break;
         case ID_MENU_MAIN_WINDOWS:
            fnInitWindowsWindow();
            break;

         // GADGETS -------------------------------------------
         /***** WINDOW: MAIN        *****/
         case ID_STR_MAIN_APPOWNER  :  get( MAIN.STR_APPOWNER  , MUIA_String_Contents, &pszStat );  strcpy( MG.szAPPOWNER  , pszStat );   break;
         case ID_STR_MAIN_COMPILER  :  get( MAIN.STR_COMPILER  , MUIA_String_Contents, &pszStat );  strcpy( MG.szCOMPILER  , pszStat );   break;
         case ID_STR_MAIN_APPBASE   :  get( MAIN.STR_APPBASE   , MUIA_String_Contents, &pszStat );  strcpy( MG.szAPPBASE   , pszStat );   break;
         case ID_STR_MAIN_APPTITLE  :  get( MAIN.STR_APPTITLE  , MUIA_String_Contents, &pszStat );  strcpy( MG.szAPPTITLE  , pszStat );   break;
         case ID_STR_MAIN_APPVERS   :  get( MAIN.STR_APPVERS   , MUIA_String_Contents, &pszStat );  strcpy( MG.szAPPVERS   , pszStat );   break;
         case ID_STR_MAIN_APPCOPYR  :  get( MAIN.STR_APPCOPYR  , MUIA_String_Contents, &pszStat );  strcpy( MG.szAPPCOPYR  , pszStat );   break;
         case ID_STR_MAIN_APPDESC   :  get( MAIN.STR_APPDESC   , MUIA_String_Contents, &pszStat );  strcpy( MG.szAPPDESC   , pszStat );   break;
         case ID_STR_MAIN_HELPFILE  :  get( MAIN.STR_HELPFILE  , MUIA_String_Contents, &pszStat );  strcpy( MG.szHELPFILE  , pszStat );   break;
         case ID_STR_MAIN_TEMPLEFILE:  get( MAIN.STR_TEMPLEFILE, MUIA_String_Contents, &pszStat );  strcpy( MG.szTEMPLEFILE, pszStat );   break;

         case ID_STR_MAIN_APPNAME:
            get( MAIN.STR_APPNAME, MUIA_String_Contents, &pszStat );
            strcpy( MG.szAPPNAME, pszStat );
            sprintf( MG.szAPPBASE, "%-.15s", pszStat );
            strupr( MG.szAPPBASE );
            set( MAIN.STR_APPBASE, MUIA_String_Contents, MG.szAPPBASE );

            get( MAIN.STR_APPTITLE, MUIA_String_Contents, &pszStat2 );
            sprintf( MG.szAPPTITLE, pszStat );
            set( MAIN.STR_APPTITLE, MUIA_String_Contents, MG.szAPPTITLE );

            get( MAIN.STR_APPVERS, MUIA_String_Contents, &pszStat2 );
            sprintf( MG.szAPPVERS, "$VER: %s %s (00.00.%s)", pszStat, MG.szVERSNUM, MG.szYEAR );
            set( MAIN.STR_APPVERS, MUIA_String_Contents, MG.szAPPVERS );

            get( MAIN.STR_HELPFILE, MUIA_String_Contents, &pszStat2 );
            sprintf( MG.szHELPFILE, "PROGDIR:%s.guide", pszStat );
            set( MAIN.STR_HELPFILE, MUIA_String_Contents, MG.szHELPFILE );

            set( MG.WIN_MAIN, MUIA_Window_ActiveObject, MAIN.STR_VERSNUM );
            break;
         case ID_STR_MAIN_VERSNUM:
            get( MAIN.STR_VERSNUM, MUIA_String_Contents, &pszStat );
            strcpy( MG.szVERSNUM, pszStat );
            sprintf( MG.szAPPVERS, "$VER: %s %s (00.00.%s)", MG.szAPPNAME, pszStat, MG.szYEAR );
            set( MAIN.STR_APPVERS, MUIA_String_Contents, MG.szAPPVERS );

            set( MG.WIN_MAIN, MUIA_Window_ActiveObject, MAIN.STR_APPAUTH );
            break;
         case ID_STR_MAIN_APPAUTH:
            get( MAIN.STR_APPAUTH, MUIA_String_Contents, &pszStat );
            strcpy( MG.szAPPAUTH, pszStat );
            sprintf( MG.szAPPCOPYR, "(C) %s  %s", MG.szYEAR, pszStat );
            set( MAIN.STR_APPCOPYR, MUIA_String_Contents, MG.szAPPCOPYR );

            set( MG.WIN_MAIN, MUIA_Window_ActiveObject, MAIN.STR_YEAR );
            break;
         case ID_STR_MAIN_YEAR:
            get( MAIN.STR_YEAR, MUIA_String_Contents, &pszStat );
            strcpy( MG.szYEAR, pszStat );

            sprintf( MG.szAPPVERS, "$VER: %s %s (00.00.%s)", MG.szAPPNAME, MG.szVERSNUM, MG.szYEAR );
            set( MAIN.STR_APPVERS, MUIA_String_Contents, MG.szAPPVERS );

            sprintf( MG.szAPPCOPYR, "(C) %s  %s", MG.szYEAR, MG.szAPPAUTH );
            set( MAIN.STR_APPCOPYR, MUIA_String_Contents, MG.szAPPCOPYR );

            set( MG.WIN_MAIN, MUIA_Window_ActiveObject, MAIN.STR_APPOWNER );
            break;
         case ID_BUT_MAIN_TOGGLE:
            lStat = MUIV_List_NextSelected_Start;
            for (;;)
            {
               DoMethod( MAIN.LIS_List, MUIM_List_NextSelected, &lStat );
               if ( lStat == MUIV_List_NextSelected_End )
                  break;

               DoMethod( MAIN.LIS_List, MUIM_List_GetEntry, lStat, &pszStat );
               if ( pszStat )
               {
                  if ( *(pszStat+1) == 'n' )
                     *(pszStat+1) = 'b';
                  else
                     *(pszStat+1) = 'n';
               }
            }
            DoMethod( MAIN.LIS_List, MUIM_List_Redraw, MUIV_List_Redraw_All );
            break;
         case ID_BUT_MAIN_CANCEL:
            fnDestructMainWindow( FALSE );
            break;

         /***** WINDOW: WINDOWS        *****/
         case ID_BUT_WINDOWS_LISTCHANGE:
            fnSetWindowData();
            break;
         case ID_BUT_WINDOWS_NEW:
            pWdwData = fnSetupNewWindowNode();
            if ( pWdwData )
            {
               AddTail( &MG.WindowList, (struct Node *)pWdwData );
               DoMethod( WINDOWS.LIS_List, MUIM_List_InsertSingle, pWdwData->szName, MUIV_List_Insert_Bottom );
               set( WINDOWS.LIS_List, MUIA_List_Active, MUIV_List_Active_Bottom );
//               fnSetWindowData();
            }
            else
            {
               DisplayBeep( NULL );
            }
            break;
         case ID_BUT_WINDOWS_DEL:
            // are you sure?
            if ( MUI_Request( MG.App, MG.WIN_WINDOWS, 0, NULL, "OK|*Cancel",
                              "Are you sure you wish to delete this window?", NULL ) == 1 )
            {
               get( WINDOWS.LIS_List, MUIA_List_Active, &lStat );
               for ( pWdwData = (struct WindowData *)MG.WindowList.lh_Head, l = 0;
                     l < lStat;
                     pWdwData = (struct WindowData *)pWdwData->node.ln_Succ, l++ );
               DoMethod( WINDOWS.LIS_List, MUIM_List_Remove, lStat );
               Remove( (struct Node *)pWdwData );
               FreeVec( pWdwData );

               // if last item was deleted, replace it with MAINwindow...
               get( WINDOWS.LIS_List, MUIA_List_Entries, &lStat );
               if ( lStat == 0 )
               {
                  pWdwData = fnSetupMAINWindowNode();
                  if ( pWdwData )
                  {
                     AddTail( &MG.WindowList, (struct Node *)pWdwData );
                     DoMethod( WINDOWS.LIS_List, MUIM_List_InsertSingle, pWdwData->szName, MUIV_List_Insert_Bottom );
                     set( WINDOWS.LIS_List, MUIA_List_Active, MUIV_List_Active_Bottom );
                  }
               }
            }
            break;
         case ID_BUT_WINDOWS_OK:
            fnStoreWindowNode();
            DoMethod( WINDOWS.LIS_List, MUIM_List_InsertSingle, pWdwData->szName, MUIV_List_Insert_Active );
            DoMethod( WINDOWS.LIS_List, MUIM_List_Remove, MUIV_List_Remove_Active );
            break;
         case ID_STR_WINDOWS_NAME:
            get( WINDOWS.LIS_List, MUIA_List_Active, &lStat );
            for ( pWdwData = (struct WindowData *)MG.WindowList.lh_Head, l = 0;
                  l < lStat;
                  pWdwData = (struct WindowData *)pWdwData->node.ln_Succ, l++ );

            get( WINDOWS.STR_Name, MUIA_String_Contents, &pszStat );
            strcpy( pWdwData->szTitle, pszStat );
            set( WINDOWS.STR_Title, MUIA_String_Contents, pWdwData->szTitle );
            set( MG.WIN_WINDOWS, MUIA_Window_ActiveObject, WINDOWS.STR_Ident );
            break;
         case ID_STR_WINDOWS_IDENT:
            get( WINDOWS.LIS_List, MUIA_List_Active, &lStat );
            for ( pWdwData = (struct WindowData *)MG.WindowList.lh_Head, l = 0;
                  l < lStat;
                  pWdwData = (struct WindowData *)pWdwData->node.ln_Succ, l++ );
            get( WINDOWS.STR_Ident, MUIA_String_Contents, &pszStat );

            sprintf( pWdwData->szID, "%-4.4s", pszStat );
            set( WINDOWS.STR_ID, MUIA_String_Contents, pWdwData->szID );

            sprintf( pWdwData->szMenu, "Menu_%sMenu", pszStat );
            set( WINDOWS.STR_Menu, MUIA_String_Contents, pWdwData->szMenu );

            sprintf( pWdwData->szWHelp, "%swindow", pszStat );
            set( WINDOWS.STR_WHelp, MUIA_String_Contents, pWdwData->szWHelp );

            sprintf( pWdwData->szMHelp, "%smenus", pszStat );
            set( WINDOWS.STR_MHelp, MUIA_String_Contents, pWdwData->szMHelp );

            if ( strcmpi( pWdwData->szID, "MAIN" ) )
            {
               sprintf( pWdwData->szClose, "MUIV_Application_ReturnID_Quit" );
            }
            else
            {
               sprintf( pWdwData->szClose, "ID_BUT_%s_CANCEL", pszStat );
            }
            set( MG.WIN_WINDOWS, MUIA_Window_ActiveObject, WINDOWS.STR_ID );
            break;
         case ID_BUT_WINDOWS_CANCEL:
            fnDestructWindowsWindow( FALSE );
            break;
      }
      if ( MG.running && signals ) Wait(signals);
   }

   set( MG.WIN_MAIN, MUIA_Window_Open, FALSE );
   JMH_Quit( NULL );
}
