/* A program to test XANT's EHLLAPI interface */

#include <stdio.h>
#include <string.h>
#include <varargs.h>
#include "hapi_c.h"

#define MAX_DATA_SIZE 65536


/* Global variables */
static char *progname;		/* The name of this program */
static void error(), dumpbuff();


/* Main program */
main(argc, argv)
     int argc;
     char *argv[];
{
  int j, function, data_length, rc;
  char *data_string;
  int cols, rows, pos, inputpos;

  progname = argv[0];

  if (!(data_string = (char *) malloc(MAX_DATA_SIZE)))
    error("Not enough memory");
  
  function = HA_RESET_SYSTEM;
  data_length = 0;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Reset failed (RC=%d)", rc);

  function = HA_CONNECT_PS;
  data_string[0] = 'a';
  data_length = 1;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Connect failed (RC=%d)", rc);

  function = HA_QUERY_SESSION_STATUS;
  data_string[0] = ' ';
  data_length = 18;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Query session status failed (RC=%d)", rc);
  printf("Session status:\n");
  printf("    Short session ID = %c\n", data_string[0]);
  printf("    Session type = %c\n", data_string[9]);
  printf("    Session characteristics = 0x%02X\n", data_string[10]);
  rows = ((int) data_string[11] << 8) + (int) data_string[12];
  cols = ((int) data_string[13] << 8) + (int) data_string[14];
  printf("    Rows = %d, cols = %d\n", rows, cols);
  
  function = HA_QUERY_SESSIONS;
  data_length = MAX_DATA_SIZE;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Query sessions failed (RC=%d)", rc);
  printf("Results of query sessions:\n");
  for (j = 0; j < data_length; j++)
    {
      printf("    Short session ID = %c\n", data_string[12*j + 0]);
      printf("    Session type = %c\n", data_string[12*j + 9]);
      printf("    Presentation space size = %d\n",
	     ((int) data_string[12*j+10] << 8) + (int) data_string[12*j+11]);
      if (data_length > 1) printf("\n");
    }
  
  function = HA_QUERY_SYSTEM;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Query system failed (RC=%d)", rc);
  printf("API version number = %c\n", data_string[0]);
  
  function = HA_SET_CURSOR;
  rc = 123;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Set cursor location failed (RC=%d)", rc);

  function = HA_QUERY_CURSOR_LOC;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Query cursor location failed (RC=%d)", rc);
  printf("Cursor location = %d\n", data_length);

  function = HA_CONVERT_POS_ROW_COL;
  data_string[0] = 'A';
  data_string[1] = 'P';
  rc = 85;
  hllc(&function, data_string, &data_length, &rc);
  if (rc == 0 || rc >= 9998) error("Convert position failed (RC=%d)", rc);
  printf("Position 85 is row %d, column %d\n", data_length, rc);

  function = HA_CONVERT_POS_ROW_COL;
  data_string[0] = 'A';
  data_string[1] = 'R';
  data_length = 2;
  rc = 3;
  hllc(&function, data_string, &data_length, &rc);
  if (rc == 0 || rc >= 9998) error("Convert rowcol failed (RC=%d)", rc);
  printf("Row 2, column 3 is position %d\n", rc);
  
  function = HA_SET_SESSION_PARMS;
  strcpy(data_string, "SRCHFRWD, srchall, EOT=$");
  data_length = strlen(data_string);
  hllc(&function, data_string, &data_length, &rc);
  if (rc == HARC_BAD_PARM) error("Session parameter %d invalid\n",
				 data_length + 1);
  if (rc != HARC_SUCCESS) error("Set session parms failed (RC=%d)", rc);

  function = HA_SEARCH_PS;
  data_length = 7;
  strcpy(data_string, "RUNNING");
  hllc(&function, data_string, &data_length, &rc);
  if (rc == HARC_STR_NOT_FOUND_UNFM_PS)
    printf("Could not find \"RUNNING\" string\n");
  else if (rc != HARC_SUCCESS)
    error("Search PS failed (RC=%d)", rc);
  else printf("Found \"RUNNING\" at position %d\n", data_length);

  function = HA_SENDKEY;
  strcpy(data_string, "@C@EMSG * Test of sendkey@E");
  data_length = strlen(data_string);
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Send key failed (RC=%d)", rc);
  
  function = HA_WAIT;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Wait failed (RC=%d)", rc);
  
  function = HA_FIND_FIELD_POS;
  data_string[0] = 'N';
  data_string[1] = 'U';
  rc = 1;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Find field pos failed (RC=%d)", rc);
  inputpos = data_length;
  printf("Position of first unprotected field = %d\n", inputpos);

  function = HA_SENDKEY;
  strcpy(data_string, "@A@F");	/* Erase input */
  data_length = strlen(data_string);
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Send key failed (RC=%d)", rc);
  
  function = HA_COPY_STR_TO_PS;
  strcpy(data_string, "MSG * Hi there!");
  data_length = strlen(data_string);
  rc = inputpos;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Copy string to PS failed (RC=%d)", rc);

  function = HA_SENDKEY;
  strcpy(data_string, "@E");
  data_length = strlen(data_string);
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Send key failed (RC=%d)", rc);
  
  function = HA_WAIT;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Wait failed (RC=%d)", rc);
  
  function = HA_SET_SESSION_PARMS;
  strcpy(data_string, "STREOT, EOT=$, SRCHBKWD, NORESET");
  data_length = strlen(data_string);
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Set session parms failed (RC=%d)", rc);

  function = HA_COPY_STR_TO_FIELD;
  rc = inputpos;
  strcpy(data_string, "MSG * Test of copy string to field$");
  data_length = 0;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Copy string to field failed (RC=%d)", rc);

  function = HA_SENDKEY;
  strcpy(data_string, "@E");
  data_length = strlen(data_string);
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Send key failed (RC=%d)", rc);
  
  function = HA_WAIT;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Wait failed (RC=%d)", rc);
  
  (void) sleep(1);

  function = HA_COPY_PS;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Copy PS failed (RC=%d)", rc);
#ifdef foo
  printf("PS contents:\n");
  dumpbuff(data_string, cols * rows);
#endif

  function = HA_COPY_PS_TO_STR;
  data_length = 16;
  rc = 81;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Copy PS to string failed (RC=%d)", rc);
  printf("Copy PS to string results:\n");
  dumpbuff(data_string, 16);

  function = HA_QUERY_FIELD_ATTR;
  rc = 1;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Query field attribute failed (RC=%d)", rc);
  printf("Field attribute for position 1 = 0x%02X\n", data_length);
  
  function = HA_FIND_FIELD_POS;
  data_string[0] = 'T';
  data_string[1] = ' ';
  rc = 1;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Find field pos failed (RC=%d)", rc);
  printf("Starting position of field = %d\n", data_length);

  function = HA_FIND_FIELD_LEN;
  data_string[0] = 'T';
  data_string[1] = ' ';
  rc = 1;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Find field len failed (RC=%d)", rc);
  printf("Field length = %d\n", data_length);

  function = HA_FIND_FIELD_POS;
  data_string[0] = 'P';
  data_string[1] = ' ';
  rc = 1;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Find field pos failed (RC=%d)", rc);
  pos = data_length;
  printf("Position of last field = %d\n", pos);

  function = HA_FIND_FIELD_LEN;
  data_string[0] = 'T';
  data_string[1] = ' ';
  rc = pos;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Find field len failed (RC=%d)", rc);
  printf("Field length = %d\n", data_length);

  function = HA_COPY_FIELD_TO_STR;
  rc = pos;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Copy field to string failed (RC=%d)", rc);
  printf("Contents:\n");
  dumpbuff(data_string, data_length);

  function = HA_SEARCH_FIELD;
  data_length = 1;
  strcpy(data_string, "READ$");
  rc = pos + 2;
  hllc(&function, data_string, &data_length, &rc);
  if (rc == HARC_STR_NOT_FOUND_UNFM_PS)
    printf("Could not find \"READ\" string\n");
  else if (rc != HARC_SUCCESS)
    error("Search field failed (RC=%d)", rc);
  else printf("Found \"READ\" at position %d\n", data_length);

  function = HA_DISCONNECT_PS;
  hllc(&function, data_string, &data_length, &rc);
  if (rc != HARC_SUCCESS) error("Disconnect failed (RC=%d)", rc);

  return 0;
}


/* Print an error message to stderr and halt */
static void error(va_alist)
     va_dcl
{
  va_list ap;
  char *format;

  fprintf(stderr, "%s: ", progname);
  va_start(ap);
  format = (char *) va_arg(ap, char *);
  vfprintf(stderr, format, ap);
  va_end(ap);
  putc('\n', stderr);
  exit(1);
}


/* Print out a data buffer */
static void dumpbuff(buff, len)
     char *buff;
     int len;
{
  int i, j, numrows;
  char c;

  numrows = (len + 15) / 16;
  for (i = 0; i < numrows; i++) 
    {
      printf("    ");
      for (j = 0; j < 16; j++) 
	{
	  if (j + i * 16 >= len) printf("  ");
	  else printf("%02X", buff[j + i * 16]);
	  if (j % 4 == 3) putchar(' ');
	}
      printf(" |");
      for (j = 0; j < 16; j++)
	{
	  if (j + i * 16 >= len) putchar(' ');
	  else 
	    {
	      c = buff[j + i * 16];
	      putchar((c >= 32 && c < 127) ? c : '.');
	    }
	}
      printf("|\n");
    }
}
