#include "DLGRexxBase.h"

#include <rexx/errors.h>

#include <clib/rexxsyslib_protos.h>
#include <clib/utility_protos.h>

#include <pragmas/rexxsyslib_pragmas.h>
#include <pragmas/utility_pragmas.h>

#include <string.h>

#include "Protos.h"

char *TextRC = NULL;

/// Command Table ************************************************************
STATIC struct RexxCmd CommandTable[] =
{
   "ACTIVATEPORT",      1, 2, 0, Cmd_ActivatePort,
   "DEACTIVATEPORT",    1, 2, 0, Cmd_DeactivatePort,
   "FREEPORT",          1, 2, 0, Cmd_FreePort,
   "IMMEDLOCKPORT",     1, 5, 0, Cmd_ImmedLockPort,
   "LOCKPORT",          1, 5, 0, Cmd_LockPort,
   "TRANSFERPORTLOCK",  1, 6, 0, Cmd_TransferPortLock,
   "GETPORTINFO",       1, 1, 1, Cmd_GetPortInfo,
   "LISTPORTS",         0, 1, 1, Cmd_ListPorts,

   "LOCKAREA",          1, 5, 0, Cmd_LockArea,
   "FREEAREA",          1, 3, 0, Cmd_FreeArea,
   "BORROWAREA",        1, 5, 0, Cmd_BorrowArea,
   "ENTERAREA",         1, 2, 0, Cmd_EnterArea,
   "LEAVEAREA",         1, 2, 0, Cmd_LeaveArea,
   "GETAREAINFO",       1, 2, 1, Cmd_GetAreaInfo,

   NULL, NULL, NULL, NULL
};
//- **************************************************************************

#define SAME   (0)
#define OK     (0)
#define NOT    !

/****************************************************************************/

   /* RexxDispatch():
    *
    * This is the function dispatcher. For every ARexx script that has
    * added this library to its list of hosts to be searched the ARexx
    * resident process will pass each single command through here.
    * If we can handle one of the commands, we tell the resident process
    * by returning 0, indicating "no error, command was handled". If
    * the command is unknown to us, we *must* return error ERR10_001,
    * indicating "we do not know this command". In the latter case,
    * the resident process will pass the command on to the next host
    * in the list of hosts.
    */

LONG ASM
RexxDispatch(
   REG(a0) struct RexxMsg       *RexxMsg,
   REG(a1) STRPTR               *Result,
   REG(a6) struct DLGRexxBase   *DLGRexxBase)
{
   LONG Error = ERR10_001; /* Program not found. */
   LONG  NumArgs = 0;
   BOOL Found = FALSE;
   LONG i;

   NumArgs = (RexxMsg->rm_Action & 0xFF);

      /* Search the table for the command. */

   for(i = 0 ; NOT Found && CommandTable[i].Name != NULL ; i++)
   {
         /* Does this one match? */

      if(Stricmp(RexxMsg->rm_Args[0],CommandTable[i].Name) == SAME)
      {

         Found = TRUE;

         /* Do the number of arguments match? The number is passed in the lower eight bits
          * of the action field. Up to 15 arguments can be passed to your library. Each
          * argument represents a pointer to a * null-terminated string.
          */

         if( (NumArgs < CommandTable[i].MinArgs) || (NumArgs > CommandTable[i].MaxArgs))
         {
            Error = ERR10_017;   /* Wrong number of arguments. */
         }
         else
         {
            UBYTE String[20];
            LONG Number;

               /* Clear the error value. */

            Error = OK;

               /* Invoke the command. */

            Number = (*CommandTable[i].Cmd)(&RexxMsg->rm_Args[1], &Error, &NumArgs, DLGRexxBase);

               /* Did the command return without error? */

            if(Error == OK)
            {

               switch(CommandTable[i].Type)
               {
                  case 0:  /* Convert the number to a string. The library result has to be
                            * a standard ARexx string.
                            */

                           NumberToString(Number,String,DLGRexxBase);
                           (*Result) = CreateArgstring(String,strlen(String));
                           break;

                  case 1:  // We want to return text placed on global variable TextRC
                           (*Result) = CreateArgstring(TextRC,strlen(TextRC));
                           break;
               }



                  /* If the result string could not
                   * be created, flag this as an error.
                   */

               if((*Result) == NULL)
                  Error = ERR10_003;   /* No memory available. */
            }
         }
      }
   }

      /* Return the error if any. */

   return(Error);
}
