/* simhelp.c

   written by Don Robert Maszle
   27 July 1992

   Copyright (c) 1993.  Don Maszle, Frederic Bois.  All rights reserved.

   -- Revisions -----
     Logfile:  SCCS/s.simhelp.c
    Revision:  1.7
        Date:  28 Jan 1995
     Modtime:  03:43:37
      Author:  @a
   -- SCCS  ---------

*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>

#include "simhelp.h"

static char *vszHelpFilename = "simhelp.txt";


/* -----------------------------------------------------------------------------
   IgnoreCase_strstr

   returns non-NULL if szSub matches the head of szSearch, ignoring
   case.
*/

char *IgnoreCase_strstr (char *szSearch, char *szSub)
{
  char *szSearchSave = szSearch;

  if (!szSearch || !szSub)
    return NULL;

  while (*szSub && *szSearch &&
         tolower(*szSearch) == tolower(*szSub)) {
    szSearch++; /* Don't inc these in the macro tolower()! */
    szSub++;
  } /* while */

  /* Matched if nothing left of szSub! */
  return (*szSub ? NULL : szSearchSave);

} /* *IgnoreCase_strstr */


/* -----------------------------------------------------------------------------
   FindNextMatch

   searches the given file for the szKeyword in brackets at the
   beginning of the line.  Returns TRUE if a match is found and
   leaves the pfileHelp set to the beginning of the the relevant help
   section.
*/

BOOL FindNextMatch (FILE *pfileHelp, char *szTestKeyword)
{
  int ch;
  BOOL bFound = FALSE;
  char szKeyword[MAX_KEYWORD];

  if (pfileHelp)
    while (!feof(pfileHelp)) {
      ch = getc (pfileHelp);

      switch (ch) {
        case EOF:
          goto Exit_FindNextMatch; /* Stop processsing */
          break;

        case '[':
          while (!bFound) {
            while ((ch = getc(pfileHelp)) == ' ' /* Skip whitespace */
                   || ch == '\t' || ch == '\n')
              ;
            if (ch == ']') /* No more keys left here */
              break;

            ungetc (ch, pfileHelp);
            fscanf (pfileHelp, "%[^]\n \t]", szKeyword);
            bFound = ((int) IgnoreCase_strstr(szKeyword, szTestKeyword));
          } /* while */

          fscanf (pfileHelp, "%*[^\n]");
          getc (pfileHelp);
          if (bFound) goto Exit_FindNextMatch; /* Found one! */
          break;

        default:
          ungetc (ch, pfileHelp);
          fscanf (pfileHelp, "%*[^\n]");  getc (pfileHelp);
          break; /* Continue looking next line */
      } /* switch */

    } /* while */

Exit_FindNextMatch:
  return (bFound);

} /* FindNextMatch */


char PauseForKey (char *szKeys)
{
  int ch;
  printf ("-- More --");

  do {
    ch = getchar();
  }
  while (!strchr (szKeys, ch));
  return ch;

} /* PauseForKey */


/* -----------------------------------------------------------------------------
   MoreToNextTopic

   displays the text in a file from lPos to the next occurence of
   `[keyword]' at the begining of a line.
*/

void MoreToNextTopic (FILE *pfile)
{
  #define LINES_PER_PAGE 22

  int ch;
  long cLines = 0;
  char szLine[MAX_HELP_LINE];

  while (!feof(pfile)) {

    ch = getc (pfile);
    if (ch == '[') {
      ungetc (ch, pfile);
      break;
    }

    if (ch == '\n') putchar ('\n');
    else {
      szLine[0] = '\0';
      fscanf (pfile, "%[^\n]", szLine);
      getc (pfile);
      printf ("%c%s\n", ch, szLine);
    }

    cLines++;
    if (!(cLines % LINES_PER_PAGE)) {
      char chKey = PauseForKey ("\n qQ");
      cLines = 0;
      if (tolower(chKey) == 'q') break;
    }

  } /* while */

} /* MoreToNextTopic */


/* -----------------------------------------------------------------------------
*/

void ShowTopics (FILE *pfileHelp)
{

  printf ("Topics not implemented.\n");

} /* ShowTopics */


/* -----------------------------------------------------------------------------
   SimOpenFile

   Opens file with the specified access priveledges.

   Return non-zero on error.
*/

int SimOpenFile (FILE **ppfile, char *szFilename, SOF_FLAGS sofFlags)
{
  *ppfile = NULL;

  switch (sofFlags) {
    case SOF_READ:
      *ppfile = fopen (szFilename, "r");
      break;

    default:
      printf ("SimOpenFiles unknown flags :%x\n", sofFlags);
  } /* switch */

  return (!ppfile);

} /* SimOpenFile */


/* -----------------------------------------------------------------------------
*/

void ShowHelpMessage (char *const szProgName)
{

  printf ("\nHelp!  For help on a topic enter\n\t%s -h topic\n\n",
      szProgName);
  printf ("Several topics are:  Usage, Intro, Commands, and Topics\n\n");

} /* ShowHelpMessage */


/* -----------------------------------------------------------------------------
   ShowHelp

   displays help about keyword szKeyword if it can find an exact
   match or an abbreviated match int the vszHelpFilename.
*/

void ShowHelp (char *szKeyword)
{
  FILE *pfileHelp;
  BOOL bFound = FALSE;

  printf ("Help topic: `%s'\n\n", szKeyword);

  if (!SimOpenFile(&pfileHelp, vszHelpFilename, SOF_READ)) {

    if (IgnoreCase_strstr("Topics", szKeyword)) ShowTopics (pfileHelp);
    else {
      while (FindNextMatch (pfileHelp, szKeyword)) {
        if (bFound) {
          /* Pause between sections */
          char chKey = PauseForKey ("\n qQ");
          if (tolower(chKey) == 'q') break;
        } /* if */

        MoreToNextTopic (pfileHelp);
        bFound = TRUE;
      } /* while */

      if (!bFound)
        printf ("** Sorry, no help available on topic `%s' "
                "in documentation `%s'.\n", szKeyword, vszHelpFilename);
    } /* else */

  } /* if */

} /* ShowHelp */



