# include "dvoImagesAtCoords.h"

typedef struct {
    int     id;
    double  ra;
    double  dec;
} Point;

static int readPoints(char *filename, Point **pointsOut);
static int ListImagesAtCoords (Image *dbImages, int id, double ra, double dec, int *matches, int Nmatches);

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

  int i, Nimages, NdbImages, status;
  int Nmatches, *matches;
  Image *dbImages;
  int Npoints;
  FITS_DB db;

  SetSignals ();
  ConfigInit_coords (&argc, argv);
  args_coords (argc, argv);
  
  Point *points;
  Npoints = readPoints(argv[1], &points);
  if (!Npoints) {
    exit(0);
  }

  if (astromFile) {
      dbImages = ReadImageFiles(astromFile, &NdbImages);
    } else {
    /*** update the image table ***/
    /* setup image table format and lock */
    db.mode   = dvo_catalog_catmode (CATMODE);
    db.format = dvo_catalog_catformat (CATFORMAT);
    status    = dvo_image_lock (&db, ImageCat, 3600.0, LCK_SOFT);  // shorter timeout?
    if (!status) Shutdown ("ERROR: failure to lock image catalog %s", db.filename);

    /* load or create the image table */
    if (db.dbstate == LCK_EMPTY) {
      fprintf (stderr, "no images in database (%s)\n", ImageCat);
      exit (1);
    } else {
      if (!dvo_image_load (&db, VERBOSE, FALSE)) {
        Shutdown ("can't read image catalog %s", db.filename);
      }
    }
    dvo_image_unlock (&db);

    // convert database table to internal structure
    dbImages = gfits_table_get_Image (&db.ftable, &NdbImages, &db.swapped);
  }
  
  Point *pt;
  for (i = 0, pt = points; i < Npoints; i++, pt++) {
    matches = MatchCoords (dbImages, NdbImages, pt->ra, pt->dec, &Nmatches);
    ListImagesAtCoords(dbImages, pt->id, pt->ra, pt->dec, matches, Nmatches);
  }

  exit (0);
}

static int readPoints(char *filename, Point **pointsOut)
{
    FILE *f = fopen(filename, "r");
    if (!f) {
      fprintf (stderr, "failed to open coordinate file %s", filename);
      exit(1);
    }

    int LEN = 20;
    Point *pts;
    ALLOCATE(pts, Point, LEN);
    int Npoints = 0;

    int Nread;
    // File Format is simple text file.
    // Each Line has 3 values separated by spaces that represent the coordinates to match.
    //
    // 'unique integer id' 'ra in degrees' 'declination in degrees'
    // we don't check the id for uniqueness (garbage in garbage out).

    while ((Nread = fscanf(f, "%d %lf %lf\n", &pts[Npoints].id, &pts[Npoints].ra, &pts[Npoints].dec)) == 3) {
        Npoints++;
        if (Npoints >= LEN) {
            LEN += 20;
            REALLOCATE(pts, Point, LEN);
        }
    }
    if (Nread != -1) {
      fprintf (stderr, "unexpected data on line %d of points file %s", Npoints, filename);
      exit(1);
    }

    *pointsOut = pts;

    return Npoints;
}

static int ListImagesAtCoords (Image *dbImages, int id, double ra, double dec, int *matches, int Nmatches)
{
  int i;
  for (i = 0; i < Nmatches; i++) {
    int N = matches[i];

    char *name;
    // output of lookup is filename[class_id.hdr] for astrometry files
    char *left_bracket = rindex(dbImages[N].name, '[');
    if (left_bracket) {
        name = strdup(left_bracket + 1);
        // zap the .hdr]
        char *dot = index(name, '.');
        if (dot) {
            *dot = 0;
        }
    } else {
        name = dbImages[N].name;
    }
    fprintf (stdout, "%d %lf %lf %s\n", id, ra, dec, name);
  }
  
  return (TRUE);
}

