/* $Filename:    ReportPlus/Source/rp1.c
 * $VER:         Report+ 4.12
 * $Description: Multi-function utility
 *
 * © Copyright 2000 James R. Jacobs. Freely distributable.
 *        _
 *       //      -=AMIGA=-
 *      //
 * _   //
 * \\ //
 *  \X/

done:  about letter shadows.
       more efficient memory.
       'finish' button for autodocs.
       bugfixes. (no longer crashes)
       aminet listviews.
       f10 shortcuts.
do:    eol wildcard capability.
       finish type entries for f2.c.
       more shortcuts.
       make f9, f10 modules: remember IDCMP_CLOSEWINDOW.
next version?:
       /M implementation for EOL arguments
consider:
       remember to provide as much source to developers as is feasible.
       shaded window backgrounds.

0394962978

#INCLUDES -------------------------------------------------------------- */

// #include <assert.h>

#include <exec/types.h>
#include <exec/alerts.h>
#include <exec/nodes.h>
#include <exec/memory.h>
#include <pragmas/exec_pragmas.h>
#include <clib/exec_protos.h>
#include <exec/execbase.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <graphics/displayinfo.h>
#include <libraries/gadtools.h>
#include <workbench/workbench.h> /* struct DiskObject */
#include <libraries/asl.h>
#include <resources/battmem.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <dos/dosextens.h>

#include <stdio.h>          /* FILE, printf() */
#include <stdlib.h>         /* EXIT_SUCCESS, EXIT_FAILURE */

#include "amigan.h"
#include "rp.h"

#define PALMENUHEIGHT   206 // page 0 (+8 pixels per extra function)
#define PUBMENUHEIGHT   (PALMENUHEIGHT + 28)

#define DEPTH              4

#define PROJECTSTART       0 /* array offsets of menu headers */
#define HELPSTART          2
#define MN_PROJECT         0
#define IN_QUIT            0
#define MN_HELP            1
#define IN_MANUAL          0
#define IN_ABOUT           2

#define SECRETLENGTH       4 /* how many characters in secret? */

