# include "display.h"
# define DEBUG 0

/* we have space for several kii windows */
# define NXIMAGE 5

static int       Active;
static int       Ximage[NXIMAGE];  
static char      Ximbuffer[NXIMAGE][512];
static double    Xzero[NXIMAGE];
static double    Xrange[NXIMAGE];

/* define a structure to carry the relevant image data, eqiv to GraphData? */

void QuitImage () {

  int i;
  
  for (i = 0; i < NXIMAGE; i++) {
    if (Ximage[i] > 0) {
      write (Ximage[i], "QUIT", 4);
    }
  }
}


void InitImage () {

  int i;

  Active = 0;
  for (i = 0; i < NXIMAGE; i++) {
    Ximage[i] = -1;
    Xzero[i] = 0;
    Xrange[i] = 1024;
    strcpy (Ximbuffer[i], "none");
  }
}

/* set SIGPIPE to this function to close cleanly */ 
void XImageDead (int input) {
  signal (SIGPIPE, XImageDead);
  fprintf (stderr, "kii is dead, must restart\n");
  Ximage[Active] = -1;
}

/** start socketed connection */
int open_image (int N) {

  int InitSocket, status, addreslen;
  struct sockaddr_un Address;
  char temp[128], socket_name[64], *kii_exec;
  int Ntry, fd;

  kii_exec = get_variable ("KII");
  if (kii_exec == (char *) NULL) {
    fprintf (stderr, "variable KII not found\n");
    return (FALSE);
  }

  sprintf (socket_name, "/tmp/Kii.XXXXXX");
  if ((fd = mkstemp (socket_name)) == -1) {
    fprintf (stderr, "error starting kapa\n");
    return (FALSE);
  }
  close (fd);
  unlink (socket_name);

  strcpy (Address.sun_path, socket_name); 
  Address.sun_family = AF_UNIX; 
  InitSocket = socket (AF_UNIX, SOCK_STREAM, 0); 
  status = bind (InitSocket, (struct sockaddr *) &Address, sizeof (Address));
  status = listen (InitSocket, 1);
  
  sprintf (temp, "%s %s &", kii_exec, socket_name);
  free (kii_exec);

# if DEBUG
  fprintf (stderr, "start kii, press return: %s\n", temp);
  fscanf (stdin, "%d", &i);
# else  
  system (temp);
# endif
  
  addreslen =  sizeof (Address);
  fcntl (InitSocket, F_SETFL, O_NONBLOCK); 

# define NTRY 2000
  Ntry = 0;
  while (Ntry < NTRY) {
    Ximage[N] = accept (InitSocket, (struct sockaddr *)&Address, &addreslen);
    if (Ximage[N] == -1) {
      if (errno == EAGAIN) {
	usleep (10000);
	Ntry ++;
      } else { 
	Ntry = NTRY;
      }
    } else {
      Ntry = NTRY;
    }
  }

  if (Ximage[N] < 0) {
    fprintf (stderr, "error starting kii\n");
    return (FALSE);
  } else {
    fcntl (Ximage[N], F_SETFL, !O_NONBLOCK); 
    return (TRUE);
  }
  
}

/* return pointers for current Ximage, set if desired, test, open if needed */
int GetImage (int *socket, int *N) {

  int i, n;
  char buffer[70];

  SetImageDevice (TRUE);
  if (N == (int *) NULL) {
    n = Active;
  } else {
    if (*N >= NXIMAGE) {
      fprintf (stderr, "invalid Ximage window %d\n", *N); 
      return (FALSE);
    }
    if (*N < 0) {
      *N = n = Active;
    } else {
      Active = n = *N;
    }
  }
  
  /* test Ximage[0], flush junk from pipe */
  signal (SIGPIPE, XImageDead);
  fcntl (Ximage[n], F_SETFL,  O_NONBLOCK); 
  for (i = 0; (read (Ximage[n], buffer, 64) > 0) && (i < 20); i++);
  fcntl (Ximage[n], F_SETFL, !O_NONBLOCK); 
  
  if (Ximage[n] < 1) {
    if (!open_image(n)) {
      return (FALSE);
    }
  }

  if (socket != (int *) NULL) *socket = Ximage[n];

  return (TRUE);

}

void SetImageName (char *name) {
  strcpy (Ximbuffer[Active], name);
}

char *GetImageName () {
  return (Ximbuffer[Active]);
}
  
void SetImageScale (double zero, double range) {
  Xzero[Active] = zero;
  Xrange[Active] = range;
}
void GetImageScale (double *zero, double *range) {
  *zero = Xzero[Active];
  *range = Xrange[Active];
}
