
#include "common/extern.h"
#include "common/subtasksupp.h"
#include "common/Grab_mcc.h"
#include "asl.h"

extern struct MsgPort *myport;
extern struct SignalSemaphore mem_sema;

// extern hooks
extern struct Hook AppMsgHook;
extern struct Hook GrabHook;
extern struct Hook UpdateHook;
extern struct Hook StopGrabHook;
extern struct Hook QuitHook;


extern struct SubTask *SpawnNetTask (char *name, BPTR func, APTR data);


/* *********************************************** */
/*                                                 */
/*  MainWin MUI class.                             */
/*                                                 */
/* *********************************************** */

/// "Extern images"

extern const struct BitMapHeader new_header;
extern const UBYTE new_body[];
extern const ULONG new_colors[];

extern const struct BitMapHeader open_header;
extern const UBYTE open_body[];
extern const ULONG open_colors[];

extern const struct BitMapHeader save_header;
extern const UBYTE save_body[];
extern const ULONG save_colors[];

extern const struct BitMapHeader grab_header;
extern const UBYTE grab_body[];
extern const ULONG grab_colors[];

extern const struct BitMapHeader update_header;
extern const UBYTE update_body[];
extern const ULONG update_colors[];

extern const struct BitMapHeader stopgrab_header;
extern const UBYTE stopgrab_body[];
extern const ULONG stopgrab_colors[];

///

