# include "dimm.h"
# define EXIT_STATUS(S) { seteuid (UID); return (S); }

static uid_t UID, EUID;

SetEUID () {

  /* save the UID (ID of calling process) and EUID (should be root) */
  UID = getuid ();
  EUID = geteuid ();
  seteuid (UID);
}

int camera (int argc, char **argv) {
  
  /* USAGE: 
     camera init port
     camera expose exptime
     camera readout x y dx dy
     camera temp set value
     camera temp get var
  */

  if (argc < 2) goto usage;

  seteuid (EUID);
  
  if (!strcasecmp (argv[1], "init")) {
    int port, status;

    if (argc != 3) {
      fprintf (stderr, "USAGE: camera init (port)\n");
      EXIT_STATUS (FALSE);
    }
    sscanf (argv[2], "%x", &port);
    status = InitCamera (port);
    EXIT_STATUS (status);
  }

  if (!strcasecmp (argv[1], "expose")) {

    int status;
    double exptime;

    if (argc != 3) {
      fprintf (stderr, "USAGE: camera expose (exptime)\n");
      EXIT_STATUS (FALSE);
    }
    exptime = atof (argv[2]);
    status = Exposure (exptime);
    EXIT_STATUS (status);
  }

  if (!strcasecmp (argv[1], "temp")) {

    int status;
    double temp;

    if (argc != 3) {
      fprintf (stderr, "USAGE: camera temp (temperature)\n");
      EXIT_STATUS (FALSE);
    }
    temp = atof (argv[2]);
    status = SetTemperature (temp);
    EXIT_STATUS (status);
  }

  if (!strcasecmp (argv[1], "status")) {

    int status;
    double temp;

    if (argc != 2) {
      fprintf (stderr, "USAGE: camera status\n");
      EXIT_STATUS (FALSE);
    }
    DumpCameraStatus ();
    EXIT_STATUS (TRUE);
  }

  if (!strcasecmp (argv[1], "readout")) {

    int Nbuf, status;
    double temp;
    int x, y, dx, dy, NX, NY;
    Buffer *buf;

    if ((argc != 7) && (argc != 3)) {
      fprintf (stderr, "USAGE: camera readout (buffer) x y dx dy\n");
      EXIT_STATUS (FALSE);
    }

    if ((buf = SelectBuffer (argv[2], OLDBUFFER, TRUE)) == NULL) EXIT_STATUS (FALSE);

    CameraFullSize (&NX, &NY);
    x = y = 0;
    dx = NX;
    dy = NY;
    if (argc == 7) {
      x  = atof (argv[3]);
      y  = atof (argv[4]);
      dx = atof (argv[5]);
      dy = atof (argv[6]);
    } 

    /* generate a buffer to store the image */
    fits_free_matrix (&buf[0].matrix);
    fits_free_header (&buf[0].header);
    buf[0].header.bitpix = buf[0].bitpix = 16;
    buf[0].header.unsign = buf[0].unsign = FALSE;
    buf[0].header.bscale = buf[0].bscale = 1.0;
    buf[0].header.bzero  = buf[0].bzero  = 0.0;
    buf[0].header.Naxes = 2;
    buf[0].header.Naxis[0] = dx;
    buf[0].header.Naxis[1] = dy;
    fits_create_header (&buf[0].header);
    fits_create_matrix (&buf[0].header, &buf[0].matrix);

    ReadOut (x, y, dx, dy, 1, buf[0].matrix.buffer);

    fits_convert_format (&buf[0].header, &buf[0].matrix, -32, 1.0, 0.0, FT_UNSIGN_MODE);

    EXIT_STATUS (TRUE);
  }

usage:
  fprintf (stderr, "camera init port\n");
  fprintf (stderr, "camera expose exptime\n");
  fprintf (stderr, "camera readout x y dx dy\n");
  fprintf (stderr, "camera temp set value\n");
  fprintf (stderr, "camera temp get var\n");
  seteuid (UID);
  return (FALSE);

}