MODULE UWORD LogoData[754] =
{   /* Plane 0 */
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8000,0x000F,
    0x1FFF,0xFC00,0x1FFF,0xFFFF,0xFFF0,0x0000,0x7FF0,0x007F,0xFFC0,0x007F,0xFFFF,0x8000,0x000F,
    0x1FFF,0xFFE0,0x1FFF,0xFFFF,0xFFFF,0xE007,0xFFFF,0xC07F,0xFFFF,0x807F,0xFFFF,0x8001,0xF00F,
    0x1FFF,0xFFF8,0x1FFF,0xFFDF,0xFFFF,0xF81F,0xFFFF,0xE07F,0xFFFF,0xE07F,0xFFFF,0x800F,0xF00F,
    0x1FE0,0x0FFC,0x1F80,0x001F,0xE07F,0xFC3F,0xC00F,0xF07F,0x81FF,0xF000,0x7FC0,0x000F,0xF00F,
    0x1FE0,0x03FC,0x1F80,0x001F,0xE003,0xFC7F,0x8007,0xF87F,0x800F,0xF000,0x7FC0,0x000F,0xF0FF,
    0x1FE0,0x03FC,0x1F00,0x401F,0xE003,0xFC7F,0x8007,0xF87F,0x800F,0xF000,0x7FC0,0x000F,0xE7FF,
    0x1FE0,0x07F8,0x1FFF,0x801F,0xE00F,0xF87F,0x8007,0xF87F,0x803F,0xE000,0x7FC0,0x000F,0xFFFF,
    0x1FE0,0x1FE0,0x1FFE,0x001F,0xE07F,0xE07F,0x8007,0xF87F,0x81FF,0x8000,0x7FC0,0x01FF,0xFF0F,
    0x1FFF,0xFF80,0x1FF8,0x001F,0xFFFF,0x807F,0x8007,0xF87F,0xFFFE,0x0000,0x7FC0,0x0FFF,0xF80F,
    0x1FFF,0xFE00,0x1F80,0x001F,0xFFFE,0x007F,0x8007,0xF07F,0xFFF8,0x0000,0x7FC0,0x0FEF,0xF00F,
    0x1FFF,0xFE00,0x1F80,0x001F,0xFFE0,0x003F,0xC00F,0xF07F,0xFFF8,0x0000,0x7FC0,0x1E0F,0xF00F,
    0x1FE0,0xFF00,0x1F80,0x001F,0xE000,0x001F,0xF03F,0xE07F,0x83FC,0x0000,0x7FC0,0x000F,0xF00F,
    0x1FE0,0x7F80,0x1FFF,0xFE1F,0xE000,0x0007,0xFFFF,0x807F,0x81FE,0x0000,0x7F80,0x000F,0xF00F,
    0x1FE0,0x3FC0,0x1FFF,0xF81F,0xE000,0x0007,0xFFFE,0x007F,0x80FF,0x0000,0x7E00,0x000F,0x000F,
    0x1FE0,0x1FE0,0x1FFF,0xE01F,0xE000,0x0000,0x7FE0,0x007F,0x807F,0x8000,0x7800,0x0000,0x000F,
    0x1FE0,0x0FF0,0x0000,0x001F,0xE000,0x0000,0x0000,0x007F,0x803F,0xC000,0x6000,0x0000,0x000F,
    0x1FE0,0x07F8,0x0000,0x001F,0xE000,0x0000,0x0000,0x007F,0x801F,0xE000,0x0000,0x0000,0x000F,
    0x7FE0,0x03FC,0x0000,0x007F,0xE000,0x0000,0x0000,0x01FF,0x800F,0xF000,0x0000,0x0000,0x000F,
    0x7FE0,0x01FE,0x0000,0x00FF,0xE000,0x0000,0x0000,0x01FF,0x8007,0xF800,0x0000,0x0000,0x000F,
    0x0000,0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0xFC00,0x0000,0x0000,0x000F,
    0x0000,0x007F,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0xFE00,0x0000,0x0000,0x000F,
    0x0000,0x003F,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFF00,0x0000,0x0000,0x000F,
    0x0000,0x001F,0xE000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7F80,0x0000,0x0000,0x000F,
    0x0000,0x000F,0xF0F0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3FC3,0xC000,0x0000,0x000F,
    0x0000,0x0007,0xFFF0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1FFF,0xC000,0x0000,0x000F,
    0x0000,0x0003,0xFFE0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0FFF,0x8000,0x0000,0x000F,
    0x0000,0x0000,0xFF80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03FE,0x0000,0x0000,0x000F,
    0x0000,0x0000,0xFF00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03FC,0x0000,0x0000,0x000F,
    /* Plane 1 */
    0x3FFF,0xFC00,0x3FFF,0xFFFF,0xFFF0,0x0000,0x7FF0,0x00FF,0xFFC0,0x00FF,0xFFFF,0x0000,0x0000,
    0x3FFF,0xFF80,0x3FFF,0xFFFF,0xFFFE,0x0007,0xFFFF,0x00FF,0xFFFE,0x00FF,0xFFFF,0x0001,0xF000,
    0x3FFF,0xFFC0,0x3FFF,0xFFFF,0xFFFF,0xC01F,0xFFFF,0x00FF,0xFFFE,0x00FF,0xFFFF,0x001F,0xE000,
    0x3FC0,0x0FF0,0x3F00,0x003F,0xC07F,0xE03F,0xE07F,0xC0FF,0x01FF,0x8080,0x7F80,0x001F,0xE000,
    0x3FC0,0x07F8,0x3F00,0x003F,0xC007,0xF87F,0x801F,0xE0FF,0x001F,0xE000,0xFF80,0x001F,0xE0F0,
    0x3FC0,0x07F8,0x3F00,0x003F,0xC007,0xF8FF,0x000F,0xF0FF,0x001F,0xE000,0xFF80,0x001F,0xE7E0,
    0x3FC0,0x07F8,0x3FFF,0x803F,0xC00F,0xF8FF,0x000F,0xF0FF,0x001F,0xE000,0xFF80,0x001F,0xFFE0,
    0x3FC0,0x1FE0,0x3FFE,0x003F,0xC07F,0xE0FF,0x000F,0xF0FF,0x007F,0x8000,0xFF80,0x03FF,0xFF00,
    0x3FDF,0xFF80,0x3FF8,0x003F,0xDFFF,0x80FF,0x000F,0xF0FF,0x7FFE,0x0000,0xFF80,0x1FFF,0xF800,
    0x3FFF,0xFE00,0x3F00,0x003F,0xFFFE,0x00FF,0x000F,0xF0FF,0xFFF0,0x0000,0xFF80,0x1FFF,0xE000,
    0x3FFF,0xFC00,0x3F00,0x003F,0xFFE0,0x00FF,0x000F,0xE0FF,0xFFF0,0x0000,0xFF80,0x1E1F,0xE000,
    0x3FC1,0xFC00,0x3F00,0x003F,0xC000,0x007F,0x801F,0xE0FF,0x07F0,0x0000,0xFF80,0x001F,0xE000,
    0x3FC1,0xFE00,0x3F7F,0xFF3F,0xC000,0x003F,0xFFFF,0x80FF,0x07F8,0x0000,0xFF80,0x001F,0xE000,
    0x3FC0,0xFF00,0x3FFF,0xFC3F,0xC000,0x001F,0xFFFE,0x00FF,0x03FC,0x0000,0xFE00,0x001F,0x0000,
    0x3FC0,0x7F80,0x3FFF,0xF03F,0xC000,0x0000,0x7FE0,0x00FF,0x01FE,0x0000,0xF800,0x0010,0x0000,
    0x3FC0,0x3FC0,0x2000,0x003F,0xC000,0x0000,0x0000,0x00FF,0x00FF,0x0000,0xE000,0x0000,0x0000,
    0x3FC0,0x1FE0,0x0000,0x003F,0xC000,0x0000,0x0000,0x00FF,0x007F,0x8000,0x8000,0x0000,0x0000,
    0xFFC0,0x0FF0,0x0000,0x00FF,0xC000,0x0000,0x0000,0x03FF,0x003F,0xC000,0x0000,0x0000,0x0000,
    0xFFC0,0x07F8,0x0000,0x00FF,0xC000,0x0000,0x0000,0x03FF,0x001F,0xE000,0x0000,0x0000,0x0000,
    0x8000,0x03FC,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x000F,0xF000,0x0000,0x0000,0x0000,
    0x0000,0x01FE,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0007,0xF800,0x0000,0x0000,0x0000,
    0x0000,0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0xFC00,0x0000,0x0000,0x0000,
    0x0000,0x007F,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0xFE00,0x0000,0x0000,0x0000,
    0x0000,0x003F,0xC1F0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFF03,0xC000,0x0000,0x0000,
    0x0000,0x001F,0xE1E0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7F8F,0x8000,0x0000,0x0000,
    0x0000,0x000F,0xF9E0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3FEF,0x8000,0x0000,0x0000,
    0x0000,0x0007,0xFFC0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1FFF,0x0000,0x0000,0x0000,
    0x0000,0x0001,0xFF00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07FC,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
};
MODULE UWORD chip PubLogoData[1482] =
{   /* Plane 0 */
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8000,0x0000,
    0x1FFF,0xF000,0x0000,0x0000,0x0000,0x0000,0x7FF0,0x007F,0xFFC0,0x007F,0xFFFF,0x8000,0x0000,
    0x1FFF,0xFE00,0x1FFF,0xFFFF,0xFFF0,0x0003,0xFFFE,0x007F,0xFFF8,0x007F,0xFFFF,0x8000,0x0000,
    0x1FFF,0xFFC0,0x1FFF,0xFFFF,0xFFFE,0x0007,0xFFFF,0x807F,0xFFFF,0x007F,0xFFFF,0x8000,0x1000,
    0x1FFF,0xFFE0,0x1FFF,0xFFFF,0xFFFF,0xE00F,0xFFFF,0xC07F,0xFFFF,0x807F,0xFFFF,0x8001,0xF000,
    0x1FFF,0xFFF0,0x1FFF,0xFFFF,0xFFFF,0xF01F,0xFFFF,0xE07F,0xFFFF,0xC07F,0xFFFF,0x800F,0xF000,
    0x1FFF,0xFFF8,0x1FFF,0xFFDF,0xFFFF,0xF81F,0xFFFF,0xE07F,0xFFFF,0xE07F,0xFFFF,0x800F,0xF000,
    0x1FE0,0x7FF8,0x1F80,0x001F,0xE07F,0xF83F,0xE01F,0xF07F,0x81FF,0xE000,0x7FC0,0x000F,0xF000,
    0x1FE0,0x0FFC,0x1F80,0x001F,0xE00F,0xFC3F,0xC00F,0xF07F,0x803F,0xF000,0x7FC0,0x000F,0xF000,
    0x1FE0,0x0FFC,0x1F80,0x001F,0xE00F,0xFC3F,0x800F,0xF07F,0x803F,0xF000,0x7FC0,0x000F,0xF000,
    0x1FE0,0x03FC,0x1F80,0x001F,0xE003,0xFC7F,0x8007,0xF87F,0x800F,0xF000,0x7FC0,0x000F,0xF010,
    0x1FE0,0x03FC,0x1F80,0x001F,0xE003,0xFC7F,0x8007,0xF87F,0x800F,0xF000,0x7FC0,0x000F,0xF0F0,
    0x1FE0,0x03FC,0x1FFF,0xE01F,0xE003,0xFC7F,0x8007,0xF87F,0x800F,0xF000,0x7FC0,0x000F,0xE7F0,
    0x1FE0,0x07F8,0x1FFF,0xC01F,0xE007,0xF87F,0x8007,0xF87F,0x801F,0xE000,0x7FC0,0x000F,0xFFF0,
    0x1FE0,0x0FF8,0x1FFF,0x801F,0xE00F,0xF87F,0x8007,0xF87F,0x803F,0xE000,0x7FC0,0x000F,0xFFF0,
    0x1FE0,0x1FF0,0x1FFF,0x001F,0xE01F,0xF07F,0x8007,0xF87F,0x807F,0xC000,0x7FC0,0x007F,0xFFC0,
    0x1FE0,0x7FE0,0x1FFE,0x001F,0xE07F,0xE07F,0x8007,0xF87F,0x81FF,0x8000,0x7FC0,0x03FF,0xFF00,
    0x1FFF,0xFFC0,0x1FFC,0x001F,0xFFFF,0xC07F,0x8007,0xF87F,0xFFFF,0x0000,0x7FC0,0x0FFF,0xF800,
    0x1FFF,0xFF80,0x1FF8,0x001F,0xFFFF,0x807F,0x8007,0xF87F,0xFFFE,0x0000,0x7FC0,0x0FFF,0xF000,
    0x1FFF,0xFF00,0x1F80,0x001F,0xFFFF,0x007F,0x8007,0xF87F,0xFFFC,0x0000,0x7FC0,0x0FFF,0xF000,
    0x1FFF,0xFE00,0x1F80,0x001F,0xFFFE,0x007F,0x8007,0xF07F,0xFFF8,0x0000,0x7FC0,0x0F8F,0xF000,
    0x1FFF,0xFE00,0x1F80,0x001F,0xFFFC,0x003F,0xC007,0xF07F,0xFFF8,0x0000,0x7FC0,0x0C0F,0xF000,
    0x1FFF,0xFE00,0x1F80,0x001F,0xFFE0,0x003F,0xC00F,0xF07F,0xFFF8,0x0000,0x7FC0,0x000F,0xF000,
    0x1FE1,0xFF00,0x1F80,0x001F,0xE000,0x003F,0xC01F,0xE07F,0x87FC,0x0000,0x7FC0,0x000F,0xF000,
    0x1FE0,0xFF00,0x1F80,0x001F,0xE000,0x001F,0xF03F,0xE07F,0x83FC,0x0000,0x7FC0,0x000F,0xF000,
    0x1FE0,0xFF80,0x1FFF,0xFF1F,0xE000,0x001F,0xFFFF,0xC07F,0x83FE,0x0000,0x7FC0,0x000F,0xF000,
    0x1FE0,0x7F80,0x1FFF,0xFE1F,0xE000,0x000F,0xFFFF,0x807F,0x81FE,0x0000,0x7F80,0x000F,0xF000,
    0x1FE0,0x7FC0,0x1FFF,0xFC1F,0xE000,0x000F,0xFFFF,0x007F,0x81FF,0x0000,0x7F00,0x000F,0xC000,
    0x1FE0,0x3FC0,0x1FFF,0xF81F,0xE000,0x0007,0xFFFE,0x007F,0x80FF,0x0000,0x7E00,0x000E,0x0000,
    0x1FE0,0x3FE0,0x1FFF,0xF01F,0xE000,0x0003,0xFFFC,0x007F,0x80FF,0x8000,0x7C00,0x0000,0x0000,
    0x1FE0,0x1FE0,0x1FFF,0xE01F,0xE000,0x0000,0x7FE0,0x007F,0x807F,0x8000,0x7800,0x0000,0x0000,
    0x1FE0,0x1FF0,0x0000,0x001F,0xE000,0x0000,0x0000,0x007F,0x807F,0xC000,0x7000,0x0000,0x0000,
    0x1FE0,0x0FF0,0x0000,0x001F,0xE000,0x0000,0x0000,0x007F,0x803F,0xC000,0x6000,0x0000,0x0000,
    0x1FE0,0x0FF8,0x0000,0x001F,0xE000,0x0000,0x0000,0x007F,0x803F,0xE000,0x4000,0x0000,0x0000,
    0x1FE0,0x07F8,0x0000,0x001F,0xE000,0x0000,0x0000,0x007F,0x801F,0xE000,0x0000,0x0000,0x0000,
    0x7FE0,0x07FC,0x0000,0x007F,0xE000,0x0000,0x0000,0x01FF,0x801F,0xF000,0x0000,0x0000,0x0000,
    0x7FE0,0x03FC,0x0000,0x007F,0xE000,0x0000,0x0000,0x01FF,0x800F,0xF000,0x0000,0x0000,0x0000,
    0x7FE0,0x03FE,0x0000,0x007F,0xE000,0x0000,0x0000,0x01FF,0x800F,0xF800,0x0000,0x0000,0x0000,
    0x7FE0,0x01FE,0x0000,0x00FF,0xE000,0x0000,0x0000,0x01FF,0x8007,0xF800,0x0000,0x0000,0x0000,
    0x0000,0x01FF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0007,0xFC00,0x0000,0x0000,0x0000,
    0x0000,0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0xFC00,0x0000,0x0000,0x0000,
    0x0000,0x00FF,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0xFE00,0x0000,0x0000,0x0000,
    0x0000,0x007F,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0xFE00,0x0000,0x0000,0x0000,
    0x0000,0x007F,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0xFF00,0x0000,0x0000,0x0000,
    0x0000,0x003F,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFF00,0x0000,0x0000,0x0000,
    0x0000,0x003F,0xE000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFF80,0x0000,0x0000,0x0000,
    0x0000,0x001F,0xE000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7F80,0x0000,0x0000,0x0000,
    0x0000,0x001F,0xF000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7FC0,0x0000,0x0000,0x0000,
    0x0000,0x000F,0xF0F0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3FC3,0xC000,0x0000,0x0000,
    0x0000,0x000F,0xF9F0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3FE7,0xC000,0x0000,0x0000,
    0x0000,0x0007,0xFFF0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1FFF,0xC000,0x0000,0x0000,
    0x0000,0x0003,0xFFE0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0FFF,0x8000,0x0000,0x0000,
    0x0000,0x0003,0xFFE0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0FFF,0x8000,0x0000,0x0000,
    0x0000,0x0001,0xFFC0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07FF,0x0000,0x0000,0x0000,
    0x0000,0x0000,0xFF80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03FE,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x3F00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00FC,0x0000,0x0000,0x0000,
    0x0000,0x0000,0x3E00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00F8,0x0000,0x0000,0x0000,
    /* Plane 1 */
    0x3FFF,0xF000,0x0000,0x0000,0x0000,0x0000,0x7FF0,0x00FF,0xFFC0,0x00FF,0xFFFF,0x0000,0x000F,
    0x3FFF,0xFE00,0x3FFF,0xFFFF,0xFFF0,0x0003,0xFFFE,0x00FF,0xFFF8,0x00FF,0xFFFF,0x0000,0x000F,
    0x3FFF,0xFF80,0x3FFF,0xFFFF,0xFFFE,0x0007,0xFFFF,0x00FF,0xFFFE,0x00FF,0xFFFF,0x0000,0x000F,
    0x3FFF,0xFF80,0x3FFF,0xFFFF,0xFFFF,0x800F,0xFFFF,0x00FF,0xFFFE,0x00FF,0xFFFF,0x0001,0xE00F,
    0x3FFF,0xFFC0,0x3FFF,0xFFFF,0xFFFF,0xC01F,0xFFFF,0x80FF,0xFFFF,0x00FF,0xFFFF,0x001F,0xE00F,
    0x3FFF,0xFFE0,0x3FFF,0xFFFF,0xFFFF,0xE03F,0xFFFF,0xC0FF,0xFFFF,0x80FF,0xFFFF,0x001F,0xE00F,
    0x3FC0,0x7FF0,0x3F00,0x003F,0xC07F,0xF03F,0xE07F,0xC0FF,0x01FF,0xC080,0x7F80,0x001F,0xE00F,
    0x3FC0,0x0FF0,0x3F00,0x003F,0xC00F,0xF07F,0xC07F,0xE0FF,0x003F,0xC000,0xFF80,0x001F,0xE00F,
    0x3FC0,0x07F8,0x3F00,0x003F,0xC007,0xF87F,0x801F,0xE0FF,0x001F,0xE000,0xFF80,0x001F,0xE00F,
    0x3FC0,0x07F8,0x3F00,0x003F,0xC007,0xF87F,0x001F,0xE0FF,0x001F,0xE000,0xFF80,0x001F,0xE00F,
    0x3FC0,0x07F8,0x3F00,0x003F,0xC007,0xF8FF,0x000F,0xF0FF,0x001F,0xE000,0xFF80,0x001F,0xE0EF,
    0x3FC0,0x07F8,0x3F7F,0xE03F,0xC007,0xF8FF,0x000F,0xF0FF,0x001F,0xE000,0xFF80,0x001F,0xE7EF,
    0x3FC0,0x07F8,0x3FFF,0xC03F,0xC007,0xF8FF,0x000F,0xF0FF,0x001F,0xE000,0xFF80,0x001F,0xFFEF,
    0x3FC0,0x0FF0,0x3FFF,0x803F,0xC00F,0xF0FF,0x000F,0xF0FF,0x003F,0xC000,0xFF80,0x001F,0xFFEF,
    0x3FC0,0x1FF0,0x3FFF,0x003F,0xC01F,0xF0FF,0x000F,0xF0FF,0x007F,0xC000,0xFF80,0x007F,0xFFCF,
    0x3FC0,0x7FE0,0x3FFE,0x003F,0xC07F,0xE0FF,0x000F,0xF0FF,0x01FF,0x8000,0xFF80,0x03FF,0xFF0F,
    0x3FDF,0xFFC0,0x3FFC,0x003F,0xDFFF,0xC0FF,0x000F,0xF0FF,0x7FFF,0x0000,0xFF80,0x1FFF,0xF80F,
    0x3FFF,0xFF80,0x3FF8,0x003F,0xFFFF,0x80FF,0x000F,0xF0FF,0xFFFE,0x0000,0xFF80,0x1FFF,0xE00F,
    0x3FFF,0xFF00,0x3F00,0x003F,0xFFFF,0x00FF,0x000F,0xF0FF,0xFFFC,0x0000,0xFF80,0x1FFF,0xE00F,
    0x3FFF,0xFE00,0x3F00,0x003F,0xFFFE,0x00FF,0x000F,0xF0FF,0xFFF8,0x0000,0xFF80,0x1F8F,0xE00F,
    0x3FFF,0xFC00,0x3F00,0x003F,0xFFFC,0x00FF,0x000F,0xE0FF,0xFFF0,0x0000,0xFF80,0x1C1F,0xE00F,
    0x3FFF,0xFC00,0x3F00,0x003F,0xFFE0,0x007F,0x800F,0xE0FF,0xFFF0,0x0000,0xFF80,0x101F,0xE00F,
    0x3FC1,0xFC00,0x3F00,0x003F,0xC000,0x007F,0x801F,0xE0FF,0x07F0,0x0000,0xFF80,0x001F,0xE00F,
    0x3FC3,0xFE00,0x3F00,0x003F,0xC000,0x007F,0xF03F,0xC0FF,0x0FF8,0x0000,0xFF80,0x001F,0xE00F,
    0x3FC1,0xFE00,0x3F7F,0xFF3F,0xC000,0x003F,0xFFFF,0xC0FF,0x07F8,0x0000,0xFF80,0x001F,0xE00F,
    0x3FC1,0xFF00,0x3FFF,0xFE3F,0xC000,0x003F,0xFFFF,0x80FF,0x07FC,0x0000,0xFF80,0x001F,0xE00F,
    0x3FC0,0xFF00,0x3FFF,0xFC3F,0xC000,0x001F,0xFFFF,0x00FF,0x03FC,0x0000,0xFF00,0x001F,0xC00F,
    0x3FC0,0xFF80,0x3FFF,0xF83F,0xC000,0x0007,0xFFFE,0x00FF,0x03FE,0x0000,0xFE00,0x001E,0x000F,
    0x3FC0,0x7F80,0x3FFF,0xF03F,0xC000,0x0003,0xFFFC,0x00FF,0x01FE,0x0000,0xFC00,0x0010,0x000F,
    0x3FC0,0x7FC0,0x3FFF,0xE03F,0xC000,0x0000,0x7FE0,0x00FF,0x01FF,0x0000,0xF800,0x0000,0x000F,
    0x3FC0,0x3FC0,0x2000,0x003F,0xC000,0x0000,0x0000,0x00FF,0x00FF,0x0000,0xF000,0x0000,0x000F,
    0x3FC0,0x3FE0,0x0000,0x003F,0xC000,0x0000,0x0000,0x00FF,0x00FF,0x8000,0xE000,0x0000,0x000F,
    0x3FC0,0x1FE0,0x0000,0x003F,0xC000,0x0000,0x0000,0x00FF,0x007F,0x8000,0xC000,0x0000,0x000F,
    0x3FC0,0x1FF0,0x0000,0x003F,0xC000,0x0000,0x0000,0x00FF,0x007F,0xC000,0x8000,0x0000,0x000F,
    0xFFC0,0x0FF0,0x0000,0x00FF,0xC000,0x0000,0x0000,0x03FF,0x003F,0xC000,0x0000,0x0000,0x000F,
    0xFFC0,0x0FF8,0x0000,0x00FF,0xC000,0x0000,0x0000,0x03FF,0x003F,0xE000,0x0000,0x0000,0x000F,
    0xFFC0,0x07F8,0x0000,0x00FF,0xC000,0x0000,0x0000,0x03FF,0x001F,0xE000,0x0000,0x0000,0x000F,
    0xFFC0,0x07FC,0x0000,0x00FF,0xC000,0x0000,0x0000,0x03FF,0x001F,0xF000,0x0000,0x0000,0x000F,
    0x8000,0x03FC,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x000F,0xF000,0x0000,0x0000,0x000F,
    0x0000,0x03FE,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000F,0xF800,0x0000,0x0000,0x000F,
    0x0000,0x01FE,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0007,0xF800,0x0000,0x0000,0x000F,
    0x0000,0x01FF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0007,0xFC00,0x0000,0x0000,0x000F,
    0x0000,0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0xFC00,0x0000,0x0000,0x000F,
    0x0000,0x00FF,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0xFE00,0x0000,0x0000,0x000F,
    0x0000,0x007F,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0xFE00,0x0000,0x0000,0x000F,
    0x0000,0x007F,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0xFF00,0x0000,0x0000,0x000F,
    0x0000,0x003F,0xC000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFF00,0x0000,0x0000,0x000F,
    0x0000,0x003F,0xE0F0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFF83,0xC000,0x0000,0x000F,
    0x0000,0x001F,0xE1E0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7F87,0x8000,0x0000,0x000F,
    0x0000,0x001F,0xF3E0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7FCF,0x8000,0x0000,0x000F,
    0x0000,0x000F,0xFBE0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3FEF,0x8000,0x0000,0x000F,
    0x0000,0x0007,0xFFC0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1FFF,0x0000,0x0000,0x000F,
    0x0000,0x0007,0xFFC0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1FFF,0x0000,0x0000,0x000F,
    0x0000,0x0003,0xFF80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0FFE,0x0000,0x0000,0x000F,
    0x0000,0x0001,0xFF00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07FC,0x0000,0x0000,0x000F,
    0x0000,0x0000,0xFE00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03F8,0x0000,0x0000,0x000F,
    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000F,
};
MODULE UWORD chip AboutData[66] =
{   0xFFFF,0xFFFF,0xFFF8,
    0xFDFF,0xC7FF,0xFFF8,
    0xE53F,0x83FF,0xFFF8,
    0xF8FF,0x01FF,0xFFF8,
    0xE53E,0x10FF,0xFBF8,
    0xFDFC,0x387F,0x9B38,
    0xFFF8,0x7C3F,0xE0F8,
    0xC3F0,0x0000,0x0018,
    0xE1E0,0x1F0F,0xE0F8,
    0xF0C3,0xE387,0x9B38,
    0xF807,0xFC43,0xFBF8,
    0xFC0F,0xFF81,0xFFF8,
    0xFE1F,0xFFF0,0xFFF8,
    0xFFFF,0xFFFF,0xFFF8,
    0xFFFF,0xFFFF,0xFFF8,
    0xF1C4,0x6C0E,0x39D8,
    0xEEDB,0x6BFD,0xDAD8,
    0xE0DB,0x6B8C,0x1B58,
    0xDF5F,0x6BEB,0xEB98,
    0xDF5F,0x6C0B,0xEBD8,
    0xFFFF,0xFFFF,0xFFF8,
    0xFFFF,0xFFFF,0xFFF8
};
MODULE UWORD chip PubAboutData[132] =
{   0xFFFF,0xFFFF,0xFFE0,
    0xFFFF,0xFFFF,0xFFE0,
    0xFFFF,0xFFFF,0xFFE0,
    0xFFFF,0xFFFF,0xFFE0,
    0xFBFF,0x8FFF,0xFFE0,
    0xFBFF,0x8FFF,0xFFE0,
    0xCA7F,0x07FF,0xFFE0,
    0xCA7F,0x07FF,0xFFE0,
    0xF1FE,0x03FF,0xFFE0,
    0xF1FE,0x03FF,0xFFE0,
    0xCA7C,0x21FF,0xF7E0,
    0xCA7C,0x21FF,0xF7E0,
    0xFBF8,0x70FF,0x3660,
    0xFBF8,0x70FF,0x3660,
    0xFFF0,0xF87F,0xC1E0,
    0xFFF0,0xF87F,0xC1E0,
    0x87E0,0x0000,0x0020,
    0x87E0,0x0000,0x0020,
    0xC3C0,0x3E1F,0xC1E0,
    0xC3C0,0x3E1F,0xC1E0,
    0xE187,0xC70F,0x3660,
    0xE187,0xC70F,0x3660,
    0xF00F,0xF887,0xF7E0,
    0xF00F,0xF887,0xF7E0,
    0xF81F,0xFF03,0xFFE0,
    0xF81F,0xFF03,0xFFE0,
    0xFC3F,0xFFE1,0xFFE0,
    0xFC3F,0xFFE1,0xFFE0,
    0xFFFF,0xFFFF,0xFFE0,
    0xFFFF,0xFFFF,0xFFE0,
    0xE1C8,0xDC38,0x6EE0,
    0xE1C8,0xDC38,0x6EE0,
    0xDDB6,0xDBF7,0x66E0,
    0xDDB6,0xDBF7,0x66E0,
    0xC1B6,0xDB30,0x6AE0,
    0xC1B6,0xDB30,0x6AE0,
    0xDDBE,0xDBB7,0x6CE0,
    0xDDBE,0xDBB7,0x6CE0,
    0xDDBE,0xD877,0x6EE0,
    0xDDBE,0xD877,0x6EE0,
    0xFFFF,0xFFFF,0xFFE0,
    0xFFFF,0xFFFF,0xFFE0,
    0xFFFF,0xFFFF,0xFFE0,
    0xFFFF,0xFFFF,0xFFE0
};

