/* $Filename:    ReportPlus/Source/rp.c
 * $VER:         Report+ 4.22
 * $Description: Multi-function utility
 *
 * © Copyright 2000 James R. Jacobs. Freely distributable.
 *        _
 *       //      -=AMIGA=-
 *      //
 * _   //
 * \\ //
 *  \X/

#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 <dos/dos.h>
#include <dos/dostags.h>
#include <dos/dosextens.h>
#include <gadgets/listbrowser.h>
#include <pragmas/listbrowser_pragmas.h>
#include <graphics/gels.h>
#include <graphics/gfxmacros.h>
#include <utility/tagitem.h>

// boing ball
#define ID_BORDER 0
#define ID_BNG    3
#define ANFS      ANFRACSIZE
#define BNFS      (ANFRACSIZE-2)
#define CNFS      (ANFRACSIZE-2)
#define RBMDEPTH  4

#include "animtools.h"
#include "animtools_proto.h"
#include "anim_images.h"

#include <stdio.h>          /* FILE, printf() */
#include <stdlib.h>         /* EXIT_SUCCESS, EXIT_FAILURE */

#include "amigan.h"

#define PALMENUHEIGHT   206 // page 0 (+8 pixels per extra function)
#define PUBMENUHEIGHT   (PALMENUHEIGHT + 28)

#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

/*--------------------------------------------------------------*/
/* Structures for the boing ball and satellites.                */
/*--------------------------------------------------------------*/

NEWBOB newBoingBob =
{   NULL,               // initial image
    BNG3WWIDTH,         // WORD width
    BNG3HEIGHT,         // line height
    BNG3DEPTH,          // image depth
    0x3,                // plane pick
    0x0,                // plane on/off
    SAVEBACK | OVERLAY, // VSprite flags
    0,                  // dbuf (0=false)
    RBMDEPTH,           // raster depth
    32, 100,            // x, y position
    (1L<<ID_BORDER),    // hit mask
    (1L<<ID_BNG)        // me mask
};
NEWANIMSEQ newBoingSeq =
{   NULL, (WORD *)boing3Image, boing3XTranses, boing3YTranses,
    boing3Times, boing3CRoutines, 0, BNG3COUNT, 0,
};

NEWBOB newSatABob =
	{
	NULL, SATWWIDTH, SATHEIGHT, SATDEPTH,
        1,
        11,
	SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
	};
NEWANIMSEQ newSatASeq =
	{
	NULL, (WORD *)satImage, satAXTranses, satAYTranses,
	satTimes, satACRoutines, 0, SATCOUNT, 1,
	};

NEWBOB newSatBBob =
	{
	NULL, SATWWIDTH, SATHEIGHT, SATDEPTH,
        12,
        0,
	SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
	};
NEWANIMSEQ newSatBSeq =
	{
	NULL, (WORD *)satImage, satBXTranses, satBYTranses,
	satTimes, satBCRoutines, 0, SATCOUNT, 1,
	};
NEWBOB newSatCBob =
	{
	NULL, SATWWIDTH, SATHEIGHT, SATDEPTH,
        1,
        9,
	SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
	};
NEWANIMSEQ newSatCSeq =
	{
	NULL, (WORD *)satImage, satCXTranses, satCYTranses,
	satTimes, satCCRoutines, 0, SATCOUNT, 1,
	};

// help|about...

MODULE struct AnimOb*   setupBoing(void);
MODULE struct GelsInfo* setupDisplay(void);
       WORD             bounceORoutine(struct AnimOb *anOb);
                        // this is an oroutine so parameters are fixed
MODULE WORD             goInFrontOfHead(struct AnimComp *aComp);
MODULE WORD             goBehindHead(struct AnimComp *aComp);

MODULE struct Window*   AboutWindowPtr = NULL;
MODULE struct GelsInfo  *gInfo;
MODULE struct AnimOb    *boingOb;
MODULE struct AnimOb    *animKey;

