# include "data.h"
# include "basic.h"
# include "astro.h"

# ifndef DVOSHELL_H
# define DVOSHELL_H

typedef enum {
  DB_STACK_NONE  = 0,
  DB_STACK_INT   = 0x01,
  DB_STACK_FIELD = 0x02,
  DB_STACK_TEMP  = 0x04,
  DB_STACK_VALUE = 0x08,
  DB_STACK_CLOSE_PAR = 0x10,
  DB_STACK_OPEN_PAR,
  DB_STACK_LOGIC,
  DB_STACK_COMPARE,
  DB_STACK_BITWISE,
  DB_STACK_SUM,
  DB_STACK_MULTIPLY,
  DB_STACK_POWER,
  DB_STACK_UNARY,
} dbStackTypes;

/* magnitude types */
enum {MAG_NONE, 
      MAG_INST, 
      MAG_CAT, 
      MAG_SYS, 
      MAG_REL, 
      MAG_CAL, 
      MAG_AVE, 
      MAG_REF, 
      MAG_ERR, 
      MAG_PHOT_FLAGS, 
      MAG_CHISQ,
      MAG_NCODE,
      MAG_NPHOT,
};

/* measure fields */
enum {MEAS_ZERO, 
      MEAS_GLON, 
      MEAS_GLAT, 
      MEAS_GLON_AVE, 
      MEAS_GLAT_AVE,
      MEAS_ELON, 
      MEAS_ELAT, 
      MEAS_ELON_AVE, 
      MEAS_ELAT_AVE,
      MEAS_RA, 
      MEAS_DEC, 
      MEAS_RA_AVE, 
      MEAS_DEC_AVE,
      MEAS_RA_AVE_ERR, 
      MEAS_DEC_AVE_ERR, 
      MEAS_U_RA, 
      MEAS_U_DEC, 
      MEAS_U_RA_ERR, 
      MEAS_U_DEC_ERR, 
      MEAS_PAR, 
      MEAS_PAR_ERR, 
      MEAS_RA_OFFSET, 
      MEAS_DEC_OFFSET, 
      MEAS_RA_FIT_OFFSET, 
      MEAS_DEC_FIT_OFFSET, 
      MEAS_RA_OFFSET_ERR, 
      MEAS_DEC_OFFSET_ERR, 
      MEAS_XP, 
      MEAS_NMEAS, 
      MEAS_NMISS, 
      MEAS_OBJFLAGS, 
      MEAS_MAG, 
      MEAS_MINST, 
      MEAS_MCAT, 
      MEAS_MSYS, 
      MEAS_MREL, 
      MEAS_MCAL, 
      MEAS_EXPTIME, 
      MEAS_AIRMASS, 
      MEAS_ALT, 
      MEAS_AZ, 
      MEAS_PHOTCODE, 
      MEAS_TIME, 
      MEAS_FWHM, 
      MEAS_FWHM_MAJ, 
      MEAS_FWHM_MIN, 
      MEAS_THETA, 
      MEAS_DOPHOT, 
      MEAS_DB_FLAGS, 
      MEAS_PHOT_FLAGS, 
      MEAS_XCCD, 
      MEAS_YCCD, 
      MEAS_XCCD_ERR, 
      MEAS_YCCD_ERR, 
      MEAS_XMOSAIC, 
      MEAS_YMOSAIC, 
      MEAS_SKY, 
      MEAS_dSKY, 
      MEAS_DET_ID, 
      MEAS_OBJ_ID, 
      MEAS_CAT_ID, 
      MEAS_IMAGE_ID, 
      MEAS_PSF_QF, 
      MEAS_PSF_CHISQ, 
      MEAS_CR_NSIGMA, 
      MEAS_EXT_NSIGMA, 
};

/* average fields */
enum {AVE_ZERO, 
      AVE_RA, 
      AVE_DEC, 
      AVE_RA_ERR, 
      AVE_DEC_ERR, 
      AVE_GLON, 
      AVE_GLAT, 
      AVE_ELON, 
      AVE_ELAT, 
      AVE_U_RA, 
      AVE_U_DEC, 
      AVE_U_RA_ERR, 
      AVE_U_DEC_ERR, 
      AVE_PAR, 
      AVE_PAR_ERR, 
      AVE_Xp, 
      AVE_NMEAS, 
      AVE_NMISS, 
      AVE_NPHOT, 
      AVE_NCODE, 
      AVE_MAG, 
      AVE_dMAG, 
      AVE_Xm, 
      AVE_FLAG, 
      AVE_TYPE, 
      AVE_TYPEFRAC,
      AVE_OBJID,
      AVE_CATID
};