MODULE struct Image Logo =
{   0,0,
    204, 29, 2,
    LogoData,
    0x3, BLACK,
    NULL
}, PubLogo =
{   0, 0,
    204, 57, 2,
    PubLogoData,
    0x3, BLACK,
    NULL
}, About =
{   0, 0,
    45, 22, 1,
    AboutData,
    0x1, 3,
    NULL
}, PubAbout =
{   0, 0,
    45, 44, 1,
    PubAboutData,
    0x1, 3,
    NULL
};

MODULE UBYTE secret[SECRETLENGTH] =
{   '4', '4', '8', '9'
};

MODULE struct EasyStruct EasyStruct =
{   sizeof(struct EasyStruct),
    0,
    "Report+: Error",
    NULL,
    "Quit"
};

AGLOBAL struct SharedStruct shared =
{   TRUE, 0,
    "", ""
};
AGLOBAL struct SizeStruct size =
{   0, 0, 0, "", "", "SYS:", "SYS:"
};

IMPORT  ABOOL  certified;

IMPORT  ULONG  subdirallocated,
               topdirallocated,
               stackentries;

AGLOBAL ULONG oldhostid;

#define FUNCTIONS 10

MODULE STRPTR FunctionOptions[FUNCTIONS + 1] =
{   (STRPTR) "Bug report",
    (STRPTR) "Aminet readme",
    (STRPTR) "ACSE test",
    (STRPTR) "Autodoc",
    (STRPTR) "ID database",
    (STRPTR) "IFF registry",
    (STRPTR) "EOL/tab converter",
    (STRPTR) "Path size report",
    (STRPTR) "Battery RAM",
    (STRPTR) "System file report",
    NULL
};

AGLOBAL struct NewGadget Gadget =
{	0, 0,					/* left-x, top-y */
	0, 0,					/* width, height */
        0,                                      /* text */
	NULL,					/* font */
	NULL,					/* gadget ID */
	NULL,					/* flags */
	NULL,					/* visual info */
	NULL					/* user data */
};