MODULE UWORD chip PalLogoData[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 PalAboutData[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
};

IMPORT ABOOL certified;

#define FUNCTIONS 10

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

#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,         TITLEBARTEXT,              },
    {80, 35,         "Wednesday 24 January 2001"},
    {80, 43,         "© 2000 Amigan Software"   },
    {80, 59,         "By James R. Jacobs"       },
    {80, KICKSTARTY, "Kickstart:"               },
    {80, WORKBENCHY, "Workbench:"               },
    {80, 106,        "Public Screen: RPLUS"     }
};
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
};
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}
};

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 EOLStruct        eol;
IMPORT  struct ExecBase*        SysBase;

AGLOBAL struct Library          *WindowBase      = NULL,
                                *LayoutBase      = NULL,
                                *ButtonBase      = NULL,
                                *TextEditorBase  = NULL,
                                *LabelBase       = NULL,
                                *ListBrowserBase = NULL;
AGLOBAL ABOOL                   pal              = FALSE;
AGLOBAL TEXT                    asldir[VLONGFIELD + 1],
                                aslresult[MEDFIELD + 1],
                                IOBuffer[LONGESTFIELD + 1],
                                globalname[VLONGFIELD + 1];
AGLOBAL UBYTE                  *FileNamePtr[16768],
                               *DirNamePtr[2048];
AGLOBAL SBYTE                   page             = 0;
AGLOBAL SWORD                   y;
AGLOBAL ULONG                   elements, // for ReAction texteditor.gadget
                                DirNames, // position of top of stack
                                DirNamesAllocated = 0,
                                FileNamesAllocated = 0,
                                wbval;
AGLOBAL APTR                    OldWindowPtr     = NULL;
AGLOBAL STRPTR                  textBuffer[MAXELEMENTS + 1];
AGLOBAL struct Process*         ProcessPtr       = NULL;
AGLOBAL struct Screen*          ScreenPtr        = NULL;
AGLOBAL struct Window*          MainWindowPtr    = NULL;
AGLOBAL struct Gadget*          MX101_OSVersion  = NULL;
AGLOBAL struct VisualInfo*      VisualInfoPtr    = NULL;
AGLOBAL struct ExAllData*       ead              = NULL;
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;
AGLOBAL struct SharedStruct shared =
{   TRUE, 0,
    "", ""
};

MODULE  TEXT                    string[VLONGFIELD + 1];
MODULE  WORD                    xsize, ysize;
MODULE  ULONG                   ksval;
MODULE  struct Menu*            MenuPtr           = NULL;
MODULE  struct RDArgs*          ArgsPtr           = NULL;
MODULE  struct TextFont*        FontPtr           = NULL;
MODULE  struct Window          *BkgrndWindowPtr   = NULL;
MODULE  struct Gadget          *TE00_FunctionText[FUNCTIONS] =
        {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
                               *MX00_Function     = NULL,
                               *ST00_Editor       = NULL,
                               *BU00_EditorASL    = NULL;
MODULE  struct WBArg*           WBArg             = NULL;
MODULE  struct WBStartup*       WBMsg             = 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
};
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;
MODULE  struct Image
PalLogo =
{   0, 0,
    204, 29, 2,
    PalLogoData,
    0x3, BLACK,
    NULL
}, PubLogo =
{   0, 0,
    204, 57, 2,
    PubLogoData,
    0x3, BLACK,
    NULL
}, PalAbout =
{   0, 0,
    45, 22, 1,
    PalAboutData,
    0x4, 3,
    NULL
}, PubAbout =
{   0, 0,
    45, 44, 1,
    PubAboutData,
    0x1, 3,
    NULL
};
MODULE  struct EasyStruct       EasyStruct =
{   sizeof(struct EasyStruct),
    0,
    "Report+: Error",
    NULL,
    "Quit"
};

