!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!  Manual.H                     An Inform 6 library
!                               to generate nicely-formatted browseable text
!    Version 5.0                for Z-Machine books and built-in manuals.
!                               By L. Ross Raszewski
!
!  Requires Utility.h, Istring.h, Center.h
!
! New in this version:  Table of contents
!
! The above description pretty much explains what this library does, which
! means that the only really salient point now is how to use it.
!
! A manual is defined as a set of objects contained within a manual class
! object.  The name of the manual object is used for the top-level title
! bar on the manual display.  The name of the individual page object is
! used as the subtitle for the current page.  The text of the page is
! contained in the description property of the page object.
!
! The description of the Manual is used as page 0, the title page.
!
!
! To activate the menu, send the select() message to a manual object:
!                game_manual.select();
! To start on a page other than the title page, pass the page number as an
! argument to select();
! To, for instance, start on page 2, call game_manual.select(2);
!
! To use a table of contents:
!
! Create a page of class ContentsPage.  All manual pages with the "on"
! attribute will be displayed in the table by name.
! The PageHeader property contains a routine to print text heading the
! table.
! The ListEntry property contains the routine to print the table entries.
! For tables over one page, use the page property to set a contents page:
! for a 3-page table of contents, create 3 ContentsPage pages, with .page
! set to 1, 2, and 3 respectively.  Uneeded pages will be left blank.
!
!
! Questions, comments, suggestions?  e-mail me at
!    [email protected]
!    [email protected]
!    [email protected]
!    [email protected]
!    [email protected]
!    [email protected]
!    [email protected]
!
!       I'm currently looking for a way to detect how many lines
!       a printed passage will occupy on the screen.  If anyone
!       can offer any help, I'll be much obliged.

Iffalse UTILITY_LIBRARY >= 21;
message error "Manual.H requires version 2.1 or greater of the utility library.";
Endif;
Ifndef CenterU;
message error "Manual.H requires the center.h library";
Endif;
Iffalse ISTRING_LIBRARY >= 20;
message error "Manual.H requires version 2 or greater of the IString library.";
Endif;

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Language Definition Block
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Constant MAN_PKEY__TX "P = previous page";
Constant MAN_NKEY__TX "N = next page";
Constant MAN_QKEY__TX "Q = resume story";
Constant MAN_GKEY__TX "G = Go to page ";


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!Manual Class
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Class Manual
       with

            emblazon [ i j;
                       if (pretty_flag==0) return self.Lowkey_emblazon();
                       @erase_window -1;
                       i=0->33; if (i==0) i=80;
                       style roman;
                       @split_window 3; @set_window 1; style reverse;
                       @set_cursor 1 1; spaces(i);
                       @set_cursor 2 1; spaces(i);
                       @set_cursor 3 1; spaces(i);
                       @set_cursor 1 1; print "Page ", self.pagen;
                       CenterU(self.doname,1);
                       style bold;style reverse;
                       CenterU(self.dopagename,2); style roman;
                       style reverse;
                       @set_cursor 2 2; print (string) MAN_PKEY__TX;
                       j=i-14 ;
                       @set_cursor 2 j; print (string) MAN_NKEY__TX;
                       @set_cursor 3 2; print (string) MAN_QKEY__TX;
                       @set_cursor 3 j; print (string) MAN_GKEY__TX;
                       @set_window 0; style roman; font on;
                      ],
             Lowkey_emblazon [;
                               print "^^---"; self.doname(); print "---^";
                               print "Page:", self.pagen, " ";
                                       self.dopagename(); print "^^";
                               print (string) MAN_PKEY__TX;
                               spaces(4);
                               print (string) MAN_NKEY__TX;
                               new_line;
                               print (string) MAN_QKEY__TX;
                               spaces(4);
                               print (string) MAN_GKEY__TX;
                               new_line; new_line;
                             ],
             select [ startpage;
                       self.pagen=startpage;
                       while (self.dopage()~=2);
                       if (pretty_flag~=0) @erase_window -1;
                       print "^^Back to story...^^"; rtrue;
                    ],
             page 0, pagen 0,
             doname [; print (name) self;],
             dopagename [; print (name) self.page;],
             dopage [ j;
                       self.page=Scion(self,self.pagen);
                       self.emblazon();
                       self.page.description();
                       j=self.keyloop();
                       switch (j)
                       {
                        0: self.pagen--;
                        1: self.pagen++;
                        2: return 2;
                       }
                       if (self.pagen<0) self.pagen=0;
                       if (self.pagen>children(self))
                               self.pagen=children(self);
                        return 1;
                     ],
             keyloop [ keypress k;
                       do { @read_char 1 0 0 keypress;}
                       until ((keypress==129 or 'P' or 'p' or 130
                              or 'N' or 'n' or 'q' or 'Q' or 27
                              or 'g' or 'G')
                              || (keypress==32 or 10 or 13 && self.pagen==0));

                       if (keypress==129 or 'P' or 'p') return 0;
                       if (keypress==32 or 10 or 13 && self.pagen==0) return 1;
                       if (keypress=='G' or 'g')
                               {
                                if (pretty_flag)
                                       box "Go to what page?";
                                else print "Go to what page? >";
                                read buffer parse;
                                k=parse-->1;
                                if (parse->1==0) return 4;
                                k=TryNumber(1);
                                self.pagen=k;
                                return 3;
                                }
                        if (keypress==130 or 'N' or 'n') return 1;
                        if (keypress==27 or 'Q' or 'q') return 2;
                       ];

Class ContentsPage
   with
        description [ o i; new_line;
                          self.PageHeader();
                          objectloop(i in parent(self))
                          {
                           o++;
                           if (i has on && o<ValueOrRun(self,ucutoff)
                               && o>ValueOrRun(self,lcutoff))
                           {
                            self.listitem=i;
                            self.ListEntry(o);
                            new_line;
                           }
                          }
                    ],
       ucutoff [; return (self.page)*(0->33-5);],
       lcutoff [; return (self.page-1)*(0->33-5)+1;],
       page 1,
       PageHeader [; rtrue;],
       ListItem 0,
       PrintItem [;
                   print (name) self.ListItem;
                 ],
       ListEntry [ num i;
                       i=(0->33)-13;
                       if (i<=0) i=(0->33)-3;
                       spaces(5);
                       LJustify(Self.PrintItem,i,LEFT,'.');
                       print num;
                 ];