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

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

 API version of REXX TeXServer

 Misc 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;

///
/// "Misc functions"
BPTR
getOutput(mhandle)

struct MAPIClient *mhandle;
{
  #ifdef DEBUG
     DbgPrintf("getOutput(mhandle=%08x)\n", mhandle);
  #endif

  if (!mhandle->api_ConOut)

      dupConHandler(mhandle);

  return(mhandle->api_ConOut);

}

char *
getFullName(name)

UBYTE *name;
{
  static char fullname[MAX_LEN+1];
  BPTR fl;

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

  if (fl=Lock(name, SHARED_LOCK)) {

    if (NameFromLock(fl,fullname, 281)) {

       UnLock(fl);

       return(fullname);
    }

  }

  return(NULL);
}

char *
getGEDPSName(screen)

struct Screen *screen;
{
  struct List *pubScreenList;
  struct PubScreenNode *pubScreenNode;
  static char pubScreenName[MAX_LEN+1];

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

  if (pubScreenList=LockPubScreenList()) {

      for (pubScreenNode=(struct PubScreenNode *)pubScreenList->lh_Head; pubScreenNode; pubScreenNode=(struct PubScreenNode *)pubScreenNode->psn_Node.ln_Succ) {

           if (pubScreenNode->psn_Screen == screen) {

               strcpy(pubScreenName, pubScreenNode->psn_Node.ln_Name);

               UnlockPubScreenList();

               return(pubScreenName);
           }
      }
      UnlockPubScreenList();
  }
  return(NULL);
}

struct Window *
getServerWindow(mhandle)

struct MAPIClient *mhandle;
{
  struct Window *windowNode;
  char winName[81];

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

  sprintf(winName, "TeXServer.%x", mhandle);

  for (windowNode=mhandle->api_Screen->FirstWindow; windowNode; windowNode=windowNode->NextWindow) {

       if (windowNode->Title && !strcmp(windowNode->Title, winName))

           return(windowNode);
  }

  return(NULL);
}

LONG
sendCloseWindow(window)

struct Window *window;
{
  struct InputEvent inputEvent;
  struct IOStdReq *inputRequest;
  struct MsgPort *replyPort;

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

  if (!(replyPort=CreateMsgPort()))

      return(RC_WARN);

  if (!(inputRequest=(struct IOStdReq *) CreateExtIO(replyPort, sizeof(struct IOStdReq)))) {

      DeleteMsgPort(replyPort);

      return(RC_WARN);
  }

  if (OpenDevice("input.device", 0, (struct IORequest *) inputRequest, 0L)) {

      DeleteMsgPort(replyPort);

      DeleteExtIO((struct IORequest *) inputRequest);

      return(RC_WARN);
  }

  ActivateWindow(window);

  inputEvent.ie_NextEvent=NULL;
  inputEvent.ie_Class=IECLASS_CLOSEWINDOW;
  inputRequest->io_Command=IND_WRITEEVENT;
  inputRequest->io_Data=&inputEvent;
  inputRequest->io_Length=sizeof(struct InputEvent);

  DoIO((struct IORequest *) inputRequest);

  CloseDevice((struct IORequest *) inputRequest);

  DeleteMsgPort(replyPort);

  DeleteExtIO((struct IORequest *) inputRequest);

  return(RC_OK);
}

LONG
apiSystemTags(cmd, path, mhandle, apiMsg)

UBYTE             *cmd,*path;
struct MAPIClient *mhandle;
struct APIMessage *apiMsg;
{
  char args[MAX_LEN+1];
  char err[MAX_LEN+1], *pos;

  #ifdef DEBUG
     DbgPrintf("apiSystemTags(cmd=%s, path=%s, mhandle=%08x, apiMsg=%08x)\n", cmd, path, mhandle, apiMsg);
  #endif

  if (getOutput(mhandle)) {

      sprintf(args, "%08x %08x %08x\n", cmd, path, mhandle);

      if (!CreateNewProcTags(NP_Entry, exCliSystemTags, NP_Name, "exCliSystemTags", NP_CopyVars, FALSE, NP_Arguments, args, NP_Cli, TRUE, SYS_UserShell, TRUE, TAG_END)) {

          apiMsg->api_Error=API_ERROR_FAIL;

          pos=strchr(cmd, ' ');
          strncpy(err, cmd, pos-cmd);
          strcat(err, GetString(&li, MSG_ERREXE_REQ));

          apiMsg->api_CommandError=err;

          return(RC_WARN);
      }

  } else {

      apiMsg->api_Error=API_ERROR_FAIL;

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

      return(RC_WARN);
  }

  return(RC_OK);
}

struct Process *
findCommandName(mhandle, cmdname)