#define MENUENTRIES 7
MODULE struct NewMenu NewMenu[MENUENTRIES] =
{   { NM_TITLE, "Project",       0 , 0, 0, 0},
    {  NM_ITEM, "Quit Report+", "Q", 0, 0, 0},
    { NM_TITLE, "Help",          0 , 0, 0, 0},
    {  NM_ITEM, "Manual...",    "M", 0, 0, 0},
    {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, 0},
    {  NM_ITEM, "About...",     "?", 0, 0, 0},
    {   NM_END, NULL,            0 , 0, 0, 0}
};

#define ABOUTLINES      6
#define ABOUTSHADOW BLACK
#define ABOUTSHINE  WHITE
#define KICKSTARTX    168
#define KICKSTARTY     75
#define WORKBENCHX    168
#define WORKBENCHY     83

MODULE struct
{   WORD   x, y;
    STRPTR text;
} about[ABOUTLINES + 1] =
{   {80, 27,         "Report+ 4.12"          },
    {80, 35,         "@@day @@ December 2000"},
    {80, 43,         "© 2000 Amigan Software"},
    {80, 59,         "By James R. Jacobs"    },
    {80, KICKSTARTY, "Kickstart:"            },
    {80, WORKBENCHY, "Workbench:"            },
    {80, 106,        "Public Screen: RPORT"  }
};

MODULE void clearkybd(void);
MODULE void gadtools(void);
MODULE void helpabout(void);
MODULE void menu(void);
MODULE void parsewb(void);

AGLOBAL TEXT               weekdaystring[10],
                           datestring[10],
                           timestring[9];

int CXBRK(void) { return(0); }    /* Disable SAS/C Ctrl-C handling */
int chkabort(void) { return(0); } /* really */

IMPORT  struct ExecBase*        SysBase;
MODULE  struct ASLBase*         ASLBase         = NULL;
MODULE  struct DiskFontBase*    DiskFontBase    = NULL;
MODULE  struct GadToolsBase*    GadToolsBase    = NULL;
MODULE  struct IntuitionBase*   IntuitionBase   = NULL;
MODULE  struct Library*         VersionBase     = NULL;
AGLOBAL struct Resource*        BattMemBase     = NULL;

AGLOBAL struct Library          *WindowBase      = NULL,
                                *LayoutBase      = NULL,
                                *ButtonBase      = NULL,
                                *TextEditorBase  = NULL,
                                *LabelBase       = NULL,
                                *ListBrowserBase = NULL;

AGLOBAL struct ExAllControl*    eac              = NULL;
AGLOBAL BPTR                    DirHandle        = NULL;
AGLOBAL STRPTR                  EADataPtr        = NULL;
AGLOBAL ABOOL                   pal              = FALSE;
AGLOBAL APTR                    OldWindowPtr     = NULL;
AGLOBAL struct Process*         ProcessPtr       = NULL;
AGLOBAL struct Screen*          ScreenPtr        = NULL;
AGLOBAL SBYTE                   page             = 0;
AGLOBAL ULONG                   elements; // for ReAction texteditor.gadget
AGLOBAL BPTR                    SharedFileHandle = NULL;
MODULE  struct Menu*            MenuPtr          = NULL;
AGLOBAL SWORD  y;
MODULE  WORD   xsize, ysize;
AGLOBAL TEXT   asldir[VLONGFIELD + 1],
               aslresult[MEDFIELD + 1];
MODULE  TEXT   string[VLONGFIELD + 1];
AGLOBAL TEXT   IOBuffer[LONGESTFIELD + 1];
MODULE  ULONG  ksval;
AGLOBAL ULONG  wbval;
MODULE  struct RDArgs*                  ArgsPtr               = NULL;
MODULE  struct TextFont*                FontPtr               = NULL;
MODULE  struct Window                   *BkgrndWindowPtr      = NULL;
AGLOBAL struct Window                   *MainWindowPtr        = NULL,
                                        *AboutWindowPtr       = NULL;

IMPORT struct EOLStruct eol;

AGLOBAL UBYTE* FileNamePtr[16768];
AGLOBAL UBYTE* DirNamePtr[2048];
AGLOBAL ULONG  DirNames, // position of top of stack
               DirNamesAllocated = 0,
               FileNamesAllocated = 0;

// manufacturer IDs
AGLOBAL UBYTE         whichboard       = 0;
AGLOBAL ULONG         querymanuf       = (ULONG) 0,
                      queryproduct     = (ULONG) 0;

// path size report
AGLOBAL struct List*     SizeListPtr      = NULL;

// battery RAM
IMPORT  UBYTE            BattBuffer[32];

// system file report
IMPORT  struct PenStruct penn[7];
AGLOBAL UWORD            osversion;

AGLOBAL struct Gadget *BU99_Left               = NULL,
                      *BU99_Right              = NULL,
                      *ST99_Output             = NULL,
                      *BU99_OutputASL          = NULL,
                      *CB99_Log                = NULL,
                      *BU99_Update             = NULL,
                      *BU99_Stop               = NULL,
                      *GListPtr                = NULL,
                      *PrevGadPtr              = NULL;
MODULE  struct Gadget *MX00_Function           = NULL,
                      *ST00_Editor             = NULL,
                      *BU00_EditorASL          = NULL;

AGLOBAL struct Gadget *TE51_Desc           = NULL,
                      *IN51_ManufID        = NULL,
                      *TE51_ManufNames     = NULL,
                      *BU51_NextBoard      = NULL,
                      *BU51_PrevBoard      = NULL,
                      *IN51_ProductID      = NULL,
                      *TE51_ProductNames   = NULL,
                      *BU51_Query          = NULL,
                      *LV81_Listview       = NULL,
                      *ST81_Path           = NULL,
                      *BU81_PathASL        = NULL,
                      *BU81_Root           = NULL,
                      *BU81_Parent         = NULL,
                      *TE81_Total          = NULL,
                      *TE81_Free           = NULL,
                      *BU91_Revert         = NULL,
                      *BU91_Write          = NULL,
                      *CB91_SharedAmnesia  = NULL,
                      *IN91_SCSIHostID     = NULL,
                      *CB91_SCSISyncXfer   = NULL,
                      *CB91_SCSIFastSync   = NULL,
                      *CB91_SCSITagQueues  = NULL,
                      *CB91_AmigaAmnesia   = NULL,
                      *CB91_SCSITimeout    = NULL,
                      *CB91_SCSILUNS       = NULL,
                      *MX101_OSVersion     = NULL;

MODULE	struct WBArg*			WBArg							= NULL;
MODULE	struct WBStartup*		WBMsg							= NULL;
AGLOBAL struct VisualInfo*              VisualInfoPtr = NULL;
MODULE  struct TextAttr                 Topaz8 =
{	(STRPTR) "topaz.font", 8, FS_NORMAL, FPF_ROMFONT | FPF_DESIGNED
}, /* "topaz.font" is case-sensitive */ WormWars8 =
{	(STRPTR) "WormWars.font", 8, FS_NORMAL, FPF_DISKFONT | FPF_DESIGNED
};

/* FUNCTIONS -------------------------------------------------------------- */

