#ifndef LIBRARIES_AMARQUEE_H
#define LIBRARIES_AMARQUEE_H

#ifndef EXEC_PORTS_H
#include <exec/ports.h>
#endif
#ifndef EXEC_SEMAPHORES_H
#include <exec/semaphores.h>
#endif

/* This library contains definitions and structures necessary to use amarquee.library. */

/* Different error types that can be returned to the client in QMessages */
#define QERROR_NO_ERROR       0 /* Everything is okay */
#define QERROR_UNKNOWN       -1 /* Don't know what the error was. */
#define QERROR_MALFORMED_KEY -2 /* Keystring could not be parsed or "dir" does not exist */
#define QERROR_NO_SERVER_MEM -3 /* Server did not have enough mem available to complete request */
#define QERROR_NO_CONNECTION -4 /* The connection to the server went south */
#define QERROR_UNPRIVILEGED  -5 /* You're not allowed to do that! */
#define QERROR_UNIMPLEMENTED -6 /* Feature you requested does not exist yet */
#define QERROR_NO_CLIENT_MEM -7 /* Your computer didn't have enough memory available to complete an action */
#define QERROR_SYS_MESSAGE   -8 /* This message is a "wall" text message from a server admin */
#define QERROR_SEND_DONE     -9 /* This message is a "send done" notification from your client TCP thread (new for v47) */

/* These error types may be returned by QFreeSession() or set to the error code
variable (set with the QSESSION_ERRORCODEPTR tag), after a QSession
allocation attempt fails. */
#define QERROR_NO_TCP_STACK    -20 /* TCP stack wasn't running */
#define QERROR_HOSTNAME_LOOKUP -21 /* Hostname lookup of server failed */
#define QERROR_ABORTED         -22 /* TCP thread got a control-C */
#define QERROR_NO_SERVER       -23 /* No AMarquee server at requested host/port */
#define QERROR_NO_INETD        -24 /* The program wasn't launched by inetd */
#define QERROR_ACCESS_DENIED   -25 /* The server wouldn't accept our connection */
#define QERROR_NO_MEMORY       -26 /* The client is out of memory */
#define QERROR_NO_TCPSERVER    -27 /* No server at requested host/port */

/* Flags to use with QGo() */
#define QGOF_SYNC   (1L<<0)     /* Request notification via sync packet when all has settled on the server side */
#define QGOF_NOTIFY (1L<<1)     /* Request notification via QERROR_SEND_DONE message when the TCP thread has finished sending this transaction (new for v47) */

/* Flags representing special privileges; used with QRequestPrivileges(), etc */
#define QPRIV_KILLCLIENTS        (1L<<0) /* license to kill! */
#define QPRIV_ADMIN              (1L<<1) /* Ability to set env vars, etc, on the server */
#define QPRIV_GETSYSMESSAGES     (1L<<2) /* Ability to receive special sysadmin messages */
#define QPRIV_SENDSYSMESSAGES    (1L<<3) /* Ability to send special sysadmin messages */  
#define QPRIV_ALL                ( 0x0F) /* all possible QPRIV_* bits */

struct QSession
{
  struct MsgPort * qMsgPort;  /* Wait() on this for QMessages! */

  /********************************************************************/
  /* Invisible, private info is here... don't trust sizeof(QSession)! */
  /********************************************************************/
};

/* All events from AMarquee come in this package! */
struct QMessage 
{
  struct Message qm_Msg;/* Don't directly use the contents of qm_Msg! */
  LONG    qm_ID;        /* Message ID # of transaction related to this opCode, or -1 if no ID is applicable. */
  int     qm_Status;    /* One of the QERROR_* codes defined in AMarquee headers. */
  char  * qm_Path;      /* Pathname of a node, or NULL if not applicable. */
  void  * qm_Data;      /* Pointer to beginning of data buffer, or NULL if not applicable. */
  ULONG   qm_DataLen;   /* Length of qm_Data buffer, or 0 if not applicable. */
  ULONG   qm_ActualLen; /* Length of the data buffer stored on the AMarquee server. */
  ULONG   qm_ErrorLine; /* Line # of the server source code that generated the error.  Useful for debugging. */
  void  * qm_Private;   /* Private info used by FreeQMessage() */
  void  * qm_Private2;  /* Added for v48; more private info used by FreeQMessage() */
  struct QSession *qm_Session; /* Added for v50. The session this message comes from. Necessary with shared msgports  */
};

struct QRunInfo
{
  LONG qr_Allowed; /* The theoretical maximum number of bytes your server may allocate. */
  LONG qr_Alloced; /* The number of bytes currently allocated by your server. */
  LONG qr_Avail;   /* The number of bytes that may actually be allocated by your server. */
  ULONG qr_CurrentPrivs;  /* Bit-chord of QPRIV_* bits, showing what special privs you have. */
  ULONG qr_PossiblePrivs; /* Bit-chord of QPRIV_* bits, showing what special privs you could get if you asked. */
};

struct QSharedMessagePort {
  struct SignalSemaphore qs_private; /* Used internally */
  struct MsgPort *qs_mp; /* the message port to listen on */
};

/* the QRAWSESSION_PROTOCOLSTOPHOOK Hook function receive a pointer to the Hook in A0, the QSession
pointer in A2 and a pointer to a QProtocolStopMarkerMessage in A1. Return the length of the buffer
to send to the client. Return a length of 0 if not enough data is present. With this function
it's easy to make sure that no structs or other datatypes get stripped. */
struct QProtocolStopMarkerMessage {
    STRPTR buffer; 
    ULONG length;
    ULONG userdata;
    LONG id;
};

/* Tags to use with QNewSocketSession(Async) */
#define QRAWSESSION_MAXBUFFERSIZE   0xa0000001 /* (ULONG maxBufSize) The maximum buffer size to use (same as QSetMaxRawBufSize()) */
#define QRAWSESSION_PROTOCOLSTOPHOOK 0xa0000002 /* (struct Hook *stopmarkerfunc) A hook with the function which sets the stop marker for a block of data */
#define QRAWSESSION_RECEIVE_EXCEEDING_DATA 0xa0000003 /* (BOOL b) default TRUE. Shall the last data before the connection is broken be sent to the client even though the PROTOCOLSTOPHOOK hook specify it shouldn't ?*/
#define QRAWSESSION_PROTOCOLSTOPHOOK_USERDATA 0xa0000004 /* (ULONG u) The initial value of the userdata field in struct QProtocolStopMarkerMessage */

/* Tags to use with QNew*Session(Async) and QNewSocket*Session(Async) */
#define QSESSION_ERRORCODEPTR       0xb0000001 /* (LONG *errorCode) A pointer to the variable that will hold the error code */
#define QSESSION_SHAREDMSGPORT      0xb0000002 /* (struct QSharedMessagePort *mp) A shared message port created with QCreateSharedMessagePort() */

#endif /* LIBRARIES_AMARQUEE_H */