enum {IMAGE_ZERO, 
      IMAGE_RA, 
      IMAGE_DEC, 
      IMAGE_GLON, 
      IMAGE_GLAT, 
      IMAGE_ELON, 
      IMAGE_ELAT, 
      IMAGE_XM, 
      IMAGE_AIRMASS, 
      IMAGE_MCAL, 
      IMAGE_dMCAL, 
      IMAGE_PHOTCODE, 
      IMAGE_TIME, 
      IMAGE_FWHM, 
      IMAGE_EXPTIME, 
      IMAGE_NSTAR, 
      IMAGE_NCAL, 
      IMAGE_SKY, 
      IMAGE_FLAG, 
      IMAGE_CCDNUM, 
      IMAGE_NX_PIX, 
      IMAGE_NY_PIX, 
      IMAGE_THETA, 
      IMAGE_SKEW, 
      IMAGE_SCALE, 
      IMAGE_DSCALE, 
      IMAGE_APRESID,
      IMAGE_DAPRESID,
      IMAGE_SIDTIME,
      IMAGE_LATITUDE,
      IMAGE_DET_LIMIT,
      IMAGE_SAT_LIMIT,
      IMAGE_CERROR,
      IMAGE_FWHM_MAJ,
      IMAGE_FWHM_MIN,
      IMAGE_TRATE,
      IMAGE_IMAGE_ID,
      IMAGE_EXTERN_ID,
      IMAGE_SOURCE_ID,
      IMAGE_X_LL_CHIP,
      IMAGE_X_LR_CHIP,
      IMAGE_X_UL_CHIP,
      IMAGE_X_UR_CHIP,
      IMAGE_Y_LL_CHIP,
      IMAGE_Y_LR_CHIP,
      IMAGE_Y_UL_CHIP,
      IMAGE_Y_UR_CHIP,
      IMAGE_X_LL_FP,
      IMAGE_X_LR_FP,
      IMAGE_X_UL_FP,
      IMAGE_X_UR_FP,
      IMAGE_Y_LL_FP,
      IMAGE_Y_LR_FP,
      IMAGE_Y_UL_FP,
      IMAGE_Y_UR_FP,
};


enum {DVO_TABLE_AVERAGE, DVO_TABLE_MEASURE, DVO_TABLE_IMAGE};
enum {DVO_DB_CMDLINE_ERROR, DVO_DB_CMDLINE_IS_END, DVO_DB_CMDLINE_IS_WHERE, DVO_DB_CMDLINE_IS_MATCH}; 

// options for selecting the ra,dec limits of the db selections
typedef struct {
  char *name;
  char *list;
  int useDisplay;
  int useSkyregion;
} SkyRegionSelection;

// a single db field 
typedef struct {
  char *name;
  int extract;
  int table;
  int ID;
  int magMode;
  char type;
  PhotCode *photcode;
} dbField;

// db boolean operations
typedef struct {
  char   *name;
  char    type;
  int     field;
  opihi_flt FltValue;
  opihi_int IntValue;
} dbStack;

typedef struct {
  opihi_flt Flt;
  opihi_int Int;
} dbValue;

typedef struct {
  char name[64];
  double RA0, RA1, DEC0, DEC1;
} RegionFile;

typedef struct {
  double X;
  double Y;
  double R;
  double D;
  double M, dM;
  char   dophot;
  double sky;
  double fx, fy, df;
  double Mgal, Map;
  int found;
  short int code;
  e_time t;
} CMPstars;

/*** dvo prototypes ***/
int           DetermineTypeCode     PROTO((Average *average, Measure *measure, int code));
double        DetermineTypefrac     PROTO((Average *average, Measure *measure, PhotCode *code));
double        ExtractAverages       PROTO((PhotCode *code, int mode, Average *average, SecFilt *secfilt, Measure *measure, int param));
double       *ExtractByDMag         PROTO((PhotCode **code, int *mode, Average *average, SecFilt *secfilt, Measure *measure, int *nlist, int param));
double       *ExtractDMag           PROTO((PhotCode **code, int *mode, Average *average, SecFilt *secfilt, Measure *measure, int *nlist));
double       *ExtractMagnitudes     PROTO((PhotCode *code, int mode, Average *average, SecFilt *secfilt, Measure *measure, int *n));
double       *ExtractMeasures       PROTO((PhotCode *code, int mode, Average *average, SecFilt *secfilt, Measure *measure, int *nlist, int param));
double       *ExtractMeasuresByDMag PROTO((PhotCode **code, int *mode, int use_first, Average *average, SecFilt *secfilt, Measure *measure, int *nlist, int param));
double       *ExtractMeasuresDMag   PROTO((PhotCode **code, int *mode, Average *average, SecFilt *secfilt, Measure *measure, int *nlist));
void          FreeImageSelection    PROTO((void));
void          FreeImageSelection    PROTO((void));
int           GetAverageParam       PROTO((char *parname));
void          GetAverageParamHelp   PROTO((void));
int           GetMagMode            PROTO((char *string));
double        GetMeasure            PROTO((int param, Average *average, Measure *measure, double mag));
int           GetMeasureParam       PROTO((char *parname));
int           GetMeasureTypeCode    PROTO((Measure *measure));
int           GetPhotcodeInfo       PROTO((char *string, PhotCode **Code, int *Mode));
int           GetSelectionParam     PROTO((void));
int           GetTimeSelection      PROTO((time_t *tz, time_t *te));
void          InitDVO               PROTO((void));
void          FreeDVO               PROTO((void));
int           InitPhotcodes         PROTO((void));
Image        *LoadImages            PROTO((int *Nimage));
Image        *MatchImage            PROTO((unsigned int time, short int source));
Coords       *MatchMosaic           PROTO((unsigned int time, short int source));
int           Quality               PROTO((Measure *measure, int IsDophot));
int           SelectMags            PROTO((int Nphot, int Tphot, int Ns, Average *average, Measure *measure, SecFilt *secfilt, int UL));