struct MAPIClient *mhandle;
char *cmdname;
{
  int i,n;
  struct Process *pr;
  struct CommandLineInterface *cli;
  char cmd[MAX_LEN+1], *s;
  BPTR seglist;
  struct Process *res=NULL;

  #ifdef DEBUG
     DbgPrintf("findCommandName(mhandle=%08x, cmdname=\"%s\")\n", mhandle, cmdname);
  #endif

  n=MaxCli();

  for (i=1; i <= n && !res; i++) {

       Forbid();

       if (pr=FindCliProc(i)) {

           cli=BADDR(pr->pr_CLI);

           if (seglist=cli->cli_Module) {

               s=BADDR(cli->cli_CommandName);
               CopyMem(s+1, cmd, (ULONG)s[0]);
               cmd[s[0]]='\0';

               if (!strcmp(cmd, cmdname)) {

                   if (pr->pr_WindowPtr == mhandle->api_Window)

                       res=pr;
               }
           }
       }

       Permit();
    }

   return(res);
}

LONG
ezRequest(mhandle, bodyfmt, gadfmt, argarray)

struct MAPIClient *mhandle;
char *bodyfmt;
char *gadfmt;
APTR argarray;
{
  struct rtReqInfo *reqinfo;
  LONG ret=FALSE;

  if (reqinfo=rtAllocRequestA(RT_REQINFO, NULL)) {

      ret=rtEZRequestTags(bodyfmt, gadfmt, reqinfo, argarray, RT_Window, mhandle->api_Window, TAG_DONE);

      rtFreeRequest(reqinfo);

      return(ret);
  }

  return(-1);
}

APTR
openReqFile(title, filename, path, pubscrname, matchpat)

char * title;
char * filename;
char * path;
char * pubscrname;
const char *matchpat;
{
  struct rtFileRequester *req;
  APTR ret;
  UBYTE freqname[108]={""};

  if ((req=(struct rtFileRequester *)rtAllocRequestA(RT_FILEREQ,NULL)) == NULL)

     return(FALSE);

  rtChangeReqAttr(req, RTFI_Dir, path, RTFI_MatchPat, matchpat, TAG_DONE);

  ret=rtFileRequest(req, freqname, title, RT_PubScrName, pubscrname, RTFI_OkText, GetString(&li, MSG_FILBUT_REQ), RTFI_Flags, FREQF_PATGAD, TAG_DONE);

  if (ret) {

     strcpy(filename, req->Dir);

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

        strcat(filename, "/");

     strcat(filename, freqname);

     rtFreeRequest(req);
  }

  return(ret);
}

ULONG
dupConHandler(struct MAPIClient *mhandle)
{
  struct MsgPort *old;
  char con[MAX_LEN+1];
  char infos[]={"TeXServer API © 1996 BURGHARD Eric\nWaiting for orders\n\n"};

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

  sprintf(con, "CON:0/%d/%d/90/TeXServer.%x/SCREEN%s/AUTO/CLOSE", mhandle->api_Screen->Height-90, mhandle->api_Screen->Width, mhandle, mhandle->api_GEDPSName);

  if (mhandle->api_ConIn=Open(con, MODE_NEWFILE)) {

      old=SetConsoleTask(((struct FileHandle *) BADDR(mhandle->api_ConIn))->fh_Type);

      mhandle->api_ConOut=Open("*", MODE_OLDFILE);

      SetConsoleTask(old);

      myWriteChars(infos, sizeof(infos), mhandle, NULL);

      return(RC_OK);

  }  else

      return(RC_ERROR);
}

LibCall LONG
exCliSystemTags(register __d0 long argc, register __a0 const char *argv)
{
  char *cmd=NULL, cmd2[7];
  char *path=NULL;
  struct MAPIClient *mhandle=NULL;
  BPTR oldin, oldout;
  LONG ret;

  sscanf(argv, "%08x %08x %08x", &cmd, &path, &mhandle);

  if (!cmd || !path || !mhandle)

      return(RETURN_FAIL);

  #ifdef DEBUG
     DbgPrintf("exSystemTags(cmd=\"%s\", path=\"%s\", mhandle=%08x)\n", cmd, path, mhandle);
  #endif

  strncpy(cmd2, cmd, 6);
  cmd2[6]='\0';

  oldin=SelectInput(mhandle->api_ConIn);
  oldout=SelectOutput(mhandle->api_ConOut);

  ret=SystemTags(cmd, NP_StackSize, 10000, NP_CurrentDir, Lock(path, SHARED_LOCK), NP_WindowPtr, mhandle->api_Window, NP_Input, Input(), NP_Output, Output(), TAG_DONE);

  if (!ret && !strcmp(cmd2, "VirTeX")) {

      if (FindPort("showdvi")) {

          struct MsgPort *replyPort;

          if (replyPort=CreateMsgPort()) {

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

             DeleteMsgPort(replyPort);
          }
      }
  }

  SelectInput(oldin);
  SelectOutput(oldout);

  return(ret);
}

LONG
myWriteChars(buffer, length, mhandle, apiMsg)

struct MAPIClient *mhandle;
char *buffer;
ULONG length;
struct APIMessage *apiMsg;
{
  LONG ret=0;
  BPTR oldin, oldout;

  if (getOutput(mhandle)) {

      oldin=SelectInput(mhandle->api_ConIn);
      oldout=SelectOutput(mhandle->api_ConOut);

      ret=Write(Output(), buffer, length);

      SelectInput(oldin);
      SelectOutput(oldout);

  }
  return(ret);
}
///
