/****************************************************************** 
 *
 * structs.h --
 *
 *     Data structures and type definitions shared by classes.
 *
 *
 * Author : Dan Gunter
 * Created: 7 June 1998
 *
 * Modification history
 * --------------------
 *
 ****************************************************************** 
 */
#include <pthread.h>
#include "const.h"

#ifndef NLV_STRUCTS_INCLUDED
#define NLV_STRUCTS_INCLUDED


/*========== MACROS ===================================================*/

/* 
 * Printing errors
 */

#define POLITE_ABORT "Due to this error, NLV must quit immediately.\n"
#define NLV_FATAL(x) fprintf(stderr,"NLV: Error at file %s:%d\n.%s",__FILE__,__LINE__,POLITE_ABORT);
#define NLV_FATAL_S(x) fprintf(stderr,"NLV: Error at file %s:%d\nTermination message: '%s'\n%s",__FILE__,__LINE__,x,POLITE_ABORT);
#define NLV_FATAL_S2(x,y) fprintf(stderr,"NLV: Error at file %s:%d\n%s: %s\n%s",__FILE__,__LINE__,(x),(y),POLITE_ABORT);
#define NLV_FATAL_I(x) fprintf(stderr,"NLV: Error at file %s:%d\nTermination message: %d\n%s",__FILE__,__LINE__,x,POLITE_ABORT);
#define NLV_FATAL_F(x) fprintf(stderr,"NLV: Error at file %s:%d\nTermination message: %g\n%s",__FILE__,__LINE__,x,POLITE_ABORT);

/*
 * Tcl_Eval with minimal error-handling
 */

#define NLV_SAFE_EVAL(terp,buf) if (TCL_OK != Tcl_Eval((terp),buf)) { \
  NLV_FATAL_S((terp)->result); return -1; }
#define NLV_SAFE_GLOBAL_EVAL(terp,buf) if (TCL_OK != Tcl_GlobalEval((terp),buf)) { \
  NLV_FATAL_S((terp)->result); return -1; }

/*
 * Debugging values
 */

#define NLV_WAIT(d,msg,buf) if ( d ){ printf("%s",msg); fflush(stdout); fscanf(stdin,"%s",&buf[0]);\
fflush(stdin);}
#define NLV_DBG(d,msg) if (d) printf(msg);
 
/*========= TYPEDEFS ================================================*/

typedef char *LogLine;
typedef double GraphTime;
typedef int (*Nlv_filterFn)( void*, void* );

/*========= STRUCTS ================================================*/

struct Nlv_fi;
struct Nlv_ix;
struct Nlv_pa;
struct Nlv_cl;
struct Nlv_gr;
struct Nlv_an;
struct Nlv_ky;
struct Nlv_cc;
typedef struct Nlv_State {
  struct Nlv_fi *fi;
  struct Nlv_ix *ix;
  struct Nlv_pa *pa;
  struct Nlv_cl *cl;
  struct Nlv_gr *gr;
  struct Nlv_an *an;
  struct Nlv_ky *ky;
  int    firstLine;
  int    keyErrs;
  pthread_t ixTid;        /* Indexing thread */
  char   *globalCalcString; /* Pending calculation, so yylex() can get at it */
  char   *globalCalcPos;    /* Remember where we are in string */
} Nlv_State;

typedef double Nlv_CalcResult;

typedef struct Nlv_Fields {
  LogLine raw;
  int    *names;
  int    *vals;
  int     num;
} Nlv_Fields;
#define FIELD_NAME(f,i) ((char*)&(f->raw[f->names[i]]))
#define FIELD_VAL(f,i)  ((char*)&(f->raw[f->vals [i]]))
#define FREE_FIELDS(x) do {\
if (x) {free(x->freeme);  \
        free(x->vals);    \
        free(x->names);   \
        free(x); x=NULL;} \
} \
while(0)
#define CLEAR_FIELDS(x) do {\
if (x) {free(x->vals);    \
        free(x->names);   \
        memset(x,0,sizeof(struct Nlv_Fields));}\
} while(0)

typedef struct Nlv_GData {
  int    clIndex;
  int    event;
  int    eventSet;
  float  eventVal;
  double time;
  int    graphType;
  long   filepos;
  int    refct;
} Nlv_GData;

#define FREE_GDATA(x) do {if (--((x)->refct) == 0) free(x);} while(0);
typedef struct Nlv_LData {
  double times[ NLV_MAX_POINTS ];
} Nlv_LData;

typedef struct Nlv_Bounds {
  double x[2], y[2];
} Nlv_Bounds;

typedef struct Nlv_CalcParam {
  char           *name; /* Name of calculation */
  unsigned char   show; /* 1=Show value, 0=Don't show */
  int             precision; /* digits of accuracy to display */
} Nlv_CalcParam;

typedef struct Nlv_CalcVar {
  int    ksIndex; /* keyset index */
  int    kIndex;  /* key index */
  char * fName;   /* field name */
  double value;   /* last retrieved value */
  int    mask;    /* tbd */
} Nlv_CalcVar;

typedef struct Nlv_KeySet {
  char          *name;
  int            index;
  int            numKeys;
  char         **idFields;     /* Id fields */
  int            numIdFields;
  char         **hostFields;   /* Group id fields */
  int            numHostFields;
  char         **annFields;    /* Annotation fields */
  int            numAnnFields;
  char          *valField;
  double         valMin, valMax;
  int            gtype;
  unsigned int   visible;
  Nlv_CalcParam *calcp;     /* Calculation parameters      */
  int            numCalcp;  /* # of calculation parameters */
  struct Nlv_cc *userCalcs; /* User calculations */
  int            numUcalc;  /* # of user calculations */
  int            timeOrdered; /* Time-ordered mode on or off */
  int            rotateClients; /* Rotate clients mode on or off */
  int            autoScaleMin; /* Auto rescale if below minimum value? */
  int            autoScaleMax; /* Auto rescale if above maximum value? */
} Nlv_KeySet;

typedef struct Nlv_Key {
  char        *name;
  int          index;
  Nlv_KeySet  *ks;
  unsigned int visible;
} Nlv_Key;
#define MAKE_BOGUS_KEY(x) do { (x)=(Nlv_Key*)malloc(sizeof(Nlv_Key)); \
(x)->name = ""; (x)->index = -1; (x)->ks = NULL; (x)->visible = 1; \
} while(0)

typedef struct Nlv_Client {
  int      clIndex;
  Nlv_Key *keyPtr;
  char    *name;
  char    *host;
  char    *hostName;
} Nlv_Client;
#define FREE_CLIENT(x) do {if ((x)->name) free ((x)->name); free(x);} while(0);

typedef struct ixThreadArgs {
  struct Nlv_ix  * obj;
} Nlv_ixArgs;

#endif