/// "New"
ULONG
mMainWin_New (struct IClass *cl, Object * obj, struct opSet *msg)
{
  APTR GR_Open, GR_New, GR_Save, GR_Grab, GR_StopGrab, GR_Update;
// *INDENT-OFF*
  obj = (Object *) DoSuperNew (cl, obj,
    MUIA_Window_Title, "GiambyNetGrabber V" __VER__,
    MUIA_Window_ID, MAKE_ID('M','W','I','N'),
    MUIA_Window_AppWindow, TRUE,
    MUIA_Window_SizeGadget, FALSE,
    MUIA_HelpNode, "WIN_MAIN",
    WindowContents, GroupObject,
      MUIA_Group_Horiz, TRUE,
      Child, GroupObject,
        MUIA_Group_Horiz, TRUE,
        MUIA_Group_HorizSpacing, 0,
         // New
        Child,  GR_New = ButtonDropObject,
          MUIA_Dropable, FALSE,
          MUIA_HelpNode, "New_Button",
          MUIA_ShortHelp, STRING (ShortHelp_New, "\33cMake a new project"),
          Child, ImageIFFObject,
            MUIA_ImageIFF_Filename, "PROGDIR:images/new.img",
            MUIA_ImageIFF_BitMapHeader, &new_header,
            MUIA_ImageIFF_Body, new_body,
            MUIA_ImageIFF_SourceColors, new_colors,
            MUIA_Background, MUII_ButtonBack,
          End,
          Child, Label (STRING (Label_New, "\33cNew")),
        End,
         // Open
        Child,  GR_Open = ButtonDropObject,
          MUIA_Dropable, FALSE,
          MUIA_HelpNode, "Open_Button",
          MUIA_ShortHelp, STRING (ShortHelp_Open, "\33cOpen an existing\nproject file"),
          Child, ImageIFFObject,
            MUIA_ImageIFF_Filename, "PROGDIR:images/open.img",
            MUIA_ImageIFF_BitMapHeader, &open_header,
            MUIA_ImageIFF_Body, open_body,
            MUIA_ImageIFF_SourceColors, open_colors,
            // Here put transparent
            MUIA_Background, MUII_ButtonBack,
          End,
          Child, Label (STRING (Label_Open, "\33cOpen")),
        End,
          // Save
        Child,  GR_Save = ButtonDropObject,
          MUIA_Disabled, TRUE,
          MUIA_Dropable, FALSE,
          MUIA_HelpNode, "Save_Button",
          MUIA_ShortHelp, STRING (ShortHelp_Save, "\33cSave the current\nproject file"),
          Child, ImageIFFObject,
            MUIA_ImageIFF_Filename, "PROGDIR:images/save.img",
            MUIA_ImageIFF_BitMapHeader, &save_header,
            MUIA_ImageIFF_Body, save_body,
            MUIA_ImageIFF_SourceColors, save_colors,
            MUIA_Background, MUII_ButtonBack,
          End,
          Child, Label (STRING (Label_Save, "\33cSave")),
        End,

      End,
      Child, GroupObject,
        MUIA_Group_Horiz, TRUE,
        MUIA_Group_HorizSpacing, 0,

        // Grab
        Child,  GR_Grab = ButtonDropObject,
          MUIA_Disabled, TRUE,
          MUIA_Dropable, TRUE,
          MUIA_UserData, UDB_GRAB,
          MUIA_HelpNode, "Grab_Button",
          MUIA_ShortHelp, STRING (ShortHelp_Grab, "\33cGrab selecteg URI"),
          Child, ImageIFFObject,
            MUIA_ImageIFF_Filename, "PROGDIR:images/grab.img",
            MUIA_ImageIFF_BitMapHeader, &grab_header,
            MUIA_ImageIFF_Body, grab_body,
            MUIA_ImageIFF_SourceColors, grab_colors,
            MUIA_Background, MUII_ButtonBack,
          End,
          Child, Label (STRING (Label_Grab, "\33cGrab")),
        End,

        // Update
        Child,  GR_Update = ButtonDropObject,
          MUIA_Disabled, TRUE,
          MUIA_Dropable, TRUE,
          MUIA_UserData, UDB_UPDATE,
          MUIA_HelpNode, "Update_Button",
          MUIA_ShortHelp, STRING (ShortHelp_Update, "\33cUpdate selected URI"),
          Child, ImageIFFObject,
            MUIA_ImageIFF_Filename, "PROGDIR:images/update.img",
            MUIA_ImageIFF_BitMapHeader, &update_header,
            MUIA_ImageIFF_Body, update_body,
            MUIA_ImageIFF_SourceColors, update_colors,
            MUIA_Background, MUII_ButtonBack,
          End,
          Child, Label (STRING (Label_Update, "\33cUpdate")),
        End,

        //StopGrab
        Child,  GR_StopGrab = ButtonDropObject,
          MUIA_Disabled, TRUE,
          MUIA_Dropable, TRUE,
          MUIA_UserData, UDB_STOPGRAB,
          MUIA_HelpNode, "Stop_Button",
          MUIA_ShortHelp, STRING (ShortHelp_StopGrab, "\33cStop grabbing process"),
          Child, ImageIFFObject,
            MUIA_ImageIFF_Filename, "PROGDIR:images/stopgrab.img",
            MUIA_ImageIFF_BitMapHeader, &stopgrab_header,
            MUIA_ImageIFF_Body, stopgrab_body,
            MUIA_ImageIFF_SourceColors, stopgrab_colors,
            MUIA_Background, MUII_ButtonBack,
          End,
          Child, Label (STRING (Label_StopGrab, "\33cStop")),
        End,
      End,
    End,
  TAG_MORE, msg->ops_AttrList);
// *INDENT-ON*









  if (obj)
    {
      register struct MainWinData *data = (struct MainWinData *) INST_DATA (cl, obj);
      data->self = obj;
      data->cnd = (struct WindowNode *) GetTagData (MUIA_Main_CurrentProj, NULL, msg->ops_AttrList);

      data->bt_new = GR_New;
      data->bt_open = GR_Open;
      data->bt_save = GR_Save;

      data->bt_grab = GR_Grab;
      data->bt_stopgrab = GR_StopGrab;
      data->bt_update = GR_Update;

      /* Subtask msg */

      NewList (&data->WindowList);

      DoMethod ((Object *) GR_New, MUIM_Notify, MUIA_Pressed, FALSE,
                obj, 4, MUIM_Main_Open, FALSE, NULL, NULL);

      DoMethod ((Object *) GR_Open, MUIM_Notify, MUIA_Pressed, FALSE,
                obj, 4, MUIM_Main_Open, TRUE, NULL, NULL);


      DoMethod ((Object *) GR_Open, MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime,
                GR_Open, 3, MUIM_CallHook, &AppMsgHook, MUIV_TriggerValue);

      DoMethod ((Object *) GR_Save, MUIM_Notify, MUIA_Pressed, FALSE,
                obj, 2, MUIM_Main_Save, NULL);

      DoMethod ((Object *) GR_Grab, MUIM_Notify, MUIA_Pressed, FALSE,
                oa->App, 3, MUIM_CallHook, &GrabHook, NULL);

      DoMethod ((Object *) GR_Update, MUIM_Notify, MUIA_Pressed, FALSE,
                oa->App, 3, MUIM_CallHook, &UpdateHook, NULL);

      DoMethod ((Object *) GR_StopGrab, MUIM_Notify, MUIA_Pressed, FALSE,
                oa->App, 3, MUIM_CallHook, &StopGrabHook, NULL);

      DoMethod ((Object *) obj, MUIM_Window_SetCycleChain, 0);

      set (oa->App, MUIA_Application_DropObject, GR_Open);
      DoMethod ((Object *) oa->App, OM_ADDMEMBER, obj);
      set (obj, MUIA_Window_Open, TRUE);

      return ((ULONG) obj);
    }
  else
    error_req (STRING (MSG_OK, "*_OK"), "%s", STRING (ERR_NOMEM, "Out of Memory"));

  D (printf ("Error creating class: main_win\n"));

  return (NULL);
}
///

