{----------------------------------------------}
{                                              }
{         b   r   o   w   s   e   8   0        }
{                                              }
{ Program for previewing makedesc databases    }
{ which have been generated by make80.         }
{                                              }
{----------------------------------------------}

PROGRAM browse80;
CONST

  hashsize      =   30;
  blank40       =   '                                        ';

TYPE
  whichsection  =   (indexsection, descsection);

  pname         =   STRING[40];
  storyline     =   STRING[80];

  byte          =   0..255;

  procs         =   (pnamelookup, pentername, pdescribe, pmakename, pfindrec);

  placerec      = 
    RECORD

      CASE section:whichsection OF

        indexsection: (tableentry: INTEGER );
        
        descsection:  (name:   pname;
                       id:     INTEGER;
                       dbegin: INTEGER;
                       dend:   INTEGER;
                       link:   byte   );
    
    END;


VAR

  narrate:        FILE OF storyline;
  xfile:          FILE OF placerec;

  hash:           ARRAY[0..hashsize] OF byte;
  symhash:        INTEGER;

  where:          INTEGER;   { index TO symbol table }

  places:         ARRAY[0..255] OF placerec;

  start:          INTEGER;
  stop:           INTEGER;

  placename:      pname;
  blank80:        storyline;

  nname,
  xname:          STRING;

  i:              INTEGER;

  tracing:        BOOLEAN;
  ch:             CHAR;

  xfile_read:     placerec;
  narrate_read:   storyline;  
  


{------------------------------------}
{      t    r    a    c    e         }
{------------------------------------}
PROCEDURE trace (who: procs);
BEGIN

  CASE who OF

    pnamelookup:  writeln('namelookup');
    pentername:   writeln('entername');
    pdescribe:    writeln('describe'); 
    pmakename:    writeln('makename');
    pfindrec:     writeln('findrec');

  END { CASE who };

END { PROCEDURE trace };

{------------------------------------}
{          i    n    t    o          }
{------------------------------------}
PROCEDURE into (who: procs);
BEGIN

  IF tracing THEN
  BEGIN
  
    write ('entering ');
    trace (who);

  END;

END { PROCEDURE into };

{------------------------------------}
{    n  a  m  e  l  o  o  k  u  p    }
{------------------------------------}
FUNCTION namelookup ( thisname: pname ): BOOLEAN;
BEGIN

  into (pnamelookup);
  places[0].name := thisname;
  where          := hash[symhash];

  WHILE places[where].name <> thisname DO
    where := places[where].link
  { enddo };

    namelookup := ( where <> 0 );

END { FUNCTION namelookup };

{------------------------------------}
{      d  e  s  с  r  i   b  e       }
{------------------------------------}
PROCEDURE describe;
BEGIN

  into (pdescribe);

  start := places[where].dbegin;
  stop  := places[where].dend;

  FOR i := start TO stop DO
  BEGIN

    seek (narrate, i);

    (* old code : 
    get (narrate);
    write (narrate^);
    *)

    read (narrate, narrate_read);
    write (narrate_read);
  
  END { DO };

END { PROCEDURE describe };

{------------------------------------}
{      m  a  k  e  n  a  m  e        }
{------------------------------------}
PROCEDURE makename (VAR thisname: pname);
BEGIN

  into (pmakename);
  IF length (thisname) < 40 THEN
    thisname := concat (thisname, copy (blank40, 1, 40 - length (thisname)))
  { endif };

  writeln ('placename: ', thisname);

END { PROCEDURE makename };


{------------------------------------}
{           m   a   i   n            }
{------------------------------------}
BEGIN

  blank80   := concat (blank40, blank40);

  write ('tracing? ===>');
  readln (ch);

  IF (ch = 'y') OR (ch = 'Y') THEN
    tracing := true
  ELSE
    tracing := false
  { endif };

  nname := '';

  WHILE length (nname) = 0 DO
  BEGIN
  
    write ('description file ===> ');
    readln (nname);
  
  END { DO };

  xname := concat (nname, '.x');

  assign (xfile, xname);
  reset (xfile);
  assign (narrate, nname);
  reset (narrate);

  FOR i :=0 TO hashsize DO
  BEGIN
  
    (* old code :
    hash[i] := xfile^.tableentry;
    get (xfile);
    *)

    read (xfile, xfile_read );
    hash[i] := xfile_read.tableentry;

  END;

  i := 1;

  REPEAT

  (* old code :
  places[i] := xfile^;
  get (xfile);
  *)
  read (xfile, places[i]);
  i := i + 1;

  UNTIL eof (xfile);

  close (xfile);

{------------------------}
{  main processing loop  }
{------------------------}
  REPEAT

    writeln;
    write ('describe what place ===> ');
    readln (placename);

    IF placename[1] = '?' THEN
    BEGIN

      FOR i := 0 TO hashsize DO
      BEGIN
    
        where := hash[i];
        WHILE where <> 0 DO
        BEGIN
    
          writeln (places [where].name);
          where := places[where].link

        END { WHILE where <> 0 DO };

      END { FOR i := 1 TO hashsize DO };
  
    END
    ELSE
    BEGIN

      makename (placename);
  
      symhash := 0;

      FOR i := 1 TO length (placename) DO
        symhash := (symhash + ord (placename[i])) MOD (hashsize+1)
      { enddo };

      IF NOT namelookup (placename) THEN
        writeln ('no such place')
      ELSE
        describe

      { endif };
  
    END;
  UNTIL placename = 'quit                                    ';

END.
