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

 Example for programming an application which runs a BASIC program and responds
 to incoming commands sent by the BASIC program via DISPATCH statements. Compile
 with SAS/C (smake).

*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <exec/exec.h>
#include <dos/dos.h>
#include <rexx/rxslib.h>
#include <rexx/errors.h>
#include <clib/exec_protos.h>
#include <clib/rexxsyslib_protos.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/rexxsyslib_pragmas.h>

#include "include/basic.h"
#include "clib/basiclib_protos.h"
#include "pragmas/basiclib_pragmas.h"

struct Library *BASICBase;
struct Library *RexxSysBase;

// choose a name for our message port (in a real program, choose a unique name dynamicaly)

#define PORTNAME "TESTHOST.1"

int
main(int argc, UBYTE **argv)
{
    int rc = 20;

    // we need rexxsyslib.library to process DDE messages (which, on the Amiga, are Rexx messages)

    if (RexxSysBase = OpenLibrary("rexxsyslib.library", 0))
    {
        if (BASICBase = OpenLibrary("BASIC.library", BASIC_VERSION))
        {
            struct MsgPort *port;

            // create message port for receiving DISPATCH'ed commands

            if (port = CreateMsgPort())
            {
                static struct TagItem tags[] = { BASIC_FILENAME, (ULONG)"test.basic", BASIC_HOST, (ULONG)PORTNAME, TAG_END };

                UWORD error;

                // initialize our message port

                port->mp_Node.ln_Name = PORTNAME;
                port->mp_Node.ln_Pri  = 1;

                AddPort(port);

                // load and run BASIC program asynchronously

                if (error = basic_rx(tags))
                {
                    printf("BASIC startup error %d\n", error);
                }
                else
                {
                    ULONG signalmask;
                    ULONG signals;

                    puts("Press CTRL-C to exit !");

                    // main loop: wait for incoming commands from BASIC program, exit on CTRL-C

                    signalmask = 1L<<(port->mp_SigBit) | SIGBREAKF_CTRL_C;
                    signals    = 0;

                    for (;;)
                    {
                        struct RexxMsg *msg;

                        while (msg = (struct RexxMsg *)GetMsg(port))
                        {
                            // check incoming command

                            UBYTE *command = ARG0(msg);

                            // this example implents only one command (INFO) which always return "Welcome !" to the BASIC program

                            if (stricmp(command, "INFO") == 0)
                            {
                                // attach result to message

                                UBYTE *result = "Welcome !";

                                if (msg->rm_Result2 = (LONG)CreateArgstring(result, strlen(result)))
                                    msg->rm_Result1 = (LONG)RC_OK;
                                else
                                    msg->rm_Result1 = (LONG)RC_ERROR;
                            }
                            else
                            {
                                printf("Syntax error in incoming command: %s\n", command);

                                msg->rm_Result1 = (LONG)RC_ERROR;
                            }

                            ReplyMsg((struct Message *)msg);
                        }

                        if (signals & SIGBREAKF_CTRL_C)
                        {
                            break;
                        }
                        else
                            signals = Wait(signalmask);
                    }

                    rc = 0;
                }

                RemPort(port);

                DeleteMsgPort(port);
            }

            CloseLibrary(BASICBase);
        }
        else
            puts("Can not open BASIC.library");
    }
    else
        puts("Can not open rexxsys.library");

    return(rc);
}
