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

 texserver.api ©1996 BURGHARD Eric
    code based ©1996 Dietmar Eiler

 API version of REXX TeXServer

 Private functions
 -------------------------------------------------------------------------------
*/

/// Includes

#include "defs.h"
#define CATCOMP_NUMBERS
#include "locale.h"
#include "funcs.h"
#include "misc.h"
#include "private.h"
#include "debug.h"

///
/// Definitions

// Declared in funcs.c
extern struct LocaleInfo li;
extern struct Library *SysBase, *DOSBase, *LibBase;
extern struct Library *IntuitionBase, *RexxSysBase, *LocaleBase, *ReqToolsBase;

///
/// "Private functions"
/* --------------------------------- Dispatch ----------------------------------
 Dispatch incoming command: examine command string (command part is uppercase
 already), look for handler function related to command, parse arguments (if
 command supports arguments), call handler.
*/

void
Dispatch(handle, apiMsg)

struct APIClient *handle;
struct APIMessage *apiMsg;
{
    struct RDArgs *rdArgs, *args;
    struct MAPIClient *mhandle=(struct MAPIClient *) handle;

    #ifdef DEBUG
      DbgPrintf("Dispatch(handle=%08x, apiMsg=%08x)\n", handle, apiMsg);
    #endif

    if (rdArgs = AllocDosObject(DOS_RDARGS, NULL)) {

        // table of supported commands, handlers & template strings

        static struct parser { char *command; LONG (*handler)(struct MAPIClient *, ULONG *, struct APIMessage *); char *template; } parser[] = {

            "VIRTEX", (APTR) CommandVirTeX, "FORMAT/K,FILE/K,ASK/S,BREAK/S",
            "DVI", (APTR) CommandDVI, "PRINT/S,SHOW/S,FILE/K,ASK/S,OPT/K,MODE/S",
            "TEXSERVER", (APTR) CommandTeXServer, "SHOW/S,HIDE/S,ABOUT/S,CHECK/K",
            NULL
        };

        ULONG n;
        UBYTE buffer[80];
        ULONG argArray[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        // make LF-terminated copy of command string (required by dos/readArgs):

        strncpy(buffer, apiMsg->api_Command, sizeof(buffer));
        strcat (buffer, "\12");

        for (n = 0; parser[n].command; ++n) {

            if (memcmp(buffer, parser[n].command, strlen(parser[n].command)) == 0) {

                UBYTE *arguments = buffer + strlen(parser[n].command);

                // tell host that message has been consumed by us:

                apiMsg->api_State = API_STATE_CONSUMED;

                rdArgs->RDA_Source.CS_Buffer = arguments;
                rdArgs->RDA_Source.CS_Length = strlen(arguments);
                rdArgs->RDA_Source.CS_CurChr = 0;
                rdArgs->RDA_DAList           = NULL;
                rdArgs->RDA_Buffer           = NULL;

                if (parser[n].template) {

                    if (args = ReadArgs(parser[n].template, (LONG *) argArray, rdArgs)) {

                        apiMsg->api_RC = (*parser[n].handler)(mhandle, argArray, apiMsg);

                        FreeArgs(args);
                    }
                    else {

                        static UBYTE errorText[80 + 1];

                        apiMsg->api_RC           = RC_WARN;
                        apiMsg->api_CommandError = errorText;

                        Fault(IoErr(), "IoErr()", errorText, 80);
                    }
                }
                else
                    apiMsg->api_RC = (*parser[n].handler)(mhandle, argArray, apiMsg);
            }
        }

        FreeDosObject(DOS_RDARGS, rdArgs);
    }
}


/* ------------------------------- CommandVirTeX -------------------------------
 VIRTEX FORMAT/K, FILE/K, ASK/S, BREAK/S (Run VirTeX cmd with format on file)
*/

LONG
CommandVirTeX(mhandle, argArray, apiMsg)

struct MAPIClient *mhandle;
ULONG  *argArray;
struct APIMessage *apiMsg;
{
    struct EditConfig *apiEnvironment;
    UBYTE cmd[MAX_LEN + 1];
    UBYTE filename[281], path[141], *fullname;
    static char next[]="\n============================================================================\n";

    #ifdef DEBUG
        DbgPrintf("CommandVirTeX(mhandle=%08x, argarray=%08x, apiMsg=%08x)\n", mhandle, argArray, apiMsg);
    #endif

