/*
   *
   * $Id: subasl.c,v 1.3 1998/06/03 14:02:37 Giambattista_Bloisi Exp $
   *
 */

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <exec/types.h>

/// "Global variables"

struct SignalSemaphore *mem_sema;
APTR pool;
char *vstring = "$VER: GiambyNetGrabber ASL module V1.0";
struct Library *MUIMasterBase = NULL;
///

/// "struct SubTask *InitSubTask (void)"

struct SubTask *
InitSubTask (void)
{
  struct Task *me;
  struct SubTask *st;
  struct SubTaskMsg *stm;

  me = FindTask (NULL);

  /*
     ** Wait for our startup message from the SpawnSubTask() function.
   */

  WaitPort (&((struct Process *) me)->pr_MsgPort);
  stm = (struct SubTaskMsg *) GetMsg (&((struct Process *) me)->pr_MsgPort);
  st = (struct SubTask *) stm->stm_Parameter;

  if ((st->st_Port = CreateMsgPort ()))
    {
      /*
         ** Reply startup message, everything ok.
         ** Note that if the initialization fails, the code falls
         ** through and replies the startup message with a stm_Result
         ** of 0 after a Forbid(). This tells SpawnSubTask() that the
         ** sub task failed to run.
       */

      stm->stm_Result = TRUE;
      ReplyMsg ((struct Message *) stm);

      return (st);
    }
  else
    {
      if (st->st_Port)
        DeleteMsgPort (st->st_Port);

      Forbid ();
      stm->stm_Result = FALSE;
      ReplyMsg ((struct Message *) stm);

      return (NULL);
    }
}
///

/*******************************************************/
/* Subtask which does all the time-consuming rendering */
/*******************************************************/

/// "ULONG DoPortMethod (struct MsgPort *port, struct MsgPort *rport, APTR obj, ...)"
ULONG
DoPortMethod (struct MsgPort * port, struct MsgPort * rport, APTR obj, ...)
{
  struct MUIMessage muimsg =
  {obj, 0, (ULONG *) (&obj) + 1};

  struct SubTaskMsg stm_Message =
  {
    {
      {NULL, NULL, 0, 0, NULL},
      rport, sizeof (struct SubTaskMsg)
    },

    STC_MUIMSG,
    &muimsg,
    0
  };

  PutMsg (port, (struct Message *) &stm_Message);
  WaitPort (rport);
  GetMsg (rport);

  return (stm_Message.stm_Result);
}

ULONG
DoPortAMethod (struct MsgPort * port, struct MsgPort * rport, APTR obj, ULONG parnum,...)
{
  struct MUIMessage muimsg =
  {obj, parnum, (ULONG *) (&parnum) + 1};

  struct SubTaskMsg stm_Message =
  {
    {
      {NULL, NULL, 0, 0, NULL},
      rport, sizeof (struct SubTaskMsg)
    },

    STC_MUIAMSG,
    &muimsg,
    0
  };

  PutMsg (port, (struct Message *) &stm_Message);
  WaitPort (rport);
  GetMsg (rport);

  return (stm_Message.stm_Result);
}

///

