/*
Auto:       cc <file>
Auto:       ln +q -m <file> -lc
*/


/* ========================================

   Kleine AppIcon/Menu/Window Spielereien

   von Kai Iske, 2.9.92

   Copyright 1992 MAXON Computer, KickStart

   ======================================== */


#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/icon_protos.h>
#include <clib/wb_protos.h>
#include <clib/dos_protos.h>
#include <pragmas/exec_lib.h>
#include <pragmas/intuition_lib.h>
#include <pragmas/icon_lib.h>
#include <pragmas/wb_lib.h>
#include <pragmas/dos_lib.h>
#include <intuition/intuition.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <dos/dosextens.h>
#include <exec/memory.h>

struct IconBase *IconBase = NULL;
struct WorkbenchBase *WorkbenchBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;


/* Definitionen für die AppSaechelchen */
#define APPICON_ID 1
#define APPMENU_ID 2
#define APPWINDOW_ID 3


/* Requesterstruktur für EasyRequest */
struct EasyStruct MyRequest =
{
    sizeof(struct EasyStruct),
    0,
    (UBYTE *)"AppDemo-Message",
    NULL,
    (UBYTE *)"Sicher ???"
};



void main(void)
{
  struct MsgPort *AppPort = NULL;
  struct DiskObject *AppObject = NULL,
         *DummyObject;
  struct AppIcon *MyAppIcon = NULL;
  struct AppMenuItem *MyAppMenu = NULL;
  struct Window *MyWindow = NULL;
  struct AppWindow *MyAppWin = NULL;
  struct AppMessage *AppMsg;
  struct IntuiMessage *WinMsg;
  struct WBArg *Args;
  struct FileLock *IconLock;
  struct DosList *IconList;
  struct FileInfoBlock *FIB;
  BPTR DirLock;
  char Name[40], *Source;
  ULONG AppSig, WinSig, Signals;
  long i;
  int Len;


  if(!(IconBase = (struct IconBase *)
      OpenLibrary((UBYTE *)"icon.library",0L)))
      goto CleanUp;

  if(!(WorkbenchBase = (struct WorkbenchBase *)
      OpenLibrary((UBYTE *)"workbench.library",
          0L)))
      goto CleanUp;

  if(!(IntuitionBase = (struct IntuitionBase *)
      OpenLibrary((UBYTE *)"intuition.library",
          0L)))
      goto CleanUp;

  /* Das default Project Icon besorgen */
  if(!(AppObject = GetDefDiskObject(WBPROJECT)))
      goto CleanUp;

  /* FileInfo Block besorgen */
  if(!(FIB = (struct FileInfoBlock *)AllocVec(
     sizeof(struct FileInfoBlock), MEMF_CLEAR)))
     goto CleanUp;

  /* MsgPort besorgen */
  if(!(AppPort = CreateMsgPort()))
      goto CleanUp;

  /* AppIcon darstellen */
  if(!(MyAppIcon = AddAppIcon(APPICON_ID, 0,
      (UBYTE *)"AppDemo-Icon", AppPort, NULL,
      AppObject, NULL)))
      goto CleanUp;

  /* AppMenu in das ToolsMenü einfügen */
  if(!(MyAppMenu = AddAppMenuItem(APPMENU_ID,
      0, (UBYTE *)"AppDemo-Menu", AppPort,
      NULL)))
      goto CleanUp;

  /* Dummy-Window öffnen */
  if(!(MyWindow = OpenWindowTags(NULL,
      WA_Width, 300L, WA_Height, 150L,
      WA_IDCMP, IDCMP_CLOSEWINDOW, WA_Flags,
      WFLG_CLOSEGADGET|WFLG_DRAGBAR|
      WFLG_DEPTHGADGET, WA_Title,
      (UBYTE *)"AppDemo-Window",
      TAG_DONE)))
      goto CleanUp;

  /* Dieses Window als AppWindow deklarieren */
  if(!(MyAppWin = AddAppWindow(APPWINDOW_ID, 0,
      MyWindow, AppPort, NULL)))
      goto CleanUp;

  /* Signalflags "berechnen" */
  AppSig = 1L << (ULONG)AppPort->mp_SigBit;
  WinSig = 1L << (ULONG)MyWindow->UserPort->
           mp_SigBit;

  /* Loop */
  while(1)
  {
    /* Warten wir mal ein bissl */
    Signals = Wait(AppSig | WinSig);

    /* Signal von den AppItems */
    if(Signals & AppSig)
    {
      /* Messages bearbeiten */
      while(AppMsg = (struct AppMessage *)
          GetMsg(AppPort))
      {
        switch(AppMsg->am_Type)
        {
          /* Signal vom AppMenu */
          case MTYPE_APPMENUITEM :
          {
              /* Text ausgeben */
              MyRequest.es_TextFormat =
              (UBYTE *)"Sie haben das AppMenu
                        angewählt.";
              EasyRequest(MyWindow,
                  &MyRequest, NULL,
                  NULL);

              break;
          }
          /* Message vom Icon/Window */
          case MTYPE_APPICON :
          case MTYPE_APPWINDOW :
          {
            /* Es war ein Doppelklick
               auf das Icon */
            if(!AppMsg->am_NumArgs
                && !AppMsg->
                am_ArgList)
            {
                MyRequest.es_TextFormat =
                    (UBYTE *)"Doppelklick auf das
                              AppIcon.";
                EasyRequest(MyWindow, &MyRequest,
                    NULL, NULL);
            }
            else
            {
              /* Je nach Quelle, Text ausgeben */
              if(AppMsg->am_ID == APPICON_ID)
                  MyRequest.es_TextFormat =
                  (UBYTE *)"Es wurden %ld Icon(s)
                        auf das AppIcon gelegt.";
              else
                  MyRequest.es_TextFormat =
                  (UBYTE *)"Es wurden %ld Icon(s)
                      auf das AppWindow gelegt.";

              EasyRequest(MyWindow, &MyRequest,
                 NULL, (APTR)AppMsg->am_NumArgs);

              /*Liste der Argumente durchgehen*/
              Args = AppMsg->am_ArgList;
              i = 1L;
              while(i <= AppMsg->am_NumArgs)
              {
                /* Text vorbereiten */
                MyRequest.es_TextFormat =
                  (UBYTE *)"\n%ld. Icon : %s\n";

                /* Auf das Directory locken */
                DirLock = CurrentDir(
                  Args->wa_Lock);

                /* Versuch das Icon zu bekommen*/
                if(DummyObject = GetDiskObjectNew
                    ((UBYTE *)Args->wa_Name))
                {
                  /* Disk/Directory/Device ??? */
                  if(DummyObject->do_Type ==
                     WBDISK ||
                     DummyObject->do_Type ==
                     WBDEVICE)
                  {
                    /* "Leichtes ge-caste", um an
                       den Namen der Quelle zu
                       kommen */
                    Source = (char *)BADDR((
                       (struct DosList *)BADDR(
                       ((struct FileLock *)BADDR(
                       Args->wa_Lock))->
                       fl_Volume))->dol_Name);

                    /* Länge des Strings
                       besorgen */
                    Len = (int)*Source++;

                    /* String kopieren */
                    strncpy(Name, Source,
                       (ULONG)Len);
                    Name[Len] = '\0';

                    /* Text darstellen */
                    EasyRequest(MyWindow,
                       &MyRequest, NULL,
                       (APTR)i, (APTR)Name);
                  }
                  /* Ist es ein Directory ? */
                  else if(DummyObject->do_Type
                          == WBDRAWER)
                  {
                      /* Dann bekommen wir den
                         Namen aus dem
                         FileInfoBlock */

                      if(Examine(Args->wa_Lock,
                                  FIB))
                      {
                        EasyRequest(MyWindow,
                        &MyRequest, NULL,
                        (APTR)i,
                       (APTR)&FIB->fib_FileName);
                      }
                  }
                  else
                      /* Ansonsten findet man den
                         Namen direkt in der
                         WBArg-Struktur */
                      EasyRequest(MyWindow,
                         &MyRequest, NULL,
                         (APTR)i,
                         (APTR)Args->wa_Name);

                  /* DiskObject wieder
                     freigeben */
                  FreeDiskObject(DummyObject);
                }
                else
                    /* Sonst "nehmen" Wir einfach
                       an, dass es ein AppIcon
                       war :-)*/
                    EasyRequest(MyWindow,
                        &MyRequest, NULL,
                        (APTR)i,
                        (APTR)Args->wa_Name);

                /* Dir wieder unlocken */
                CurrentDir(DirLock);

                /* Auf zum nächsten WBArg */
                Args++;
                i++;
              }
            }
            break;
          }
        }
        /* Message zurückschicken */
        ReplyMsg((struct Message *)AppMsg);
      }
    }

    /* Sonst war es wohl das Window */
    if(Signals & WinSig)
    {
        BOOL Quit = FALSE;

        /* Messages bearbeiten */
        while(WinMsg = (struct IntuiMessage
            *)GetMsg(MyWindow->UserPort))
        {
            /* CloseGadget testen */
            if(WinMsg->Class ==IDCMP_CLOSEWINDOW)
                Quit = TRUE;

            ReplyMsg((struct Message *)WinMsg);
        }
        /* Beenden ??? */
        if(Quit)
            goto CleanUp;
    }
  }

CleanUp:

  /* Resourcen freigeben */
  if(MyAppWin)
      RemoveAppWindow(MyAppWin);

  if(MyWindow)
      CloseWindow(MyWindow);

  if(MyAppMenu)
      RemoveAppMenuItem(MyAppMenu);

  if(MyAppIcon)
      RemoveAppIcon(MyAppIcon);

  if(AppObject)
      FreeDiskObject(AppObject);

  if(IntuitionBase)
      CloseLibrary((struct Library *)
      IntuitionBase);

  if(WorkbenchBase)
      CloseLibrary((struct Library *)
      WorkbenchBase);

  if(IconBase)
      CloseLibrary((struct Library *)IconBase);

  if(AppPort)
  {
      /* Noch anstehende Messages beantworten */
      while(AppMsg = (struct AppMessage *)
          GetMsg(AppPort))
          ReplyMsg((struct Message *)AppMsg);

      DeleteMsgPort(AppPort);
  }

  if(FIB)
    FreeVec(FIB);

  exit(0);
}
