# include "relastro.h"

# define MARKTIME(MSG,...) { \
  float dtime; \
  gettimeofday (&stop, (void *) NULL); \
  dtime = DTIME (stop, start); \
  fprintf (stderr, MSG, __VA_ARGS__); }

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

  int i, status, Ncatalog;
  Catalog *catalog;
  FITS_DB db;
  struct timeval start, stop;
  SkyList *skylist = NULL;

  gettimeofday (&start, (void *) NULL);

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

  /* the object analysis is a separate process iterating over catalogs */
  if (FIT_TARGET == TARGET_OBJECTS) {
    relastro_objects ();
    exit (0);
  }

  /* the object analysis is a separate process iterating over catalogs */
  if (FIT_TARGET == TARGET_HIGH_SPEED) {
    high_speed_catalogs ();
    exit (0);
  }

  /* register database handle with shutdown procedure */
  set_db (&db);

  /* lock and load the image db table */
  status = dvo_image_lock (&db, ImageCat, 60.0, (UPDATE ? LCK_XCLD : LCK_SOFT));
  if (!status) Shutdown ("ERROR: failure to lock image catalog %s", db.filename);
  if (db.dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db.filename);
  if (!dvo_image_load (&db, VERBOSE, FALSE)) Shutdown ("can't read image catalog %s", db.filename);
  MARKTIME("load image data: %f sec\n", dtime);

  /* load regions and images based on specified sky patch (default depth) */
  skylist = load_images (&db, &UserPatch);
  MARKTIME("load images: %f sec\n", dtime);

  initCoords();

  /* load catalog data from region files : subselect high-quality measurements */
  catalog = load_catalogs (skylist, &Ncatalog, TRUE);
  MARKTIME("load catalog data: %f sec\n", dtime);

  /* match measurements with images */
  initImageBins (catalog, Ncatalog, TRUE);
  MARKTIME("make image bins: %f sec\n", dtime);

  findImages (catalog, Ncatalog, TRUE);
  MARKTIME("set up image indexes: %f sec\n", dtime);

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

  /* major modes */
  switch (FIT_TARGET) {
    case TARGET_SIMPLE:
      for (i = 0; i < NLOOP; i++) {
	UpdateObjects (catalog, Ncatalog);
	UpdateSimple (catalog, Ncatalog);
      }
      break;

    case TARGET_CHIPS:
      for (i = 0; i < NLOOP; i++) {
	UpdateObjects (catalog, Ncatalog);
	UpdateChips (catalog, Ncatalog);
	MARKTIME("update chips: %f sec\n", dtime);
      }
      break;

    case TARGET_MOSAICS:
      for (i = 0; i < NLOOP; i++) {
	UpdateObjects (catalog, Ncatalog);
	UpdateMosaic (catalog, Ncatalog);
      }
      break;

    default:
      fprintf (stderr, "programming error at %s:%d", __FILE__, __LINE__);
      exit (2);
  }

  if (!UPDATE) exit (0);

  // free the image / measurement pointers
  freeImageBins (1);

  // iterate over catalogs to make detection coordinates consistant
  UpdateObjectOffsets (skylist);

  // iterate over catalogs to make detection coordinates consistant
  FixProblemImages (skylist);

  // save the updated image parameters
  dvo_image_update (&db, VERBOSE);
  dvo_image_unlock (&db); 

  exit (0);
}
