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

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

 API version of REXX TeXServer

 Main code
 -------------------------------------------------------------------------------
*/

/// Includes

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

///
/// Definitions

// Initialized by tag.a
struct Library *SysBase, *DOSBase, *LibBase;
struct Library *IntuitionBase, *RexxSysBase, *LocaleBase, *ReqToolsBase;
BPTR SegList;
struct LocaleInfo li;

// Defined in tag.a
extern const char LibName[];
extern const char LibId[];

///
/// "Library functions"

LibCall struct APIClient *
APIMountClient(register __a0 struct APIMessage *apiMsg, register __a1 char *args)
{
    struct APIClient *apiClient;
    struct MAPIClient *mapiClient;
    char *gedPSName;
    static UBYTE           *apiCommands[] = { "VIRTEX FORMAT/K,FILE/K,ASK/S,BREAK/S",
                                              "DVI PRINT/S,SHOW/S,FILE/K,ASK/S,OPT/K,MODE/S",
                                              "TEXSERVER SHOW/S,HIDE/S,ABOUT/S,CHECK/S",
                                              NULL };

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

    if (LocaleBase)

        li.li_Catalog = OpenCatalogA(NULL,"envtex.catalog",NULL);

    if (!(mapiClient=(struct MAPIClient *) AllocMem(sizeof(struct MAPIClient), MEMF_ANY)))

        return(NULL);

    apiClient                 = (struct APIClient *) mapiClient;
    apiClient->api_APIVersion = API_INTERFACE_VERSION;
    apiClient->api_Version    = 37;
    apiClient->api_Name       = "TeXServer API";
    apiClient->api_Info       = GetString(&li,MSG_IDENT);
    apiClient->api_Commands   = apiCommands;
    apiClient->api_Serial     = 0;
    apiClient->api_Classes    = API_CLASS_COMMAND | API_CLASS_SCREEN | API_CLASS_SYSTEM;
    apiClient->api_Area       = NULL;
   mapiClient->api_ConIn      = NULL;
   mapiClient->api_ConOut     = NULL;
   mapiClient->api_Screen     = apiMsg->api_Instance->api_Screen;
   mapiClient->api_Window     = apiMsg->api_Instance->api_Window;

    if (gedPSName=getGEDPSName(mapiClient->api_Screen)) {

       strcpy(mapiClient->api_GEDPSName, gedPSName);

       #ifdef DEBUG
          DbgPrintf("PubScreenName=\"%s\"\n", mapiClient->api_GEDPSName);
       #endif

       return(apiClient);

    } else {

       FreeMem(mapiClient, sizeof(struct MAPIClient));

       return(NULL);
    }
}

LibCall void
APICloseClient(register __a0 struct APIClient *handle, register __a1 struct APIMessage *apiMsg)
{
    struct MAPIClient *mhandle=(struct MAPIClient *) handle;
    struct Window *win;

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

    if (li.li_Catalog)

        CloseCatalog(li.li_Catalog);

    if (win=getServerWindow(mhandle))

        sendCloseWindow(win);

    FreeMem(mhandle, sizeof(struct MAPIClient));
}

LibCall void
APIBriefClient(register __a0 struct APIClient *handle, register __a1 struct APIMessage *apiMsg)
{
    struct APIMessage *msg;

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

    // handle host's command notify

    for (msg = apiMsg; msg; msg = msg->api_Next) {

        if (msg->api_State == API_STATE_NOTIFY) {

            switch (msg->api_Class) {

                case API_CLASS_COMMAND:

                    if (msg->api_Action == API_ACTION_COMMAND)

                         Dispatch(handle, msg);
                    else

                         msg->api_Error = API_ERROR_UNKNOWN;

                    break;

                case API_CLASS_SCREEN:

                    switch (msg->api_Action) {

                        ULONG argArray[4];

                        case API_ACTION_SHOW:

                            argArray[0]=TRUE;
                            argArray[1]=FALSE;
                            argArray[2]=FALSE;
                            argArray[3]=NULL;

                            CommandTeXServer((struct MAPIClient *) handle, argArray, apiMsg);

                            break;

                        case API_ACTION_HIDE:

                            argArray[0]=FALSE;
                            argArray[1]=TRUE;
                            argArray[2]=FALSE;
                            argArray[3]=NULL;

                            CommandTeXServer((struct MAPIClient *) handle, argArray, apiMsg);

                            break;

                        default:
                            msg->api_Error = API_ERROR_UNKNOWN;
                    }

                    break;

                case API_CLASS_SYSTEM:

                    switch (msg->api_Action) {

                        ULONG argArray[4];

                        case API_ACTION_WELCOME:

                            break;

                        case API_ACTION_EXIT:

                            argArray[0]=FALSE;
                            argArray[1]=TRUE;
                            argArray[2]=FALSE;
                            argArray[3]=NULL;

                            CommandTeXServer((struct MAPIClient *) handle, argArray, apiMsg);

                            break;

                        default:

                            msg->api_Error = API_ERROR_UNKNOWN;
                    }

                    break;

                default:

                    msg->api_Error = API_ERROR_UNKNOWN;
            }
        }
    }
}

LibCall void
APIFree(register __a0 struct APIClient *handle, register __a1 struct APIOrder *apiOrder)
{
}

///
/// "ARexx functions"
/* ---------------------------------- SendRexxCommand -------------------------
 Send ARexx message & wait for answer. Return pointer to result or NULL.
*/

ULONG *
SendRexxCommand(port, cmd, replyPort, result2)

struct MsgPort *replyPort;
UBYTE          *cmd, *port, *result2;
{
    struct MsgPort *rexxport;

    #ifdef DEBUG
       DbgPrintf("SendRexxCommand(port=\"%s\", cmd=\"%s\", replyPort=%08x, result2=\"%s\")\n", port, cmd, replyPort, result2);
    #endif

    Forbid();

    if (rexxport = FindPort(port)) {

        struct RexxMsg *rexxMsg, *answer;

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

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

                static ULONG result;

                rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;

                PutMsg(rexxport, &rexxMsg->rm_Node);

                do {

                    WaitPort(replyPort);

                    if (answer = (struct RexxMsg *)GetMsg(replyPort))

                        result = answer->rm_Result1;

                } while (!answer);

                Permit();

                if (answer->rm_Result1 == RC_OK)

                    if (answer->rm_Result2) {

                        #ifdef DEBUG
                            DbgPrintf("rm_Result2=\"%s\"\n", answer->rm_Result2);
                        #endif

                        if (result2)

                            strcpy((char *)result2, (char *)answer->rm_Result2);

                        DeleteArgstring((UBYTE *)answer->rm_Result2);

                    }

                DeleteArgstring((UBYTE *)ARG0(answer));

                DeleteRexxMsg(answer);

                return(&result);
            }
        }
    }

    Permit();

    return(NULL);
}

///