/// "Dispose"
ULONG
mMainWin_Dispose (struct IClass * cl, Object * obj, Msg msg)
{
  //register struct MainWinData *data = (struct MainWinData *) INST_DATA (cl, obj);

  DoMethod ((Object *) oa->App, OM_REMMEMBER, obj);

  return (DoSuperMethodA (cl, obj, msg));
}
///

/// "Set"
ULONG
mMainWin_Set (struct IClass * cl, Object * obj, Msg msg)
{
  register struct MainWinData *data = (struct MainWinData *) INST_DATA (cl, obj);
  struct Node *rn;
  int i;

  struct TagItem *tags, *tag;
  for (tags = ((struct opSet *) msg)->ops_AttrList; (tag = (struct TagItem *) NextTagItem (&tags));)
    {
      switch (tag->ti_Tag)
        {
        case MUIA_Window_CloseRequest:
          if (tag->ti_Data == TRUE)
            {
              DoMethod ((Object *) oa->App, MUIM_CallHook, &QuitHook, NULL);
            }
          break;

        case MUIA_Main_CurrentProj:
          rn = (struct Node *) tag->ti_Data;
          if (rn)
            {
              Remove (rn);
              AddHead (&data->WindowList, rn);

              data->cnd = (struct WindowNode *) rn;

              set (data->bt_save, MUIA_Disabled, FALSE);

              for (i = 0; oa->menus[i] != NULL; i++)
                {
                  set (oa->menus[i], MUIA_Menuitem_Enabled, TRUE);
                }

              for (++i; oa->menus[i] != NULL; i++)
                {
                  set (oa->menus[i], MUIA_Menu_Enabled, TRUE);
                }

              if (test_flag (data->cnd->status, PWST_GRABBING))
                {
                  set (data->bt_grab, MUIA_Disabled, TRUE);
                  set (data->bt_update, MUIA_Disabled, TRUE);
                  set (data->bt_stopgrab, MUIA_Disabled, FALSE);
                }
              else if (data->cnd->status & PWST_REQ)
                {
                  set (data->bt_save, MUIA_Disabled, TRUE);
                  set (data->bt_grab, MUIA_Disabled, TRUE);
                  set (data->bt_update, MUIA_Disabled, TRUE);
                  set (data->bt_stopgrab, MUIA_Disabled, TRUE);


                  for (i = 0; oa->menus[i] != NULL; i++)
                    {
                      set (oa->menus[i], MUIA_Menuitem_Enabled, FALSE);
                    }

                  for (++i; oa->menus[i] != NULL; i++)
                    {
                      set (oa->menus[i], MUIA_Menu_Enabled, FALSE);
                    }

                }
              else
                {
                  set (data->bt_grab, MUIA_Disabled, FALSE);
                  set (data->bt_update, MUIA_Disabled, FALSE);
                  set (data->bt_stopgrab, MUIA_Disabled, TRUE);
                }
            }
          break;

        case MUIA_Main_CloseProj:

          if ((rn = (struct Node *) tag->ti_Data))
            {
              Remove (rn);

              data->cnd = (struct WindowNode *) rn;

              // Now Add to Open Recent List
              {
                ULONG size;
                char *tmp;

                if ((tmp = (STRPTR) AllocVecPooled (gd.gd_pool, size = s_strlen (data->cnd->dir) + strlen (data->cnd->title) + 2)))
                  {
                    if (data->cnd->dir)
                      {
                        strcpy (tmp, data->cnd->dir);
                        AddPart (tmp, data->cnd->title, size);
                      }
                    else
                      strcpy (tmp, data->cnd->title);

                    size = 0;

                    ObtainSemaphore (&prefs->sema);

                    prefs->recents[5] = prefs->recents[4];
                    prefs->recents[4] = prefs->recents[3];
                    prefs->recents[3] = prefs->recents[2];
                    prefs->recents[2] = prefs->recents[1];
                    prefs->recents[1] = prefs->recents[0];

                    prefs->recents[0] = tmp;


                    for (i = 1; (i < 5) && (prefs->recents[i]); i++)
                      {
                        if (stricmp (tmp, prefs->recents[i]) == 0)
                          {
                            FreeVecPooled (gd.gd_pool, prefs->recents[i]);
                            prefs->recents[i] = NULL;

                            while (i < 5)
                              {
                                prefs->recents[i] = prefs->recents[i + 1];
                                ++i;
                              }

                            prefs->recents[i] = NULL;
                            break;
                          }
                      }

                    if (prefs->recents[5])
                      {
                        FreeVecPooled (gd.gd_pool, prefs->recents[5]);
                        prefs->recents[5] = NULL;
                      }

                    for (i = 0; (i < 5) && (prefs->recents[i]); i++)
                      {
                        set (oa->menus_recent[i], MUIA_Menuitem_Title, prefs->recents[i]);
                        set (oa->menus_recent[i], MUIA_Menuitem_Enabled, TRUE);
                      }

                    ReleaseSemaphore (&prefs->sema);
                  }

              }


              FreeSPooled (gd.gd_pool, rn, sizeof (struct WindowNode));
            }

          data->cnd = (struct WindowNode *) data->WindowList.lh_Head;

          if (data->cnd->wnd_node.mln_Succ)
            {
              set (data->cnd->wnd_win, MUIA_Window_Open, TRUE);

              if (test_flag (data->cnd->status, PWST_GRABBING))
                {
                  set (data->bt_grab, MUIA_Disabled, TRUE);
                  set (data->bt_update, MUIA_Disabled, TRUE);
                  set (data->bt_stopgrab, MUIA_Disabled, FALSE);
                }
              else
                {
                  set (data->bt_grab, MUIA_Disabled, FALSE);
                  set (data->bt_update, MUIA_Disabled, FALSE);
                  set (data->bt_stopgrab, MUIA_Disabled, TRUE);
                }

              for (i = 0; oa->menus[i] != NULL; i++)
                {
                  set (oa->menus[i], MUIA_Menuitem_Enabled, TRUE);
                }

              for (++i; oa->menus[i] != NULL; i++)
                {
                  set (oa->menus[i], MUIA_Menu_Enabled, TRUE);
                }

            }
          else
            {
              data->cnd = NULL;
              set (data->bt_save, MUIA_Disabled, TRUE);
              set (data->bt_grab, MUIA_Disabled, TRUE);
              set (data->bt_update, MUIA_Disabled, TRUE);
              set (data->bt_stopgrab, MUIA_Disabled, TRUE);

              for (i = 0; oa->menus[i] != NULL; i++)
                {
                  set (oa->menus[i], MUIA_Menuitem_Enabled, FALSE);
                }
              for (++i; oa->menus[i] != NULL; i++)
                {
                  set (oa->menus[i], MUIA_Menu_Enabled, FALSE);
                }
            }
          break;

        }
    }

  return (DoSuperMethodA (cl, obj, msg));
}
///

