/*

    This module is responsible for communicating with Rexx.
    Specifically it opens a message port and tells rexx to execute
    a program. Rexx should signal host of errors or death.
 
*/

#include <rexx/storage.h>
#include <rexx/rxslib.h>
#include <rexx/errors.h>
#include "flist.h"

/* system types */

extern void ClearMem(),AddPort(),FreePort(),InitPort(),RemPort(),Forbid();
extern void Permit();
extern LONG OpenLibrary();
extern struct RexxMsg *GetMsg();
extern struct RexxMsg myrexxport;
extern struct Library *RexxSysBase;
extern void control_keys();

/* My stuff */

struct FileHandle *fh;
struct RexxMsg *rxmsg;
extern char strbuf[256];
extern long collum, row, line, first, top;

#define PUBFAST MEMF_FAST+MEMF_PUBLIC+MEMF_CLEAR

void OpenRexxPort(string,port)
char *string;
struct MsgPort *port;
{

    ClearMem(port,(LONG)sizeof(struct MsgPort));
    InitPort(port,string);
    AddPort(port);
}

void DeleteRexxPort(port)
struct MsgPort *port;
{
    if(port != NULL){
        RemPort(port);
        FreePort(port);
    }
}

struct RexxMsg *PollRexxPort(port)
struct MsgPort *port;
{
    struct RexxMsg *rxport;

    rxport = GetMsg(port);
    return(rxport);

}

struct RexxMsg *WaitRexxPort(port)
struct MsgPort *port;
{

    WaitPort(port);
    return(PollRexxPort(port));
}

void CleanupRexx()
{

/*    Close(fh); */
    DeleteArgstring(rxmsg->rm_Args[0]);
    DeleteRexxMsg(rxmsg);
}

long StartRexxProg(rexport)
struct MsgPort *rexport;
{
    struct MsgPort *port;
    struct Window *strptr;

    strbuf[0] = '\0';
    strptr = make_gadget("Enter the REXX macro name ");

    if (strptr == NULL) {
        auto_req("Couldn't open Requestor!");
        return FALSE;
    }

    wait_for_event(strptr); 

    if (strbuf[0] == '\0') {
        return FALSE;
    }

    rxmsg = CreateRexxMsg(rexport,"flex","flport");
    rxmsg->rm_Args[0] = strbuf;
    rxmsg->rm_Action = RXCOMM;
/*    rxmsg->rm_Stdout = Output(); */

    if(!FillRexxMsg(rxmsg, 1L, 0L)) {
        DeleteRexxMsg(rxmsg);
        return FALSE;
    }

    Forbid();
    port = (struct RexxMsg *)FindPort("REXX");
    if(port == NULL){
        Permit();
        auto_req("REXX is not here!");
        CleanupRexx();
        return FALSE;
    }

    PutMsg(port,rxmsg);         /* email in it's truest form */
    Permit();
    return TRUE;
}

char *rexx_strings[] = {
    "end",
    "iconify",
    "sort s",
    "sort z",
    "sort t",
    "sort o",
    "parent",
    "redraw",
    "reget",
    "request",
    "makedir",
    "changedir",
    "sort y"
};

dorexx()
{
    struct RexxMsg *resultmsg;
    char buf[256];
    int equal, i;
                
    if(RexxSysBase == NULL){
        auto_req(" Rexx library not Available");
        return;
    }

    if(!StartRexxProg(&myrexxport)){    /* start up fl.flex as a rexx task */
        if (strbuf[0] != '\0')
            auto_req(" PANIC - couldn't start up rexx program!");
        return;
    }

    /* this is a communication test ... */

    for(;;) {

        resultmsg = WaitRexxPort(&myrexxport);

#ifdef DEBUG
        sprintf(buf,"Return of -%d- , -%s-",resultmsg->rm_Result1,resultmsg->rm_Args[0]);
        auto_req(buf);
#endif

        if (resultmsg->rm_Result1 > 0) {

            if (Strcmp(strbuf, resultmsg->rm_Args[0]) == 0) {
                sprintf(buf,"Error %d in -%s.flex-.",
                    resultmsg->rm_Result1,strbuf);
                auto_req(buf);
                resultmsg->rm_Result1 = 5; 
                resultmsg->rm_Result2 = 0; 
                CleanupRexx();
                return;
            }
        }

        resultmsg->rm_Result1 = 0;  /* no error  */
        resultmsg->rm_Result2 = 0;  /* no secondary */

        for(i=0;i<13;i++){
            equal = Strncmp(resultmsg->rm_Args[0],rexx_strings[i],
                        strlen(rexx_strings[i]));
            if (equal == 0)
                break;
        }

#ifdef DEBUG
        sprintf(buf,"I = %d, string is %s",i,rexx_strings[i]);
        auto_req(buf);
#endif

        blankcur();
        switch (i) {
        
            case 0:
                ReplyMsg(resultmsg);        /* send back 'end' message */
                WaitRexxPort(&myrexxport);  /* wait for original Msg to ret */
                CleanupRexx();
                return;

            case 1:         /* Iconify */
                tticon();
                break;

            case 2:         /* sort by name */
                sort(0);
                refresh();
                break;

            case 3:         /* sort by size */
                sort(1);
                refresh();
                break;

            case 4:         /* sort by time */
                sort(2);
                refresh();
                break;

            case 5:         /* sort by pattern */
                sort(3);
                refresh();
                break;

            case 6:         /* get parent dir */
                parent();
                refresh();
                break;

            case 7:         /* redraw screen */
                control_keys(0x0c);
                break;

            case 8:         /* reget directory */
                getdir();
                refresh();
                break;

            case 9:
                control_keys(0x01); /* ARP requestor */
                break;

            case 10:
                control_keys(0x0e); /* Makedir */
                break;

            case 11:                /* changedir 'string' */
                if (strlen(resultmsg->rm_Args[0]) > 10) {
#ifdef DEBUG
                    auto_req(&resultmsg->rm_Args[0][10]);
#endif
                    strcpy(buf,&resultmsg->rm_Args[0][10]);
                    changedir(buf);
                    refresh();
                } else
                    auto_req("Bad arguments to CHANGEDIR.");
                break;

            case 12:         /* sort by day */
                sort(4);
                refresh();
                break;

            default:
                resultmsg->rm_Result1 = 5;  /* shows an error code */
                resultmsg->rm_Result2 = 0;  /* no secondary        */

                if (Strcmp(strbuf, resultmsg->rm_Args[0]) == 0) {
                    sprintf(buf,"End keyword not found in -%s.flex-.",
                        strbuf);
                    auto_req(buf);
                    ReplyMsg(resultmsg);
                    WaitRexxPort(&myrexxport);
                    CleanupRexx();
                    return;
                }
                sprintf(buf,"Bad command -%s- from macro %s.flex",
                    resultmsg->rm_Args[0],strbuf);
                auto_req(buf);
                break;
        }
        ReplyMsg(resultmsg);
        drawcur();
    }   /* end of forever */
}
