/*
***************************************************************************
*
* Datei:
*    RSysIconify.c
*
* Inhalt:
*    int LookTypeOfFile(long lock, char *fname, int num, int totalnum);
*    void Iconify(void);
*
* Bemerkungen:
*    Enthält die Routinen für das Application Icon und das
*    aufsetzende Actioning.
*
* Erstellungsdatum:
*    20-Jan-93    Rolf Böhme
*
* Änderungen:
*    20-Jan-93    Rolf Böhme    Erstellung
*
***************************************************************************
*/

#include "RSysDebug.h"
#include "RSysFunc.h"

extern struct Image AppIconI1, AppIconI2;

struct DiskObject *ProgramIcon;
struct AppIcon *appicon = NULL;

   /*
    * LookTypeOfFile() ermittelt den Typen einer Datei und
    * startet entsprechend das Action-Window
    */
int
LookTypeOfFile(BPTR lock, char *fname, int num, int totalnum)
{
   char  filename[MAXFULLNAME+1];
   int   ft = 0;
   BOOL  lastentry;

   DPOS;

   NameFromLock(lock, (UBYTE *) filename, MAXFULLNAME);

   AddPart((UBYTE *) filename, (UBYTE *) fname, MAXFULLNAME);

   if (strlen(fname) != 0)
      ft = filetype(filename);

   lastentry = ((num == totalnum) ? TRUE : FALSE);

   return (StartAction(ft, filename, lastentry));
}


	/* GetProgramIcon():
	 *
	 *	Try to find the icon of the program.
	 */

static struct DiskObject *
GetProgramIcon(void)
{
	struct DiskObject *Icon = NULL;

   DPOS;
	if(Icon = GetDiskObjectNew((STRPTR)RSysName))
	{
		if(Icon -> do_Type != WBTOOL)
		{
			FreeDiskObject(Icon);

			Icon = NULL;
		}
	}

   DPOS;
	if(!Icon)
	{
		BPTR NewLock;

			/* Move to the directory the
			 * program was run from.
			 */

		if(NewLock = Lock((STRPTR)"PROGDIR:",ACCESS_READ))
		{
			BPTR OldLock;

			OldLock = CurrentDir(NewLock);

				/* Try to fetch the icon, use the
				 * default name if necessary.
				 */

			if(Icon = GetDiskObjectNew((STRPTR)RSysName))
			{
				if(Icon -> do_Type != WBTOOL)
				{
					FreeDiskObject(Icon);

					Icon = NULL;
				}
			}

			if(!Icon)
			{
				if(Icon = GetDiskObjectNew((STRPTR)"RSys"))
				{
					if(Icon -> do_Type != WBTOOL)
					{
						FreeDiskObject(Icon);

						Icon = NULL;
					}
				}
			}

			CurrentDir(OldLock);

			UnLock(NewLock);
		}
	}

	if(!Icon)
	{
			/* Use the default names. */

		if(Icon = GetDiskObjectNew((STRPTR)"RSys"))
		{
			if(Icon -> do_Type != WBTOOL)
			{
				FreeDiskObject(Icon);

				Icon = NULL;
			}
		}

		if(!Icon)
		{
			if(Icon = GetDiskObjectNew((STRPTR)"PROGDIR:RSys"))
			{
				if(Icon -> do_Type != WBTOOL)
				{
					FreeDiskObject(Icon);

					Icon = NULL;
				}
			}
		}
	}

	return(Icon);
}

   /*
    * Iconify() schließt das Hauptfenster von RSys und
    * erzeugt auf der Workbench ein Application-Icon. Werden
    * WorkBench-Objekte auf dieses Icon gelegt, werden
    * entsprechende Aktionen gestartet. Die Nachrichten vom
    * Broker werden ebenfalls behandelt
    */