/// "Get"
ULONG
mMainWin_Get (struct IClass * cl, Object * obj, struct opGet * msg)
{
  register struct MainWinData *data = (struct MainWinData *) INST_DATA (cl, obj);

  switch (msg->opg_AttrID)
    {
    case MUIA_Main_CurrentProj:
      *(msg->opg_Storage) = (ULONG) data->cnd;
      return (TRUE);
    }

  return (DoSuperMethodA (cl, obj, (Msg) msg));
}
///

/// "Open"
struct TagItem opentags[] =
{

  {TAG_IGNORE, NULL},
  {TAG_IGNORE, NULL},

  {ASLFR_InitialPattern, (ULONG) "#?.gnp"},

  {ASLFR_DoPatterns, TRUE},
  {ASLFR_RejectIcons, TRUE},

  {TAG_DONE, NULL},

};


ULONG
mMainWin_Open (struct IClass *cl, Object * obj, struct MUIP_Main_Open *msg)
{
  register struct MainWinData *data = (struct MainWinData *) INST_DATA (cl, obj);

  STRPTR projname = NULL, filename = NULL, dirname = NULL;
  struct EditNode *nd = NULL;
  struct FileRequester *req = NULL;
  BOOL load = TRUE;
  APTR newproj;

  struct WindowNode *wnd = data->cnd;

  struct SubTask *st;
  struct AslMessage *asl_msg;

  if (msg->req == TRUE)
    {
      if (wnd)
        {
          opentags[0].ti_Tag = ASLFR_InitialDrawer;
          opentags[1].ti_Tag = ASLFR_InitialFile;
          opentags[0].ti_Data = (ULONG) wnd->dir;
          opentags[1].ti_Data = (ULONG) wnd->title;

        }
      else
        {
          if (msg->dirname)
            {
             opentags[0].ti_Tag = ASLFR_InitialDrawer;
             opentags[0].ti_Data = (ULONG) msg->dirname;
            }
          else
            opentags[0].ti_Tag = TAG_IGNORE;

          if (msg->filename)
            {
             opentags[1].ti_Tag = ASLFR_InitialFile;
             opentags[1].ti_Data = (ULONG) msg->filename;
            }
          else
            opentags[1].ti_Tag = TAG_IGNORE;
        }

      if ((asl_msg = (struct AslMessage *) AllocSPooled (gd.gd_pool, sizeof (struct AslMessage))))
        {
          if ((asl_msg->aslfunc = LoadSeg ("PROGDIR:modules/asl")))
            {

              if ((st = SpawnNetTask ("asl", asl_msg->aslfunc, &asldata)))
                {
                  asl_counter++;
                  asl_msg->obj = (APTR) obj;
                  asl_msg->rmsg = MUIM_Main_Open;
                  asl_msg->tags = opentags;

                  SendSubTaskMsg (st, STC_START, asl_msg);
                }
              else
                {
                  UnLoadSeg (asl_msg->aslfunc);
                  FreeSPooled (gd.gd_pool, asl_msg, sizeof (struct AslMessage));
                  error_req (STRING (MSG_OK, "*_OK"), "%s", STRING (ERR_NOFILEREQ, "Cannot open file requester"));
                }
            }
          else
            {
              FreeSPooled (gd.gd_pool, asl_msg, sizeof (struct AslMessage));
              error_req (STRING (MSG_OK, "*_OK"), "\033c%s", STRING (ERR_NOASL, "Failed to load\nasl requester module"));
            }
        }
      else
        error_req (STRING (MSG_OK, "*_OK"), "%s", STRING (ERR_NOMEM, "Out of Memory"));

    }
  else if (msg->filename)
    {
      filename = newstrcpy (gd.gd_pool, msg->filename);
      dirname = newstrcpy (gd.gd_pool, msg->dirname);
    }
  else
    {
      filename = newstrcpy (gd.gd_pool, STRING (VAR_Untitled, "Untitled.gnp"));
      load = FALSE;
    }

  if (filename)
    {
      if ((wnd = (struct WindowNode *) AllocSPooled (gd.gd_pool, sizeof (struct WindowNode))))
        {
          wnd->title = filename;
          wnd->dir = dirname;
          wnd->status = 0;

          AddHead (&data->WindowList, (struct Node *) wnd);

          if ((wnd->wnd_win = newproj = ProjectWinObject,
               MUIA_Window_Title, filename,
               MUIA_ProjWin_WinNode, wnd,
               End))
            {
              set (newproj, MUIA_ProjWin_Dir, dirname);

              if (load)
                {               // Loading nodes...

                  DoMethod ((Object *) newproj,
                            MUIM_ProjWin_Open, filename, dirname);
                }

              set (obj, MUIA_Main_CurrentProj, wnd);

              return ((ULONG) newproj);
            }

          Remove ((struct Node *) wnd);
          FreeSPooled (gd.gd_pool, wnd, sizeof (struct WindowNode));
        }

      error_req (STRING (MSG_OK, "*_OK"), "%s", STRING (ERR_NOMEM, "Out of Memory"));
    }

  return (NULL);
}
///