/// "void AslFunc(void)"
int
main (int argc, char **argv)
{
  struct SubTask *st;
  struct AslData *data;
  struct SubTaskMsg *stm;

  BOOL worktodo = FALSE;
  struct AslMessage *aslmsg;
  struct Screen *scr;
  UBYTE *scrname = NULL;

  STRPTR projname = NULL, filename = NULL, dirname = NULL;
  struct FileRequester *req = NULL;
  struct preferences *myprefs;
  ULONG left, top, width, height;

  if ((st = InitSubTask ()))
    {
      data = (struct AslData *) st->st_Data;

      SetProgramName ("GNG-ASL module");

      MUIMasterBase = OpenLibrary (MUIMASTER_NAME, MUIMASTER_VMIN);

      if (MUIMasterBase)
        {
          ObtainSemaphore (&data->sema);
          pool = data->pool;
          mem_sema = data->mem_sema;
          myprefs = data->prefs;
          ReleaseSemaphore (&data->sema);

          ObtainSemaphore (&myprefs->sema);
          left = myprefs->req_left;
          top = myprefs->req_top;
          width = myprefs->req_width;
          height = myprefs->req_height;
          ReleaseSemaphore (&myprefs->sema);

          WaitPort (st->st_Port);

          if ((stm = (struct SubTaskMsg *) GetMsg (st->st_Port)))
            {
              if (stm->stm_Command == STC_START)
                {
                  aslmsg = (struct AslMessage *) stm->stm_Parameter;
                  get (aslmsg->obj, MUIA_Window_Screen, &scr);

                  if (scr->Flags & PUBLICSCREEN)
                   {
                    struct List *scrlist;
                    struct PubScreenNode *nd, *succ;

                    scrlist = LockPubScreenList ();

                    nd = (struct PubScreenNode *) scrlist->lh_Head;

                    while ((succ = (struct PubScreenNode *) nd->psn_Node.ln_Succ))
                        {
                         if (nd->psn_Screen == scr)
                             scrname = nd->psn_Node.ln_Name;

                         nd = succ;
                        }

                     UnlockPubScreenList ();
                   }
                  worktodo = TRUE;
                }

              ReplyMsg ((struct Message *) stm);
            }

          if (worktodo == TRUE)
            {
              if ((scr = LockPubScreen (scrname)))
                {

                  if ((req = (struct FileRequester *) MUI_AllocAslRequestTags (ASL_FileRequest, TAG_DONE)))
                    {
                      // *INDENT-OFF*
                      if (MUI_AslRequestTags (req,
                                              ASLFR_Screen, scr,
                                              ASLFR_PrivateIDCMP, TRUE,

                                              ASLFR_InitialLeftEdge, left,
                                              ASLFR_InitialTopEdge, top,
                                              ASLFR_InitialWidth, width,
                                              ASLFR_InitialHeight, height,

                                              TAG_MORE, (ULONG) aslmsg->tags,

                                              TAG_DONE))
                      // *INDENT-ON*

                      {
                        if (req->fr_File&&(*req->fr_File != '\0'))
                          {

                            if (filename)
                              FreeVecPooled (pool, filename);
                            filename = newstrcpy (pool, req->fr_File);

                            if (dirname)
                              FreeVecPooled (pool, dirname);

                            if (req->fr_Drawer&&(*req->fr_Drawer != '\0'))
                              {
                               dirname = newstrcpy (pool, req->fr_Drawer);
                              }
                            else dirname = newstrcpy (pool, "");


                            if ((aslmsg->rmsg > 0x804200FF) && (aslmsg->rmsg < 0x80420200))     //ProjWin class ? (0x80420100 - 0x804201FF)

                              {
                                DoPortMethod (st->st_Reply, st->st_Port, aslmsg->obj,
                                           aslmsg->rmsg, filename, dirname);
                              }
                            else
                              {
                                DoPortMethod (st->st_Reply, st->st_Port, aslmsg->obj,
                                    aslmsg->rmsg, FALSE, filename, dirname);
                              }
                          }

                      }

                      // Change coordinate...
                      ObtainSemaphore (&myprefs->sema);
                      myprefs->req_left = req->fr_LeftEdge;
                      myprefs->req_top = req->fr_TopEdge;
                      myprefs->req_width = req->fr_Width;
                      myprefs->req_height = req->fr_Height;
                      ReleaseSemaphore (&myprefs->sema);

                      MUI_FreeAslRequest (req);
                    }
                  else
                    {
                      /* MUI displayng error....

                         ObtainSemaphore (&sub_sema);
                         DoMethod ((Object *)oa->App, MUIM_Application_PushMethod, oa->main_win, 4,
                         aslmsg->rmsg, FALSE, filename, dirname);
                         ReleaseSemaphore (&sub_sema);

                       */
                      ;
                    }

                  UnlockPubScreen (NULL, scr);
                }

              if ((aslmsg->rmsg > 0x804200FF) && (aslmsg->rmsg < 0x80420200))   //ProjWin class ? (0x80420100 - 0x804201FF)

                {
                  DoPortMethod (st->st_Reply, st->st_Port, aslmsg->obj,
                                MUIM_Set, MUIA_ProjWin_Sleep, FALSE);
                }


              //FreeSPooled (pool, aslmsg, sizeof (struct AslMessage));
            }

            CloseLibrary (MUIMasterBase);
        }

      while ((stm = (struct SubTaskMsg *) GetMsg (st->st_Port)))
        {
          ReplyMsg ((struct Message *) stm);
        }

      ObtainSemaphore (&data->sema);
      DoPortMethod (st->st_Reply, st->st_Port, data->main_win, MUIM_Main_Closereq, aslmsg);
      ReleaseSemaphore (&data->sema);

      if (st->st_Port)
        DeleteMsgPort (st->st_Port);

      Forbid ();
      //stm->stm_Result = FALSE;
      //ReplyMsg ((struct Message *) stm);

    }
}
///












/* end */
