/* -----------------------------------------------------------------------------

  Example: How to read GoldED's project list. DICE:

  dcc prj.c -// -o ram:ReadList

  This is C source code to demonstrate reading of GoldED's project list using
  ARexx. Might be useful if you intend to develop external project management
  tools.

  ------------------------------------------------------------------------------
*/

/// "includes & prototypes"

#include <amiga20/exec/exec.h>
#include <amiga20/rexx/errors.h>
#include <amiga20/rexx/rxslib.h>
#include <amiga20/clib/exec_protos.h>
#include <amiga20/clib/rexxsyslib_protos.h>

#define Prototype extern

Prototype void   main(ULONG, char **);
Prototype struct RexxMsg *SendRexxCommand(char *, char *, struct MsgPort *);
Prototype void   FreeRexxCommand (struct RexxMsg *);
Prototype ULONG  WaitForAnswer(struct MsgPort *, char *);

///
/// "main"

void
main(argc, argv)

ULONG argc;
char *argv[];
{
    static UBYTE version[] = "$VER: PRJ 1.1 (" __COMMODORE_DATE__ ")";

    struct MsgPort *replyPort;

    char *host = "GOLDED.1";

    if (replyPort = CreateMsgPort()) {

        if (SendRexxCommand(host, "LOCK CURRENT", replyPort)) {

            char result[80];

            if (WaitForAnswer(replyPort, result) == RC_OK) {

                if (SendRexxCommand(host, "QUERY PRJLIST", replyPort)) {

                    if (WaitForAnswer(replyPort, result) == RC_OK) {

                        struct List *list;
                        struct Node *node;

                        list = (struct List *)atol(result);

                        if (list->lh_Head->ln_Succ) {

                            for (node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
                                printf("%s (selected: %s)\n", node->ln_Name, node->ln_Pri ? "YES" : "NO");
                        }
                        else
                            puts("project list is empty");
                    }
                }
                if (SendRexxCommand(host, "UNLOCK", replyPort))
                    WaitForAnswer(replyPort, result);
            }
        }
        DeleteMsgPort(replyPort);
    }
    exit(0);
}

///
/// "ARexx"

/* -------------------------------------- WaitForAnswer -----------------------

  Wait for answer on previously sent message. Free message afterwards. Primary
  return code is returned, the result string (if any) written to <result>.

*/

ULONG
WaitForAnswer(port, result)

struct MsgPort *port;
char   *result;
{
    struct RexxMsg *rexxMsg;
    ULONG  error;

    *result = NULL;

    do {
        
        WaitPort(port);

        if (rexxMsg = (struct RexxMsg *)GetMsg(port))
            if ((error = rexxMsg->rm_Result1) == RC_OK)
                if (rexxMsg->rm_Result2)
                    strcpy(result, (char *)rexxMsg->rm_Result2);

    } while (!rexxMsg);

    FreeRexxCommand(rexxMsg);
    return(error);
}

/* ------------------------------------- FreeRexxCommand ----------------------

 Free ARexx message

*/

void
FreeRexxCommand(rexxmessage)

struct RexxMsg *rexxmessage;
{
    if (rexxmessage->rm_Result1 == RC_OK) 
        if (rexxmessage->rm_Result2)
            DeleteArgstring((char *)rexxmessage->rm_Result2);

    DeleteArgstring((char *)ARG0(rexxmessage));

    DeleteRexxMsg(rexxmessage);
}

/* ---------------------------------- SendRexxCommand -------------------------

 Send ARexx message

*/

struct RexxMsg *
SendRexxCommand(port, cmd, replyPort)

char   *cmd,   *port;
struct MsgPort *replyPort;
{
    struct MsgPort *rexxport;
    struct RexxMsg *rexx_command_message = NULL;

    Forbid();

    if (rexxport = FindPort(port)) {

        if (rexx_command_message = CreateRexxMsg(replyPort, NULL, NULL)) {

            if (rexx_command_message->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {

                rexx_command_message->rm_Action = RXCOMM | RXFF_RESULT;

                PutMsg(rexxport, &rexx_command_message->rm_Node);
            }
        }
    }

    Permit();
    return(rexx_command_message);
}

///
