# include "data.h"

int medimage_list (int argc, char **argv) {
  OHANA_UNUSED_PARAM(argv);

  if (argc != 1) {
    gprint (GP_ERR, "USAGE: medimage list\n");
    return FALSE;
  }

  ListMedImages();
  return TRUE;
}

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

  Buffer *image;

  if (argc != 3) {
    gprint (GP_ERR, "USAGE: medimage add (name) (image)\n");
    gprint (GP_ERR, "       add the given image to the set of images to be medianed\n");
    return FALSE;
  }

  if ((image = SelectBuffer (argv[2], OLDBUFFER, TRUE)) == NULL) return (FALSE);

  MedImageType *median = FindMedImage (argv[1]);
  if (!median) {
    // create a new median with this name
    median = CreateMedImage (argv[1], image->matrix.Naxis[0], image->matrix.Naxis[1]);
    if (!median) {
      gprint (GP_ERR, "failed to generate a new median image\n");
      return FALSE;
    }
  }

  if (median->Nx != image->matrix.Naxis[0]) {
    gprint (GP_ERR, "image does not match medimage dimensions\n");
    return FALSE;
  }
  if (median->Ny != image->matrix.Naxis[1]) {
    gprint (GP_ERR, "image does not match medimage dimensions\n");
    return FALSE;
  }

  // new image should match existing medimage dimensions

  int Ninput = median->Ninput;
  median->Ninput ++;
  REALLOCATE (median->buffers, float *, median->Ninput);

  ALLOCATE (median->buffers[Ninput], float, median->Nx*median->Ny);
  memcpy (median->buffers[Ninput], image->matrix.buffer, sizeof(float)*median->Nx*median->Ny);

  return TRUE;
}

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

  int ix, iy, n;
  Buffer *output;

  if (argc != 3) {
    gprint (GP_ERR, "USAGE: medimage calc (name) (output)\n");
    gprint (GP_ERR, "       calculate the median image for the median image set\n");
    return FALSE;
  }

  MedImageType *median = FindMedImage (argv[1]);
  if (!median) {
    gprint (GP_ERR, "median image %s not found\n", argv[1]);
    return FALSE;
  }

  if ((output = SelectBuffer (argv[2], ANYBUFFER, TRUE)) == NULL) return (FALSE);

  int Ninput = median->Ninput;
  int Nx = median->Nx;
  int Ny = median->Ny;

  float *value = NULL;
  ALLOCATE (value, float, Ninput);

  gfits_free_matrix (&output->matrix);
  gfits_free_header (&output->header);
  if (!CreateBuffer (output, Nx, Ny, -32, 0.0, 1.0)) return FALSE;

  float *outvalue = (float *) output->matrix.buffer;

  for (iy = 0; iy < Ny; iy++) {
    for (ix = 0; ix < Nx; ix++) {

      int N = 0;
      int Npix = ix + Nx*iy;
      for (n = 0; n < Ninput; n++) {
	float v = median->buffers[n][Npix];
	if (!isfinite(v)) continue;
	value[N] = v;
	N++;
      }
      if (N == 0) continue;

      fsort (value, N);
      outvalue[Npix] = value[(int)(0.5*N)];
    }
  }

  return TRUE;
}

/* 
int medimage_save (int argc, char **argv) {

  int N;

  int APPEND = FALSE;
  if ((N = get_argument (argc, argv, "-append"))) {
    APPEND = TRUE;
    remove_argument (N, &argc, argv);
  }

  if (argc != 3) {
    gprint (GP_ERR, "USAGE: medimage save (name) (filename) [-append]\n");
    return FALSE;
  }

  if (!SaveMedImage(argv[2], argv[1], APPEND)) {
    gprint (GP_ERR, "failed to save medimage %s\n", argv[1]);
    return (FALSE);
  }
  return TRUE;
}

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

  if (argc != 3) {
    gprint (GP_ERR, "USAGE: medimage load (name) (filename)\n");
    return FALSE;
  }

  if (!LoadMedImage(argv[2], argv[1])) {
    gprint (GP_ERR, "failed to load medimage %s\n", argv[1]);
    return (FALSE);
  }
  return TRUE;
}
*/

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

  int status;
  MedImageType *medimage;

  if (argc != 2) {
    gprint (GP_ERR, "USAGE: medimage delete (medimage)\n");
    return FALSE;
  }

  medimage = FindMedImage (argv[1]);
  if (medimage == NULL) {
    gprint (GP_ERR, "medimage %s not found\n", argv[1]);
    return FALSE;
  }

  status = DeleteMedImage (medimage);
  if (!status) abort ();
  return TRUE;
}

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

  MedImageType *medimage;

  if (argc != 3) {
    gprint (GP_ERR, "USAGE: medimage rename (medimage) (newname)\n");
    return FALSE;
  }

  medimage = FindMedImage (argv[1]);
  if (medimage == NULL) {
    gprint (GP_ERR, "medimage %s not found\n", argv[1]);
    return FALSE;
  }

  free (medimage->name);
  medimage->name = strcreate (argv[2]);
  return TRUE;
}
