# include "dvo.h"

static char typename[5][32] = {"none", "object", "dark", "bias", "flat"};
static char modename[3][32] = {"none", "mef", "single"};

imsearch (int argc, char **argv) {
 
  char DataBase[256], name[64];
  FILE *f;
  Header header;
  RegImage *pimage;
  int i, Nimage, status, N, TimeSelect, SaveNames;
  int ModeSelect, TypeSelect, CCDSelect, FilterSelect;
  char *Filter, *Type, *Mode, *pmode, *ptype, *obstime;
  int type, mode, CCD;
  unsigned long int tzero;
  double trange;
   
  VarConfig ("REGISTRATION_DATABASE", "%s", DataBase);

  SaveNames = FALSE;
  if (N = get_argument (argc, argv, "-save")) {
    remove_argument (N, &argc, argv);
    SaveNames = TRUE;
  }
 
  TimeSelect = FALSE;
  if (N = get_argument (argc, argv, "-time")) {
    remove_argument (N, &argc, argv);
    if (!str_to_time (argv[N], &tzero)) { 
      fprintf (stderr, "syntax error\n");
      return (FALSE);
    }
    remove_argument (N, &argc, argv);
    if (!str_to_dtime (argv[N], &trange)) { 
      fprintf (stderr, "syntax error\n");
      return (FALSE);
    }
    remove_argument (N, &argc, argv);
    TimeSelect = TRUE;
  }
 
  TypeSelect = FALSE;
  if (N = get_argument (argc, argv, "-type")) {
    remove_argument (N, &argc, argv);
    Type = strcreate (argv[N]);
    remove_argument (N, &argc, argv);
    TypeSelect = TRUE;
  }
 
  ModeSelect = FALSE;
  if (N = get_argument (argc, argv, "-mode")) {
    remove_argument (N, &argc, argv);
    Mode = strcreate (argv[N]);
    remove_argument (N, &argc, argv);
    ModeSelect = TRUE;
  }
 
  CCDSelect = FALSE;
  if (N = get_argument (argc, argv, "-ccd")) {
    remove_argument (N, &argc, argv);
    CCD = atoi (argv[N]);
    remove_argument (N, &argc, argv);
    CCDSelect = TRUE;
  }
 
  FilterSelect = FALSE;
  if (N = get_argument (argc, argv, "-filter")) {
    remove_argument (N, &argc, argv);
    Filter = strcreate (argv[N]);
    remove_argument (N, &argc, argv);
    FilterSelect = TRUE;
    if (!strcasecmp (Filter, "X")) {
      FilterSelect = FALSE;
    }
  }

  if (argc != 1) {
    fprintf (stderr, "USAGE: imsearch [-time start range] [-type type] [-mode mode] [-ccd N] [-filter name]\n");
    exit (1);
  }

  type = TYPE_NONE;
  if (TypeSelect) {
    if (!strncasecmp (Type, "obj", 3)) {
      type = TYPE_OBJECT;
    }
    if (!strncasecmp (Type, "bias", 4)) {
      type = TYPE_BIAS;
    }
    if (!strncasecmp (Type, "dark", 4)) {
      type = TYPE_DARK;
    }
    if (!strncasecmp (Type, "flat", 4)) {
      type = TYPE_FLAT;
    }
    if (type == TYPE_NONE) {
      fprintf (stderr, "invalid image type %s\n", Type);
      return (FALSE);
    }
  }

  mode = MODE_NONE;
  if (ModeSelect) {
    if (!strncasecmp (Mode, "mef", 3)) {
      mode = MODE_MEF;
    }
    if (!strncasecmp (Mode, "single", 4) || !strncasecmp (Mode, "split", 4)) {
      mode = MODE_SINGLE;
    }
    if (mode == MODE_NONE) {
      fprintf (stderr, "invalid image mode %s\n", Mode);
      return (FALSE);
    }
  }

  /* load in database header */
  if (!fits_read_header (DataBase, &header)) {
    fprintf (stderr, "ERROR: trouble reading database header\n");
    return (FALSE);
  }

  /* open database */
  f = fopen (DataBase, "r");
  if (f == (FILE *) NULL) {
    fprintf (stderr, "ERROR: can't open Registration Database\n");
    return (FALSE);
  }
  fseek (f, header.size, SEEK_SET);

  /* load existing data from database */
  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
  ALLOCATE (pimage, RegImage, Nimage);
  status = Fread (pimage, sizeof(RegImage), Nimage, f, "regimage");
  fclose (f);

  if (status != Nimage) {
    fprintf (stderr, "ERROR: header and data in dB don't match (%d vs %d)\n", Nimage, status);
    fits_free_header (&header);
    free (pimage);
    return (FALSE);
  }

  /* print out all data */
  N = 0;
  for (i = 0; i < Nimage; i++) {
    if (TimeSelect && ((pimage[i].obstime < tzero) || (pimage[i].obstime > tzero + trange))) continue;
    if (FilterSelect && (strcasecmp (pimage[i].filter, Filter))) continue;
    if (ModeSelect && (pimage[i].mode != mode)) continue;
    if (CCDSelect && (pimage[i].ccd != CCD)) continue;
    if (TypeSelect && (pimage[i].type != type)) continue;

    if ((pimage[i].mode < 0) || (pimage[i].mode > 2)) 
      pmode = modename[0];
    else
      pmode = modename[(int)pimage[i].mode];

    if ((pimage[i].type < 0) || (pimage[i].type > 4)) 
      ptype = typename[0];
    else
      ptype = typename[(int)pimage[i].type];

    obstime = ctime (&pimage[i].obstime);
    obstime[strlen(obstime)-1] = 0;
    fprintf (stdout, "%5d %6s %6s %2d %2d   ", i, ptype, pmode, pimage[i].ccd, pimage[i].type);
    fprintf (stdout, "%s %s  ", pimage[i].pathname, pimage[i].filename);
    fprintf (stdout, "%s %s %f %s\n", pimage[i].filter, pimage[i].instrument, pimage[i].exptime, obstime);

    if (SaveNames) {
      sprintf (name, "IMAGEpath:%d", N);
      set_str_variable (name, pimage[i].pathname);
      sprintf (name, "IMAGEfile:%d", N);
      set_str_variable (name, pimage[i].filename);
      sprintf (name, "IMAGEmode:%d", N);
      set_int_variable (name, pimage[i].mode);
    }
    N++;
  }
  if (SaveNames) {
    set_int_variable ("IMAGEpath:n", N);
    set_int_variable ("IMAGEfile:n", N);
  }

  free (pimage);
  fits_free_header (&header);
  return (TRUE);
}
