/*******************  help.c  ********************
 *                                               *
 *                                               *
 *  v1.19 written by Koessi                      *
 *                                               *
 *  05 Oct 94 : added "PRT/K"                    *
 *                                               *
 *  Source Copyright RBF Software                *
 *                                               *
 * use within PD releases encouraged.            *
 * Any alterations may not be released, however, *
 * you are requested to send your ideas on to us *
 *                                               *
 * Shareware/Commercial use requires a licence   *
 *                                               *
 *  this is help showing the usage of            *
 *  "hyper" from inside another program          *
 *                                               *
 *  Compile with DICE:                           *
 *  dcc help.c -ohelp -rr -2.0                   *
 *                                               *
 *************************************************/

#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <rexx/storage.h>

/* Prototypes */
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>
#include <clib/rexxsyslib_protos.h>

#define  MSG struct Message
#define RMSG struct RexxMsg
#define MSGP struct MsgPort
#define SIZE 32

extern void SendRxMsg(char *);
extern __stkargs void _main(short, char *);
extern int main(int, char **);

#define NUMARGS    13
#define ANSI_COL_2 "\x9B32m"
#define ANSI_RESET "\x9B0m"

const char version[]    = "$VER: "
                          "Help 1.19 ("__DATE__") © RBF Software";
const char exthelpstr[] = ANSI_COL_2
                          "\nUsage:\tHelp [FILENAME] [DOC chapter] [SCREEN publicscreen]\n"
                          "\t\t[PRT filename] [X n] [Y n] [WIDTH n] [HEIGHT n]\n"
                          "\t\t[GADS ON|OFF] [FONT name.font<n>] [SLEEP] [QUIT]\n"
                          ANSI_RESET
                          "\n\tcall Hyper's ARexx-port:\n"
                          "\tFILENAME\tshould be a hyper-text-file\n"
                          "\tDOC/K\t\trequest a special chapter\n"
                          "\tSCREEN/K\tmake Hyper appear on that screen\n"
                          "\tPRT/K\t\tsend print output to this (default \"prt:\")\n"
                          "\tX/N, Y/N\n"
                          "\tW=WIDTH/N\n"
                          "\tH=HEIGHT/N\tset position&size for the window\n"
                          "\tG=GADS/T\ttoggle gadgets ON/OFF (default OFF)\n"
                          "\tF=FONT/K\tuse this font to render text\n"
                          "\tonly if Hyper is already running:\n"
                          "\tS=SLEEP/S\tstart Hyper into the background\n"
                          "\tQ=QUIT/S\tend Hyper and free memory\n"
                          "\t\t\t";

const char template[]   = "FILENAME,DOC/K,SCREEN/K,PRT/K,X/N,Y/N,W=WIDTH/N,H=HEIGHT/N,"
                          "G=GADS/T,F=FONT/K,S=SLEEP/S,Q=QUIT/S";

const char portname[]   = "HYPER_RXPORT";
const char command[]    = "SYS:Utilities/hyper S";    /*  hardcoded path :-| */
const char error[]      = "\n\n"ANSI_COL_2"***ERROR"ANSI_RESET;

const void *argarray[NUMARGS] = {0};                  /*  holds argptrs   */

char *taskname = &version[6];

/*************************************************
 *                                               *
 *                                               *
 *    FUNCTION: _main                            *
 *                                               *
 *                                               *
 *    INPUT:    short len                        *
 *              char *arg                        *
 *                                               *
 *    OUTPUT:   __stkargs void                   *
 *                                               *
 *    NOTE:                                      *
 *                                               *
 *************************************************/


__stkargs void
_main(short len, char *arg)
{
  PutStr(ANSI_COL_2);
  PutStr(taskname);
  PutStr(ANSI_RESET"\n");
  int errorcode = ERROR_REQUIRED_ARG_MISSING;
  if (len > 1)          /*  args ? */
  {
    struct RDArgs *rdargs;
    if (rdargs = AllocVec(sizeof(struct RDArgs), MEMF_PUBLIC|MEMF_CLEAR))
    {
      rdargs->RDA_ExtHelp = exthelpstr;   /*  shown if 2 x ? */

      struct RDArgs *rda;
      if (rda = ReadArgs(template, argarray, rdargs))
      {
        long **argptr = argarray;
        for (BYTE i = 0; i < NUMARGS; ++i)
        {
          if (argptr && *argptr)
          {
            errorcode = RETURN_OK;
            break;
          }
          ++argptr;
        }
        if (errorcode == RETURN_OK)
        {
          MSGP *port;
          if (!(port = FindPort(portname)))
          {
            SystemTags(command, SYS_Asynch, TRUE,
                                SYS_Output, NULL,
                                SYS_Input,  NULL,
                                TAG_DONE);

            for (BYTE i = 10; i; --i)
            {
              Delay(20);
              if (port = FindPort(portname))
                break;
            }
          }
          PutStr("\n");
          if (port)
            SendRxMsg(arg);
          else
            errorcode = ERROR_OBJECT_NOT_FOUND;
        }
        FreeArgs(rda);
      }
      else
        errorcode = IoErr();

      FreeVec(rdargs);
    }
    else
      errorcode = ERROR_NO_FREE_STORE;
  }
  if (errorcode)
    PrintFault(errorcode, error);
}

/*************************************************
 *                                               *
 *                                               *
 *    FUNCTION: SendRxMsg                        *
 *                                               *
 *                                               *
 *    INPUT:    char *msgtxt                     *
 *                                               *
 *    OUTPUT:   void                             *
 *                                               *
 *    NOTE:     like cmdline                     *
 *                                               *
 *************************************************/


void
SendRxMsg(char *msgtxt)
{
  MSGP *reply_port;
  if (reply_port = CreateMsgPort())
  {
    void *rx_msg;       /*  casted to parts of a RexxMsg struct */
    if (rx_msg = AllocVec(sizeof(RMSG), MEMF_PUBLIC|MEMF_CLEAR))
    {
      ((struct Node *)rx_msg)->ln_Type      = NT_MESSAGE;
      ((MSG         *)rx_msg)->mn_ReplyPort = reply_port;
      ((MSG         *)rx_msg)->mn_Length    = sizeof(RMSG);
      ((RMSG        *)rx_msg)->rm_Args[0]   = msgtxt;

      Forbid();
      MSGP *rx_port;
      if (rx_port = (MSGP *)FindPort(portname))
      {
        PutMsg(rx_port, (MSG *)rx_msg);
        Permit();
        WaitPort(reply_port);
        ReplyMsg(GetMsg(reply_port));
      }
      else
        Permit();

      FreeVec(rx_msg);
    }
    DeleteMsgPort(reply_port);
  }
}