# include "relphot.h"
# include <signal.h>

static int Xgraph[5] = {0,0,0,0,0};
static int active;

void XDead () {
  signal (SIGPIPE, XDead);
  fprintf (stderr, "kapa is dead, must restart\n");
  Xgraph[active] = -1;
}

int open_graph (int N) {

# ifdef ANSI
#   define F_SETFL      4   
#   define O_NONBLOCK 0200000  
#   define       AF_UNIX         1          
#   define       SOCK_STREAM     1          
#define ENOENT          2       /* No such file or directory    */
# endif /* ANSI */

  int i, InitSocket, status, addreslen;
  struct sockaddr_un Address;
  char temp[100], *display_name;
  char socket_name[100];
  FILE *f;
  
  active = N;
  sprintf (socket_name, "/tmp/kapa%d", N);
  sprintf (temp, "rm -f %s", socket_name);
  system (temp);
    
  strcpy (Address.sun_path, socket_name); 
  Address.sun_family = AF_UNIX; 
  InitSocket = socket (AF_UNIX, SOCK_STREAM, 0); 
  status = bind (InitSocket, &Address, sizeof (Address));
  status = listen (InitSocket, 1);
  
  sprintf (temp, "kapa %s &", socket_name);
# ifndef DEBUG
  system (temp);
# else  
  fprintf (stderr, "start kapa, press return: %s\n", temp);
  fscanf (stdin, "%d", &i);
# endif
  
  addreslen =  sizeof (Address);
  Xgraph[N] = accept (InitSocket, &Address, &addreslen);
  if (Xgraph[N] < 0) {
    fprintf (stderr, "error starting kapa\n");
    return (FALSE);
  }
  else {
    return (TRUE);
  }
  
}

void DonePlotting (Graphdata *graphmode, int N) {
  char buffer[65], buffer2[65];

  if (Xgraph[N] == 0) return;

  write (Xgraph[N], "DBOX", 4);
  sprintf (buffer, "%f %f %f %f", graphmode[0].xmin, graphmode[0].xmax, graphmode[0].ymin, graphmode[0].ymax);
  sprintf (buffer2, "NBYTES: %6d", strlen (buffer));
  write (Xgraph[N], buffer2, 16);
  write (Xgraph[N], buffer, strlen (buffer));

  sprintf (buffer, "%s %s %s", "2222", "2222", "2222");
  sprintf (buffer2, "NBYTES: %6d", strlen (buffer));
  write (Xgraph[N], buffer2, 16);
  write (Xgraph[N], buffer, strlen (buffer));
}

void JpegPlot (Graphdata *graphmode, int N, char *filename) {
  char buffer[65], buffer2[65];

  if (Xgraph[N] == 0) return;

  write (Xgraph[N], "PNGF", 4);
  sprintf (buffer, "LEN: %11d", strlen (filename));
  write (Xgraph[N], buffer, 16);
  write (Xgraph[N], filename, strlen (filename));
  read (Xgraph[N], buffer, 4);
}

void PSPlot (Graphdata *graphmode, int N, char *filename) {
  char buffer[65], buffer2[65];

  if (Xgraph[N] == 0) return;

  write (Xgraph[N], "PSIT", 4);
  sprintf (buffer, "LEN: %11d", strlen (filename));
  write (Xgraph[N], buffer, 16);
  write (Xgraph[N], filename, strlen (filename));
  read (Xgraph[N], buffer, 4);
}