    if (argArray[3]) {
        struct Process *pr;

        if (pr=findCommandName(mhandle, "VirTeX"))

            Signal((struct Task *)pr, SIGBREAKF_CTRL_C);

        return(RC_OK);
    }

    apiEnvironment=(struct EditConfig *)apiMsg->api_Instance->api_Environment;

    strcpy(filename, apiEnvironment->Path);

    strcpy(path, apiEnvironment->Path);

    if (argArray[2]) {

       if (!openReqFile(GetString(&li, MSG_TEXFIL_REQ), filename, path, mhandle->api_GEDPSName, "(*.(tex|ltx|txi))"))

          return(RC_OK);

    } else {

        if ((filename[strlen(filename)-1] != ':') && (filename[strlen(filename)-1] != '/'))

            strcat(filename, "/");

        strcat(filename, apiEnvironment->Name);
    }

    if (fullname=getFullName(filename))

        strcpy(filename,fullname);

    else {

        apiMsg->api_Error=API_ERROR_FAIL;

        apiMsg->api_CommandError=GetString(&li, MSG_TEXSRC_REQ);

        return(RC_WARN);
    }

    sprintf(cmd, "VirTeX &%s \"%s\"", (argArray[0] == NULL) ? "latex" : (char *) argArray[0], (argArray[1] == NULL) ? filename : (UBYTE *) argArray[1]);

    myWriteChars(next, strlen(next), mhandle, apiMsg);

    return(apiSystemTags(cmd, path, mhandle, apiMsg));
}


/* ------------------------------- CommandDVI ----------------------------------
 DVI PRINT/S, SHOW/S, FILE/K, ASK/S, OPT/K, MODE/S (Run dviprint or showdvi cmds on file)
*/

LONG
CommandDVI(mhandle, argArray, apiMsg)

struct MAPIClient *mhandle;
ULONG  *argArray;
struct APIMessage *apiMsg;
{
     struct EditConfig *apiEnvironment;
     UBYTE cmd[MAX_LEN + 1];
     UBYTE filename[281], dviname[281], path[141], *filext, *fullname;
     APTR ret=FALSE;

     #ifdef DEBUG
         DbgPrintf("CommandDVI(mhandle=%08x, argarray=%08x, apiMsg=%08x)\n", mhandle, argArray, apiMsg);
     #endif

     cmd[0]='\0';

     apiEnvironment=(struct EditConfig *)apiMsg->api_Instance->api_Environment;

     strcpy(filename, apiEnvironment->Path);

     strcpy(path, apiEnvironment->Path);

     if (argArray[3]) {

        if (!(ret=openReqFile(GetString(&li, MSG_DVIFIL_REQ), filename, path, mhandle->api_GEDPSName, "(*.dvi)")))

           return(RC_OK);

     } else {

         if ((filename[strlen(filename)-1] != ':') && (filename[strlen(filename)-1] != '/'))

             strcat(filename, "/");

         strcat(filename, apiEnvironment->Name);

         if (filext=strrchr(filename, '.'))

             strcpy(filext,".dvi");
     }

     if (fullname=getFullName(filename))

         strcpy(filename,fullname);

     else {
         apiMsg->api_Error=API_ERROR_FAIL;

         apiMsg->api_CommandError=GetString(&li, MSG_NODVI_REQ);

         return(RC_WARN);
     }

     #ifdef DEBUG
       DbgPrintf("filename= \"%s\"\n", filename);
     #endif

