#ifndef DPUSER_H
#define DPUSER_H

#ifdef WIN
#pragma warning (disable: 4786) // disable warning for STL maps
#endif /* WIN */

#include <map>

#include "dpstring.h"

class dpStringList;
class dpuserTypeList;
class dpComplex;
class Fits;

#define DP_VERSION "3.3"
#define DPUSERVERSION "DPUSER - The Next Generation "
#define DPUSERVERSION2 " ____  ____  _   _ ____  _____ ____  \n|  _ \\|  _ \\| | | / ___|| ____|  _ \\ \n| | | | |_) | | | \\___ \\|  _| | |_) |\n| |_| |  __/| |_| |___) | |___|  _ < \n|____/|_|    \\___/|____/|_____|_| \\_\\ - The Next Generation "

// BEGIN PARSE FOR DPUSER2C

typedef enum { typeUnknown = 0, typeCon = 0x01, typeId = 0x02, typeOpr = 0x04,
typeDbl = 0x08, typeFnc = 0x10, typeStr = 0x20, typeCom = 0x40,
typeFits = 0x80, typeFitsFile = 0x100, typeRng = 0x200, typePgplot = 0x400,
typeStrarr = 0x800, typeDpArr = 0x1000 } nodeEnum;

typedef struct {
	nodeEnum type;
	long lvalue;
	double dvalue;
	dpComplex *cvalue;
	dpString *svalue;
	Fits *fvalue;
    dpString *ffvalue;
    dpStringList *arrvalue;
    dpuserTypeList *dparrvalue;
//    dpString *name;
} conValue;

// END PARSE FOR DPUSER2C

/* constants */
typedef struct {
    nodeEnum type;              /* type of node */
    conValue value;
} conNodeType;

/* identifiers */
typedef struct {
    nodeEnum type;              /* type of node */
    int i;                      /* subscript to ident array */
    union nodeTypeTag *range;   /* range for dereferencing Fits Lists */
} idNodeType;

/* operators */
typedef struct {
    nodeEnum type;              /* type of node */
    int oper;                   /* operator */
    int nops;                   /* number of operands */
    union nodeTypeTag *op[1];   /* operands (expandable) */
} oprNodeType;

/* functions */
typedef struct {
    nodeEnum type;              /* type of node */
    int func;                   /* function */
    int nops;                   /* number of operands */
	int options;                /* optional parameters */
    union nodeTypeTag *op[1];   /* operands (expandable) */
} fncNodeType;

/* pgplot procedures */
typedef struct {
    nodeEnum type;              /* type of node */
    int proc;                   /* number of routine */
    int nops;                   /* number of operands */
	int options;                /* optional parameters */
    union nodeTypeTag *op[1];   /* operands (expandable) */
} pgplotNodeType;

/* functions */
typedef struct {
    nodeEnum type;              /* type of node */
    int func;                   /* function */
    int nops;                   /* number of operands */
    union nodeTypeTag *op[1];   /* operands (expandable) */
} rngNodeType;

/* string arrays */
typedef struct {
    nodeEnum type;              /* type of node */
    int func;                   /* function */
    int nops;                   /* number of operands */
    union nodeTypeTag *op[1];   /* operands (expandable) */
} strarrNodeType;

typedef union nodeTypeTag {
    nodeEnum type;              /* type of node */
    conNodeType con;            /* constants */
    idNodeType id;              /* identifiers */
    oprNodeType opr;            /* operators */
	fncNodeType fnc;            /* functions */
	rngNodeType rng;            /* ranges */
	strarrNodeType strarr;      /* string arrays */
	pgplotNodeType pgplot;      /* pgplot routines */
} nodeType;

extern conValue *variables;
extern int nvariables;
extern dpStringList svariables;
extern int npgwords;
extern int nfncpro;
extern int looplock;
int keyWord(char *s);
conValue ex(nodeType *p);
void dpoutline(const char *);
void dpoutput(const char *);
void checkQFitsViewDisplay(int id);
int isStringAVariable(const char *);

#endif /* DPUSER_H */