void PrepPlotting (int Npts, Graphdata *graphmode, int N) {

  int i, status;
  char buffer[128], buffer2[128];

  active = N;
  if (Npts < 1) return;

  if (Xgraph[N] < 1) if (!open_graph(N)) return;

  /* test Xgraph[N], flush junk from pipe */
  signal (SIGPIPE, XDead);
  fcntl (Xgraph[N], F_SETFL,  O_NONBLOCK); 
  for (i = 0; (read (Xgraph[N], buffer, 64) > 0) && (i < 20); i++);
  fcntl (Xgraph[N], F_SETFL, !O_NONBLOCK); 
  
  write (Xgraph[N], "ERAS", 4);
  
  /* tell kapa to look for the incoming image */
  status = write (Xgraph[N], "PLOT", 4); 

  /* send Xgraph[N] the plot details */
  sprintf (buffer, "%8d %8d %d %d %d %d %f %f", 
	   Npts, graphmode[0].style, 
	   graphmode[0].ptype, graphmode[0].ltype, 
	   graphmode[0].etype, graphmode[0].color, 
	   graphmode[0].lweight, graphmode[0].size);
  sprintf (buffer2, "NBYTES: %6d", strlen (buffer));
  write (Xgraph[N], buffer2, 16);
  write (Xgraph[N], buffer, strlen (buffer));
  
  sprintf (buffer, "%f %f %f %f", 
	   graphmode[0].xmin, graphmode[0].xmax, 
	   graphmode[0].ymin, graphmode[0].ymax);
  sprintf (buffer2, "NBYTES: %6d", strlen (buffer));
  write (Xgraph[N], buffer2, 16);
  write (Xgraph[N], buffer, strlen (buffer));

}

void PlotLabel (char *string, int N) {

  char buffer[32];

  if (Xgraph[N] == 0) return;

  write (Xgraph[N], "LABL", 4);
  sprintf (buffer, " %6d %6d", strlen (string), 2);
  write (Xgraph[N], buffer, 16);
  write (Xgraph[N], string, strlen (string));
}

void PlotVector (int Npts, double *vect, int mode, int N) {

  float *values;
  int i, Nbytes;

  active = N;
  if (Npts < 1) return;

  ALLOCATE (values, float, Npts);
  for (i = 0; i < Npts; i++) {
    values[i] = vect[i];
  }

  Nbytes = Npts * sizeof (float);
  write (Xgraph[N], values, Nbytes);
  free (values);

}

plot_list (Graphdata *graphdata, double *xlist, double *ylist, int N, char *label, char *file) {

  int i;
  char c;
  StatType stats;
  
  stats.min = stats.max = xlist[0];
  for (i = 0; i < N; i++) {
    stats.min = MIN (stats.min, xlist[i]);
    stats.max = MAX (stats.max, xlist[i]);
  }
  if (graphdata[0].xmin == dUNDEF) graphdata[0].xmin = 1.05*stats.min - 0.05*stats.max;
  if (graphdata[0].xmax == dUNDEF) graphdata[0].xmax = 1.05*stats.max - 0.05*stats.min;

  stats.min = stats.max = ylist[0];
  for (i = 0; i < N; i++) {
    stats.min = MIN (stats.min, ylist[i]);
    stats.max = MAX (stats.max, ylist[i]);
  }
  if (graphdata[0].ymin == dUNDEF) graphdata[0].ymin = 1.05*stats.min - 0.05*stats.max;
  if (graphdata[0].ymax == dUNDEF) graphdata[0].ymax = 1.05*stats.max - 0.05*stats.min;

  PrepPlotting (N, graphdata, 0);
  PlotVector (N, xlist, 0, 0);
  PlotVector (N, ylist, 1, 0);
  if (label != NULL) PlotLabel (label, 0);
  DonePlotting (graphdata, 0);

  if ((file != NULL) && SAVEPLOT) JpegPlot (graphdata, 0, file);
  if (PLOTDELAY > 500000) {
    fprintf (stdout, "press return\n"); 
    fscanf (stdin, "%*c");
  } else {
    usleep (PLOTDELAY);
  }
}

plot_defaults (Graphdata *graphdata) {

  graphdata[0].style = 2;
  graphdata[0].ptype = 2;
  graphdata[0].ltype = 0;
  graphdata[0].etype = 0;
  graphdata[0].color = black;
  graphdata[0].lweight = 0;
  graphdata[0].size = 0.5;

  graphdata[0].xmin = dUNDEF;
  graphdata[0].xmax = dUNDEF;
  graphdata[0].ymin = dUNDEF;
  graphdata[0].ymax = dUNDEF;
   
}