     if (argArray[0]) {

         if (argArray[5]) {

             switch (ezRequest(mhandle, GetString(&li, MSG_PRTBOD_REQ), GetString(&li, MSG_PRTBUT_REQ), NULL)) {

                 case 0:
                     *cmd='\0';
                     break;

                 case 1:
                     sprintf(cmd, "DVIPrint \"%s\" PUB %s", (argArray[2] == NULL) ? filename : (UBYTE *) argArray[2], mhandle->api_GEDPSName, (argArray[4] == NULL) ? "" : (char *) argArray[4]);
                     break;

                 case 2:
                     ezRequest(mhandle, GetString(&li, MSG_PGEBOD_REQ), GetString(&li, MSG_REQBOK_REQ), NULL);

                     sprintf(cmd, "DVIPrint \"%s\" PUB %s %s ODD\nDVIPrint \"%s\" PUB %s %s EVEN",
                     (argArray[2] == NULL) ? filename : (UBYTE *) argArray[2],
                     mhandle->api_GEDPSName,
                     (argArray[4] == NULL) ? "" : (char *) argArray[4],
                     (argArray[2] == NULL) ? filename : (UBYTE *) argArray[2],
                     mhandle->api_GEDPSName,
                     (argArray[4] == NULL) ? "" : (char *) argArray[4]);
             }

         } else
            sprintf(cmd, "DVIPrint \"%s\" PUB %s %s", (argArray[2] == NULL) ? filename : (UBYTE *) argArray[2], mhandle->api_GEDPSName, (argArray[4] == NULL) ? "" : (char *) argArray[4]);


         if (*cmd == '\0')

             return(RC_OK);

         else

             return(apiSystemTags(cmd, path, mhandle, apiMsg));

     } else if (argArray[1]) {

         if (FindPort("showdvi")) {

             struct MsgPort *replyPort;
             ULONG *result;
             char result2[141];

             if (!(replyPort=CreateMsgPort())) {

                 apiMsg->api_Error=API_ERROR_FAIL;

                 apiMsg->api_CommandError=GetString(&li, MSG_MSGPOR_REQ);

                 return(RC_WARN);
             }

             result=SendRexxCommand("showdvi", "GETDIR", replyPort, result2);

             strcpy(dviname, result2);

             if ((dviname[strlen(dviname)-1] != ':') && (dviname[strlen(dviname)-1] != '/'))

                 strcat(dviname, "/");

             result=SendRexxCommand("showdvi", "GETFILE", replyPort, result2);

             strcat(dviname, result2);

             strcat(dviname, ".dvi");

             if (fullname=getFullName(dviname))

                 strcpy(dviname,fullname);

             else {

                 apiMsg->api_Error=API_ERROR_FAIL;

                 apiMsg->api_CommandError=GetString(&li, MSG_SDVIFI_REQ);

                 return(RC_WARN);
             }

             #ifdef DEBUG
               DbgPrintf("dviname= \"%s\"\n", dviname);
             #endif

             if (!strcmp(filename, dviname))

                 result=SendRexxCommand("showdvi", "LOADAGAIN", replyPort, NULL);

             else {

                 sprintf(cmd, "LOADNEW %s", filename);

                 result=SendRexxCommand("showdvi", cmd, replyPort, NULL);
             }

             SendRexxCommand("showdvi", "TOFRONT\nACTIVATE", replyPort, NULL);

             DeleteMsgPort(replyPort);

             return(RC_OK);

         } else {

             sprintf(cmd, "ShowDVI \"%s\" %s", (argArray[2] == NULL) ? filename : (UBYTE *) argArray[2], (argArray[4] == NULL) ? "" : (char *) argArray[4]);

             return(apiSystemTags(cmd, path, mhandle, apiMsg));
         }
    }
}

/* ------------------------------- CommandTeXServer --------------------------------
 TEXSERVER SHOW/S, HIDE/S, ABOUT/S, CHECK/K (Show or hide the output of initex)
*/

LONG
CommandTeXServer(mhandle, argArray, apiMsg)

struct MAPIClient *mhandle;
ULONG  *argArray;
struct APIMessage *apiMsg;
{
   struct Window *window;

   #ifdef DEBUG
       DbgPrintf("CommandTeXServer(mhandle=%08x, argarray=%08x, apiMsg=%08x)\n", mhandle, argArray, apiMsg);
   #endif

   if (argArray[0]) {

       if (window=getServerWindow(mhandle)) {

           WindowToFront(window);

           #ifdef DEBUG
              DbgPrintf("WindowToFront(window=%08x)\n", window);
           #endif

        } else if (mhandle->api_ConOut) {

           static char activate[4];

           activate[0]='\x1B';
           activate[1]='\x5B';
           activate[2]='0';
           activate[3]='E';

           myWriteChars(activate, 4, mhandle, apiMsg);
        }

   } else if (argArray[1]) {

       if (window=getServerWindow(mhandle))

           sendCloseWindow(window);
   }

   if (argArray[2]) {

       if (ezRequest(mhandle, GetString(&li, MSG_ABTBOD_REQ), GetString(&li, MSG_ABTBUT_REQ), NULL) == -1) {

          apiMsg->api_Error=API_ERROR_FAIL;

          apiMsg->api_CommandError=GetString(&li, MSG_NOABOT_REQ);

          return(RC_WARN);

       }

       return(RC_OK);
   }

   if (argArray[3]) {

        if (findCommandName(mhandle, (char *) argArray[3]))

            apiMsg->api_CommandResult="TRUE";
        else
            apiMsg->api_CommandResult="FALSE";
   }

   return(RC_OK);
}
///
