# include <ohana.h>
# include <loneos.h>

/* # define GRID_V1 */
# define GRID_V2

static union { unsigned char c[4]; float f; } f_undef = { 0xff, 0xff, 0xff, 0xfe };
# define fUNDEF (f_undef.f)

static union { unsigned char c[8]; float d; } d_undef = { 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00 };
# define dUNDEF (d_undef.d)

typedef struct {
  double xmin, xmax, ymin, ymax;
  int style, ptype, ltype, etype, color;
  double lweight, size;
} Graphdata;

typedef struct {
  unsigned int start;
  unsigned int stop;
  short int Mcal;
  short int dMcal;
  short int Xm;
  short int 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   CameraConfig[256];

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    RELPHOT_GRID_X;
int    RELPHOT_GRID_Y;
int    RELPHOT_GRID_BINNING;

PhotCode      *photcode;
int            PhotPrimary;
int            PhotNsec;
int            PhotSec;

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

int ImagSelect, ImagMin, ImagMax;

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

int TimeSelect;
unsigned int TSTART, TSTOP;

/***** prototypes ****/
int main (int argc, char **argv);
Catalog *load_catalogs (GSCRegion *region, int Nregion, GSCRegion *fullregion);
GSCRegion *load_images (char *seed, int *nregion, GSCRegion *fullregion);
GSCRegion *name_region (char *name, int *Nregions);
GSCRegion *find_regions (Image *image, int Nimage, int *Nregions, GSCRegion *fullregion);
GSCRegion *get_regions (double minRa, double maxRa, double minDec, double maxDec, int *Nregions);
Image *find_images (GSCRegion *region, int Nregion, int *Nimages, int **LineNum);
double opening_angle (double x1, double y1, double x2, double y2, double x3, double y3);
int edge_check (double *x1, double *y1, double *x2, double *y2);
int corner_check (double *x1, double *y1, double *x2, double *y2);
int hms_to_deg (double *h0, double *h1, double *d0, double *d1, char *string);
int bcatalog (Catalog *subcatalog, Catalog *catalog, GSCRegion *fullregion);
int findMosaics (Catalog *catalog, int Ncatalog);
int setMmos (Catalog *catalog, int Poor);
int setMrel (Catalog *catalog, int Ncatalog);
int setrefcode (Image *image, int Nimage); 
int args (int argc, char **argv);
short getMgrid (int meas, int cat);
short getMcal (int meas, int cat);
short getMmos (int meas, int cat);
short getMrel (Catalog *catalog, int meas, int cat);
void initGrid (int dX, int dY);
void initGridBins (Catalog *catalog, int Ncatalog);
void initMosaics (Image *image, int Nimage);
void initMosaicGrid (Image *image, int Nimage);
void initMosaicBins (Catalog *catalog, int Ncatalog);
void initMrel (Catalog *catalog, int Ncatalog);
void initialize (int argc, char **argv);
void ConfigInit (int *argc, char **argv);
void mark_images (Image *image, int Nimage, Image *timage, int Ntimage);
void setMgrid (Catalog *catalog);
void dumpGrid ();
void initImages (Image *input, int N);
void initImageBins (Catalog *catalog, int Ncatalog);
void findImages (Catalog *catalog, int Ncatalog);
void matchImage (Catalog *catalog, int meas, int cat);
void matchMosaics (Catalog *catalog, int meas, int cat);
void setMcal (Catalog *catalog, int Poor);
void clean_images ();
void clean_stars (Catalog *catalog, int Ncatalog);
void reload_catalogs (GSCRegion *region, int Nregion, GSCRegion *fullregion);
void free_catalogs (Catalog *catalog, int Ncatalog);

# 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

void set_ZP (double ZERO);

char *GetPhotnamebyCode (PhotCodeData *photcodes, int code);
StatType statsStarS (Catalog *catalog, int Ncatalog);
StatType statsStarX (Catalog *catalog, int Ncatalog);
StatType statsStarN (Catalog *catalog, int Ncatalog);
StatType statsImageN (Catalog *catalog);
StatType statsImageX (Catalog *catalog);
StatType statsImageM (Catalog *catalog);
