# include "relphot.h"
# define USE_DIRECT 0

int main (int argc, char **argv) {

  int i, status, Ncatalog;
  Catalog *catalog;
  FITS_DB db;

  SkyList *skylist = NULL;

  /* get configuration info, args */
  initialize (argc, argv);

  /* the object analysis is a separate process iterating over catalogs */
  if (UpdateAverages) {
    relphot_objects ();
    exit (0);
  }

  /* register database handle with shutdown procedure */
  set_db (&db);
  db.mode   = dvo_catalog_catmode (CATMODE);
  db.format = dvo_catalog_catformat (CATFORMAT);

  /* lock and load the image db table */
  status = dvo_image_lock (&db, ImageCat, 60.0, (UPDATE ? LCK_XCLD : LCK_SOFT));
  if (!status && UPDATE) {
    fprintf (stderr, "error\n");
    Shutdown ("ERROR: failure to lock image catalog %s", db.filename);
  }
  // if the file is missing, db.dbstate will have a value of either:
  // LCK_EMPTY (if UPDATE) or LCK_MISSING (if !UPDATE)
  if ((db.dbstate == LCK_EMPTY) || (db.dbstate == LCK_MISSING)) {
    // XXX get ZERO_POINT from config
    dvo_image_create (&db, 25.0);
    // Shutdown ("ERROR: No images in catalog %s (1)", db.filename);
  } else {
    if (!dvo_image_load (&db, VERBOSE, FALSE)) Shutdown ("can't read image catalog %s", db.filename);
  }

  /* load regions and images based on specified sky patch */
  // XXX need to mimic old-style load by passing patch name
  // XXX need to reduce number of global variables in use.
  // XXX this is fairly lame: argv[1] is photcode if UserPatchSelect is true
  skylist = load_images (&db, argv[1], &UserPatch, UserPatchSelect);

  /* unlock, if we can (else, unlocked below) */
  if (!UPDATE) dvo_image_unlock (&db); 

  /* load catalog data from region files */
  catalog = load_catalogs (skylist, &Ncatalog);
  
  /* add in a loop over the catalogs calling dvo_catalog_chipcoords */

  /* match measurements with images, mosaics */
  initImageBins  (catalog, Ncatalog);
  initMosaicBins (catalog, Ncatalog);
  initGridBins   (catalog, Ncatalog);
  initMrel (catalog, Ncatalog);

  findImages (catalog, Ncatalog);
  findMosaics (catalog, Ncatalog);  /* also sets Grid values */
  SAVEPLOT = FALSE;

  setExclusions (catalog, Ncatalog);

  if (PLOTSTUFF) {
    plot_star_coords (catalog, Ncatalog);
    plot_mosaic_fields (catalog);
  }

  // if we are measuring the flat-field correction grid, we need to perform a number of iterations first:
  if (USE_GRID) {
      int star_toofew;

# if (USE_DIRECT)
      // until we finish the grid analysis, do not reject stars out-of-hand based on ID_STAR_FEW
      // XXX this is kind of poor: need to have a better distinctions about STAR_BAD in setMrel vs getMrel
      star_toofew = STAR_TOOFEW;
      STAR_TOOFEW = 0;
      STAR_BAD  = ID_STAR_POOR;

      showGridCount ();
      setMgridDirect (catalog, Ncatalog);

      STAR_BAD  = ID_STAR_POOR | ID_STAR_FEW;
      STAR_TOOFEW = star_toofew;

      dump_grid ();
      exit (0);

# else

      // until we finish the grid analysis, do not reject stars out-of-hand based on ID_STAR_FEW
      // XXX this is kind of poor: need to have a better distinctions about STAR_BAD in setMrel vs getMrel
      star_toofew = STAR_TOOFEW;
      STAR_TOOFEW = 0;
      for (i = 0; i < NGRID; i++) {
	  STAR_BAD = ID_STAR_POOR;
	  setMrel  (catalog, Ncatalog);
	  STAR_BAD  = ID_STAR_POOR | ID_STAR_FEW;
	  setMgrid (catalog);
      }
      STAR_BAD  = ID_STAR_POOR | ID_STAR_FEW;
      STAR_TOOFEW = star_toofew;
# endif
  }

  /* determine fit values */
  for (i = 0; i < NLOOP; i++) {
    setMrel  (catalog, Ncatalog);
    setMcal  (catalog, FALSE);
    setMmos  (catalog, FALSE);
    setMgrid (catalog);
    
    if (PLOTSTUFF) {
      plot_scatter (catalog, Ncatalog); 
      plot_grid (catalog); 
      plot_mosaics ();
      plot_images ();
      plot_stars (catalog, Ncatalog);
      plot_chisq (catalog, Ncatalog);
    }
    if ((i == 1) || (i == 5) || (i ==  9) || (i == 13)) clean_measures (catalog, Ncatalog, FALSE); 
    if ((i == 2) || (i == 6) || (i == 10) || (i == 14)) clean_stars (catalog, Ncatalog);
    if ((i == 4) || (i == 8) || (i == 12) || (i == 16)) clean_mosaics (catalog, Ncatalog);
    if ((i == 4) || (i == 8) || (i == 12) || (i == 16)) clean_images ();
    global_stats (catalog, Ncatalog);
  }

  SAVEPLOT = TRUE;
  plot_scatter (catalog, Ncatalog); 
  plot_grid (catalog); 
  plot_mosaics ();
  plot_images ();
  plot_stars (catalog, Ncatalog);
  plot_chisq (catalog, Ncatalog);

  if (USE_GRID) dump_grid ();
  if (!UPDATE) exit (0);

  /* set Mcal & Mmos for bad images */
  setMcal  (catalog, TRUE);
  setMmos  (catalog, TRUE);

  /* at this point, we have correct cal coeffs in the image/mosaic structures */
  for (i = 0; i < Ncatalog; i++) dvo_catalog_free (&catalog[i]);
  freeImageBins (Ncatalog);
  freeMosaicBins (Ncatalog);
  freeGridBins (Ncatalog);

  /* load catalog data from region files, update Mrel include all data */
  reload_catalogs (skylist);
  setMcalFinal ();

  reload_images (&db);
  
  dvo_image_update (&db, VERBOSE);
  dvo_image_unlock (&db); 

  exit (0);
}

