#include <exec/types.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <exec/libraries.h>
#include <stdio.h>
#include <clib/intuition_protos.h>
#include <clib/exec_protos.h>
#include <clib/wb_protos.h>

struct Library   *IntuitionBase = NULL;
struct Library   *WorkbenchBase = NULL;
struct MsgPort   *myport = NULL;
struct Window    *win = NULL;
struct AppWindow *appwin = NULL;

void cleanexit(char *msg);

void main(int argc, char **argv)
{
  struct IntuiMessage *imsg;
  struct AppMessage *amsg;
  struct WBArg   *argptr;

  ULONG winsig, appwinsig, signals;
  BOOL finito = FALSE;
  int  i;

  /* apro le librerie e creo la porta messaggi */
  IntuitionBase = OpenLibrary("intuition.library", 37);
  if (!IntuitionBase) cleanexit("Non si apre la intuition.library\n");
  WorkbenchBase = OpenLibrary("workbench.library", 37);
  if (!IntuitionBase) cleanexit("Non si apre la worbench.library\n");
  myport = CreateMsgPort();
  if (!myport) cleanexit("Non si apre la porta messaggi\n");

  /* apro la finestra e la registro come AppWindow */
  win = OpenWindowTags(NULL, WA_Width, 200, WA_Height, 50,
                             WA_IDCMP, CLOSEWINDOW,
                             WA_Flags, WINDOWCLOSE | WINDOWDRAG,
                             WA_Title, "AppWindow",
                             TAG_DONE);
  if (! win) cleanexit("Non si apre la finestra\n");
  appwin = AddAppWindow(1, 0, win, myport, NULL);
  if (!appwin) cleanexit("Non posso registrare la AppWindow\n");
  winsig =    1L << win->UserPort->mp_SigBit;
  appwinsig = 1L << myport->mp_SigBit;

  /* ciclo di gestione eventi */
  while (! finito)
  {
    /* attendo sia eventi IDCMP che AppMessages */
    signals = Wait( winsig | appwinsig );
    if(signals & winsig)
    {
      /* ricevuto messaggio IDCMP */
      while (imsg = (struct IntuiMessage *)GetMsg(win->UserPort))
      {
        if (imsg->Class = CLOSEWINDOW) finito = TRUE;
        ReplyMsg((struct Message *) imsg);
      }
    }
    if(signals & appwinsig)
    {
      /* ricevuto AppMessage */
      while (amsg = (struct AppMessage *) GetMsg(myport))
      {
        /* ne scrivo tipo, id e numero argomenti */
        printf("AppMsg: Type=%ld, ID=%ld, NumArgs=%ld\n",
        amsg->am_Type, amsg->am_ID, amsg->am_NumArgs);

        /* ora scrivo gli argomenti (nome e lock) */
        argptr = amsg->am_ArgList;
        for (i = 0; i < amsg->am_NumArgs; i++)
        {
          printf("   arg(%ld): Name='%s', Lock=%lx\n",
            i, argptr->wa_Name, argptr->wa_Lock);
          argptr++;
        }
        ReplyMsg((struct Message *) amsg);
      }
    }
  } /* finito */
  cleanexit("tutto ok!\n");
}

void cleanexit(char *msg)
{
  struct AppMessage *amsg;

  if (msg) printf(msg);
  if (appwin) RemoveAppWindow(appwin);
  if (win)    CloseWindow(win);

  if (myport)
  { /* elimino eventuali messaggi rimasti */
    while(amsg = (struct AppMessage *)GetMsg(myport))
      ReplyMsg((struct Message *)amsg);
    DeleteMsgPort(myport);
  }
  if (WorkbenchBase) CloseLibrary(WorkbenchBase);
  if (IntuitionBase) CloseLibrary(IntuitionBase);
  exit(0);
}
