/*
   script.library
   client example
*/

#include <string.h>
#include <stdlib.h>
#include <rexx/rxslib.h>
#include <rexx/storage.h>
#include <proto/rexxsyslib.h>
#include <proto/exec.h>
#include <proto/dos.h>

#if defined (__SASC)
#include "/script.h"
#include "/script_pragmas.h"
#elif defined (__GNUC__)
#include "../script_inline.h"
#endif

#include "example.h"

#if defined (__GNUC__)
#define RXSLIB struct RxsLib
#elif defined (__SASC)
#define RXSLIB struct Library
#endif

struct Library *ScriptBase = NULL;
RXSLIB *RexxSysBase = NULL;
struct RexxMsg *RexxMesg = NULL;
struct MsgPort *RexxPort = NULL;
struct ScriptContext *ScriptC;

int
init (void)
{
  if (!(RexxSysBase = (RXSLIB *) OpenLibrary ("rexxsyslib.library", 36)))
    return 0;
  if (!(ScriptBase = OpenLibrary ("script.library", 0)))
    return 0;
  if (!(RexxPort = CreateMsgPort ()))
    return 0;
  if (!(RexxMesg = CreateRexxMsg (RexxPort, NULL, NULL)))
    return 0;
  if (!(ScriptC = Script_AllocContext ()))
    return 0;

  Script_SetMsgContext (RexxMesg, ScriptC);
  return 1;
}

void
clear_rexx_result (void)
{
  if (RexxMesg -> rm_Result2)  /* I guess this is correct :-) */
  {
    DeleteArgstring ((UBYTE *) RexxMesg -> rm_Result2);
    RexxMesg -> rm_Result2 = 0;
  }
}

void
cleanup (void)
{
  clear_rexx_result ();

  if (ScriptC)
    Script_FreeContext (ScriptC);
  if (RexxMesg)
    DeleteRexxMsg (RexxMesg);
  if (RexxPort)
    DeleteMsgPort (RexxPort);
  if (RexxSysBase)
    CloseLibrary ((struct Library *) RexxSysBase);
  if (ScriptBase)
    CloseLibrary (ScriptBase);
}

int
main (int argc, char *argv[])
{
  char *port_name = PORT_NAME,
       *func_name = FUNC_NAME,
       *variable_name  = VAR_NAME,
       *variable_value = VAR_VALUE;
  struct MsgPort *port;

  atexit (cleanup);
  init ();

  if (argc >= 2)
    port_name = argv[1];
  if (argc >= 3)
    func_name = argv[2];
  if (argc >= 4)
    variable_name = argv[3];
  if (argc >= 5)
    variable_value = argv[4];

  Script_SetStringVar (ScriptC, variable_name, variable_value);

  if (!(RexxMesg -> rm_Args[0] = CreateArgstring (func_name, strlen (func_name))))
    return NULL;
  RexxMesg -> rm_Node.mn_Node.ln_Type = NT_MESSAGE;
  RexxMesg -> rm_Node.mn_Length = sizeof (struct RexxMsg);
  RexxMesg -> rm_Action = RXFUNC | RXFF_RESULT;
  RexxMesg -> rm_Node.mn_ReplyPort = RexxPort;

  Forbid ();
  if (!(port = FindPort (port_name)))
  {
    Permit ();
    PutStr ("Port \"");
    PutStr (port_name);
    PutStr ("\" not found.\n");
    return NULL;
  }
  PutMsg (port, (struct Message *) RexxMesg);
  Permit ();
  do
    WaitPort (RexxPort);
  while (GetMsg (RexxPort) != (struct Message *) RexxMesg);

  Script_GetStringVar (ScriptC, variable_name, &variable_value);

  PutStr ("Returned value for: \"");
  PutStr (variable_name);
  PutStr ("\" is \"");
  PutStr (variable_value);
  PutStr ("\".\n");

  ClearRexxMsg (RexxMesg, 1); /* doesn't clear rm_Result2 */
  return 0;
}
