# include <ohana.h>
# include <dvo.h>
# include <kapa.h>
# include <signal.h>

/* # define GRID_V1 */
# define GRID_V2
# define NO_IMAGE -100

# if (0)
typedef struct {
  double xmin, xmax, ymin, ymax;
  int style, ptype, ltype, etype, color;
  double lweight, size;
} Graphdata;
# endif

typedef struct {
  unsigned int start;
  unsigned int stop;
  float Mcal;
  float dMcal;
  short Xm;
  float secz;
  char code;
  Coords coords;
} Mosaic; 

typedef struct {
  double median;
  double mean;
  double sigma;
  double error;
  double chisq;
  double min;
  double max;
  double total;
  int    Nmeas;
} StatType;

/* global variables set in parameter file */
char   ImageCat[256];
char   ImageTemplate[256];
char   CatTemplate[256];
char   GSCFILE[256];
char   CATDIR[256];
char   CATMODE[16];    /* raw, mef, split, mysql */
char   CATFORMAT[16];  /* internal, elixir, loneos, panstarrs */
char   CameraConfig[256];
char   SKY_TABLE[256];
int    SKY_DEPTH;  /** XXX EAM : depth of catalog tables, fix usage */

double MAG_LIM;
double SIGMA_LIM;
double IMAGE_SCATTER;
double IMAGE_OFFSET;
double STAR_SCATTER;
double STAR_CHISQ;
double MIN_ERROR;

int    VERBOSE;

int    NLOOP;
int    RESET;
int    UPDATE;
int    PLOTSTUFF;
int    SAVEPLOT;
int    SHOW_PARAMS;
char   MOSAICNAME[256];
char   STATMODE[32];
int    STAR_BAD;
int    MEAS_BAD;
int    STAR_TOOFEW;
int    IMAGE_TOOFEW;
double IMAGE_GOOD_FRACTION;
int    IMAGE_BAD;
int    FREEZE_IMAGES;
int    USE_GRID;
int    PLOTDELAY;
int    UpdateAverages;

int    RELPHOT_GRID_X;
int    RELPHOT_GRID_Y;
int    RELPHOT_GRID_BINNING;

PhotCode      *photcode;
int            PhotNsec;
int            PhotSec;

int AreaSelect;
double AreaXmin, AreaXmax, AreaYmin, AreaYmax;

int ImagSelect, ImagMin, ImagMax;

int DophotSelect, DophotValue;

double  PlotMmin, PlotMmax, PlotdMmin, PlotdMmax;
enum {black, white, red, orange, yellow, green, blue, indigo, violet};

int TimeSelect;
time_t TSTART, TSTOP;

SkyRegion UserPatch;
int UserPatchSelect;

# ifdef GRID_V1
int setGridMeasure (int meas, int cat, double X, double Y);
# endif

# ifdef GRID_V2
int setGridMeasure (int meas, int cat, double X, double Y, int ccdnum);
# endif

/*** relphot prototypes ***/
void          ConfigInit          PROTO((int *argc, char **argv));
void          GetConfig           PROTO((char *config, char *field, char *format, int N, void *ptr));
char         *GetPhotnamebyCode   PROTO((PhotCodeData *photcodes, int code));
void          InterpolateGrid     PROTO((float *buffer, int Nx, int Ny, Coords *ccd, Coords *gcoords));
int          *SelectRefMosaic     PROTO((Mosaic **refmosaic, int *Nimage));
int           args                PROTO((int argc, char **argv));
int           bcatalog            PROTO((Catalog *subcatalog, Catalog *catalog));
void          clean_images        PROTO(());
void          clean_measures      PROTO((Catalog *catalog, int Ncatalog, int final));
void          clean_mosaics       PROTO(());
void          clean_stars         PROTO((Catalog *catalog, int Ncatalog));
int           corner_check        PROTO((double *x1, double *y1, double *x2, double *y2));
void          dumpGrid            PROTO(());
void          dump_grid           PROTO(()); 
int           edge_check          PROTO((double *x1, double *y1, double *x2, double *y2));
void          findImages          PROTO((Catalog *catalog, int Ncatalog));
int           findMosaics         PROTO((Catalog *catalog, int Ncatalog));

void set_db (FITS_DB *in);
int Shutdown (char *format, ...);
void TrapSignal (int sig);
void SetProtect (int mode);
int SetSignals ();

