# include <dvo.h>

/* chip-match table: j = ChipMatch[i], images[j] is DIS for images[i] WRP */

static int    iDIS = -1;      // DIS entry in ChipMatch[]
static int    Ndis = 0;
static int    *DISentry = NULL;
static e_time *DIStzero = NULL;
static int    *ChipMatch = NULL;

/* what is the currently registered mosaic image? */
int GetRegisteredMosaic () {
  return (iDIS);
}

/* given an image array and a current entry of type WRP, find matching DIS & Register it */
int FindMosaicForImage (Image *images, int Nimages, int entry) {

  int status;

  if (ChipMatch == NULL) {
    status = FindMosaicForImage_TableSearch (images, Nimages, entry);
    return (status);
  }
  status = FindMosaicForImage_MatchSearch (images, Nimages, entry);
  return (status);
}

/* given an image array and a current entry of type WRP, find matching DIS & Register it */
int FindMosaicForImage_TableSearch (Image *images, int Nimages, int entry) {

  e_time tzero;
  int i;

  /* search backwards for image with same time and type DIS */

  if (strcmp(&images[entry].coords.ctype[4], "-WRP")) {
    /* not a wrp image, do nothing */
    return (TRUE); /* error or not */
  }

  tzero = images[entry].tzero;
  
  for (i = entry - 1; i >= 0; i--) {
    if (images[i].tzero != tzero) continue;
    if (strcmp(&images[i].coords.ctype[4], "-DIS")) continue;

    /* found a valid match */
    RegisterMosaic (&images[i].coords);
    iDIS = i;
    return (TRUE);
  }

  for (i = entry + 1; i < Nimages; i++) {
    if (images[i].tzero != tzero) continue;
    if (strcmp(&images[i].coords.ctype[4], "-DIS")) continue;

    /* found a valid match */
    RegisterMosaic (&images[i].coords);
    iDIS = i;
    return (TRUE);
  }
  return (FALSE);
}

/* given an image array and a current entry of type WRP, find matching DIS & Register it */
int FindMosaicForImage_MatchSearch (Image *images, int Nimages, int entry) {

  int N;

  if (strcmp(&images[entry].coords.ctype[4], "-WRP")) {
    /* not a wrp image, do nothing */
    return (TRUE); /* error or not */
  }

  if (ChipMatch == NULL) return (FALSE);

  N = ChipMatch[entry];
  if (N < 0) return (FALSE);
  if (N >= Nimages) return (FALSE);

  RegisterMosaic (&images[N].coords);
  iDIS = N;
  return (TRUE);
}

int BuildChipMatch (Image *images, int Nimages) {

  int i, j, NDIS;

  if (DISentry != NULL) free (DISentry);
  if (DIStzero != NULL) free (DIStzero);
  if (ChipMatch != NULL) free (ChipMatch);

  /* find all DIS images, save tzero (& instrument) */
  Ndis = 0;
  NDIS = 100;
  ALLOCATE (DISentry, int, NDIS);
  ALLOCATE (DIStzero, e_time, NDIS);

  for (i = 0; i < Nimages; i++) {
    if (strcmp(&images[i].coords.ctype[4], "-DIS")) continue;
    DISentry[Ndis] = i;
    DIStzero[Ndis] = images[i].tzero;
    Ndis ++;
    if (Ndis >= NDIS) {
      NDIS += 100;
      REALLOCATE (DISentry, int, NDIS);
      REALLOCATE (DIStzero, e_time, NDIS);
    }
  }

  /* find all matched WRP images */
  ALLOCATE (ChipMatch, int, Nimages);
  for (i = 0; i < Nimages; i++) {
    ChipMatch[i] = -1;
    if (strcmp(&images[i].coords.ctype[4], "-WRP")) continue;
    for (j = 0; j < Ndis; j++) {
      if (DIStzero[j] < images[i].tzero) continue;
      if (DIStzero[j] > images[i].tzero + (int) images[i].exptime) continue;
      ChipMatch[i] = DISentry[j];
      goto got_match;
    }

    fprintf (stderr, "WARNING: can't find matching mosaic \n");
    ChipMatch[i] = -2;

  got_match:
    continue;
  }
  return (TRUE);
}