int main(int argc, char** argv)
{   UWORD Pens[10] =
    {   BLACK,     /* DETAILPEN        text in title bar */
        WHITE,     /* BLOCKPEN         fill title bar */
        BLACK,     /* TEXTPEN          regular text on BACKGROUNDPEN */
        WHITE,     /* SHINEPEN         bright edge */
        BLACK,     /* SHADOWPEN        dark edge */
        RED,       /* FILLPEN          filling active window borders
                                       and selected gadgets */
        BLACK,     /* FILLTEXTPEN      text rendered over FILLPEN */
        LIGHTGREY, /* BACKGROUNDPEN    background colour */
        WHITE,     /* HIGHLIGHTTEXTPEN highlighted text on BACKGROUNDPEN */
        (UWORD) ~0
    };
    struct ColorSpec Colours[17] =
    {   /* colour   red   green     blue    description */
        {    0,     0x9,    0x8,    0xA},   /* GREY */
        {    1,     0x0,    0x0,    0x0},   /* BLACK */
        {    2,     0xF,    0xF,    0xF},   /* WHITE */
        {    3,     0xF,    0x7,    0x7},   /* RED. */
        {    4,     0x6,    0x6,    0xF},   /* BLUE. */          
        {    5,     0xD,    0xC,    0xE},   /* LIGHTGREY */
        {    6,     0x6,    0x0,    0x6},   /* PURPLE. */
        {    7,     0xF,    0xF,    0x5},   /* YELLOW! */
    // pens for listbrowser
        {    8,     0xF,    0x2,    0x2},   // red
        {    9,     0xF,    0x8,    0x0},   // orange
        {   10,     0xF,    0xF,    0x0},   // yellow
        {   11,     0x5,    0xF,    0x5},   // green
        {   12,     0x5,    0x5,    0xF},   // blue (obsolete)
        {   13,     0x0,    0xF,    0xF},   // cyan (3rd-party)
        {   14,     0xF,    0xF,    0xF},   // white (missing)!
        {   15,     0x0,    0x0,    0x0},   // (spare)!
        {   -1,    NULL,   NULL,   NULL}
    };
    UWORD            i;
    SLONG            args[3] = { 0L, 0L, 0L };
    BPTR             OldDir;
    SLONG            number = 0;

    /* Start of program.

    version embedding into executable */

    if (0) /* that is, never */
        Printf("$VER: Report+ 4.12 (@@.12.100");

    if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37L)))
    {   Printf("Report+: Need intuition.library V37+!\n");
        cleanexit(EXIT_FAILURE);
    }
    if ((ksval = SysBase->LibNode.lib_Version) < 36L)
    {   Printf("Report+: Need exec.library V36+!\n");
        cleanexit(EXIT_FAILURE);
    }

    autodoc_init();

    /* From this point onwards, we can be sure we have Kickstart 2.04+... */

    BattMemBase = OpenResource(BATTMEMNAME);
    if (!(VersionBase = (struct VersionBase *) OpenLibrary("version.library", 0L)))
        rq("Can't open version.library!");
    wbval = VersionBase->lib_Version;
    CloseLibrary(VersionBase);
    VersionBase = NULL;
    if (wbval <= 43)
        osversion = 0; // OS3.1
    else osversion = 2; // OS3.5 + BB1
    if (!(GadToolsBase = (struct GadToolsBase *) OpenLibrary("gadtools.library", 37L)))
        rq("Can't open GadTools.library V37+!");
    if (!(ASLBase = (struct ASLBase *) OpenLibrary("asl.library", 0L)))
        rq("Can't open ASL.library!");
    if (
        (!(DiskFontBase = (struct DiskFontBase *) OpenLibrary("diskfont.library", 0L)))
    ||  (!(FontPtr = (struct TextFont *) OpenDiskFont(&WormWars8)))
       )
        Gadget.ng_TextAttr = (struct TextAttr *) &Topaz8;
    else Gadget.ng_TextAttr = (struct TextAttr *) &WormWars8;

    if (wbval >= 44)
    {   if (!(ListBrowserBase = OpenLibrary("gadgets/listbrowser.gadget", 0)))
            rq("OpenLibrary(\"gadgets/listbrowser.gadget\") failed!");
    }

    if (argc) /* started from CLI */
    {   if (!(ArgsPtr = ReadArgs
        (   "-P=PAL/S,FUNCTION/N,FILE/F",
            (LONG *) args,
            NULL
	)))
        {   Printf
            (   "Usage: %s [-p=PAL] [[FUNCTION] <function> [<file(s)...>]\n",
                argv[0]
            );
            cleanexit(EXIT_FAILURE);
	}
        if (args[0])
            pal = TRUE;
        if (args[1])
        {   number = (SLONG) (*((SLONG*) args[1]));
            if (number >= 1 && number <= FUNCTIONS)
                page = (number * 10) + 1;
            else
            {   Printf("Report+: <function> must be 1-%ld!\n", FUNCTIONS);
                cleanexit(EXIT_FAILURE);
        }   }
        if (args[2])
        {   if (number != 7)
            {   Printf("Report+: Need FUNCTION=7 for this!\n");
                cleanexit(EXIT_FAILURE);
            } else
            {   strcpy(eol.pathname, args[2]);
                if (eol_do(FALSE))
                {   Printf("All done.\n");
                    cleanexit(EXIT_SUCCESS);
                } else
                {   Printf("Done, with errors.\n");
                    cleanexit(EXIT_FAILURE);
    }   }   }   }
    else /* started from WB */
    {   WBMsg = (struct WBStartup *) argv;
        WBArg = WBMsg->sm_ArgList; /* head of the arg list */
        for (i = 0; i < WBMsg->sm_NumArgs; i++, WBArg++)
        {   if (WBArg->wa_Lock)
            {   /* something that does not support locks */
                parsewb();
            } else
            {   /* lock supported; change to the proper directory */
                OldDir = CurrentDir(WBArg->wa_Lock);
                parsewb();
                CurrentDir(OldDir);
            }
            if (i == 1)
                ; /* we were started from a project icon, which is
                currently unsupported */
    }   }

    ProcessPtr = (struct Process *) FindTask(NULL);
    strcpy(asldir, "PROGDIR:");

    if (pal)
    {   xsize = 640;
        ysize = 256;
    } else
    {   /* RKM Libraries, p. 59-61: */
        if (!(ScreenPtr = LockPubScreen(NULL)))
            rq("Can't lock default public screen!");
        if (GetVPModeID(&(ScreenPtr->ViewPort)) == INVALID_ID)
            rq("Invalid default public screen mode ID!");
        xsize = ScreenPtr->Width;
        ysize = ScreenPtr->Height;
        UnlockPubScreen(NULL, ScreenPtr);
        ScreenPtr = NULL;
    }

    /* PREPARE DISPLAY -----------------------------------------------

    screen */

    if (pal)
    {   if (!(ScreenPtr = (struct Screen *) OpenScreenTags(NULL,
            SA_Width,        xsize,
            SA_Height,       ysize,
            SA_Depth,        DEPTH,
            SA_DisplayID,    HIRES_KEY | PAL_MONITOR_ID,
            SA_Title,        "Report+ 4.12",
            SA_Colors,       Colours,
            SA_Font,         Gadget.ng_TextAttr,
            SA_Pens,         Pens,
            SA_DetailPen,    BLACK,
            SA_BlockPen,     WHITE,
            SA_AutoScroll,   TRUE,
            SA_PubName,      "RPLUS",
            TAG_DONE
        )))
            rq("Can't open custom PAL screen!");
        if (!(BkgrndWindowPtr = (struct Window *) OpenWindowTags(NULL,
            WA_Top,          12,
            WA_Width,        xsize,
            WA_Height,       ysize - 12,
            WA_IDCMP,        NULL,
            WA_Gadgets,      NULL,
            WA_CustomScreen, ScreenPtr,
            WA_Activate,     FALSE,
            WA_Title,        NULL,
            WA_Borderless,   TRUE,
            WA_Backdrop,     TRUE,
            TAG_DONE
        )))
            rq("Can't open backdrop window!");
        SetAPen(BkgrndWindowPtr->RPort, BLUE);
        RectFill(BkgrndWindowPtr->RPort, 0, 0, xsize, ysize - 12);
        PubScreenStatus(ScreenPtr, 0); // take the screen public
    }

    report_init();

    if (shared.editor[0] == 0)
        if (GetVar("EDITOR", &(shared.editor), LONGFIELD, NULL) == -1)
            strcpy(shared.editor, "SYS:Tools/MEmacs");

    if (!pal)
    {   if (!(ScreenPtr = LockPubScreen(NULL)))
            rq("Can't lock default public screen!");
        for (i = 0; i <= 6; i++)
        {   penn[i].pennumber = FindColor
            (   ScreenPtr->ViewPort.ColorMap,
                penn[i].red,
                penn[i].green,
                penn[i].blue,
                256
            );
        }
        UnlockPubScreen(NULL, ScreenPtr);
    }

    while(1)
    {   if (page == 11)
            report1();
        elif (page == 12)
            report2();
        elif (page == 13)
            sender();
        elif (page == 14)
            config();
        elif (page == 15)
            report3();
        elif (page == 21)
            aminet1();
        elif (page == 22)
            aminet2();
        elif (page == 31)
            acse1();
        elif (page == 32)
            acse2();
        elif (page == 33)
            acse3();
        elif (page == 41)
            autodoc1();
        elif (page == 42)
            autodoc2();
        elif (page == 51)
            manuf0();
        elif (page == 61)
            iff1();
        elif (page == 71)
            eol1();
        elif (page == 72)
            eol2();
        elif (page == 81)
            size1();
        elif (page == 91)
            batt1();
        elif (page == 101)
            files1();
        else
        {   // assert(page == 0);
            menu();
}   }   }

MODULE void menu(void)
{   /* PAGE 0 ************************************************************* */

    SWORD menuheight;

    if (pal)
        menuheight = PALMENUHEIGHT;
    else menuheight = PUBMENUHEIGHT;

    navigate();

    /* function */
    setgadget(100, menuheight - 146, 0, 0, NULL, PLACETEXT_RIGHT);
    MX00_Function = PrevGadPtr = (struct Gadget *) CreateGadget
    (   MX_KIND,
	PrevGadPtr,
	&Gadget,
	GTMX_Labels, &FunctionOptions,
        GTMX_Active, shared.function,
	GT_Underscore, '_',
	TAG_DONE
    );
    
	/* editor */
        if (shared.editor[0] == 0)
            if (GetVar("EDITOR", &(shared.editor), LONGFIELD, NULL) == -1)
                strcpy(shared.editor, "SYS:Tools/MEmacs");
        setgadget(146, menuheight - 42, 180, 12, "Editor pathname:", NULL);
        ST00_Editor = PrevGadPtr = (struct Gadget *) CreateGadget
	(	STRING_KIND,
		PrevGadPtr,
		&Gadget,
                GTST_String, &(shared.editor),
		GTST_MaxChars, LONGFIELD,
		GA_TabCycle, TRUE,
		TAG_DONE
	);
	/* editor... */
        setgadget(328, menuheight - 42, 28, 12, "...", NULL);
        BU00_EditorASL = PrevGadPtr = (struct Gadget *) CreateGadget
	(	BUTTON_KIND,
		PrevGadPtr,
		&Gadget,
		TAG_DONE
	);

        if (osversion >= 44)
        {   GT_SetGadgetAttrs
            (   ST00_Editor,
                MainWindowPtr, NULL,
                GA_Disabled, FALSE,
                TAG_DONE
            );
            GT_SetGadgetAttrs
            (   BU00_EditorASL,
                MainWindowPtr, NULL,
                GA_Disabled, FALSE,
                TAG_DONE
            );
        }

        newwindow
        (   366, menuheight,
            "Report+: Main Menu",
            BUTTONIDCMP | MXIDCMP
        );
        if (pal)
            DrawImage(MainWindowPtr->RPort, &Logo, 81, 20);
        else DrawImage(MainWindowPtr->RPort, &PubLogo, 81, 20);

        loop();
	strcpy
        (       shared.editor,
                ((struct StringInfo *) ST00_Editor->SpecialInfo)->Buffer
	);
	closewindow();
}

AGLOBAL void cleanexit(SBYTE rc)
{   /* ASL requesters are assumed to be already closed. */

    // help|about...
    if (AboutWindowPtr)
    {   if (pal)
            unboingball();
        CloseWindow(AboutWindowPtr);
        AboutWindowPtr = NULL;
    }

    // all
    if (LabelBase)
    {   CloseLibrary(LabelBase);
        LabelBase = NULL;
    }
    if (TextEditorBase)
    {   CloseLibrary(TextEditorBase);
        TextEditorBase = NULL;
    }
    if (ButtonBase)
    {   CloseLibrary(ButtonBase);
        ButtonBase = NULL;
    }
    if (LayoutBase)
    {   CloseLibrary(LayoutBase);
        LayoutBase = NULL;
    }
    if (WindowBase)
    {   CloseLibrary(WindowBase);
        WindowBase = NULL;
    }

    // function 10
    if (ListBrowserBase)
    {   clearlblist();
        CloseLibrary(ListBrowserBase);
        ListBrowserBase = NULL;
    }

    autodoc_exit();

    // functions 8 & 10
    while(DirNamesAllocated)
    {   FreeMem(DirNamePtr[DirNamesAllocated], VLONGFIELD);
        DirNamePtr[DirNamesAllocated--] = NULL;
    }
    while(FileNamesAllocated)
    {   FreeMem(FileNamePtr[FileNamesAllocated], VLONGFIELD);
        FileNamePtr[FileNamesAllocated--] = NULL;
    }
    if (SharedFileHandle)
    {   Close(SharedFileHandle);
        SharedFileHandle = NULL;
    }
    if (eac)
    {   FreeDosObject(DOS_EXALLCONTROL, eac);
        eac = NULL;
    }
    if (DirHandle)
    {   UnLock(DirHandle);
        DirHandle = NULL;
    }
    if (EADataPtr)
    {   FreeMem(EADataPtr, 2048);
        EADataPtr = NULL;
    }

    // all
    if (!pal && ScreenPtr)
    {   UnlockPubScreen(NULL, ScreenPtr);
        ScreenPtr = NULL;
    }
    if (OldWindowPtr)
    {   ProcessPtr->pr_WindowPtr = OldWindowPtr;
        OldWindowPtr = NULL;
    }
    if (MainWindowPtr)
        closewindow(); // this sets appropriate pointers to NULL

    /* Remember that you can't fool around with the list whilst the
    gadget is still using it. */

    report_exit();
    size_exit();

    // all
    if (pal)
    {   if (BkgrndWindowPtr)
        {   CloseWindow(BkgrndWindowPtr);
            BkgrndWindowPtr = NULL;
        }
        if (ScreenPtr)
        {   if (!CloseScreen(ScreenPtr))
            {   DisplayBeep(ScreenPtr);
            } // about to crash, because of open visitor windows
            ScreenPtr = NULL;
    }   }

    // function 3
    acse_exit();

    // all
    if (FontPtr)
    {   CloseFont(FontPtr);
        FontPtr = NULL;
    }
    if (DiskFontBase)
    {   CloseLibrary((struct Library *) DiskFontBase);
        DiskFontBase = NULL;
    }

        if (ASLBase)                    CloseLibrary((struct Library *) ASLBase);
        if (GadToolsBase)               CloseLibrary((struct Library *) GadToolsBase);
        if (ArgsPtr)                    FreeArgs(ArgsPtr);
        if (IntuitionBase)          {   OpenWorkBench();
                                        CloseLibrary((struct Library *) IntuitionBase);
                                    }

                                        exit(rc);
                                        /* End of program. */
}

MODULE void clearkybd(void)
{	struct IntuiMessage* MsgPtr;

	while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
            GT_ReplyIMsg(MsgPtr);
}

