# include "display.h"
# include "shell.h"
# define DEBUG 0

/* we have space for several kapa windows */
# define NXGRAPH 5

static int       Active;
static int       Xgraph[NXGRAPH];  
static Graphdata graphdata[NXGRAPH];

void QuitGraph () {

  int i;
  
  for (i = 0; i < NXGRAPH; i++) {
    KiiClose (Xgraph[i]);
  }
}

void InitGraph () {

  int i;

  Active = 0;
  for (i = 0; i < NXGRAPH; i++) {
    Xgraph[i] = -1;

    graphdata[i].xmin = graphdata[i].ymin = 0.0;
    graphdata[i].xmax = graphdata[i].ymax = 1.0;
    graphdata[i].style = graphdata[i].ptype = 0;
    graphdata[i].ltype = graphdata[i].color = 0;
    graphdata[i].etype = graphdata[i].ebar = 0;
    graphdata[i].lweight = graphdata[i].size = 1.0;
    
    graphdata[i].coords.pc1_1 = graphdata[i].coords.pc2_2 = 1.0;
    graphdata[i].coords.pc1_2 = graphdata[i].coords.pc2_1 = 0.0;
    strcpy (graphdata[i].coords.ctype, "RA---LIN");
    graphdata[i].coords.crval1 = 0.0;
    graphdata[i].coords.crval2 = 0.0;
    graphdata[i].coords.crpix1 = 0.0;
    graphdata[i].coords.crpix2 = 0.0;
    graphdata[i].coords.cdelt1 = graphdata[i].coords.cdelt2 = 1.0;
    graphdata[i].flipeast = TRUE;
    graphdata[i].flipnorth = FALSE;
    strcpy (graphdata[i].axis, "2222");
    strcpy (graphdata[i].ticks, "2222");
    strcpy (graphdata[i].labels, "2222");
  }
}

/* set SIGPIPE to this function to close cleanly */ 
void XGraphDead (int input) {
  signal (SIGPIPE, XGraphDead);
  gprint (GP_ERR, "kapa is dead, must restart\n");
  Xgraph[Active] = -1;
}

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

  int fd;
  char *kapa_exec, name[16];
  
  kapa_exec = get_variable ("KAPA");
  if (kapa_exec == (char *) NULL) {
    gprint (GP_ERR, "variable KAPA not found\n");
    return (FALSE);
  }

  snprintf (name, 16, "[%d]", N);
  fd = KiiOpen (kapa_exec, name);
  free (kapa_exec);

  if (fd < 0) {
    gprint (GP_ERR, "error starting kapa\n");
    return (FALSE);
  } 

  Xgraph[N] = fd;
  return (TRUE);
}

int close_graph (int N) {

  if (N <  0) return (FALSE);
  if (N >= NXGRAPH) return (FALSE);

  KiiClose (Xgraph[N]); 
  Xgraph[N] = -1;
  return (TRUE);
}

/* return pointers for current Xgraph, set if desired, test, open if needed */
int GetGraph (Graphdata *data, int *socket, int *N) {

  int i, n;
  char buffer[70];

  SetImageDevice (FALSE);
  if (N == (int *) NULL) {
    n = Active;
  } else {
    if (*N >= NXGRAPH) {
      gprint (GP_ERR, "invalid Xgraph window %d\n", *N); 
      return (FALSE);
    }
    if (*N < 0) {
      *N = n = Active;
    } else {
      Active = n = *N;
    }
  }
  
  /* test Xgraph[0], flush junk from pipe */
  signal (SIGPIPE, XGraphDead);
  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); 
  
  if (Xgraph[n] < 1) {
    if (!open_graph(n)) {
      return (FALSE);
    }
  }

  if (data != (Graphdata *) NULL) *data  = graphdata[n];
  if (socket != (int *) NULL) *socket = Xgraph[n];

  return (TRUE);

}

/* return pointers for given Xgraph, don't set or open */
int GetGraphData (Graphdata *data, int *sock, int *N) {

  int n;

  if (N == (int *) NULL) {
    n = Active;
  } else {
    if (*N >= NXGRAPH) {
      gprint (GP_ERR, "invalid Xgraph window %d\n", *N); 
      return (FALSE);
    }
    if (*N < 0) {
      n = Active;
    } else {
      n = *N;
    }
  }
  
  if (data != (Graphdata *) NULL) *data  = graphdata[n];
  if (sock != (int *) NULL) *sock = Xgraph[n];

  return (TRUE);

}

/* assign given values to current Xgraph */
void SetGraph (Graphdata data) {
  graphdata[Active] = data;
}

/** internal tracking of current active device type **/

static int       IsImage = FALSE;

int GetCurrentDevice () {
  return (IsImage);
}

void SetImageDevice (int state) {
  IsImage = state;
}

