 
#ifndef LIBRARIES_PROGARGS_H
#define LIBRARIES_PROGARGS_H 1
 
#ifndef EXEC_TYPES_H
#include <exec/types.h>
#endif

#ifndef UTILITY_TAGITEM_H
#include <utility/tagitem.h>
#endif

#ifndef WORKBENCH_STARTUP_H
#include <workbench/startup.h>
#endif

#ifndef WORKBENCH_WORKBENCH_H
#include <workbench/workbench.h>
#endif

#ifndef DOS_RDARGS_H
#include <dos/rdargs.h>
#endif

struct TagArgs {
    struct TagItem* ta_Arguments;       // argument tag list
};

/**
 ** This is where tag argument ID values should start.
 **/
 
#define TAG_ARGENTRY (TAG_USER+0x10000)

/**
 ** These are tags which control the behaviour of AddProgArgsA()
 ** and RemProgArgsA().  They affect all tags which sequentially
 ** follow them in the tag list.
 **/
 
#define TAG_ARGCONTROL (TAG_USER+0x8000)

#define PAC_RDArgsMode (TAG_ARGCONTROL+1)
     /* BOOL
      * Argument parameters are in ReadArgs() style.
      * Default: FALSE.
      */
#define PAC_CopyMode (TAG_ARGCONTROL+2)
     /* BOOL
      * Copy supplied arguments.
      * Default: FALSE.
      */

// Value which can be put into ti_Data when calling RemProgArgsA()
// and RemTagArgsA().

#define REMARG_IGNORE   (0)     // Don't remove this argument
#define REMARG_REMOVE   (1)     // Remove this argument

struct ArgEntry {
    Tag ae_Argument;                // Argument tag code, > TAG_ARGENTRY
    UBYTE* ae_Template;             // Arg template string, ie "FROM/K/M"
    UBYTE* ae_Description;          // Extended description of argument
    ULONG ae_Flags;                 // Entry codes, see below
    APTR ae_Default;                // Default val if AEFLAG_DEFAULT else NULL
    struct TagItem* ae_Ext;         // Extended info, ALWAYS SET TO NULL
};

#define AEFLAG_DEFAULT  (1<<0)      // A default value is supplied
#define AEFLAG_HEXNUM   (1<<1)      // Number should be written as hexadecimal

// This is not yet implemented.
#define AEFLAG_BINARY   (1<<2)      // String read/written as binary sequence;
                                    // not NULL-terminated and first ULONG is
                                    // the length of the data in bytes.

struct MultiArg {
    UBYTE* ma_String;               // Filename/etc for this entry
    BPTR ma_Directory;              // Lock on directory file is relative to
    struct TagItem* ma_Ext;         // reserved for future use
};

struct ProgArgs {
    struct TagItem* pa_Arguments;   // The returned arguments
};

/**
 ** These are tags which can be passed to both AllocProgArgsA() and
 ** ExecProgArgsA(), to control the reading and writing of arguments.
 ** These tags may occur multiple times, and each action executes
 ** the order in which the tags are found in the tag list.
 **/

// Base program argument tags -- global information. 
#define TAG_PROG_ARGS (TAG_USER+0x1000)

#define PA_CLIStartup (TAG_PROG_ARGS+1)
     /* UBYTE*
      * Supply the program's CLI arguments.
      */
#define PA_WBStartup (TAG_PROG_ARGS+2)
     /* struct WBStartup*
      * Supply the program's Workbench startup message.
      */

// Special directory values.
#define PADIR_PROGRAM   (0xFFFFFFFF)    // Program directory, PROGDIR:
#define PADIR_CURRENT   (0xFFFFFFFE)    // Process' current directory
#define PADIR_ENV       (0xFFFFFFFD)    // ENV:
#define PADIR_ENVARC    (0xFFFFFFFC)    // ENV: *and* ENVARC:
                                        //   ENV: is first updated, then
                                        //   copied to ENVARC:
#define PADIR_PREFS     (0xFFFFFFFB)    // PREFS:
#define PADIR_PRESETS   (0xFFFFFFFA)    // PREFS:Presets/
                                        //   The 'Presets' dir may be
                                        //   created, if needed.
#define PADIR_TEMP      (0xFFFFFFF9)    // T:

#define PA_SetDirectory (TAG_PROG_ARGS+3)
     /* BPTR (Lock)
      * Set directory to read/write files from.
      */
#define PA_EscapeChar   (TAG_PROG_ARGS+4)
     /* UBYTE
      * Set escape character for strings.
      */
#define PA_IgnoreError  (TAG_PROG_ARGS+5)
     /* BOOL
      * Set handling of error conditions.
      */
#define PA_CreateIcon   (TAG_PROG_ARGS+6)
     /* BOOL
      * Set creation of program icon if doesn't exit.
      */
#define PA_CreateDirs   (TAG_PROG_ARGS+7)
     /* BOOL
      * Set automatic creation of file directories.
      */
