/*
** HELP - Help driver for The Window Boss
**
** Copyright (c) 1985 - 1990 - Philip A. Mongelluzzo
** All rights reserved.
**
** Comments:
**
**  Help files must be formatted properly!
**
**  Use GENINDEX to create the index file.
**
*/

/* Header files */

#include "winboss.h"
#include "math.h"                       /* needed for atol */

/* Prototypes for this function */

#if CI86 | DLC
#else
static  void showpage(long offset);
static  int filbuf(long offset);
#endif

/* Equates & definitions */

#if AZTEC
#define RD "r"
#else
#define RD "rb"                         /* file access mode */
#endif

#if CI86                                /* Compiler specific stuff */
#define atol atoi                       
extern FILE *fopen();                   /* Stream I/O */
extern char *fgets();                   /* file line input */
extern char *strcpy();                  /* string copy */
extern char *strcat();                  /* concat function */
extern long atol();                     /* ascii to integer */
extern int fseek();                     /* DASD seek */
extern long ftell();                    /* where are we DASD */
#endif

static struct list {                    /* master list structure */
  char *key;                            /* pointer to %info string */
  long loc;                             /* file offset */
  int type;                             /* type <0=toc; 1=page; 2=menu> */
} master[HLPMAXKY];                     /* master ISAM structure */

#if CI86
static char **scrbuf = NUL;             /* screen buffer (array of ptrs) */
static char *line = NUL;                /* line buffer */
#else
static char **scrbuf = (char **) NULPTR;/* screen buffer (array of ptrs) */
static char *line = (char *) NULPTR;    /* line buffer */
#endif
static initflg = FALSE;                 /* init complete flag */
static int hrow, hcol;                  /* help window origin */
static int hwidth, hheight;             /* help window size */
static int hlsize;                      /* help line size */
static unsigned int hwatr, hbatr;       /* help window atributes */

static int cpg, eoh;                    /* clear screen, end of help flags */
static FILE *fp;                        /* stream file pointer */

static WINDOWPTR wn1;                   /* window pointer */
static int row, col;                    /* original cursor location */

#ifdef COMMENTS
/*
************
* showpage *                            /* internal */        
************
*/
#endif

static void showpage(offset)            /* display page function */
long offset;
{
int i,j;                                /* scratch integers */
long pages[HLPMAXKY];                   /* stack of pages */
int pndx;                               /* stack pointer */
int keyflg;                             /* vaild key flag */

  pndx = 0;                             /* init stack pointer */
  pages[0] = offset;                    /* initial page */

  while(TRUE) {                         /* till forever ... */
    i = filbuf(offset);                 /* fill the buffer */
    for(j=0; j<i; j++)                  /* display buffer */
      wn_puts(wn1,j,0,scrbuf[j]);
    if(eoh) 
      wn_putsa(wn1, 22, 0, " End of help, PgUp for previous screen, any other key to continue...", (wn1->style | BOLD));
    else
      wn_putsa(wn1, 22, 0, " Esc to quit help, PgUp for previous screen, any other key to continue...", (wn1->style | BOLD));
    keyflg = FALSE;                     /* valid key flag */
    do {                                /* loop till vaild key */
      switch (v_getch() ) {             /* based on user input */
        case PGUP:                      /* do all the right things */
          pndx--;
          if(pndx <0) {
            wn_close(wn1);
            v_locate(0, row, col);
            return;
          }
          offset = pages[pndx];
          keyflg = TRUE;
          eoh = FALSE;                  /* force clear screen */
          cpg = TRUE;                   /* and cancel end of help flag */
          break;
        case ESCAPE:
          wn_close(wn1);
          v_locate(0, row, col);
          return;
        default:
          offset = pages[++pndx] = ftell(fp);
          keyflg = TRUE;
          break;
      }
    } while (!keyflg);                  /* loop till valid key */
    if(cpg) wn_clr(wn1);
    if(eoh) {
      wn_close(wn1);
      v_locate(0, row, col);
      return;
    }
  }
}

#ifdef COMMENTS
/*
**********
* filbuf *                              /* internal */
**********
*/
#endif

static int filbuf(offset)               /* fill screen buffer */
long offset;
{
int i;
char *p, *p1;

  i=0;                                  /* initialize */
  cpg = eoh = FALSE;                    /* assume nothing */
  fseek(fp, offset, 0);                 /* position file */
  do {
    fgets(line, hlsize, fp);            /* fetch a line */
      cpg = !strncmp(".cp", line,3);    /* lite clear screen and */
      eoh = !strncmp("*END*\n",line,5); /* end of help flags */
      if(cpg || eoh) break;
      p = &line[0];                     /* a long way around to */
      p1 = scrbuf[i];                   /* filter the carriage */
      while (*p) {                      /* returns !! */
        switch (*p) {
          case '\r':
          case '\n':
            p++;
            break;
          default:
            *p1++ = *p++;
            break;
        }
      }
      *p1 = '\0';
      i++;
  } while (TRUE);
  return(i);                            /* return the # of lines on page */
}