static int
IconifyWithIcon(void)
{
   struct MsgPort *msgport;
   struct AppMessage *appmsg;
   SysMsg *arrived_mess;
   ULONG mask;
   BOOL  broker_sig = FALSE,
         show_dropped = TRUE,
         refresh = FALSE;
   int   ID = LastID,
         i;
   struct WBArg *argptr;
   extern struct Screen *lastpubscreen;
	extern int ReopenWindow;

   DPOS;

   Flags.quit_iconify = 0;

   if (msgport = CreateMsgPort())
   {
      DisableSysRequest(TRUE);

      ProgramIcon = GetProgramIcon();

      if (appicon = AddAppIcon(1L, NULL, (UBYTE *) "", msgport, NULL, ProgramIcon, NULL))
      {
         do
         {
            mask = Wait(SIGBREAKF_CTRL_C |
                        (1 << msgport->mp_SigBit) |
                        (1 << SysIdPort->mp_SigBit) |
                        (1 << broker_mp->mp_SigBit));

            if (mask & SIGBREAKF_CTRL_C)
               Flags.quit_iconify = 1;

            if (mask & (1 << broker_mp->mp_SigBit))
            {
               HandleBrokerPort();

               if (SysWnd)
               {
                  Flags.quit_iconify = 1;
                  ReopenWindow = TRUE;
               }
            }

            if (mask & (1 << msgport->mp_SigBit))
               while (appmsg = (struct AppMessage *) GetMsg(msgport))
               {
                  if (appmsg->am_NumArgs == NULL)
                  {
                     strcpy((char *)namebuffer, "Workbench");

                     Flags.quit_iconify = 1;
                     refresh = TRUE;
                  }
                  else
                  {
                     argptr = appmsg->am_ArgList;

                     for (i = 0; show_dropped && (i < appmsg->am_NumArgs); i++)
                     {
                        show_dropped = LookTypeOfFile(argptr->wa_Lock,
                                                      (char *)argptr->wa_Name,
                                                      i + 1, appmsg->am_NumArgs);
                        argptr++;
                     }

                     show_dropped = TRUE;
                  }

                  ReplyMsg((struct Message *) appmsg);
               }

            if (mask & (1 << SysIdPort->mp_SigBit))
            {
               while (arrived_mess = (SysMsg *)GetMsg(SysIdPort))
               {
                  ID = arrived_mess->sm_newtype;
                  ReplyMsg((struct Message *) arrived_mess);

                  refresh = TRUE;
               }

               Flags.quit_iconify = 1;
            }
         }
         while (NOT(Flags.quit_iconify));

         RemoveAppIcon(appicon);
         appicon = NULL;

         FreeDiskObject(ProgramIcon);
         ProgramIcon = NULL;

         if (mask & SIGBREAKF_CTRL_C)
         {
            DisableSysRequest(FALSE);
            DeleteMsgPort(msgport);
            CloseAll();
         }
      }
      else
      {
         DisableSysRequest(FALSE);
         ErrorHandle(ICON_ERR, CREATE_FAIL, KILL);
      }

      DisableSysRequest(FALSE);
      DeleteMsgPort(msgport);
   }
   else
      ErrorHandle(PORT_ERR, CREATE_FAIL, KILL);

   return(ID);
}

   /*
    * IconifyWithoutIcon() schließt das Hauptfenster von RSys
    * Die Nachrichten vom Broker werden behandelt
    */
static int
IconifyWithoutIcon(void)
{
   SysMsg *arrived_mess;
   ULONG mask;
   BOOL  broker_sig = FALSE,
         refresh = FALSE;
   int   ID = LastID;
   extern struct Screen *lastpubscreen;
   extern int ReopenWindow;

   DPOS;

   Flags.quit_iconify = 0;

   do
   {
      mask = Wait(SIGBREAKF_CTRL_C |
                  (1 << SysIdPort->mp_SigBit) |
                  (1 << broker_mp->mp_SigBit));

      if (mask & SIGBREAKF_CTRL_C)
         Flags.quit_iconify = 1;

      if (mask & (1 << broker_mp->mp_SigBit))
      {
         HandleBrokerPort();

         if (SysWnd)
            Flags.quit_iconify = 1;
      }

      if (mask & (1 << SysIdPort->mp_SigBit))
      {
         while (arrived_mess = (SysMsg *)GetMsg(SysIdPort))
         {
            ID = arrived_mess->sm_newtype;
            ReplyMsg((struct Message *) arrived_mess);

            refresh = TRUE;
         }

         Flags.quit_iconify = 1;
      }
   }
   while (NOT(Flags.quit_iconify));

   if (mask & SIGBREAKF_CTRL_C)
      CloseAll();

   return(ID);
}

   /*
    * Iconify() ist die Frontend-Routine für IconifyWithIcon()
    * und IconifyWithoutIcon(), je nachdem, ob der Benutzer ein Icon wünscht
    * oder nicht
    */
void
Iconify(void)
{
   int ID;

   DPOS;

   if (SysWnd)
   {
      lastpubscreen = SysWnd->WScreen;

      CloseASysWindow(&SysWnd, &SysGList, &SysMenus);
      CloseDownScreen();
   }

   if(Flags.appicon)
      ID = IconifyWithIcon();
   else
      ID = IconifyWithoutIcon();

   if (NOT(SysWnd))
   {
      OpenMainWindow();

      MakeWindowRefresh(SysWnd);

      ClearIntuiMsgPort(SysWnd);

      if (ID != LastID)
         LastID = ID;

      RefreshList(LastID);
      ReopenWindow = TRUE;
   }

   return;
}