#define PA_AllComments  (TAG_PROG_ARGS+8)
     /* BOOL
      * Set writing of all arguments as comments.
      */
#define PA_ForceWrite   (TAG_PROG_ARGS+9)
     /* BOOL
      * Set writing of all arguments in the set.
      */
#define PA_TransHook    (TAG_PROG_ARGS+10)
     /* struct Hook*
      * Hook to localize strings.
      */
#define PA_TransObject  (TAG_PROG_ARGS+11)
     /* void*
      * Parameter to pass as 'object' to hook.
      */

#define STM_NULL    (0)
#define STM_STRING  (1)

struct PA_StrTransMsg {
    ULONG stm_Message;      // STM_STRING or STM_NULL
    ULONG stm_StringID;     // ID to translate
};

// Read program argument tags -- read in arguments from external source
#define TAG_READ_PROG_ARGS (TAG_USER+0x2000)

#define RPA_CmdInput (TAG_READ_PROG_ARGS+1)
     /* BOOL
      * Do ReadArgs() style parsing of command input.
      */
#define RPA_CmdLine (TAG_READ_PROG_ARGS+2)
     /* BOOL
      * Do ReadArgs() style parsing of command line.
      */
#define RPA_CmdString (TAG_READ_PROG_ARGS+3)
     /* UBYTE*
      * Do ReadArgs() style parsing of string.
      */
#define RPA_WBArguments (TAG_READ_PROG_ARGS+4)
     /* Tag
      * Extract arguments from program's Workbench startup message.
      */
#define RPA_ProgIcon (TAG_READ_PROG_ARGS+5)
     /* BOOL
      * Extract arguments from program's icon.
      */
#define RPA_DiskObjectName (TAG_READ_PROG_ARGS+6)
     /* BOOL
      * Extract arguments from an arbitrary DiskObject.
      */
#define RPA_TextFileName (TAG_READ_PROG_ARGS+7)
     /* BOOL
      * Extract arguments from a text file.
      */

// Write program argument tags -- write arguments to an external destination
#define TAG_WRITE_PROG_ARGS (TAG_USER+0x3000)

#define WPA_ProgIcon   (TAG_WRITE_PROG_ARGS+1)
     /* BOOL
      * Write tooltypes out to program icon.
      */
#define WPA_DiskObjectName   (TAG_WRITE_PROG_ARGS+2)
     /* UBYTE*
      * Name of file to write disk object to.
      */
#define WPA_TextFileName   (TAG_WRITE_PROG_ARGS+3)
     /* UBYTE*
      * Name of file to write arguments out to as text.
      */

/**
 ** The following is not yet implemented.
 **/

struct ProgArgTrans {
    APTR pat_UserData;              // For any use.
};
 
struct ProgArgMsg {
    UWORD pam_Version;              // Version code, currently 0.
    WORD pam_Command;               // Message command code, see below.

    Tag pam_Argument;               // Argument code tag.
    ULONG pam_Type;                 // Message parameter type, see below.
    
    struct ProgArgTrans* pam_Trans; // Your actual translator.
    struct ProgArgs* pam_ProgArgs;  // Who is sending this message.
    struct TagItem* pam_UserTags;   // Tag list supplied to Alloc/Put/Get().
    APTR pam_Pool;                  // Pool that allocations can be done in.

    APTR pam_Value;                 // Value sending/getting
    struct ArgEntry* ae_ArgEntry;   // Associated ArgEntry, MAY BE NULL.
    APTR pam_UserData;              // Whatever you want.  This value is
                                    // associated uniquely with this
                                    // pam_Argument.  It is primarily
                                    // intended for tracking memory which
                                    // you may need for constructing a
                                    // version of the argument being put
                                    // somewhere else.  Ie, if it is setting
                                    // a string gadget, you will need to
                                    // allocate the string and copy the
                                    // value into that rather than directly
                                    // setting it from pam_Value.
                                    // Always initialized to NULL.
};

// Commands, placed in pam_Command when message is sent.
#define PAMC_NULL       (0)     // Do nothing
#define PAMC_INITSELF   (1)     // Initialize self, sent during allocation
#define PAMC_TERMSELF   (2)     // Terminate self, sent during free
#define PAMC_PUTARG     (3)     // Giving you this argument value
#define PAMC_GETARG     (4)     // Requesting value of this argument
#define PAMC_FREEARG    (5)     // Free this value, prev ret from PAMC_GETARG

// Result code, place in pam_Command before returning.
#define PAMR_OKAY       (0)     // All is fine
#define PAMR_TERMINATE  (-1)    // Terminate translating of arguments

// Types, found in pam_Type
#define PAMT_UNKNOWN    (0)     // Unknown type
#define PAMT_BOOLEAN    (1)     // Value is a boolean, TRUE or FALSE
#define PAMT_INTEGER    (2)     // Value is a LONG
#define PAMT_STRING     (3)     // Value is a pointer to a NULL-term string
#define PAMT_MULTIARG   (4)     // Value is a pointer to a MultiArg array

#endif