/*
*************
* wn_hlinit *
*************
*/

wn_hlinit(row,col,width,height,atrib,batrib,help_file_name)
int row, col;                           /* origin of help window */
int width, height;                      /* width and height */
unsigned int atrib, batrib;             /* window & boarder attributes */
char *help_file_name;                   /* help file name */
{
  if(initflg) {                         /* already called ?? */
    if(initflg == -2) return(FALSE);    /* died last time ?? */
    return(TRUE);                       /* avoid foolishness */
  }

  hrow = row;                           /* origin */
  hcol = col;
  hwidth = width;                       /* window size */
  hheight = height;       
  hlsize = width+2;                     /* line size (width+2 for border) */
  hwatr = atrib;                        /* attributes */
  hbatr = batrib;

  scrbuf = malloc((height+2) * sizeof(char *) * hlsize); 
  if(!scrbuf) {
    wns_errcod = 1;
    return(FALSE);
  }
  line = malloc((hlsize) * sizeof(char)); 
  if(!line) {
    wns_errcod = 2;
    return(FALSE);
  }
  if(!wn_help("@")) {                   /* allocate the memory */
    initflg = -2;                       /* DONT ALLOW FURTHER ATTEMPTS */
    return(FALSE);                      /* return if error */
  }
  else {                                /* set up buffers if ok.. */
    return(wn_help(help_file_name));    /* setup help ISAM */
  }
}

/*
***********
* wn_help *
***********
*/

wn_help(subject)                        /* help function */
char *subject;                          /* help subject request */
{
char tmpname[80];                       /* temporary filename */
int i;                                  /* scratch integer */

  switch(subject[0]) {                  /* on first char of subject ... */
    case '%':                           /* subject page */
      wn1 = wn_open(0, hrow, hcol, hwidth, hheight, hwatr, hbatr);
      if(!wn1) return(FALSE);           /* error return */
      wn_wrap(wn1,FALSE);               /* no wrap thank you */
      v_rcpos(0, &row, &col);           /* remember current location */
      v_hidec();                        /* hide the physical cursor */
      wn_locate(wn1,0,0);               /* home virtual cursor */
      if(!initflg) return(FALSE);       /* illegal sequence of calls */
      i=0;                              /* start search index */
      while(i < HLPMAXKY) {             /* look for match in key table */
        if(!strncmp(subject,master[i].key,strlen(subject))) {
          showpage(master[i].loc);      /* display all pages */
          return(TRUE);                 /* return .. all is well */
        }
        i++;
      }
      wn_printf(wn1," Sorry... No info on %s\n", subject);
      wn_printf(wn1," Press any key to continue...");
      v_getch();
      wn_close(wn1);
      return(FALSE);                    /* no match !! */
    case '$':                           /* menu page */
      break;                            /* sometime in the future */
    case '@':                           /* Initialize (allocate memory) */
      for(i=0; i<HLPMAXKY; i++) {
        master[i].key = malloc(HLPKEYLN);  /* keys can be 25 chars long */
        if(!master[i].key) {
          wns_errcod = 3;
          return(FALSE);
        }
      }
      for(i=0; i<hheight+1; i++) {       /* allocate memory for screen bfr */
        scrbuf[i] =  malloc((hlsize+1) * sizeof(char*));
        if(!scrbuf[i]) {
          wns_errcod = 4;
          return(FALSE);
        }
      }
      initflg = TRUE;
      return(TRUE);
    default:                            /* assume help filename */
      if(!initflg) return(FALSE);       /* illegal sequence of calls */
      strcpy(tmpname,subject);          /* form filename from root */
      strcat(tmpname,".ndx");
      if(!(fp = fopen(tmpname,RD))) {   /* index file cant be found ! */
        printf("Can't find index file\n");
        printf("Press any key to continue...");
        v_getch();
        return(FALSE);
      }
      i = 0;                            /* read and process key file */
      while(fgets(line,hlsize,fp)) {    /* build the master index table */
        strcpy(master[i].key, line);
        if(line[0] != '%')              /* ignore all but subects */
          continue;
        fgets(line,hlsize,fp);
        master[i].loc = atol(line);
        i++;
      }
      fclose(fp);                       /* close index file */
      strcpy(tmpname, subject);         /* form help file name from root */
      strcat(tmpname, ".hlp");          /* open and leave open ! */
      if(!(fp = fopen(tmpname, RD))) return(FALSE);
      return(TRUE);
  }
}

/* End */