/* 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.22 (24.1.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();
    batt_init();

    /* From this point onwards, we can be sure we have Kickstart 2.04+... */

    if (!(VersionBase = (struct VersionBase *) OpenLibrary("version.library", 0L)))
        rq("Can't open version.library!");
    wbval = VersionBase->lib_Version;
    CloseLibrary(VersionBase);
    VersionBase = NULL;
    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]);
                eol_do(FALSE);
                Printf("All done.\n");
                cleanexit(EXIT_SUCCESS);
    }   }   }
    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,        4,
            SA_DisplayID,    HIRES_KEY | PAL_MONITOR_ID,
            SA_Title,        TITLEBARTEXT,
            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();
    files_init();
    double_init();

    if (shared.editor[0] == 0)
        if (GetVar("EDITOR", shared.editor, LONGFIELD, NULL) == -1)
            strcpy(shared.editor, "SYS:Tools/MEmacs");

    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;
    ULONG i;
    TEXT  tempstring[5];

    if (pal)
        menuheight = PALMENUHEIGHT;
    else menuheight = PUBMENUHEIGHT;

    navigate();

    /* function labels: 1_2: */
    tempstring[1] = '_';
    tempstring[3] = ':';
    tempstring[4] = 0;

    for (i = 1; i <= FUNCTIONS; i++)
    {   if (i < 10)
        {   tempstring[0] = ' ';
            tempstring[2] = '0' + i;
        } else
        {   tempstring[0] = '1';
            tempstring[2] = '0';
        }
        setgadget(38, menuheight - 145 + ((i - 1) * 9), 24, 8, tempstring, PLACETEXT_RIGHT);
        TE00_FunctionText[i - 1] = PrevGadPtr = (struct Gadget *) CreateGadget
        (   TEXT_KIND,
	    PrevGadPtr,
            &Gadget,
            GT_Underscore, '_',
            TAG_DONE
        );
    }

    /* 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,
                GT_Underscore, '_',
		TAG_DONE
	);
	/* editor... */
        setgadget(328, menuheight - 42, 28, 12, "_...", NULL);
        BU00_EditorASL = PrevGadPtr = (struct Gadget *) CreateGadget
	(	BUTTON_KIND,
		PrevGadPtr,
		&Gadget,
                GT_Underscore, '_',
		TAG_DONE
	);

        if (wbval >= 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, &PalLogo, 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();
    files_exit();
    double_exit();

    // 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);
            }
            // Can't close screen, due to visitor windows. Yet we MUST
            // exit the program, of course - either the user has demanded
            // it, or the program has hit an error. So we leave the
            // screen open and shut down everything else, including the
            // program.
            ScreenPtr = NULL;
    }   }

    acse_exit();

    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);
        IntuitionBase = NULL;
    }
    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, 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, &PalAbout, 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                oldpage = page;
   AUTO struct Gadget*       addr;
   AUTO struct MenuItem*     ItemPtr;
   AUTO struct IntuiMessage* MsgPtr;
   AUTO UWORD                code, qual;
   AUTO ULONG                class;
   AUTO ABOOL                done = FALSE;
   AUTO SWORD                mousex, mousey;
   AUTO struct Lock*         LockPtr;

    /* 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);

            switch(class)
            {
            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",
                                (struct TagItem const *) (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;
            default:
                if (page == 0)
                {   if (class == IDCMP_GADGETDOWN)
                    {   /* radio gadgets */
                        if (addr == MX00_Function)
                            shared.function = code;
                    } elif (class == IDCMP_GADGETUP)
                    {   /* buttons, listviews, checkboxes */
                        if (addr == BU99_Right)
                        {   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;
                        }   }
                        elif (BU00_EditorASL)
                        {   asl();
                            GT_SetGadgetAttrs
                            (   ST00_Editor,
                                MainWindowPtr,
                                NULL,
                                GTST_String, aslresult,
                                TAG_DONE
                            );
                    }   }
                    elif (class == IDCMP_VANILLAKEY)
                    {   code = toupper(code);
                        if (code == '`' && ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT)))
                        {   decrypt();
                        } elif (code == ESCAPE)
                        {   cleanexit(EXIT_SUCCESS);
                        } elif (code >= '0' && code <= '9')
                        {   if (code == '0')
                                shared.function = 9;
                            else shared.function = code - '1';
                            GT_SetGadgetAttrs
                            (   MX00_Function,
                                MainWindowPtr,
                                NULL,
                                GTMX_Active, shared.function,
                                TAG_DONE
                            );
                        } elif (code == '.')
                        {   asl();
                            GT_SetGadgetAttrs
                            (   ST00_Editor,
                                MainWindowPtr,
                                NULL,
                                GTST_String, aslresult,
                                TAG_DONE
                            );
                        } elif (code == 'E')
                        {   ActivateGadget(ST00_Editor, MainWindowPtr, NULL);
                        } elif (code == 'B')
                        {   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;
                }   }   }   }
                elif (page >= 11 && page <= 15)
                    report_loop(class, addr, code);
                elif (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, code);
                elif (page == 61)
                    iff_loop(class, addr, code);
                elif (page >= 71 && page <= 72)
                    eol_loop(class, addr, code, qual);
                elif (page == 81)
                    size_loop(class, addr, code);
                elif (page == 91)
                    batt_loop(class, addr, code, qual, mousex, mousey);
                elif (page == 101)
                    files_loop(class, addr, code, qual);
            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,
                GT_Underscore, '_',
                TAG_DONE
            );
        } else
        {   BU99_Left = PrevGadPtr = (struct Gadget *) CreateGadget
            (   BUTTON_KIND,
                PrevGadPtr,
                &Gadget,
                GT_Underscore, '_',
                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;
    }

    BU99_Right = PrevGadPtr = (struct Gadget *) CreateGadget
    (   BUTTON_KIND,
        PrevGadPtr,
        &Gadget,
        GT_Underscore, '_',
        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);
}	}