/// "Save"
struct TagItem savetags[] =
{

  {ASLFR_InitialDrawer, NULL},
  {ASLFR_InitialFile, NULL},

  {ASLFR_InitialPattern, (ULONG) "#?.gnp"},
  {ASLFR_DoPatterns, TRUE},
  {ASLFR_RejectIcons, TRUE},

  {ASLFR_DoSaveMode, TRUE},

  {TAG_DONE, NULL}

};


ULONG
mMainWin_Save (struct IClass *cl, Object * obj, struct MUIP_Main_Open *msg)
{
  register struct MainWinData *data = (struct MainWinData *) INST_DATA (cl, obj);

  STRPTR filename = msg->filename, dirname = msg->dirname;
  struct FileRequester *req = NULL;
  BOOL load = TRUE;
  struct WindowNode *wnd = data->cnd;
  struct AslMessage *asl_msg;
  struct SubTask *st;


  if (wnd)
    {
      if (msg->req == TRUE)
        {
          if ((asl_msg = (struct AslMessage *) AllocSPooled (gd.gd_pool, sizeof (struct AslMessage))))
            {
              if ((asl_msg->aslfunc = LoadSeg ("PROGDIR:modules/asl")))
                {

                  if ((st = SpawnNetTask ("asl", asl_msg->aslfunc, &asldata)))
                    {
                      asl_counter++;

                      savetags[0].ti_Data = (ULONG) wnd->dir;
                      savetags[1].ti_Data = (ULONG) wnd->title;

                      asl_msg->obj = wnd->wnd_win;
                      asl_msg->rmsg = MUIM_ProjWin_Save;
                      asl_msg->tags = savetags;

                      set ((Object *) wnd->wnd_win, MUIA_ProjWin_Sleep, TRUE);
                      SendSubTaskMsg (st, STC_START, asl_msg);
                    }
                  else
                    {
                      UnLoadSeg (asl_msg->aslfunc);
                      FreeSPooled (gd.gd_pool, asl_msg, sizeof (struct AslMessage));
                      error_req (STRING (MSG_OK, "*_OK"), "%s", STRING (ERR_NOFILEREQ, "Cannot open file requester"));
                    }
                }
              else
                {
                  FreeSPooled (gd.gd_pool, asl_msg, sizeof (struct AslMessage));
                  error_req (STRING (MSG_OK, "*_OK"), "\033c%s", STRING (ERR_NOASL, "Failed to load\nasl requester module"));
                }
            }
          else
            error_req (STRING (MSG_OK, "*_OK"), "%s", STRING (ERR_NOMEM, "Out of Memory"));



        }
      else
        DoMethod ((Object *) wnd->wnd_win, MUIM_ProjWin_Save, filename, dirname);

    }

  return (NULL);
}
///

