# include "uniphot.h"

/* sort a coordinate pair (X,Y) and the associated index (S) */
static void sort_zpts_by_time (ZptTable *zpts, int Nzpts) {
  
# define SWAPFUNC(A,B){ ZptTable tmp;		\
    tmp = zpts[A]; zpts[A] = zpts[B]; zpts[B] = tmp;	\
  }
# define COMPARE(A,B)(zpts[A].time < zpts[B].time)

  OHANA_SORT (Nzpts, COMPARE, SWAPFUNC);

# undef SWAPFUNC
# undef COMPARE
}

# define SCALE 0.001

int match_zpts_to_images (Image *image, off_t Nimage, ZptTable *zpts, int Nzpts) {

  // I have two lists.  I need to match images->tzero to zpts->time.  multiple images may match a single zpt
  
  // sort both lists by time (or at least get sorted indices)
  // sweep through both lists, advancing the one that is lagging
  // apply the matches

  int dT, NImatch, Nmatch;
  off_t i, Ni, Nz, *index;
  PhotCode *code;

  // create index and sort
  ALLOCATE (index, off_t, Nimage);
  for (i = 0; i < Nimage; i++) {
    index[i] = i;
  }
  sort_image_subset(image, index, Nimage);  // slightly misnamed sort function from libdvo

  // sort the zpts
  sort_zpts_by_time (zpts, Nzpts);

  NImatch = 0; // matched images
  for (i = Nz = 0; (i < Nimage) && (Nz < Nzpts); ) {

    if (i % 1000 == 0) fprintf (stderr, ".");
    if (Nz % 100 == 0) fprintf (stderr, "!");

    Ni = index[i];
    dT = image[Ni].tzero - zpts[Nz].time;

    // negative dT, i is too small (allow a 1sec overlap window)
    if (dT < -1) {
      i++;
      continue;
    }

    // XXX careful about definition of image->tzero and zpt->time
    // negative dT, i is too small (allow a 1sec overlap window)
    if (dT > +1) {
      Nz++;
      continue;
    }

    // check that we have a valid photcode (skip mosaic images)
    code = GetPhotcodebyCode(image[Ni].photcode);
    if (!code) { 
      i++;
      continue;
    }

    // we have a match: set zpt and record the match
    image[Ni].Mcal = SCALE*code[0].C - zpts[Nz].zpt;
    image[Ni].flags &= ~ID_IMAGE_NOCAL; // clear the NOCAL flag
    zpts[Nz].found = TRUE;
    NImatch ++;

    // advance the image counter only -- a single zpt may match more than one image
    i++;
  }

  // how many zpts have we matched?
  Nmatch = 0;
  for (Nz = 0; Nz < Nzpts; Nz++) {
    if (zpts[Nz].found) Nmatch ++;
  }

  fprintf (stderr, "found %d zpt matches, %d image matches\n", Nmatch, NImatch);

  return (TRUE);
}