AGLOBAL ULONG checkbreak(void)
{   struct IntuiMessage* MsgPtr;
    struct Gadget*       addr;
    ULONG                class;
    UWORD                code;

    while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
    {   class  = MsgPtr->Class;
        code   = MsgPtr->Code;
        addr   = MsgPtr->IAddress;
        GT_ReplyIMsg((struct IntuiMessage *) MsgPtr);
        switch(class)
        {
        case IDCMP_CLOSEWINDOW:
            return(2);
        break;
        case IDCMP_GADGETUP:
            if (addr == BU99_Stop)
                return(1);
        break;
        case IDCMP_VANILLAKEY:
            if (code == ESCAPE)
                return(1);
        break;
        case IDCMP_REFRESHWINDOW:
            GT_BeginRefresh(MainWindowPtr);
            GT_EndRefresh(MainWindowPtr, TRUE);
        break;
        default:
        break;
    }   }
    return(0);
}

AGLOBAL void dirasl(void)
{   struct FileRequester* ASLRqPtr;

    if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, "~(#?.info)", ASL_Window, MainWindowPtr, ASL_ExtFlags1, FIL1F_NOFILES, TAG_DONE)))
        rq("Can't create ASL request!");
    if (AslRequestTags(ASLRqPtr, ASL_Dir, asldir, ASL_Hail, "Report+ path selector", ASL_FuncFlags, FILF_PATGAD, TAG_DONE))
        if (aslresult[0])
            strcpy(aslresult, ASLRqPtr->rf_Dir);
    if (ASLRqPtr)
        FreeAslRequest(ASLRqPtr);
}

AGLOBAL void getdate(void)
{   struct DateTime DateTime;

    DateTime.dat_Format  = FORMAT_DOS;
    DateTime.dat_Flags   = NULL;
    DateTime.dat_StrDay  = weekdaystring;
    DateTime.dat_StrDate = datestring;
    DateTime.dat_StrTime = timestring;

    DateStamp(&(DateTime.dat_Stamp));
    if (!DateToStr(&DateTime))
        rq("Can't convert date!");
}