AGLOBAL void FreeNameNodes(struct List* ListPtr)
{	/* RKM Libraries, p. 496:
	
	"Free the entire list, including the header. The header is not
	updated as the list is freed. This function demonstrates how to
        avoid referencing freed memory when deallocating nodes." */

	struct NameNode *WorkNodePtr, *NextNodePtr;
	
	WorkNodePtr = (struct NameNode *) (ListPtr->lh_Head); /* first node */
	while (NextNodePtr = (struct NameNode *) (WorkNodePtr->nn_Node.ln_Succ))
        {   FreeMem(WorkNodePtr, sizeof(struct NameNode));
            WorkNodePtr = NextNodePtr;
}	}

MODULE void gadtools(void)
{   if (!pal)
    {   if (!(ScreenPtr = LockPubScreen(NULL)))
            rq("Can't lock default public screen!");
    }
    if (!(Gadget.ng_VisualInfo = VisualInfoPtr = (struct VisualInfo *) GetVisualInfo(ScreenPtr, TAG_DONE)))
        rq("Can't get GadTools visual info!");
    if (!pal)
    {   UnlockPubScreen(NULL, ScreenPtr);
        ScreenPtr = NULL;
    }
    if (pal)
    {   if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, GTMN_FrontPen, BLACK, TAG_DONE)))
            rq("Can't create menus!");
    } else
    {   if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, TAG_DONE)))
            rq("Can't create menus!");
    }
    if (!(LayoutMenus(MenuPtr, VisualInfoPtr, GTMN_NewLookMenus, TRUE, TAG_DONE)))
        rq("Can't lay out menus!");
    if (!(PrevGadPtr = (struct Gadget *) CreateContext(&GListPtr)))
        rq("Can't create GadTools context!");
}

AGLOBAL void newwindow(SWORD width, SWORD height, STRPTR title, ULONG idcmp)
{   if (!PrevGadPtr)
        rq("Can't create GadTools gadgets!");
    if (pal)
    {   if (!(MainWindowPtr = (struct Window *) OpenWindowTags(NULL,
            WA_Left,         (xsize / 2) - (width / 2),          
            WA_Top,          12 + ((ysize - 12) / 2) - (height / 2),
            WA_Width,        width,
            WA_Height,       height,
            WA_IDCMP,        IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_REFRESHWINDOW |
                             IDCMP_MOUSEBUTTONS | IDCMP_INTUITICKS | IDCMP_VANILLAKEY
                             | idcmp,
            WA_Gadgets,      GListPtr,
            WA_CustomScreen, ScreenPtr,
            WA_Activate,     TRUE,
            WA_Title,        title,
            WA_DragBar,      TRUE,
            WA_DepthGadget,  TRUE,
            WA_CloseGadget,  TRUE,
            WA_SmartRefresh, TRUE,
            TAG_DONE)))
            rq("Can't open main window!");

        /* redirection of AmigaDOS system requesters */
        OldWindowPtr = ProcessPtr->pr_WindowPtr;
        ProcessPtr->pr_WindowPtr = (APTR) MainWindowPtr;
    } else
    {   if (!(ScreenPtr = LockPubScreen(NULL)))
            rq("Can't lock default public screen!");
        /* open the window on the public screen */
        if (!(MainWindowPtr = (struct Window*) OpenWindowTags(NULL,
                WA_Left,         (xsize / 2) - (width / 2),
                WA_Top,          12 + ((ysize - 12) / 2) - (height / 2),
                WA_Width,        width,
                WA_Height,       height,
                WA_IDCMP,
                IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_REFRESHWINDOW |
                IDCMP_MOUSEBUTTONS | IDCMP_INTUITICKS | IDCMP_VANILLAKEY | idcmp,
                WA_Gadgets,      GListPtr,
                WA_PubScreen,    ScreenPtr,
                WA_Activate,     TRUE,
                WA_Title,        title,
                WA_DragBar,      TRUE,
                WA_DepthGadget,  TRUE,
                WA_CloseGadget,  TRUE,
                WA_SmartRefresh, TRUE,
                WA_NewLookMenus, TRUE,
                TAG_DONE)))
            rq("Can't open main window!");
        UnlockPubScreen(NULL, ScreenPtr);
        ScreenPtr = NULL;
    }
    SetMenuStrip(MainWindowPtr, MenuPtr);
    GT_RefreshWindow(MainWindowPtr, NULL);
}

MODULE void helpabout(void)
{   SBYTE line;
    TEXT  ks[5], wb[5];

    OffMenu(MainWindowPtr, FULLMENUNUM(MN_HELP, IN_ABOUT, NOSUB));
    switch(ksval)
    {
    case 37:
        strcpy(ks, "2.04");
    break;
    case 38:
        strcpy(ks, "2.1 ");
    break;
    case 39:
        strcpy(ks, "3.0 ");
    break;
    case 40:
        strcpy(ks, "3.1 ");
    break;
    case 45:
        strcpy(ks, "3.9 ");
    break;
    default:
        strcpy(ks, "4.0+");
    break;
    }
    switch(wbval)
    {
    case 37:
        strcpy(wb, "2.04");
    break;
    case 38:
        strcpy(wb, "2.1 ");
    break;
    case 39:
        strcpy(wb, "3.0 ");
    break;
    case 40:
    case 41:
    case 42:
    case 43:
        strcpy(wb, "3.1 ");
    break;
    case 44:
        strcpy(wb, "3.5 ");
    break;
    case 45:
        strcpy(wb, "3.9 ");
    break;
    default:
        strcpy(wb, "4.0+");
    break;
    }

    if (pal)
    {   if (!(AboutWindowPtr = (struct Window *) OpenWindowTags(NULL,
        WA_Left,          (xsize / 2) - (ABOUTXPIXEL / 2),
        WA_Top,           12 + ((ysize - 12) / 2) - (ABOUTYPALPIXEL / 2),
        WA_Width,         ABOUTXPIXEL,
        WA_Height,        ABOUTYPALPIXEL,
        WA_IDCMP,         IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
        WA_Title,         "About Report+",
        WA_Gadgets,       NULL,
        WA_CustomScreen,  ScreenPtr,
        WA_DragBar,       TRUE,
        WA_CloseGadget,   TRUE,
        WA_NoCareRefresh, TRUE,
        WA_Activate,      TRUE,
	TAG_DONE)))
            rq("Can't open About... window!");

        SetAPen(AboutWindowPtr->RPort, LIGHTGREY);
        RectFill(AboutWindowPtr->RPort, 8, 13, ABOUTXPIXEL - 9, ABOUTYPALPIXEL - 5);
	SetAPen(AboutWindowPtr->RPort, ABOUTSHADOW);
        Move(AboutWindowPtr->RPort, 7, ABOUTYPALPIXEL - 4);
	Draw(AboutWindowPtr->RPort, 7, 12);
	Draw(AboutWindowPtr->RPort, ABOUTXPIXEL - 8, 12);
	SetAPen(AboutWindowPtr->RPort, ABOUTSHINE);
        Draw(AboutWindowPtr->RPort, ABOUTXPIXEL - 8, ABOUTYPALPIXEL - 4);
        Draw(AboutWindowPtr->RPort, 8, ABOUTYPALPIXEL - 4);
    } else
    {   if (!(AboutWindowPtr = (struct Window *) OpenWindowTags(NULL,
        WA_Left,                (xsize / 2) - (ABOUTXPIXEL / 2),
        WA_Top,                 12 + ((ysize - 12) / 2) - (ABOUTYPUBPIXEL / 2),
        WA_Width,               ABOUTXPIXEL,
        WA_Height,              ABOUTYPUBPIXEL,
        WA_IDCMP,               IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
        WA_Title,               "About Report+",
        WA_Gadgets,             NULL,
        WA_PubScreen,           ScreenPtr,
        WA_DragBar,             TRUE,
	WA_CloseGadget,		TRUE,
	WA_NoCareRefresh,	TRUE,
	WA_Activate,		TRUE,
	TAG_DONE)))
            rq("Can't open About... window!");
    }

    SetDrMd(AboutWindowPtr->RPort, JAM1);

    SetAPen(AboutWindowPtr->RPort, BLACK);
    for (line = 0; line <= ABOUTLINES; line++)
    {   if (pal || line < ABOUTLINES)
        {   Move(AboutWindowPtr->RPort, about[line].x + 1, about[line].y + 1);
            Text(AboutWindowPtr->RPort, about[line].text, (SBYTE) strlen(about[line].text));
    }   }
    SetAPen(AboutWindowPtr->RPort, WHITE);
    for (line = 0; line <= ABOUTLINES; line++)
    {   if (pal || line < ABOUTLINES)
        {   Move(AboutWindowPtr->RPort, about[line].x, about[line].y);
            Text(AboutWindowPtr->RPort, about[line].text, (SBYTE) strlen(about[line].text));
    }   }

    Move(AboutWindowPtr->RPort, KICKSTARTX, KICKSTARTY);
    Text(AboutWindowPtr->RPort, ks, 4);
    Move(AboutWindowPtr->RPort, WORKBENCHX, WORKBENCHY);
    Text(AboutWindowPtr->RPort, wb, 4);

    if (pal)
    {   DrawBevelBox(AboutWindowPtr->RPort, 18, 21, 48, 23, GT_VisualInfo, VisualInfoPtr, GTBB_Recessed, TRUE, TAG_DONE);
        DrawImage(AboutWindowPtr->RPort, &About, 20, 22);
    } else
    {   DrawBevelBox(AboutWindowPtr->RPort, 18, 21, 48, 46, GT_VisualInfo, VisualInfoPtr, GTBB_Recessed, TRUE, TAG_DONE);
        DrawImage(AboutWindowPtr->RPort, &PubAbout, 20, 22);
    }

    if (pal)
        boingball();
}

AGLOBAL void closewindow(void)
{   if (MainWindowPtr)
    {   clearkybd();
        ClearMenuStrip(MainWindowPtr);
        CloseWindow(MainWindowPtr);
        MainWindowPtr = NULL;
    }
    if (GListPtr)
    {   FreeGadgets(GListPtr);
        GListPtr = NULL;
    }
    if (MenuPtr)
    {   FreeMenus(MenuPtr);
        MenuPtr = NULL;
    }
    if (VisualInfoPtr)
    {   FreeVisualInfo(VisualInfoPtr);
        VisualInfoPtr = NULL;
}   }

AGLOBAL void asl(void)
{   struct FileRequester* ASLRqPtr;

    if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, "~(#?.info)", ASL_Window, MainWindowPtr, TAG_DONE)))
        rq("Can't create ASL request!");
    if (AslRequestTags(ASLRqPtr, ASL_Dir, asldir, ASL_Hail, "Report+ file selector", ASL_FuncFlags, FILF_PATGAD, TAG_DONE) && *(ASLRqPtr->rf_File) != 0)
    {   strcpy(asldir, ASLRqPtr->rf_Dir);
        strcpy(aslresult, ASLRqPtr->rf_Dir);
        if (!AddPart(aslresult, ASLRqPtr->rf_File, VLONGFIELD))
            rq("Can't add filename to pathname!");
    }
    if (ASLRqPtr)
        FreeAslRequest(ASLRqPtr);
}

