/*  File:  globals.h  */

#ifdef _WIN32
#include <windows.h>
#else
#include <pthread.h>
#endif /* _WIN32 */

#include "ar.h"
#include "util.h"

#ifdef MAIN
unsigned long                  gQuietMode = 0;
unsigned long                  gOutputSetting = 0;
unsigned long                  gOutputCount = 0;
char                           gResultDir[AR_MAX_FULL_FILENAME + 1] = "";
unsigned int                   gRandomNumberSeed;
unsigned int                   gRandomNumberValue;
OS_CRITICAL_SECTION            gRandomNumberCriticalSection;
OS_EVENT_OBJECT                gRandomNumberRequestEvent;
OS_EVENT_OBJECT                gRandomNumberReplyEvent;
OS_TLS_OBJECT                  gTLSKey;
#else
extern unsigned long           gQuietMode;
extern unsigned long           gOutputSetting;
extern unsigned long           gOutputCount;
extern char                    gResultDir[AR_MAX_FULL_FILENAME + 1];
extern unsigned int            gRandomNumberSeed;
extern unsigned int            gRandomNumberValue;
extern OS_CRITICAL_SECTION     gRandomNumberCriticalSection;
extern OS_EVENT_OBJECT         gRandomNumberRequestEvent;
extern OS_EVENT_OBJECT         gRandomNumberReplyEvent;
extern OS_TLS_OBJECT           gTLSKey;
#endif /* MAIN */

#define ARG_BUFFER_LEN         256

#define MAX_NESTED_INPUT_DEPTH 10
#define MAX_NESTED_LOOP_DEPTH  10

#define DRIVER_INPUT_BUFFER_LEN 1024

#define MAX_JOIN_ENTRY_IDS     5

typedef struct
{
   ARControlStruct  control;             /* control record */
   unsigned int     currentInputDepth;   /* nested input level */ 
   FILE            *inFile[MAX_NESTED_INPUT_DEPTH];/* files to read commands from */
   FILE            *outFile;             /* file to generate output to */
   FILE            *recordFile;          /* file to record commands in */
   FILE            *resultFile;          /* file to record results in */
   FILE            *loggingFile;         /* file to record logging in */
   char             buffer[DRIVER_INPUT_BUFFER_LEN];/* general use temp buffer */
   char             args[ARG_BUFFER_LEN];/* argument from the command line */
   unsigned int     primaryThread;       /* flag indicating if primary thread */
   char            *outFileName;         /* pointer to output file name */
                                         /* variables for saving GLEWF entry */
                                         /* ids - multiple for join forms    */
   AREntryIdType    firstGLEWFListId[MAX_JOIN_ENTRY_IDS];
   AREntryIdType    secondGLEWFListId[MAX_JOIN_ENTRY_IDS];
   AREntryIdType    lastGLEWFListId[MAX_JOIN_ENTRY_IDS];
                                         /* variables for saving GLE entry */
                                         /* ids - multiple for join forms  */
   AREntryIdType    firstGLEListId[MAX_JOIN_ENTRY_IDS];
   AREntryIdType    secondGLEListId[MAX_JOIN_ENTRY_IDS];
   AREntryIdType    lastGLEListId[MAX_JOIN_ENTRY_IDS];
                                         /* variable for CE entry id */
   char             createEntryId[AR_MAX_ENTRYID_SIZE + 1];
   ARNameType       firstSchemaListName; /* saved form name */
   char             currCommand[6];      /* command string */
   long             auxCount1;           /* auxilliary counter */
   long             auxCount2;           /* auxilliary counter */
   unsigned int     numHandles;          /* number of thread handles in array */
   unsigned int     maxHandles;          /* current maximum handles allowed */
   unsigned int     numFailedBeginLoop;  /* count of attempts over limit */
   int              currentLoopDepth;    /* nested loop level */
   unsigned int     numIterations[MAX_NESTED_LOOP_DEPTH];
   long             loopBeginFilePos[MAX_NESTED_LOOP_DEPTH];
#ifdef _WIN32
   HANDLE          *threadHandles;       /* thread handle array */
#else
   pthread_t       *threadHandles;       /* thread handle array */
#endif /* _WIN32 */
   OS_EVENT_OBJECT  launchWaitEvent;     /* event to notify parent thread */
   OS_EVENT_OBJECT  releaseWaitEvent;    /* event to notify child thread */
}  ThreadControlBlock;

typedef struct
{
   FILE            *inFile;     /* pointer to the file to read commands from */
   FILE            *outFile;    /* pointer to file to generate output to */
   char            *outFileName;/* pointer to optional output file name */
   char            *userName;   /* pointer to optional user name */
   char            *authString; /* pointer to optional authorization string */
   char            *password;   /* pointer to optional password */
   char            *locale;     /* pointer to optional locale */
   char            *timeZone;   /* pointer to optional time zone */
   char            *server;     /* pointer to optional server name */
   unsigned long    upperBound; /* upper bound of random thread start sleep */
   ARBoolean        waitFlag;   /* flag indicating if synchronization needed */
   OS_EVENT_OBJECT *launchWaitEventPtr;  /* event to notify parent thread */
   OS_EVENT_OBJECT *releaseWaitEventPtr; /* event to notify child thread */
}  ThreadStartInfo;