void          freeGridBins        PROTO((int Ncatalog));
void          freeImageBins       PROTO((int Ncatalog));
void          freeMosaicBins      PROTO((int Ncatalog));
void          free_catalogs       PROTO((Catalog *catalog, int Ncatalog));
int           gcatalog            PROTO((Catalog *catalog, int FINAL));
Coords       *getCoords           PROTO((int meas, int cat));
int           getImageEntry       PROTO((int meas, int cat));
float         getMcal             PROTO((int meas, int cat));
float         getMgrid            PROTO((int meas, int cat));
float         getMmos             PROTO((int meas, int cat));
float         getMrel             PROTO((Catalog *catalog, int meas, int cat));
Image        *getimage            PROTO((int N));
Image        *getimages           PROTO((int *N));
void          global_stats        PROTO((Catalog *catalog, int Ncatalog));
void          initGrid            PROTO((int dX, int dY));
void          initGridBins        PROTO((Catalog *catalog, int Ncatalog));
void          initImageBins       PROTO((Catalog *catalog, int Ncatalog));
void          initImages          PROTO((Image *input, int N));
void          initMosaicBins      PROTO((Catalog *catalog, int Ncatalog));
void          initMosaicGrid      PROTO((Image *image, int Nimage));
void          initMosaics         PROTO((Image *image, int Nimage));
void          initMrel            PROTO((Catalog *catalog, int Ncatalog));
void          initialize          PROTO((int argc, char **argv));
void          initstats           PROTO((char *mode));
int           liststats           PROTO((double *value, double *dvalue, int N, StatType *stats));
Catalog       *load_catalogs      PROTO((SkyList *skylist, int *Ncatalog));
SkyList      *load_images         PROTO((FITS_DB *db, char *regionName, SkyRegion *region, int RegionSelect));
Image         *select_images      PROTO((SkyList *skylist, Image *timage, int Ntimage, int **LineNumber, int *Nimage));

int           main                PROTO((int argc, char **argv));
void          mark_images         PROTO((Image *image, int Nimage, Image *timage, int Ntimage));
void          matchImage          PROTO((Catalog *catalog, int meas, int cat));
void          matchMosaics        PROTO((Catalog *catalog, int meas, int cat));
double        opening_angle       PROTO((double x1, double y1, double x2, double y2, double x3, double y3));
void          plot_chisq          PROTO((Catalog *catalog, int Ncatalog));
void          plot_defaults       PROTO((Graphdata *graphdata));
void          plot_grid           PROTO((Catalog *catalog));
void          plot_images         PROTO(());
void          plot_list           PROTO((Graphdata *graphdata, double *xlist, double *ylist, int N, char *label, char *file));
void          plot_mosaic_fields  PROTO((Catalog *catalog));
void          plot_mosaics        PROTO(());
void          plot_scatter        PROTO((Catalog *catalog, int Ncatalog));
void          plot_star_coords    PROTO((Catalog *catalog, int Ncatalog));
void          plot_stars          PROTO((Catalog *catalog, int Ncatalog));
void          reload_catalogs     PROTO((SkyList *skylist));
int           reload_images       PROTO((FITS_DB *db));
int           setExclusions       PROTO((Catalog *catalog, int Ncatalog));
void          setMcal             PROTO((Catalog *catalog, int Poor));
void          setMcalFinal        PROTO(());
int           setMcalOutput       PROTO((Catalog *catalog, int Ncatalog));
void          setMgrid            PROTO((Catalog *catalog));
int           setMmos             PROTO((Catalog *catalog, int Poor));
int           setMrel             PROTO((Catalog *catalog, int Ncatalog));
void          setMrelFinal        PROTO((Catalog *catalog));
int           setMrelOutput       PROTO((Catalog *catalog, int Ncatalog, int mark));
int           setMave             PROTO((Catalog *catalog, int Ncatalog));
void          set_ZP              PROTO((double ZERO));
int           setrefcode          PROTO((Image *image, int Nimage)); 
void          skip_measurements   PROTO((Catalog *catalog, int pass));
void          sortA               PROTO((double *X, int N));
void          sortB               PROTO((double *X, double *Y, int N));
void          sortC               PROTO((double *X, double *Y, double *F1, double *F2, int N));
void          sortD               PROTO((double *X, double *Y, double *Z, int N));
StatType      statsImageM         PROTO((Catalog *catalog));
StatType      statsImageN         PROTO((Catalog *catalog));
StatType      statsImageX         PROTO((Catalog *catalog));
StatType      statsImagedM        PROTO((Catalog *catalog));
StatType      statsMosaicM        PROTO((Catalog *catalog));
StatType      statsMosaicN        PROTO((Catalog *catalog));
StatType      statsMosaicX        PROTO((Catalog *catalog));
StatType      statsMosaicdM       PROTO((Catalog *catalog));
StatType      statsStarN          PROTO((Catalog *catalog, int Ncatalog));
StatType      statsStarS          PROTO((Catalog *catalog, int Ncatalog));
StatType      statsStarX          PROTO((Catalog *catalog, int Ncatalog));
void          wcatalog            PROTO((Catalog *catalog));
void          wimages             PROTO(());
void          write_coords        PROTO((Header *header, Coords *coords));
int relphot_objects ();