AGLOBAL void loop(void)
{  AUTO SWORD                i, oldpage = page;
   AUTO struct Gadget*       addr;
   AUTO struct MenuItem*     ItemPtr;
   AUTO struct IntuiMessage* MsgPtr;
   AUTO UWORD                code, qual;
   AUTO ULONG                class, hostid;
   AUTO ABOOL                done = FALSE;
   AUTO SWORD                mousex, mousey, realx, realy, bit;
   AUTO struct Lock*         LockPtr;
PERSIST UBYTE                pos = 0;

    /* i must be signed, and at least 16 bits wide. */

    while (page == oldpage && (!done))
    {   if (AboutWindowPtr)
        {   if (pal)
                DrawGels();
            else
            {   Wait((1L <<  MainWindowPtr->UserPort->mp_SigBit) |
                     (1L << AboutWindowPtr->UserPort->mp_SigBit));
            }
            if (aboutloop())
            {   if (pal)
                    unboingball();
                CloseWindow(AboutWindowPtr);
                AboutWindowPtr = NULL;
                OnMenu(MainWindowPtr, FULLMENUNUM(MN_HELP, IN_ABOUT, NOSUB));
        }   }
        else
        {   Wait(1L <<  MainWindowPtr->UserPort->mp_SigBit);
        }
        while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
        {   class  = MsgPtr->Class;                       
            code   = MsgPtr->Code;
            addr   = MsgPtr->IAddress;
            qual   = MsgPtr->Qualifier;
            mousex = MsgPtr->MouseX;
            mousey = MsgPtr->MouseY;
            GT_ReplyIMsg(MsgPtr);
            if (page >= 11 && page <= 15)
                report_loop(class, addr, code);
            if (page >= 21 && page <= 22)
                aminet_loop(class, addr, code);
            elif (page >= 31 && page <= 33)
                done = acse_loop(class, addr, code);
            elif (page >= 41 && page <= 42)
                autodoc_loop(class, addr, code);
            elif (page == 51)
                manuf_loop(class, addr);
            elif (page == 61)
                iff_loop(class, addr);
            elif (page >= 71 && page <= 72)
                eol_loop(class, addr, code);
            elif (page == 81)
                size_loop(class, addr, code);
            else {
            switch(class)
            {
            case IDCMP_INACTIVEWINDOW:
                ActivateWindow(MainWindowPtr);
            break;
            case IDCMP_VANILLAKEY:
                if (page == 0)
                {   if (code == secret[pos])
                        pos++;
                    else pos = 0;
                    if (pos >= SECRETLENGTH)
                    {   /* decrypt RAM:ReportPlus.ACSE */
                        readordie("RAM:ReportPlus.ACSE");
                        for (i = 0; i < strlen(IOBuffer) - 1; i++)
                            IOBuffer[i] = 255 - IOBuffer[i];
                        write("RAM:ReportPlus.ASCII");
                        pos = 0;
                }   }
                elif (page == 101)
                {   code = toupper(code);
                    if (code == 'V')
                    {   if (!(qual & IEQUALIFIER_LSHIFT) && !(qual & IEQUALIFIER_RSHIFT))
                        {   if (osversion < 2)
                                osversion++;
                            else osversion = 0;
                        } else
                        {   if (osversion > 0)
                                osversion--;
                            else osversion = 2;
                        }
                        GT_SetGadgetAttrs
                        (   MX101_OSVersion,
                            MainWindowPtr,
                            NULL,
                            GTMX_Active, osversion,
                            TAG_DONE
                        );
                    } elif (code == 'L')
                    {   if (shared.log)
                            shared.log = FALSE;
                        else shared.log = TRUE;
                        GT_SetGadgetAttrs
                        (   CB99_Log,
                            MainWindowPtr,
                            NULL,
                            GTCB_Checked, shared.log,
                            TAG_DONE
                        );
                    } elif (code == 'U')
                    {   updatefiles();
                    } elif (code == 'O')
                    {   ActivateGadget(ST99_Output, MainWindowPtr, NULL);
                    } elif (code == ESCAPE)
                    {   page = 0;
                }   }
            break;
            case IDCMP_MOUSEBUTTONS:
                if (page == 91 && code == SELECTDOWN && !(qual & IEQUALIFIER_REPEAT))
                    if (mousex >= BOXLEFTX && mousex <= BOXRIGHTX && mousey >= BOXTOPY && mousey <= BOXBOTTOMY)
                    {   realx = (mousex - BOXLEFTX - 2) / 8;
                        realy = (mousey - BOXTOPY - 4) / 8;
                        if (realx < 0)
                            realx = 0;
                        elif (realx > 31)
                            realx = 31;
                        if (realy < 0)
                            realy = 0;
                        elif (realy > 7)
                            realy = 7;
                        // now flip it
                        bit = (realy * 32) + realx;
                        if ((BattBuffer[bit / 8]) & (1 << (bit % 8)))
                            BattBuffer[bit / 8] &= 255 - (1 << (bit % 8));
                        else BattBuffer[bit / 8] |= (1 << (bit % 8));
                        drawbit(bit, WHITE);
                        updatebattgadgets();
                    }
                break;
            case IDCMP_MENUPICK:
                while (code != MENUNULL)
                {   ItemPtr = ItemAddress(MenuPtr, code);
                    switch (MENUNUM(code))
                    {
                    case MN_PROJECT:
                        switch (ITEMNUM(code))
                        {
                        case IN_QUIT:
                            cleanexit(EXIT_SUCCESS);
                        break;
                        default:
                        break;
                        }
                    break;
                    case MN_HELP:
                        switch (ITEMNUM(code))
                        {
                        case IN_ABOUT:
                            helpabout();
                        break;
                        case IN_MANUAL:
                            LockPtr = GetProgramDir(); /* never UnLock() this! */
                            if (SystemTagList("SYS:Utilities/MultiView ReportPlus.guide", SYS_Input, LockPtr, SYS_Output, NULL, SYS_Asynch, TRUE, TAG_DONE) == -1)
                                DisplayBeep(ScreenPtr);
                            elif (pal)
                                ScreenToFront(ScreenPtr);
                        break;
                        default:
                        break;
                        }
                    break;
                    default:
                    break;
                    }
                    code = ItemPtr->NextSelect;
                }
            break;
            case IDCMP_CLOSEWINDOW:
                cleanexit(EXIT_SUCCESS);
            break;
            case IDCMP_REFRESHWINDOW:
                GT_BeginRefresh(MainWindowPtr);
                GT_EndRefresh(MainWindowPtr, TRUE);
            break;
            case IDCMP_GADGETDOWN:
                /* radio gadgets */
                switch(page)
                {
                case 0:
                    if (addr == MX00_Function)
                         shared.function = code;
                break;
                case 101:
                    if (addr == MX101_OSVersion)
                        osversion = code;
                break;
                default:
                break;
                }
            break;
            case IDCMP_GADGETUP:
                /* buttons, listviews, checkboxes */
                if (addr == BU99_Right)
                {   switch(page)
                    {
                    case 0:
                        if (shared.function == 0)
                            page = 11;
                        elif (shared.function == 1)
                            page = 21;
                        elif (shared.function == 2)
                            page = 31;
                        elif (shared.function == 3)
                            page = 41;
                        elif (shared.function == 4)
                            page = 51;
                        elif (shared.function == 5)
                            page = 61;
                        elif (shared.function == 7)
                            page = 81;
                        elif (shared.function == 8)
                            page = 91;
                        elif (shared.function == 9)
                            page = 101;
                        else
                        {   /* assert(shared.function == 6); */
                            page = 71;
                        }
                    break;
                    case 91:
                    case 101:
                        page = 0;
                    break;
                    default:
                        page++;
                    break;
                }   }
                else
                {   switch(page)
                    {
                    case 0:
                        if (addr == BU00_EditorASL)
                        {   asl();
                            GT_SetGadgetAttrs
                            (   ST00_Editor,
                                MainWindowPtr,
                                NULL,
                                GTST_String, aslresult,
                                TAG_DONE
                            );
                        }
                    break;
                    case 91:
                        if (addr == CB91_AmigaAmnesia)
                        {   if (CB91_AmigaAmnesia->Flags & GFLG_SELECTED)
                                BattBuffer[0] &= 255 - 1;
                            else BattBuffer[0] |= 1;
                            drawbit(0, WHITE);
                        } elif (addr == CB91_SharedAmnesia)
                        {   if (CB91_SharedAmnesia->Flags & GFLG_SELECTED)
                                BattBuffer[8] &= 255 - 1;
                            else BattBuffer[8] |= 1;
                            drawbit(64, WHITE);
                        } elif (addr == CB91_SCSITimeout)
                        {   if (CB91_SCSITimeout->Flags & GFLG_SELECTED)
                                BattBuffer[0] &= 255 - 2;
                            else BattBuffer[0] |= 2;
                            drawbit(1, WHITE);
                        } elif (addr == CB91_SCSILUNS)
                        {   if (CB91_SCSILUNS->Flags & GFLG_SELECTED)
                                BattBuffer[0] &= 255 - 4;
                            else BattBuffer[0] |= 4;
                            drawbit(2, WHITE);
                        }
                        elif (addr == IN91_SCSIHostID)
                        {   hostid = ((struct StringInfo *) IN91_SCSIHostID->SpecialInfo)->LongInt;
                            if (hostid < 0 || hostid > 7)
                                GT_SetGadgetAttrs
                                (   IN91_SCSIHostID,
                                    MainWindowPtr, NULL,
                                    GTIN_Number, oldhostid,
                                    TAG_DONE
                                );
                            else
                            {   oldhostid = hostid;
                                if (hostid & 4)
                                    BattBuffer[8] &= 255 - 2; // then clear the '4' bit
                                else BattBuffer[8] |= 2;
                                drawbit(65, WHITE);
                                if (hostid & 2)
                                    BattBuffer[8] &= 255 - 4; // then clear the '2' bit
                                else BattBuffer[8] |= 4;
                                drawbit(66, WHITE);
                                if (hostid & 1)
                                    BattBuffer[8] &= 255 - 8; // then clear the '1' bit
                                else BattBuffer[8] |= 8;
                                drawbit(67, WHITE);
                        }   }
                        elif (addr == CB91_SCSISyncXfer)
                        {   if (CB91_SCSISyncXfer->Flags & GFLG_SELECTED)
                                BattBuffer[8] &= 255 - 16;
                            else BattBuffer[8] |= 16;
                            drawbit(68, WHITE);
                        } elif (addr == CB91_SCSIFastSync)
                        {   if (CB91_SCSIFastSync->Flags & GFLG_SELECTED)
                                BattBuffer[8] &= 255 - 32;
                            else BattBuffer[8] |= 32;
                            drawbit(69, WHITE);
                        } elif (addr == CB91_SCSITagQueues)
                        {   if (CB91_SCSITagQueues->Flags & GFLG_SELECTED)
                                BattBuffer[8] &= 255 - 64;
                            else BattBuffer[8] |= 64;
                            drawbit(70, WHITE);
                        } elif (addr == BU91_Revert)
                            readbatt(TRUE);
                        elif (addr == BU91_Write)
                        {   ObtainBattSemaphore();
                            if (WriteBattMem(&BattBuffer, 0, 256))
                                rq("Can't write battery-backed memory!");
                            ReleaseBattSemaphore();
                            readbatt(TRUE);
                        }
                    break;
                    case 101:
                        /* IDCMP_GADGETUP is sent by the string gadget
                        when the user presses RETURN, ENTER, Help, Tab
                        or Shift-Tab inside the string gadget. */

                        if (addr == BU99_Update)
                            updatefiles();
                        elif (addr == CB99_Log)
                        {   if (CB99_Log->Flags & GFLG_SELECTED)
                            {   shared.log = TRUE;
                                GT_SetGadgetAttrs
                                (   ST99_Output,
                                    MainWindowPtr, NULL,
                                    GA_Disabled, FALSE,
                                    TAG_DONE
                                );
                                GT_SetGadgetAttrs
                                (   BU99_OutputASL,
                                    MainWindowPtr, NULL,
                                    GA_Disabled, FALSE,
                                    TAG_DONE
                                );
                            } else
                            {   shared.log = FALSE;
                                GT_SetGadgetAttrs
                                (   ST99_Output,
                                    MainWindowPtr, NULL,
                                    GA_Disabled, TRUE,
                                    TAG_DONE
                                );
                                GT_SetGadgetAttrs
                                (   BU99_OutputASL,
                                    MainWindowPtr, NULL,
                                    GA_Disabled, TRUE,
                                    TAG_DONE
                                );
                        }   }
                        elif (addr == ST99_Output)
                        {   strcpy
                            (   shared.output,
                                ((struct StringInfo *) ST99_Output->SpecialInfo)->Buffer
                            );
                        } elif (addr == BU99_OutputASL)
                        {   asl();
                            GT_SetGadgetAttrs
                            (   ST99_Output,
                                MainWindowPtr,
                                NULL,
                                GTST_String, aslresult,
                                TAG_DONE
                            );
                        }
                    break;
                    default:
                    break;
                }   }
            break; // esac IDCMP_GADGETUP
            default:
            break;
}   }   }   }   }