/// "ShutDown"
ULONG
mMainWin_ShutDown (struct IClass * cl, Object * obj, Msg msg)
{
  register struct MainWinData *data = (struct MainWinData *) INST_DATA (cl, obj);
  struct Message *stm;
  struct WindowNode *wn;

  // here I'd save/close windows

  while ((wn = (struct WindowNode *) RemTail (&data->WindowList)))
    {
      DoMethod ((Object *) wn->wnd_win, MUIM_ProjWin_StopGrab, NULL);
      // Now Add to Open Recent List
      {
        ULONG size;
        char *tmp;

        if ((tmp = (STRPTR) AllocVecPooled (gd.gd_pool, size = s_strlen (wn->dir) + strlen (wn->title) + 2)))
          {
            if (wn->dir)
              {
                strcpy (tmp, wn->dir);
                AddPart (tmp, wn->title, size);
              }
            else
              strcpy (tmp, wn->title);

            size = 0;

            ObtainSemaphore (&prefs->sema);

            prefs->recents[5] = prefs->recents[4];
            prefs->recents[4] = prefs->recents[3];
            prefs->recents[3] = prefs->recents[2];
            prefs->recents[2] = prefs->recents[1];
            prefs->recents[1] = prefs->recents[0];

            prefs->recents[0] = tmp;


            for (int i = 1; (i < 5) && (prefs->recents[i]); i++)
              {
                if (stricmp (tmp, prefs->recents[i]) == 0)
                  {
                    FreeVecPooled (gd.gd_pool, prefs->recents[i]);
                    prefs->recents[i] = NULL;

                    while (i < 5)
                      {
                        prefs->recents[i] = prefs->recents[i + 1];
                        ++i;
                      }

                    prefs->recents[i] = NULL;
                    break;
                  }
              }

            if (prefs->recents[5])
              {
                FreeVecPooled (gd.gd_pool, prefs->recents[5]);
                prefs->recents[5] = NULL;
              }

            ReleaseSemaphore (&prefs->sema);
          }
      }
    }

  while ((stm = GetMsg (myport)))
    {
      ReplyMsg (stm);
    }

  return (FALSE);
}
///