AGLOBAL void AddNameToTail(struct List* ListPtr, STRPTR name)
{   /* RKM Libraries, p. 496:
	
    "Allocate a NameNode structure, copy the given name into the
    structure, then add it [to] the...list." */

	struct NameNode* NameNodePtr;
	
	if (!(NameNodePtr = AllocMem(sizeof(struct NameNode), MEMF_CLEAR)))
            rq("Out of memory!");
	strcpy(NameNodePtr->nn_Data, name);
        NameNodePtr->nn_Node.ln_Name = NameNodePtr->nn_Data;
        NameNodePtr->nn_Node.ln_Type = NT_USER;
        NameNodePtr->nn_Node.ln_Pri  = 0;
        AddTail((struct List *) ListPtr, (struct Node *) NameNodePtr);
}

AGLOBAL void append(STRPTR pathname)
{   BPTR FileHandle;

    if (!(FileHandle = (BPTR) Open(pathname, MODE_READWRITE)))
        rq("Can't open file for appending!");
    Seek(FileHandle, 0, OFFSET_END);
    if (Write(FileHandle, IOBuffer, strlen(IOBuffer)) == -1)
    {   Close(FileHandle);
        rq("Can't append to file!");
    }
    if (!Close(FileHandle))
        rq("Can't close appended file!");
}

AGLOBAL ABOOL aboutloop(void)
{   struct IntuiMessage* MsgPtr;
    ABOOL                done = FALSE;
    UWORD                code, qual;
    ULONG                class;

    // processes any outstanding messages for the About... window.
    // returns TRUE if user wants to exit, FALSE otherwise.

    while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(AboutWindowPtr->UserPort))
    {   class = MsgPtr->Class;
        code  = MsgPtr->Code;
        qual  = MsgPtr->Qualifier;
        GT_ReplyIMsg(MsgPtr);

        if (class == CLOSEWINDOW)
            done = TRUE;
        elif (class == IDCMP_RAWKEY)
        {   if ((!(qual & IEQUALIFIER_REPEAT)) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
                done = TRUE;
    }   }
    return(done);
}

MODULE struct GelsInfo* setupDisplay(void)
{   struct GelsInfo* gInfo;

    /* set up the gels system.
    ** 0x03 says: when you allocate sprites for me, don't ever use
    ** sprites zero or one. This guarantees that sprite zero, the
    ** intuition pointer, stays intact. Remember sprite one shares
    ** colors with sprite zero. */

    if (NULL != (gInfo = setupGelSys(AboutWindowPtr->RPort, 0x03)))
       return(gInfo);
    else rq("Can't set up GEL system!");
}

AGLOBAL VOID DrawGels(void)
{   Animate(&animKey, AboutWindowPtr->RPort);

    SortGList(AboutWindowPtr->RPort);   /* Put the list in order. */
    DoCollision(AboutWindowPtr->RPort); /* Collision routines may called now */
    SortGList(AboutWindowPtr->RPort);   /* Put the list in order. */

    /* Draw 'em. */
    DrawGList(AboutWindowPtr->RPort, ViewPortAddress(AboutWindowPtr));

    WaitTOF();
}

