#ifndef DPUSER_UTILS_H
#define DPUSER_UTILS_H

/*
 * Project: dpuser data reduction package
 * File:    dpuser_utils.h
 * Author:  Thomas Ott
 * History: June 14, 2001: file created
 *
 * Purpose: Utility functions (declarations)
 */

#ifdef DPQT
#include "events.h"
#else
void dpProgress(const int, const char *);
#endif // DPQT
int dp_output(const char *, ...);
int dp_output_string(const char *, const char *);
int dp_debug(const char *, ...);

// XPA definitions
#include <xpa.h>
extern XPA xpa;
#define NXPA 10
extern char* xpaServer;
int ds9_running();
int ds9_frame_loaded();

#ifdef NOXPA
int XPAGet(XPA xpa, char *xtemplate, char *paramlist, char *mode,
		   char **bufs, int *lens, char **names, char **errs, int n);

int XPASet(XPA xpa, char *xtemplate, char *paramlist, char *mode,
		   char *buf, int len, char **names, char **errs, int n);

int XPANSLookup(XPA xpa, char *tname, char *ttype, char ***xclasses,
				char ***names, char ***methods, char ***infs);

void XPAClose(XPA xpa);

XPA XPAOpen(char *mode);
#endif

#include "dpuser.h"
class Fits;
class dpString;
class dpStringList;

#include <gsl/gsl_rng.h>
#include "functions.h"
extern gsl_rng *gsl_rng_r;  // global generator
extern void** protectedpntrs;

extern int ScriptInterrupt;
extern int npg;
extern int nunderscores;
extern int nprotected;
extern int silence;
extern int dpdebuglevel;
extern int qftracelevel;
extern int nglobals;

extern dpStringList userpronames, userprovars;
extern dpStringList userfncnames, userfncvars;
extern dpStringList script;

extern std::vector<FunctionDeclaration> funcs;
extern std::vector<FunctionDeclaration> procs;

int read_inp(char *res);

void createGlobalVariables();
int funcWord(char *s);
int pgWord(char *s);

//#ifndef NO_READLINE
#ifdef __cplusplus
extern "C" {
#endif
char *readline(char *);
void add_history(char *);
extern FILE *rl_instream;
#ifdef __cplusplus
}
#endif
//#endif // !NO_READLINE

// Variables that hold allocated strings
extern long nListOfOStrings;
extern dpString **listOfOStrings;

// misc. utility routines
int freeBufferNumber(void);
dpString freeBufferName(void);

// functions to add and delete strings from memory
dpString *CreateString(void);
dpString *CreateString(const dpString &);
dpString *CreateString(const double);
dpString *CreateString(const long);
dpString *CreateString(const char *);
dpString *CreateString(const dpComplex &);
void DeleteString(dpString *);


// Variables that hold allocated string arrays
extern long nListOfdpStringArrays;
extern dpStringList **listOfdpStringArrays;

// functions to add and delete string arrays from memory
dpStringList *CreateStringArray(void);
dpStringList *CreateStringArray(const dpint64 &);
dpStringList *CreateStringArray(const dpStringList &);
void DeleteStringArray(dpStringList *);

// Variables that hold allocated complex numbers
extern long nListOfOComplex;
extern dpComplex **listOfOComplex;

extern long idum;

// functions to add and delete complex numbers from memory
dpComplex *CreateComplex(double r=0.0, double i=0.0);
dpComplex *CreateComplex(const dpComplex &);
void DeleteComplex(dpComplex *);

// Variables that hold allocated FITS objects
extern long nListOfFits;
extern Fits **listOfFits;

// functions to add and delete FITS objects from memory
Fits *CreateFits(void);
Fits *CreateFits(int, int, int, int);
void DeleteFits(Fits *);

// Variables that hold allocated dpuserTypeLists
extern long nListOfDpLists;
extern dpuserTypeList **listOfDpLists;

// functions to add and delete FITS list objects from memory
dpuserTypeList *CreateDpList(void);
dpuserTypeList *CreateDpList(const dpuserTypeList &);
void DeleteDpList(dpuserTypeList *);

const dpString &FormatComplexQString(const dpComplex & z);
const dpString &FormatComplexQString2(const dpComplex & z);

bool createStringIndex(Fits &result, const dpString &string, bool reverse);
bool createStringArrayIndex(Fits &result, const dpStringList &stringarray,
                            bool reverse);
bool reindexString(dpString &string, const Fits &indices);
bool reindexStringArray(dpStringList &stringarray, const Fits &indices);
dpuserType modulo(const dpuserType &arg1, const dpuserType &arg2);
bool mosaic(Fits &result, dpStringList files, float *xshift, float *yshift,
            float *scale = NULL);
bool CubeAverage(Fits &result, const dpStringList & files);
bool CubeMerge(const char *outname, dpStringList &innames);
bool qssa(Fits &result, dpStringList &fnames, int x, int y, int method,
          Fits *sky, Fits *flat, Fits *dpl, Fits *mask, int resizing);

int isVariable(void *pntr);
void addToListOfFits(Fits *pntr);
void addToListOfdpStringArrays(dpStringList *pntr);
void deleteFromListOfFits(Fits *pntr);
void deleteFromListOfDpLists(dpuserTypeList *pntr);
void deleteFromListOfdpStringArrays(dpStringList *pntr);

#endif // DPUSER_UTILS_H