/// "CloseReq"
ULONG
mMainWin_Closereq (struct IClass * cl, Object * obj, struct MUIP_Main_Closereq *msg)
{
  register struct MainWinData *data = (struct MainWinData *) INST_DATA (cl, obj);

  asl_counter--;

  DoMethod ((Object *) oa->App, MUIM_Application_PushMethod, data->self, 2, MUIM_Main_Closereq2, msg->aslmsg);

  return (NULL);
}

ULONG
mMainWin_Closereq2 (struct IClass * cl, Object * obj, struct MUIP_Main_Closereq *msg)
{
  register struct MainWinData *data = (struct MainWinData *) INST_DATA (cl, obj);

  UnLoadSeg (msg->aslmsg->aslfunc);
  FreeSPooled (gd.gd_pool, msg->aslmsg, sizeof (struct AslMessage));

  return (NULL);
}
///

/// "Dispatcher"
SAVEDS (ULONG)
MainWin_Dispatcher (REG (a0, struct IClass * cl), REG (a2, Object * obj), REG (a1, Msg msg))
{
  switch (msg->MethodID)
    {
    case OM_NEW:
      return ((ULONG) mMainWin_New (cl, obj, (struct opSet *) msg));
    case OM_DISPOSE:
      return ((ULONG) mMainWin_Dispose (cl, obj, (Msg) msg));
    case OM_SET:
      return ((ULONG) mMainWin_Set (cl, obj, (Msg) msg));
    case OM_GET:
      return ((ULONG) mMainWin_Get (cl, obj, (struct opGet *) msg));

    case MUIM_Main_Open:
      return ((ULONG) mMainWin_Open (cl, obj, (struct MUIP_Main_Open *) msg));
    case MUIM_Main_Save:
      return ((ULONG) mMainWin_Save (cl, obj, (struct MUIP_Main_Open *) msg));

    case MUIM_Main_ShutDown:
      return ((ULONG) mMainWin_ShutDown (cl, obj, (Msg) msg));

    case MUIM_Main_Closereq:
      return ((ULONG) mMainWin_Closereq (cl, obj, (struct MUIP_Main_Closereq *) msg));

    case MUIM_Main_Closereq2:
      return ((ULONG) mMainWin_Closereq2 (cl, obj,(struct MUIP_Main_Closereq *) msg));
    }

  return (DoSuperMethodA (cl, obj, msg));
}
///