SkyList      *SelectRegions         PROTO((SkyRegionSelection *selection));
SkyList      *SkyListLoadFile       PROTO((char *filename));
int           SetCATDIR             PROTO((char *path, int verbose));
char *        GetCATDIR             PROTO((void));
SkyTable     *GetSkyTable           PROTO((void));
SkyList      *SkyListFromFile       PROTO((char *filename));
SkyRegionSelection *SetRegionSelection    PROTO((int *argc, char **argv));

int           SetImageSelection     PROTO((int mode, SkyRegionSelection *selection));
int           SetPhotSelections     PROTO((int *argc, char **argv, int Nparams));
int           SetSelectionParam     PROTO((int param));
int           TestAverage           PROTO((PhotCode *code, Average *average, SecFilt *secfilt, Measure *measure));
int           TestPhotSelections    PROTO((PhotCode **code, int *mode, int param));
void          compare               PROTO((Catalog *catlog1, Catalog *catlog2, Vector *rvec,  Vector *dvec,  Vector *mvec, Vector *drvec, Vector *ddvec, Vector *dmvec, double radius));
void          cprecess              PROTO((Average *average, int Naverage, double in_epoch, double out_epoch));
void          image_subset          PROTO((Image *image, int Nimage, int **Subset, int *Nsubset, SkyRegionSelection *selection, unsigned long int tzero, double trange, int TimeSelect));
int           match_image           PROTO((Image *image, int Nimage, unsigned int T, short int S));
int           match_image_subset    PROTO((Image *image, int *subset, int Nsubset, unsigned int T, short int S));
void          print_value           PROTO((double value, short int ival));
void          sort_image_subset     PROTO((Image *image, int *subset, int N));
void          sort_images           PROTO((Image *image, int N));
void          sortave               PROTO((Average *ave, int N));
CMPstars     *cmpReadFits           PROTO((FILE *f, int *nstars));
CMPstars     *cmpReadText           PROTO((FILE *f, int *nstars));
int           RD_to_XYpic           PROTO((double *x, double *y, double r, double d, Coords *coords, double Rmin, double Rmax, double Rmid, int *leftside));

// dvo DB field functions
dbField     *dbCmdlineFields        PROTO((int argc, char **argv, int table, int *last, int *nfields));
int          dbCmdlineConditions    PROTO((int argc, char **argv, int first, int *nextField));
dbStack     *dbRPN                  PROTO((int argc, char **argv, int *nstack));
int          dbCheckStack           PROTO((dbStack *stack, int Nstack, int table, dbField **inFields, int *Nfields));
int          dbBooleanCond          PROTO((dbStack *inStack, int NinStack, dbValue *fields));
void         dbInitStack            PROTO((dbStack *stack));
void 	     dbFreeStack            PROTO((dbStack *stack, int Nstack));
void 	     dbFreeEntry            PROTO((dbStack *stack));
void         dbFreeTempEntry        PROTO((dbStack *stack));

dbStack     *dbBinary               PROTO((dbStack *V1, dbStack *V2, char *op, dbValue *fields));
dbStack     *dbUnary                PROTO((dbStack *V1, char *op, dbValue *fields));

int          GetMagMode             PROTO((char *string));
PhotCode    *ParsePhotcodeField     PROTO((char *field, int *mode, int def));
int          ParseMeasureField      PROTO((dbField *field, char *fieldName));
int          ParseAverageField      PROTO((dbField *field, char *fieldName));
int          ParseImageField        PROTO((dbField *field, char *fieldName));

dbValue      dbExtractAverages      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
dbValue      dbExtractMeasures      PROTO((Average *average, SecFilt *secfilt, Measure *measure, dbField *field));
dbValue      dbExtractImages        PROTO((Image *image, int Nimage, int N, dbField *field));

void 	     dbInitField            PROTO((dbField *field));
void 	     dbFreeFields           PROTO((dbField *fields, int Nfields));
int          dbAstroRegionLimits    PROTO((dbStack **stack, int *nstack, SkyRegionSelection *selection, int table));
char        *strfloat               PROTO((float value));

int get_skyregion (double *Rs, double *Re, double *Ds, double *De);
int set_skyregion (double Rs, double Re, double Ds, double De);
void FreeImageSelection (void);

void FreeSkyRegionSelection (SkyRegionSelection *selection);
int wordhash (char *word);

int dbExtractMeasuresInitTransform (CoordTransformSystem target);
int dbExtractMeasuresInitAve (void);
int dbExtractMeasuresInitMeas (void);
int dbExtractMeasuresInit (void);

int dbExtractAveragesInitTransform (CoordTransformSystem target);
int dbExtractAveragesInit (void);

int dbExtractImagesInitTransform (CoordTransformSystem target);
int dbExtractImagesInit (void);
int dbExtractImagesReset (void);

# endif