AGLOBAL void navigate(void)
{   gadtools();

    /* previous */
    switch(page)
    {
    case 11:
        setgadget(10,  REPORT1HEIGHT - 16, 310, 12, "Menu",     NULL);
    break;
    case 12:
        setgadget(10,  REPORT2HEIGHT - 16, 310, 12, "Previous", NULL);
    break;
    case 13:
        setgadget(10,   SENDERHEIGHT - 16, 310, 12, "Previous", NULL);
    break;
    case 14:
        setgadget(10,   CONFIGHEIGHT - 16, 310, 12, "Previous", NULL);
    break;
    case 21:
        setgadget(10,  AMINET1HEIGHT - 16, 310, 12, "Menu",     NULL);
    break;
    case 31:
        setgadget(10,    ACSE1HEIGHT - 16, 310, 12, "Pass",     NULL);
    break;
    case 41:
        setgadget(10, AUTODOC1HEIGHT - 16, 310, 12, "Menu",     NULL);
    break;
    case 71:
        setgadget(10,     EOL1HEIGHT - 16, 310, 12, "Menu",     NULL);
    break;
    default:
    break;
    }

/* p. 11 (bug report), 21 (Aminet readme), 41 (autodoc), 71 (EOL/tab
converter) have `menu' buttons.

p. 12-14 have 'previous' buttons.

p. 31 (ACSE test) has a 'pass' button.

p. 51 (ID database), 61 (IFF registry), 81 (path size report), 91
(battery RAM), 101 (system file report) use NextGadgetPtr as their 'menu'
button. */

    if ((page >= 11 && page <= 21) || page == 31 || page == 41 || page == 71)
    {   if (page == 13 && certified)
        {   BU99_Left = PrevGadPtr = (struct Gadget *) CreateGadget
            (   BUTTON_KIND,
                PrevGadPtr,
                &Gadget,
                GA_Disabled, TRUE,
                TAG_DONE
            );
        } else
        {   BU99_Left = PrevGadPtr = (struct Gadget *) CreateGadget
            (   BUTTON_KIND,
                PrevGadPtr,
                &Gadget,
                TAG_DONE
            );
    }   }

    /* next */
    switch(page)
    {
    case 0:
        if (pal)
            setgadget( 10, PALMENUHEIGHT - 16, 346, 12, "Begin", NULL);
        else setgadget( 10, PUBMENUHEIGHT - 16, 346, 12, "Begin", NULL);
    break;
    case 11:
        setgadget(320, REPORT1HEIGHT - 16, 310, 12, "Next", NULL);
    break;
    case 12:
        setgadget(320, REPORT2HEIGHT - 16, 310, 12, "Next", NULL);
    break;
    case 13:
        setgadget(320, SENDERHEIGHT - 16, 310, 12, "Next", NULL);
    break;
    case 14:
        setgadget(320, CONFIGHEIGHT - 16, 310, 12, "Finish", NULL);
    break;
    case 15:
        setgadget( 10, REPORT3HEIGHT - 16, 620, 12, "Menu", NULL);
    break;
    case 21:
        setgadget(320, AMINET1HEIGHT - 16, 310, 12, "Finish", NULL);
    break;
    case 22:
        setgadget( 10, AMINET2HEIGHT - 16, 620, 12, "Menu", NULL);
    break;
    case 31:
        setgadget(320,   ACSE1HEIGHT - 16, 310, 12, "Submit", NULL);
    break;
    case 32:
        if (certified)
            setgadget( 10, ACSE2HEIGHT - 16, 620, 12, "Finish", NULL);
        else
            setgadget( 10, ACSE2HEIGHT - 16, 620, 12, "Menu", NULL);
    break;
    case 33:
        setgadget( 10, ACSE3HEIGHT - 16, 620, 12, "Menu", NULL);
    break;
    case 41:
        setgadget(320, AUTODOC1HEIGHT - 16, 310, 12, "Finish", NULL);
    break;
    case 42:
        setgadget( 10, AUTODOC2HEIGHT - 16, 620, 12, "Finish", NULL);
    break;
    case 51:
        setgadget( 10, MANUF1HEIGHT - 16, 620, 12, "Menu", NULL);
    break;
    case 61:
        setgadget( 10, IFF1HEIGHT - 16, 620, 12, "Menu", NULL);
    break;
    case 71:
        setgadget(320, EOL1HEIGHT - 16, 310, 12, "Convert", NULL);
    break;
    case 72:
        setgadget( 10, EOL2HEIGHT - 16, 620, 12, "Menu", NULL);
    break;
    case 81:
        setgadget( 10, SIZE1HEIGHT - 16, 620, 12, "Menu", NULL);
    break;
    case 91:
        setgadget( 10, BATT1HEIGHT - 16, 620, 12, "Menu", NULL);
    break;
    case 101:
        setgadget( 10, FILES1HEIGHT - 16, 620, 12, "Menu", NULL);
    break;
    default:
    break;
    }
    if (page == 21)
    {   /* This can cause the gadget to be disabled when it shouldn't be.
        But we are not in a situation where we can check the contents of
        the 'Short:' field, because those gadgets have not been completely
        created yet. As soon as the next IDCMP_INTUITICK arrives (1/10
        seconds), all will be well. */
        BU99_Right = PrevGadPtr = (struct Gadget *) CreateGadget
        (   BUTTON_KIND,
            PrevGadPtr,
            &Gadget,
            GA_Disabled, TRUE,
            TAG_DONE
        );
    } else
    {   BU99_Right = PrevGadPtr = (struct Gadget *) CreateGadget
        (   BUTTON_KIND,
            PrevGadPtr,
            &Gadget,
            TAG_DONE
        );
}   }

AGLOBAL void setgadget(WORD leftx, WORD topy, WORD width, WORD height,
    STRPTR text, ULONG flags)
{   Gadget.ng_LeftEdge   = leftx;
    Gadget.ng_TopEdge    = topy;
    Gadget.ng_Width      = width;
    Gadget.ng_Height     = height;
    Gadget.ng_GadgetText = text;
    Gadget.ng_Flags      = flags;
}

AGLOBAL ABOOL readin(STRPTR pathname)
{   BPTR FileHandle;

    if (!(FileHandle = (BPTR) Open(pathname, MODE_OLDFILE)))
        return FALSE;
    if (Read(FileHandle, IOBuffer, VLONGFIELD) == -1)
    {   Close(FileHandle);
        return FALSE;
    }
    Close(FileHandle);
    return TRUE;
}

AGLOBAL void writeout(STRPTR pathname)
{   BPTR FileHandle;

    if (!(FileHandle = (BPTR) Open(pathname, MODE_NEWFILE)))
        rq("Can't open file for writing!");
    if (Write(FileHandle, IOBuffer, strlen(IOBuffer)) == -1)
    {   Close(FileHandle);
        rq("Can't write to file!");
    }
    Close(FileHandle);
}

AGLOBAL void say(STRPTR sentence, UBYTE colour)
{       SetAPen(MainWindowPtr->RPort, BLACK);
        Move
	(	MainWindowPtr->RPort,
		320 - (strlen(sentence) * 4),
		y
	);
	Text
	(	MainWindowPtr->RPort,
		sentence,
		strlen(sentence)
	);
        if (colour == WHITE)
        {       SetAPen(MainWindowPtr->RPort, WHITE);
                SetDrMd(MainWindowPtr->RPort, JAM1);
                Move
	        (	MainWindowPtr->RPort,
		        319 - (strlen(sentence) * 4),
	        	y - 1
	        );
        	Text
	        (	MainWindowPtr->RPort,
		        sentence,
		        strlen(sentence)
        	);
        }
	y += 16;
        SetDrMd(MainWindowPtr->RPort, JAM2);
}

AGLOBAL void launcheditor(void)
{   /* This function expects a suitable window to be ready for output;
    eg. autodoc2(). */

    y = 30;
    strcpy(string, "Launching ");

    GT_SetGadgetAttrs
    (   BU99_Right,
        MainWindowPtr, NULL,
        GA_Disabled, TRUE,
        TAG_DONE
    );

    if (wbval <= 43)
    {   ClearMenuStrip(MainWindowPtr);
        strcat(string, shared.editor);
        strcat(string, "...");
        say(string, WHITE);

        strcpy(string, shared.editor);
	strcat(string, " ");
	strcat
        (   string,
            shared.output
	);
	if (!Execute(string, NULL, NULL))
            rq("Can't launch editor!");
    } else
    {   strcat(string, "ReAction text editor...");
        say(string, WHITE);
        textedit();
    }
    GT_SetGadgetAttrs
    (   BU99_Right,
        MainWindowPtr, NULL,
        GA_Disabled, FALSE,
        TAG_DONE
    );
}

AGLOBAL void rq(STRPTR text)
{       EasyStruct.es_TextFormat = text;
        EasyRequest(MainWindowPtr, &EasyStruct, NULL);

        cleanexit(EXIT_FAILURE);
}

AGLOBAL void readordie(STRPTR pathname)
{   BPTR FileHandle;

    if (!(FileHandle = (BPTR) Open(pathname, MODE_OLDFILE)))
        rq("Can't open file for reading!");
    if (Read(FileHandle, IOBuffer, LONGESTFIELD) == -1)
    {   Close(FileHandle);
        rq("Can't read file!");
    }
    if (!Close(FileHandle))
        rq("Can't close file for reading!");
}

MODULE void parsewb(void)
{   struct DiskObject* DiskObject;
    char**             ToolArray;
    char*              s;

	if ((*WBArg->wa_Name) && (DiskObject = GetDiskObject(WBArg->wa_Name)))
	{	ToolArray = (char **) DiskObject->do_ToolTypes;
		
                if (s = (char *) FindToolType(ToolArray, "PAL"))
                    pal = TRUE;
                if (s = (char *) FindToolType(ToolArray, "FUNCTION"))
                    if (MatchToolValue(s, "1"))
                        page = 11;
                    elif (MatchToolValue(s, "2"))
                        page = 21;
                    elif (MatchToolValue(s, "3"))
                        page = 31;
                    elif (MatchToolValue(s, "4"))
                        page = 41;
                    elif (MatchToolValue(s, "5"))
                        page = 51;
                    elif (MatchToolValue(s, "6"))
                        page = 61;
                    elif (MatchToolValue(s, "7"))
                        page = 71;
                    elif (MatchToolValue(s, "8"))
                        page = 81;
                    elif (MatchToolValue(s, "9"))
                        page = 91;
                    elif (MatchToolValue(s, "10"))
                        page = 101;
		FreeDiskObject(DiskObject);
}	}

/* Must have LF before EOF. */