/*--------------------------------------------------------------
** setupBoing() - allocate and initialize an object that will
** display as a boing ball with orbiting sattellites.
**
** this is an animation object with four animation sequences
** (boing and three satellites). Note that the satellites all share the
** same single image data.
**
** return NULL on failure.
*/
MODULE struct AnimOb* setupBoing(void)
{   struct AnimOb*   bngOb;
    struct AnimComp* bngComp;
    struct AnimComp* satAComp;
    struct AnimComp* satBComp;
    struct AnimComp* satCComp;

    // Firstly, we allocate and initialize an AnimOb structure, then we
    // call makeSeq() for the main ball and for each satellite.

    if (NULL != (bngOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
    {   bngOb->NextOb           = NULL;
	bngOb->PrevOb		= NULL;
	bngOb->Clock		= 0;
        bngOb->AnY              = ( 97 << ANFRACSIZE);
        bngOb->AnX              = (  3 << ANFRACSIZE);
	bngOb->AnOldY		= bngOb->AnY;
	bngOb->AnOldX		= bngOb->AnX;
        bngOb->YVel             = 0;
        bngOb->XVel             = 1 << ANFRACSIZE;
	bngOb->YAccel		= 0;
	bngOb->XAccel		= 0;
	bngOb->RingYTrans	= BNG3RINGY << ANFRACSIZE;
	bngOb->RingXTrans	= BNG3RINGX << ANFRACSIZE;
	bngOb->AnimORoutine	= bounceORoutine;
	bngOb->AUserExt		= 0;

        newBoingBob.nb_DBuf     = 0;
        newBoingSeq.nas_HeadOb  = bngOb;

        satACRoutines[4]        = goInFrontOfHead;
        satACRoutines[12]       = goBehindHead;
        satBCRoutines[8]        = goInFrontOfHead;
        satBCRoutines[0]        = goBehindHead;
        satCCRoutines[4]        = goInFrontOfHead;
        satCCRoutines[12]       = goBehindHead;

        newSatABob.nb_DBuf      = 0;
        newSatBBob.nb_DBuf      = 0;
        newSatCBob.nb_DBuf      = 0;
        newSatASeq.nas_HeadOb   = bngOb;
        newSatBSeq.nas_HeadOb   = bngOb;
        newSatCSeq.nas_HeadOb   = bngOb;

	if (NULL != (bngComp = makeSeq(&newBoingBob, &newBoingSeq)))
        {   bngComp->Flags |= RINGTRIGGER;
            bngOb->HeadComp = bngComp;

            if (NULL != (satAComp = makeSeq(&newSatABob, &newSatASeq)))
            {   bngComp->AnimBob->Before = satAComp->AnimBob;
                satAComp->AnimBob->After = bngComp->AnimBob;

                if (NULL != (satBComp = makeSeq(&newSatBBob, &newSatBSeq)))
                {   satAComp->AnimBob->Before = satBComp->AnimBob;
                    satBComp->AnimBob->After = satAComp->AnimBob;

                    if (NULL != (satCComp = makeSeq(&newSatCBob, &newSatCSeq)))
                    {   satBComp->AnimBob->Before = satCComp->AnimBob;
                        satCComp->AnimBob->After = satBComp->AnimBob;

                        bngComp->NextComp  = satAComp;
                        bngComp->PrevComp  = NULL;

                        satAComp->NextComp = satBComp;
                        satAComp->PrevComp = bngComp;

                        satBComp->NextComp = satCComp;
                        satBComp->PrevComp = satAComp;

                        satCComp->NextComp = NULL;
                        satCComp->PrevComp = satBComp;

                        return(bngOb);
                    }
                    freeSeq(satBComp,RBMDEPTH);
                }
                freeSeq(satAComp,RBMDEPTH);
            }
            freeSeq(bngComp,RBMDEPTH);
        }
	FreeMem(bngOb, (LONG)sizeof(struct AnimOb));
    }
    return(NULL);
}

/*------------------------------------------------------
** This ORoutine makes the Object Bounce off Borders. */

WORD bounceORoutine(struct AnimOb* anOb)
{   SHORT X = anOb->AnX >> ANFRACSIZE;

    if (((X                                                     < 3              ) && (anOb->XVel < 0)) ||
        ((X + (anOb->HeadComp->AnimBob->BobVSprite->Width << 4) > ABOUTXPIXEL - 3) && (anOb->XVel > 0)))
       {   anOb->XVel = -(anOb->XVel);
       }

    return(0);
}

/*--------------------------------------------------------------
** This CRoutine rearranges Bob Before and After pointers in a
** way that makes the Component passed look like it is in front
** of its' head component.
** 
** Used for Boing satelittes.
** 
** So that they go in front of AND behind the boing ball.
*/
MODULE WORD goInFrontOfHead(struct AnimComp *aComp)
{
/* close up hole */
if (aComp->AnimBob->Before != NULL)
	aComp->AnimBob->Before->After = aComp->AnimBob->After;
if (aComp->AnimBob->After != NULL)
	aComp->AnimBob->After->Before = aComp->AnimBob->Before;

/* reinsert */
aComp->AnimBob->Before = aComp->HeadOb->HeadComp->AnimBob->Before;
aComp->AnimBob->After = aComp->HeadOb->HeadComp->AnimBob;
if (aComp->AnimBob->Before != NULL)
	aComp->AnimBob->Before->After = aComp->AnimBob;
aComp->HeadOb->HeadComp->AnimBob->Before = aComp->AnimBob;

return(0);
}

/*--------------------------------------------------------------
** This CRoutine rearranges Bob Before and After pointers in a
** way that makes the Component passed look like it is behind
** its' head component.
*/
MODULE WORD goBehindHead(struct AnimComp *aComp)
{
if (aComp->AnimBob->Before != NULL)
	aComp->AnimBob->Before->After = aComp->AnimBob->After;
if (aComp->AnimBob->After != NULL)
	aComp->AnimBob->After->Before = aComp->AnimBob->Before;

aComp->AnimBob->After = aComp->HeadOb->HeadComp->AnimBob->After;
aComp->AnimBob->Before = aComp->HeadOb->HeadComp->AnimBob;
if (aComp->AnimBob->After != NULL)
	aComp->AnimBob->After->Before = aComp->AnimBob;
aComp->HeadOb->HeadComp->AnimBob->After = aComp->AnimBob;

return(0);
}

AGLOBAL void boingball(void)
{   if (NULL != (gInfo = setupDisplay()))
    {   InitAnimate(&animKey);

        if (NULL != (boingOb = setupBoing()))
            AddAnimOb(boingOb, &animKey, AboutWindowPtr->RPort);
}   }
AGLOBAL void unboingball(void)
{   freeOb(boingOb, RBMDEPTH);
    cleanupGelSys(gInfo, AboutWindowPtr->RPort);
}

AGLOBAL void double_init(void)
{   if (!(ead = AllocMem(2048, MEMF_CLEAR)))
    {   rq("Out of memory!");
}   }

AGLOBAL void double_exit(void)
{   // Exit routine for f8.c and f10.c

    FreeMem(ead, 2048);
    ead = NULL;
    while(DirNamesAllocated)
    {   FreeMem(DirNamePtr[DirNamesAllocated], VLONGFIELD);
        DirNamePtr[DirNamesAllocated--] = NULL;
    }
    while(FileNamesAllocated)
    {   FreeMem(FileNamePtr[FileNamesAllocated], VLONGFIELD);
        FileNamePtr[FileNamesAllocated--] = NULL;
}   }

AGLOBAL void fliplog(ABOOL keyboard)
{   if (keyboard)
    {   if (CB99_Log->Flags & GFLG_SELECTED)
        {   shared.log = FALSE;
        } else
        {   shared.log = TRUE;
    }   }
    else
    {   if (CB99_Log->Flags & GFLG_SELECTED)
        {   shared.log = TRUE;
        } else
        {   shared.log = FALSE;
    }   }

    if (!shared.log)
    {   GT_SetGadgetAttrs
        (   ST99_Output,
            MainWindowPtr, NULL,
            GA_Disabled, TRUE,
            TAG_DONE
        );
        GT_SetGadgetAttrs
        (   BU99_OutputASL,
            MainWindowPtr, NULL,
            GA_Disabled, TRUE,
            TAG_DONE
        );
    } else
    {   GT_SetGadgetAttrs
        (   ST99_Output,
            MainWindowPtr, NULL,
            GA_Disabled, FALSE,
            TAG_DONE
        );
        GT_SetGadgetAttrs
        (   BU99_OutputASL,
            MainWindowPtr, NULL,
            GA_Disabled, FALSE,
            TAG_DONE
        );
    }
    GT_SetGadgetAttrs
    (   CB99_Log,
        MainWindowPtr, NULL,
        GTCB_Checked, shared.log,
        TAG_DONE
    );
}

AGLOBAL void outputasl(void)
{   asl();
    GT_SetGadgetAttrs
    (   ST99_Output,
        MainWindowPtr,
        NULL,
        GTST_String, aslresult,
        TAG_DONE
    );
}
AGLOBAL void outputstring(void)
{   strcpy
    (   shared.output,
        ((struct StringInfo *) ST99_Output->SpecialInfo)->Buffer
    );
}

/* Must have LF before EOF. */

