/*
 * mainloop.c   V1.3
 *
 * main event loop
 *
 * (c) 1991 by Stefan Becker
 *
 */
#include "ToolManager.h"

/* The main processing loop */
void mainloop(void)
{
 BOOL end=TRUE;                  /* Flag for main loop */
 BOOL windowopen=FALSE;          /* Flag for status window */
 ULONG sigs,bsigs,psigs,wsigs;   /* Buffers for signals */

 /* Init icon position */
 MyIcon->do_CurrentX=IconXPos;
 MyIcon->do_CurrentY=IconYPos;

 /* Notify Workbench about icon, if ShowIcon is true */
 if (ShowIcon)
  if (!(MyAppIcon=AddAppIcon(NULL,NULL,MyName,MyMP,NULL,MyIcon,TAG_DONE)))
   cleanup(8);

 bsigs=SIGBREAKF_CTRL_C|         /* break signals */
       SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F;
 psigs=1L<<MyMP->mp_SigBit;      /* port signal */
 sigs=bsigs|psigs;               /* merge signals */

 while (end)                     /* main loop */
  {
   struct AppMessage *msg;       /* pointer to received message */
   ULONG gotsigs;                /* received signals */

   gotsigs=Wait(sigs);           /* Wait for specified signals */

   if ((gotsigs&bsigs) && !wbactive) /* Got break signals and is no WB tool */
    end=FALSE;                       /* running? Yes, quit program */

   if (gotsigs&psigs)            /* Message arrived at message port? */
    while (msg=GetMsg(MyMP))     /* Yes, empty message queue */
     if (msg->am_Message.mn_Node.ln_Type==NT_REPLYMSG) /* Replied message? */
      {
       /* This is the death message from a tool we started some time ago */
       struct WBStartup *wbs=(struct WBStartup *) msg;
       struct WBArg *wa=wbs->sm_ArgList;
       int i=wbs->sm_NumArgs;

       while (i--)
        {
         UnLock(wa->wa_Lock);    /* Free WB argument */
         if (wa->wa_Name) free(wa->wa_Name);
         wa++;
        }

       if (wbs->sm_ToolWindow)   /* Free tool window specification */
        free(wbs->sm_ToolWindow);

       UnLoadSeg(wbs->sm_Segment); /* Unload code */
       free(wbs);                  /* Free WBStartup */
       wbactive--;                 /* One tool closed down */
      }
     else
      {
       switch(msg->am_Type)       /* Switch between message types */
        {
         case MTYPE_APPWINDOW:    /* Window action */
         case MTYPE_APPICON:      /* Icon action */
          if (msg->am_NumArgs==0) /* Did the user double click my icon? */
           {                      /* Yes! If window not open, open it */
            if ((!windowopen) && (wsigs=OpenStatusWindow()))
             {
              sigs|=wsigs;        /* Merge with other signals */
              windowopen=TRUE;    /* Window is open */
             }
           }
          else                    /* User dropped an icon on my icon */
           {                      /* Add Workbench parameters to tool list */
            if (!WBAddToolNode(msg->am_ArgList,msg->am_NumArgs))
             DisplayBeep(NULL);
            if (windowopen)       /* Refresh status window if open */
             RefreshStatusWindow();
           }
          break;

         case MTYPE_APPMENUITEM:  /* Menu action */
          switch(msg->am_ID)
           {
            case 0:               /* "Quit ToolManager" menu item */
             if (wbactive)        /* Yes. Do we have a tool running? */
              DisplayBeep(NULL);  /*      Yes, we can't quit! */
             else end=FALSE;      /*      No, quit program */
             break;

            case 1:               /* "Open TM Window" menu item */
             if ((!windowopen) && (wsigs=OpenStatusWindow()))
              {
               sigs|=wsigs;       /* Merge with other signals */
               windowopen=TRUE;   /* Window is open */
              }
             break;

            default:              /* Default: Tool selected */
             struct ToolNode *tn;
             char *cp;
             BOOL rc;

             /* Scan list for selected tool */
             for (tn=GetHead(&ToolList); tn; tn=GetSucc(tn))
              if (tn->tn_ID==msg->am_ID)
               {                            /* Corresponding tool found */
                if (!(cp=tn->tn_RealName))  /* Get tool name */
                 cp=tn->tn_Node.ln_Name;

                /* Tool type? */
                if (tn->tn_CLI) rc=StartCLITool(msg,tn,cp); /* CLI */
                else rc=StartWBTool(msg,tn,cp);             /* WB  */

                if (!rc) DisplayBeep(NULL); /* An error occured */
                break;                      /* leave 'for' loop */
               }
             break;
           }
          break;
        } /* end of switch(msg->am_Type) */

       ReplyMsg((struct Message *) msg); /* Reply message to sender */
      } /* end of if (msg->......) */

   if (windowopen && (gotsigs&wsigs)) /* If window open, got window signal? */
    if (HandleWindowEvent())          /* Handle window event */
     {                                /* Window close event? */
      CloseStatusWindow();            /* Yes, close window */
      sigs&=~wsigs;                   /* Remove window signals */
      windowopen=FALSE;               /* Window closed */
     }
  } /* end of main loop */

 /* If window open, close it */
 if (windowopen) CloseStatusWindow();

 /* Exit program */
 cleanup(99);
}

