!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!  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
!    rraszews@hotmail.com
!    lraszewski@loyola.edu
!    rraszews@usa.net
!    rraszews@teamknightrider.com
!    rraszews@skipjack.bluecrab.org
!    lraszews@csmaster.loyola.edu
!    rraszews@acm.org
!
!       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;
                  ];

