/*
 * Pctrl -- plot control 
 * This object is the app delegate for the gnuplot_x11 spoofer.
 */

#import "Pctrl.h"

@implementation Pctrl

/*
 * Handle input from fd.
 */
-handle_input
{
  char buf[128], *res, *ncmd;

  /*
   * Read commands until we run out.
   */
  while (1) {
    res = fgets(buf, 128, stdin);
    if (res == (char *) NULL) {
      if (feof(stdin)) {
	[NXApp terminate:self];
      }
      else {
	/*
	 * The most common error here is EWOULDBLOCK.
	 * This means we've run out of commands for now.
	 */
	extern int errno;

	if (errno != EWOULDBLOCK)
	  perror("fgets");
	return self;
      }
    }

#if DEBUG
    fputs(buf, debug_out);
    fflush(debug_out);
#endif
    
    switch (buf[0]) {
    case 'R':			/* bye bye */
      [NXApp terminate:self];
      break;
    case 'G':
      /*
       * Enter graphics mode; begin collecting commands.
       */
      if (commands) {		/* free old commands */
	int i;
      
	for (i = 0; i < nc; i++)
	  free(commands[i]);
	free(commands);
	commands = (char **) NULL; nc = 0;
      }
      break;
    case 'E':			/* end of commands; draw the plot */
      [plotview display_commands: commands : nc];
      break;
    default:
      /*
       * Append command to command list.
       */
      ncmd = (char *) malloc(strlen(buf) + 1);
      assert(ncmd != (char *) NULL);
      strcpy(ncmd, buf);

      if (commands) {
	commands = (char **) realloc(commands, sizeof(char *) * (nc + 1));
      }
      else {
	commands = (char **) malloc (sizeof(char *));
	nc = 0;			/* just in case */
      }
      assert(commands != (char **) NULL);
      commands[nc++] = ncmd;
    }
  }
  return self;
}

/*
 * Set to self at init time since fd_handler doesn't
 * have access to the object's instance variables.
 */
id myself;

void fd_handler (fd, data)
     int fd;
     void *data;
{
  [myself handle_input];
}

-appDidInit:sender
{
#if DEBUG
  debug_out = fopen("gplot.dbg", "w");
  if (debug_out == (FILE *) NULL) {
    perror("fopen");
    [NXApp terminate:self];
    return self;
  }
#endif
  commands = (char **) NULL; nc = 0;
   
  myself = self;
  /*
   * Call fd_handler when we have pending input.
   */
  DPSAddFD(fileno(stdin), fd_handler, (void *)0, NX_BASETHRESHOLD);
  return self;
}

@end
