/* $Filename:    ReportPlus/Source/rp.c
 * $VER:         Report+ 4.7
 * $Description: Multipurpose utility
 *
 * © Copyright 2001 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 <exec/execbase.h>
#include <proto/exec.h>
#include <intuition/intuition.h>
#include <clib/intuition_protos.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <clib/gadtools_protos.h>
#include <workbench/workbench.h> /* struct DiskObject */
#include <libraries/asl.h>
#include <proto/asl.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <dos/dosextens.h>
#include <proto/dos.h>
#include <diskfont/diskfont.h>
#include <proto/diskfont.h>
#include <graphics/gfx.h>
#include <graphics/displayinfo.h>
#include <graphics/gels.h>
#include <clib/graphics_protos.h>
#include <utility/tagitem.h>
#include <proto/utility.h>
#include <workbench/icon.h>
#include <clib/icon_protos.h>
#include <clib/alib_protos.h>
#include <resources/battmem.h>
#include <resources/battmembitsamiga.h>
#include <resources/battmembitsshared.h>

#define ALL_REACTION_CLASSES
#define ALL_REACTION_MACROS
#include <reaction/reaction.h>

#include <classes/window.h>
#include <clib/window_protos.h>
#include <gadgets/listbrowser.h>
#include <clib/listbrowser_protos.h>

/* boing ball */
#define ID_BORDER 0
#define ID_BNG    3
#define RBMDEPTH  4

#include <ctype.h>
#include <stdio.h>          /* FILE, printf() */
#include <stdlib.h>         /* EXIT_SUCCESS, EXIT_FAILURE */
#include <string.h>
#include "rp.h"
#include "animtools.h"
#include "anim_images.h"
#include "boards.h"

#define FUNCTIONS 12

#define PALMENUHEIGHT (126 + (FUNCTIONS * 8)) /* page 0 */
#define PUBMENUHEIGHT (PALMENUHEIGHT + 28)

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

#ifdef __STORM__
   #pragma chip
#endif
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
};
#ifdef __STORM__
   #pragma chip
#endif

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 ABOUTLINES      6
#define ABOUTSHADOW BLACK
#define ABOUTSHINE  WHITE

MODULE struct
{   WORD   x, y;
    STRPTR text;
} about[ABOUTLINES + 1] =
{   {80,  27, TITLEBARTEXT,           },
    {80,  35, "Friday 29 June 2001"   },
    {80,  43, "© 2001 Amigan Software"},
    {80,  59, "By James R. Jacobs"    },
    {80,  75, "Kickstart: "           },
    {80,  83, "Workbench: "           },
    {80, 106, "Public Screen: RPLUS"  }
};
MODULE STRPTR FunctionOptions[FUNCTIONS + 1] =
{   "Bug report",
    "Aminet readme",
    "ACSE test",
    "Autodoc",
    "ID database",
    "IFF registry",
    "EOL/tab converter",
    "Path size report",
    "Battery RAM",
    "System file report",
    "_AGDB review",
    "_Icon processor",
    NULL
};
#define MENUENTRIES 13
MODULE struct NewMenu NewMenu[MENUENTRIES] =
{   { NM_TITLE, "Project",       0 , 0,               0, 0},
    {  NM_ITEM, "New",          "N", NM_ITEMDISABLED, 0, 0},
    {  NM_ITEM, "Open...",      "O", NM_ITEMDISABLED, 0, 0},
    {  NM_ITEM, NM_BARLABEL,     0 , 0,               0, 0},
    {  NM_ITEM, "Save",         "S", NM_ITEMDISABLED, 0, 0},
    {  NM_ITEM, "Save As...",   "O", NM_ITEMDISABLED, 0, 0},
    {  NM_ITEM, NM_BARLABEL,     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 helpabout(void);
MODULE void menu(void);
MODULE void parsewb(void);
MODULE void eachwildcard(STRPTR subpattern);
MODULE void double_exit(void);

int CXBRK(void) { return(0); }    /* Disable SAS/C Ctrl-C handling */
int chkabort(void) { return(0); } /* really */

AGLOBAL struct Library          *WindowBase      = NULL,
                                *LayoutBase      = NULL,
                                *ButtonBase      = NULL,
                                *TextEditorBase  = NULL,
                                *LabelBase       = NULL,
                                *ListBrowserBase = NULL,
                                *ChooserBase     = NULL,
                                *StringBase      = NULL,
                                *CheckBoxBase    = NULL,
                                *BoardsBase      = NULL;
AGLOBAL ABOOL                   done             = FALSE,
                                pal              = FALSE,
                                fillwindows      = TRUE,
                                react            = FALSE,
                                stop             = FALSE;
AGLOBAL TEXT                    asldir[VLONGFIELD + 1],
                                aslresult[VLONGFIELD + 1],
                                IOBuffer[LONGESTFIELD + 1],
                                globalname[VLONGFIELD + 1],
                                string[VLONGFIELD + 1],
                                weekdaystring[LEN_DATSTRING],
                                datestring[LEN_DATSTRING],
                                timestring[LEN_DATSTRING];
AGLOBAL SBYTE                   page             = 0;
AGLOBAL ULONG                   fillcolour,
                                elements, /* for ReAction texteditor.gadget */
                                offset,
                                wbval;
AGLOBAL ABOOL                   BattBuffer[96];
AGLOBAL APTR                    OldWindowPtr     = NULL;
AGLOBAL struct Library*         IconBase         = NULL;
AGLOBAL struct Menu*            MenuPtr          = NULL;
AGLOBAL struct Process*         ProcessPtr       = NULL;
AGLOBAL struct Screen*          ScreenPtr        = NULL;
AGLOBAL struct Window*          MainWindowPtr    = NULL;
AGLOBAL struct VisualInfo*      VisualInfoPtr    = NULL;
AGLOBAL struct ExAllData*       EADataPtr        = NULL;
AGLOBAL struct Gadget          *BU99_Right       = NULL,
                               *ST99_Output      = NULL,
                               *BU99_OutputASL   = NULL,
                               *CB99_Log         = NULL,
                               *BU99_Update      = NULL,
                               *BU99_Stop        = NULL,
                               *BU99_TextEditor  = NULL,
                               *GListPtr         = NULL,
                               *PrevGadPtr       = NULL;
AGLOBAL struct SharedStruct shared =
{   TRUE, 0,
    "", "", "", "", "", ""
};

// from f9.c
IMPORT struct Library*          BattMemBase;

MODULE  WORD                    xsize;
AGLOBAL WORD                    ysize;
MODULE  ULONG                   ksval;
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, 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 Library*         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,
    43, 22, 1,
    PalAboutData,
    0x4, 3,
    NULL
}, PubAbout =
{   0, 0,
    43, 44, 1,
    PubAboutData,
    0x1, 3,
    NULL
};
MODULE  struct EasyStruct       EasyStruct =
{   sizeof(struct EasyStruct),
    0,
    "Report+: Error",
    NULL,
    "Quit"
};

IMPORT ABOOL               certified, quit;
IMPORT struct ReportStruct report;
IMPORT struct AminetStruct aminet;
IMPORT struct AGDBStruct   agdb;
IMPORT struct IFFStruct    iff;
IMPORT struct EOLStruct    eol;
IMPORT struct IconStruct   icon;
IMPORT struct ExecBase*    SysBase;
IMPORT struct Object*      object;
IMPORT ULONG               app, signal;
IMPORT struct Gadget      *TE71_Status,
                          *gadgets[GIDS_12 + 1];

/* 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 */
        ORANGE,    /* 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,     0xC,    0xB,    0xD},   /* LIGHTGREY */
        {    6,     0xF,    0xA,    0x6},   /* ORANGE */
        {    7,     0xF,    0xF,    0x5},   /* YELLOW */
        {    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,     0xB,    0xF,    0xB},   /* LIGHTGREEN */
        {   15,     0x9,    0x9,    0xF},   /* sky blue */
        {   -1,    NULL,   NULL,   NULL}
    };
    UWORD  i;
    SLONG  args[13] = { 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L };
    BPTR   OldDir;
    SLONG  number = 0, hostid = 7;

    /* Start of program.

    version embedding into executable */

    if (0) /* that is, never */
        Printf("$VER: Report+ 4.7 (29.6.2001"); /* this is always d.m.y format */

    if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 38L)))
    {   Printf("Report+: Need intuition.library V38+!\n");
        cleanexit(EXIT_FAILURE);
    }
    if ((ksval = SysBase->LibNode.lib_Version) < 38L)
    {   Printf("Report+: Need exec.library V38+!\n");
        cleanexit(EXIT_FAILURE);
    }

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

    autodoc_init();
    size_init();
    batt_init();

    if (!(VersionBase = (struct Library *) OpenLibrary("version.library", 0L)))
        rq("Can't open version.library!");
    wbval = VersionBase->lib_Version;
    CloseLibrary((struct Library *) VersionBase);
    VersionBase = NULL;

    if (!(GadToolsBase = (struct Library *) OpenLibrary("gadtools.library", 38L)))
        rq("Can't open GadTools.library V38+!");
    if (!(ASLBase = (struct ASLBase *) OpenLibrary("asl.library", 0L)))
        rq("Can't open ASL.library!");
    if (
        (DiskFontBase = (struct DiskFontBase *) OpenLibrary("diskfont.library", 0L))
    &&  (FontPtr = OpenDiskFont(&WormWars8))
       )
    {   Gadget.ng_TextAttr = (struct TextAttr *) &WormWars8;
    } elif (!(FontPtr = OpenFont(&Topaz8)))
    {   rq("Can't open fonts!");
    } else
    {   Gadget.ng_TextAttr = (struct TextAttr *) &Topaz8;
    }

    if (wbval >= 44)
    {   react = TRUE;
        if (!(ButtonBase      = OpenLibrary("gadgets/button.gadget", 44)))
                           rq("OpenLibrary(\"gadgets/button.gadget\") failed!");
        if (!(CheckBoxBase    = OpenLibrary("gadgets/checkbox.gadget", 44)))
                           rq("OpenLibrary(\"gadgets/checkbox.gadget\") failed!");
        if (!(ChooserBase     = OpenLibrary("gadgets/chooser.gadget", 44)))
                           rq("OpenLibrary(\"gadgets/chooser.gadget\") failed!");
        if (!(LabelBase       = OpenLibrary("images/label.image", 44)))
                           rq("OpenLibrary(\"images/label.image\") failed!");
        if (!(LayoutBase      = OpenLibrary("gadgets/layout.gadget", 44)))
                           rq("OpenLibrary(\"gadgets/layout.gadget\") failed!");
        if (!(ListBrowserBase = OpenLibrary("gadgets/listbrowser.gadget", 0)))
                           rq("OpenLibrary(\"gadgets/listbrowser.gadget\") failed!");
        if (!(StringBase      = OpenLibrary("gadgets/string.gadget", 44)))
                           rq("OpenLibrary(\"gadgets/string.gadget\") failed!");
        if (!(TextEditorBase  = OpenLibrary("gadgets/texteditor.gadget", 0)))
                           rq("OpenLibrary(\"gadgets/texteditor.gadget\") failed!");
        if (!(WindowBase      = OpenLibrary("window.class", 44)))
                           rq("OpenLibrary(\"window.class\") failed!");
        if (!(IconBase        = OpenLibrary("icon.library", 44L)))
                           rq("Need icon.library V44+!");
    }

    BoardsBase = OpenLibrary("boards.library", 0L);

    report_init();
    newaminet(FALSE);
    newagdb(FALSE);
    /* those must be done before we handle CLI arguments */

    if (argc) /* started from CLI */
    {   if (!(ArgsPtr = ReadArgs
        (   "-P=PAL/S,-G=GREY/S,-E=EDITOR/S,FUNCTION/N,ICONTYPE/K,"
            "RESET/S,TIMEOUT/S,LUNS/S,SYNC_XFER/S,SLOW_SYNC/S,TAG_QUEUES/S,HOST_ID/K/N,"
            "FILE/F",
            (LONG *) args,
            NULL
	)))
        {   Printf
            (   "Usage: %s [-p=PAL] [-g=GREY] [-e=EDITOR] "
                "[[FUNCTION] <function> "
                "[ICONTYPE DISK|DRAWER|TOOL|PROJECT|TRASHCAN|DEVICE|KICKSTART|APPICON] "
                "[RESET [TIMEOUT] [LUNS] [SYNC_XFER] [SLOW_SYNC] [TAG_QUEUES] [HOST_ID <host_id>]] "
                "[[FILE] <file(s)...>]]\n",
                argv[0]
            );
            cleanexit(EXIT_FAILURE);
	}
        if (args[0])
            pal = TRUE;
        if (args[1])
            fillwindows = FALSE;
        if (args[2])
        {   react = FALSE;
        }
        if (args[3])
        {   number = (SLONG) (*((SLONG *) args[3]));
            if (number == 12)
            {   if (wbval < 44)
                {   Printf("Report+: Icon converter requires OS3.5+!\n");
                    cleanexit(EXIT_FAILURE);
                }
                if (pal)
                {   Printf("Report+: Icon converter doesn't support PAL mode!\n");
                    cleanexit(EXIT_FAILURE);
            }   }
            if (number >= 1 && number <= FUNCTIONS)
            {   page = (number * 10) + 1;
                shared.function = number - 1;
            } else
            {   Printf("Report+: <function> must be 1-%ld!\n", FUNCTIONS);
                cleanexit(EXIT_FAILURE);
        }   }
        if (args[4])
        {   if (number != 12)
            {   Printf("%s: <function> must be 12 for this!\n", argv[0]);
                cleanexit(EXIT_FAILURE);
                if (!stricmp((STRPTR) args[4], "DISK"))
                {   icon.type = WBDISK - 1;
                } elif (!stricmp((STRPTR) args[4], "DRAWER"))
                {   icon.type = WBDRAWER - 1;
                } elif (!stricmp((STRPTR) args[4], "TOOL"))
                {   icon.type = WBTOOL - 1;
                } elif (!stricmp((STRPTR) args[4], "PROJECT"))
                {   icon.type = WBPROJECT - 1;
                } elif (!stricmp((STRPTR) args[4], "TRASHCAN"))
                {   icon.type = WBGARBAGE - 1;
                } elif (!stricmp((STRPTR) args[4], "DEVICE"))
                {   icon.type = WBDEVICE - 1;
                } elif (!stricmp((STRPTR) args[4], "KICKSTART"))
                {   icon.type = WBKICK - 1;
                } elif (!stricmp((STRPTR) args[4], "APPICON"))
                {   icon.type = WBAPPICON - 1;
                } else
                {   Printf("%s: <icontype> must be DISK, DRAWER, TOOL, PROJECT, TRASHCAN, DEVICE, KICKSTART or APPICON!\n", argv[0]);
                    cleanexit(EXIT_FAILURE);
        }   }   }
        if (args[5] || args[6] || args[7] || args[8] || args[9] || args[10] || args[11])
        {   if (number != 9)
            {   Printf("%s: <function> must be 9 for this!\n", argv[0]);
                cleanexit(EXIT_FAILURE);
            }
            if (!args[5])
            {   Printf("%s: You need the RESET switch for this!\n", argv[0]);
                cleanexit(EXIT_FAILURE);
            }
            for (i = 0; i <= 95; i++)
            {   BattBuffer[i] = FALSE;
            }
            BattBuffer[BATTMEM_AMIGA_AMNESIA_ADDR]          =
            BattBuffer[BATTMEM_SHARED_AMNESIA_ADDR]         = TRUE; // these bits are inverted
            if (args[6])
            {   BattBuffer[BATTMEM_SCSI_TIMEOUT_ADDR]       = TRUE;
            } else BattBuffer[BATTMEM_SCSI_TIMEOUT_ADDR]    = FALSE;
            if (args[7])
            {   BattBuffer[BATTMEM_SCSI_LUNS_ADDR]          = TRUE;
            } else BattBuffer[BATTMEM_SCSI_LUNS_ADDR]       = FALSE;
            if (args[8])
            {   BattBuffer[BATTMEM_SCSI_SYNC_XFER_ADDR]     = TRUE;
            } else BattBuffer[BATTMEM_SCSI_SYNC_XFER_ADDR]  = FALSE;
            if (args[9])
            {   BattBuffer[BATTMEM_SCSI_FAST_SYNC_ADDR]     = TRUE;
            } else BattBuffer[BATTMEM_SCSI_FAST_SYNC_ADDR]  = FALSE;
            if (args[10])
            {   BattBuffer[BATTMEM_SCSI_TAG_QUEUES_ADDR]    = TRUE;
            } else BattBuffer[BATTMEM_SCSI_TAG_QUEUES_ADDR] = FALSE;
            if (args[11]) // these bits are inverted
            {   hostid = (SLONG) (*((SLONG *) args[11]));
                if (hostid < 0 || hostid > 7)
                {   Printf("%s: <host_id> must be 0-7!\n", argv[0]);
                    cleanexit(EXIT_FAILURE);
                }
                BattBuffer[BATTMEM_SCSI_HOST_ID_ADDR]     = (hostid & 4)? 0 : 1;
                BattBuffer[BATTMEM_SCSI_HOST_ID_ADDR + 1] = (hostid & 2)? 0 : 1;
                BattBuffer[BATTMEM_SCSI_HOST_ID_ADDR + 2] = (hostid & 1)? 0 : 1;
            }
            if (!BattMemBase)
            {   if (!(BattMemBase = OpenResource(BATTMEMNAME)))
                {   rq("Can't open battery RAM resource!");
            }   }
            writebatt(FALSE);
            Printf("Done.\n");
            cleanexit(EXIT_SUCCESS);
        }
        if (args[12])
        {   switch(number)
            {
            case 1:
                strcpy(report.output, (STRPTR) args[12]);
                report.loaded = TRUE;
                loadreport();
            break;
            case 2:
                strcpy(aminet.output, (STRPTR) args[12]);
                aminet.loaded = TRUE;
                loadaminet();
            break;
            case 6:
                strcpy(iff.pathname, (STRPTR) args[12]);
            break;
            case 7:
                strcpy(shared.pathname, (STRPTR) args[12]);
                convert(FALSE);
                Printf("All done.\n");
                cleanexit(EXIT_SUCCESS);
            break;
            case 11:
                strcpy(  agdb.output, (STRPTR) args[12]);
                agdb.loaded = TRUE;
                loadagdb();
            break;
            case 12:
                strcpy(shared.pathname, (STRPTR) args[12]);
                convert(FALSE);
                Printf("All done.\n");
                cleanexit(EXIT_SUCCESS);
            break;
            default:
                Printf("Report+: <function> must be 1, 2, 6, 7, 11 or 12 for this!\n");
                cleanexit(EXIT_FAILURE);
            break;
    }   }   }
    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, LIGHTGREEN);
        RectFill(BkgrndWindowPtr->RPort, 0, 0, xsize, ysize - 12);
        PubScreenStatus(ScreenPtr, 0); /* take the screen public */
    }

    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)
            sender();
        elif (page == 13)
            config();
        elif (page == 21)
            aminet1();
        elif (page == 31)
            acse1();
        elif (page == 32)
            acse2();
        elif (page == 33)
            acse3();
        elif (page == 41)
            autodoc1();
        elif (page == 51)
            manuf1();
        elif (page == 61)
            iff1();
        elif (page == 71)
            eol1();
        elif (page == 81)
            size1();
        elif (page == 91)
            batt1();
        elif (page == 101)
            files1();
        elif (page == 111)
            agdb1();
        elif (page == 121)
        {   icon1();
        } else
        {   /* assert(page == 0); */
            menu();
}   }   }

MODULE void menu(void)
{   /* PAGE 0 ************************************************************* */

    SWORD menuheight;
    ULONG i;
    TEXT  tempstring[5];

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

    navigate();

    /* function labels: 1_2: */
    tempstring[3] = ':';
    tempstring[4] = 0;
    for (i = 1; i <= FUNCTIONS; i++)
    {   if (i < 10)
        {   strcpy(tempstring, " _#:");
            tempstring[2] = '0' + i;
        } elif (i == 10)
        {   strcpy(tempstring, "1_0:");
        } elif (i == 12)
        {   strcpy(tempstring, "12:");
        } else
        {   /* assert(i == 11); */
            strcpy(tempstring, "11:");
        }
        setgadget(38, menuheight - 64 - (FUNCTIONS * 8) + ((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 - 65 - (FUNCTIONS * 8), 0, 0, NULL, PLACETEXT_RIGHT); /* -8 for each extra function */
    MX00_Function = PrevGadPtr = (struct Gadget *) CreateGadget
    (   MX_KIND,
	PrevGadPtr,
	&Gadget,
	GTMX_Labels, &FunctionOptions,
        GTMX_Active, shared.function,
	GT_Underscore, '_',
	TAG_DONE
    );
    
    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, '_',
        GA_Disabled, FALSE,
        TAG_DONE
    );
    setgadget(328, menuheight - 42, 28, 12, "_...", NULL);
    BU00_EditorASL = PrevGadPtr = (struct Gadget *) CreateGadget
    (   BUTTON_KIND,
	PrevGadPtr,
	&Gadget,
        GT_Underscore, '_',
        GA_Disabled, FALSE,
        TAG_DONE
    );

    newwindow
    (   366, menuheight,
        "Report+: Main Menu",
        BUTTONIDCMP | MXIDCMP | STRINGIDCMP
    );
    if (pal)
        DrawImage(MainWindowPtr->RPort, &PalLogo, 81, 20);
    else DrawImage(MainWindowPtr->RPort, &PubLogo, 81, 20);

    if (react)
    {   GT_SetGadgetAttrs(ST00_Editor,    MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
        GT_SetGadgetAttrs(BU00_EditorASL, MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
    }
    loop();
    strcpy
    (   shared.editor,
        ((struct StringInfo *) ST00_Editor->SpecialInfo)->Buffer
    );
    closewindow();
}

MODULE void double_exit(void)
{   if (EADataPtr)
    {   FreeVec(EADataPtr);
        EADataPtr = NULL;
}   }

AGLOBAL void cleanexit(SBYTE rc)
{   /* ASL requesters are assumed to be already closed.

    iffparse.library is never opened or closed. :-O */

    /* help|about... */
    if (AboutWindowPtr)
    {   if (pal)
            unboingball();
        CloseWindow(AboutWindowPtr);
        AboutWindowPtr = NULL;
    }

    /* Reaction (functions 1, 2, 4, 10-12) */
    if (wbval >= 44)
    {   CloseLibrary(ButtonBase);
        CloseLibrary(CheckBoxBase);
        CloseLibrary(ChooserBase);
        CloseLibrary(LabelBase);
        CloseLibrary(LayoutBase);
        CloseLibrary(ListBrowserBase);
        CloseLibrary(StringBase);
        CloseLibrary(TextEditorBase);
        CloseLibrary(WindowBase);

        CloseLibrary((struct Library *) IconBase);
    }

    /* function 10 */
    if (ListBrowserBase)
    {   clearlblist();
        CloseLibrary(ListBrowserBase);
        ListBrowserBase = NULL;
    }

    /* all */
    unlockscreen();
    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. So we close the window before calling
    these next routines. */

    report_exit();
    size_exit();
    aminet_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();
    files_exit();
    double_exit();

    if (FontPtr)
    {   CloseFont(FontPtr);
        FontPtr = NULL;
    }
    if (BoardsBase)
    {   CloseLibrary(BoardsBase);
    }
    if (DiskFontBase)
        CloseLibrary((struct Library *) DiskFontBase);
    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;
}   }

AGLOBAL 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!");
    GListPtr = NULL; /* that needs doing for the CreateContext() call */
    if (!(PrevGadPtr = (struct Gadget *) CreateContext(&GListPtr)))
        rq("Can't create GadTools context!");
}

AGLOBAL void verynewwindow(SWORD width, SWORD height, STRPTR title, ULONG idcmp)
{   gadtools();

    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_RAWKEY | idcmp,
            WA_Gadgets,      NULL,
            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_RAWKEY | idcmp,
                WA_Gadgets,      NULL,
                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);
    SetFont(MainWindowPtr->RPort, FontPtr);

    if (fillwindows)
    {   getfillcolour();
        SetAPen
        (   MainWindowPtr->RPort,
            fillcolour
        );
        RectFill
        (   MainWindowPtr->RPort,
            MainWindowPtr->BorderLeft,
            MainWindowPtr->BorderTop,
             width - 1 - MainWindowPtr->BorderRight,
            height - 1 - MainWindowPtr->BorderBottom
        );
    }

    navigate();
}

AGLOBAL void newwindow(SWORD width, SWORD height, STRPTR title, ULONG idcmp)
{   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_RAWKEY | 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
    {   lockscreen();
        /* 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_RAWKEY | 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!");
        unlockscreen();
    }
    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 38:
        strcpy(ks, "2.1 ");
    break;
    case 39:
        strcpy(ks, "3.0 ");
    break;
    case 40:
        strcpy(ks, "3.1 ");
    break;
    default:
        strcpy(ks, "4.0+");
    break;
    }
    switch(wbval)
    {
    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_DepthGadget,   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
    {   lockscreen();
        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_DepthGadget,   TRUE,
            WA_CloseGadget,   TRUE,
            WA_NoCareRefresh, TRUE,
            WA_Activate,      TRUE,
            TAG_DONE
        )))
        {   rq("Can't open About... window!");
        }
        unlockscreen();
    }

    SetFont(AboutWindowPtr->RPort, FontPtr);
    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));
            if (line == 4)
            {   Text(AboutWindowPtr->RPort, ks, 4);
            } elif (line == 5)
            {   Text(AboutWindowPtr->RPort, wb, 4);
    }   }   }

    if (pal)
    {   DrawBevelBox(AboutWindowPtr->RPort, 19, 21, 45, 23, GT_VisualInfo, VisualInfoPtr, GTBB_Recessed, TRUE, TAG_DONE);
        DrawImage(AboutWindowPtr->RPort, &PalAbout, 20, 22);
    } else
    {   DrawBevelBox(AboutWindowPtr->RPort, 19, 21, 45, 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 ABOOL asl(void)
{   struct FileRequester* ASLRqPtr;
    ABOOL                 success;

    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!");
        success = TRUE;
    } else
    {   strcpy(asldir, "");
        strcpy(aslresult, "");
        success = FALSE;
    }
    FreeAslRequest(ASLRqPtr);
    return(success);
}

AGLOBAL void reaction_loop(void)
{   SWORD oldpage = page;
    ULONG signals, result;
    UWORD code;

    done = FALSE;
    while (page == oldpage && (!done))
    {   if (AboutWindowPtr)
        {   if (pal)
            {   DrawGels();
            }
            signals = SetSignal(0L, 0L);
            if (signals & SIGBREAKF_CTRL_C)
            {   done = TRUE;
                SetSignal(0L, SIGBREAKF_CTRL_C); /* clear the Ctrl-C signal */
            }
            if (aboutloop())
            {   if (pal)
                {   unboingball();
                }
                CloseWindow(AboutWindowPtr);
                AboutWindowPtr = NULL;
                OnMenu(MainWindowPtr, FULLMENUNUM(MN_HELP, IN_ABOUT, NOSUB));
        }   }
        else
        {   if ((Wait(signal | SIGBREAKF_CTRL_C | app)) & SIGBREAKF_CTRL_C)
            {  done = TRUE;
               /* should we clear the Ctrl-C signal? */
        }   }
        while ((result = DoMethod((Object *) object, WM_HANDLEINPUT, &code)) != WMHI_LASTMSG)
        {   switch (result & WMHI_CLASSMASK)
            {
            case WMHI_MENUPICK:
                handlemenus(code);
            break;
            case WMHI_CLOSEWINDOW:
                done = quit = TRUE;
            break;
            case WMHI_GADGETUP:
                icon_loop(result & WMHI_GADGETMASK);
            break;
            default:
            break;
}   }   }   }

AGLOBAL void loop(void)
{   AUTO SWORD                oldpage = page;
    AUTO struct Gadget*       addr;
    AUTO struct IntuiMessage* MsgPtr;
    AUTO UWORD                code, qual;
    AUTO ULONG                class;
    AUTO SWORD                mousex, mousey;

    /* i must be signed, and at least 16 bits wide. */

    done = FALSE;
    while (page == oldpage && (!done))
    {   if (AboutWindowPtr)
        {   if (pal)
            {   DrawGels();
            }
            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:
                handlemenus(code);
            break;
            case IDCMP_CLOSEWINDOW:
                cleanexit(EXIT_SUCCESS);
            break;
            case IDCMP_REFRESHWINDOW:
                GT_BeginRefresh(MainWindowPtr);
                GT_EndRefresh(MainWindowPtr, TRUE);
            break;
            default:
                if (class == IDCMP_RAWKEY && code == SCAN_HELP)
                {   helpabout();
                } elif (page == 0)
                {   if (class == IDCMP_GADGETDOWN)
                    {   /* radio gadgets */
                        if (addr == MX00_Function)
                        {   shared.function = code;
                            if ((wbval < 44 || pal) && code == 11)
                            {   GT_SetGadgetAttrs
                                (   BU99_Right,
                                    MainWindowPtr,
                                    NULL,
                                    GA_Disabled, TRUE,
                                    TAG_DONE
                                );
                            } else
                            {   GT_SetGadgetAttrs
                                (   BU99_Right,
                                    MainWindowPtr,
                                    NULL,
                                    GA_Disabled, FALSE,
                                    TAG_DONE
                                );
                    }   }   }
                    elif (class == IDCMP_GADGETUP)
                    {   /* buttons, listviews, checkboxes */
                        if (addr == BU99_Right)
                        {   page = 11 + (shared.function * 10);
                        } elif (BU00_EditorASL)
                        {   asl();
                            GT_SetGadgetAttrs
                            (   ST00_Editor,
                                MainWindowPtr,
                                NULL,
                                GTST_String, aslresult,
                                TAG_DONE
                            );
                    }   }
                    elif (class == IDCMP_RAWKEY)
                    {   if (code == SCAN_UP && shared.function > 0)
                        {   if (qual & IEQUALIFIER_CONTROL)
                                shared.function = 0;
                            else shared.function--;
                            GT_SetGadgetAttrs
                            (   MX00_Function,
                                MainWindowPtr,
                                NULL,
                                GTMX_Active, shared.function,
                                TAG_DONE
                            );
                            if (shared.function == 11 && wbval < 44)
                            {   GT_SetGadgetAttrs
                                (   BU99_Right,
                                    MainWindowPtr,
                                    NULL,
                                    GA_Disabled, TRUE,
                                    TAG_DONE
                                );
                            } else
                            {   GT_SetGadgetAttrs
                                (   BU99_Right,
                                    MainWindowPtr,
                                    NULL,
                                    GA_Disabled, FALSE,
                                    TAG_DONE
                                );
                        }   }
                        elif (code == SCAN_DOWN && shared.function < FUNCTIONS - 1)
                        {   if (qual & IEQUALIFIER_CONTROL)
                            {   shared.function = FUNCTIONS - 1;
                            } else shared.function++;
                            GT_SetGadgetAttrs
                            (   MX00_Function,
                                MainWindowPtr,
                                NULL,
                                GTMX_Active, shared.function,
                                TAG_DONE
                            );
                            if (shared.function == 11 && (wbval < 44 || pal))
                            {   GT_SetGadgetAttrs
                                (   BU99_Right,
                                    MainWindowPtr,
                                    NULL,
                                    GA_Disabled, TRUE,
                                    TAG_DONE
                                );
                            } else
                            {   GT_SetGadgetAttrs
                                (   BU99_Right,
                                    MainWindowPtr,
                                    NULL,
                                    GA_Disabled, FALSE,
                                    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 == 'A')
                        {   shared.function = 10;
                            GT_SetGadgetAttrs
                            (   MX00_Function,
                                MainWindowPtr,
                                NULL,
                                GTMX_Active, shared.function,
                                TAG_DONE
                            );
                        } elif (code == 'I' && wbval >= 44)
                        {   shared.function = 11;
                            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' || code == CR)
                        {   if (wbval >= 44 || shared.function != 11)
                            {   page = (shared.function * 10) + 11;
                }   }   }   }
                elif (page >= 11 && page <= 14)
                    report_loop(class, addr, code, qual);
                elif (page >= 21 && page <= 22)
                    aminet_loop(class, addr, code);
                elif (page >= 31 && page <= 33)
                    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, qual);
                elif (page == 71)
                    eol_loop(class, addr, code, qual);
                elif (page == 81)
                    size_loop(class, addr, code, qual);
                elif (page == 91)
                    batt_loop(class, addr, code, qual, mousex, mousey);
                elif (page == 101)
                    files_loop(class, addr, code, qual);
                elif (page == 111)
                {   agdb_loop(class, addr, code);
                }
            break;
}   }   }   }

AGLOBAL void navigate(void)
{   gadtools();

    /* BU99_Right is created first, as all windows use it. Therefore all
    windows can safely call AddGList(), etc. with the BU99_Right argument. */

    /* 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(            10,  REPORTHEIGHT - 16,      REPORTWIDTH - 20, 12, "Menu",     NULL);
    break;
    case 12:
        setgadget(            10,  SENDERHEIGHT - 16,      SENDERWIDTH - 20, 12, "OK",     NULL);
    break;
    case 13:
        setgadget(            10,  CONFIGHEIGHT - 16,      CONFIGWIDTH - 20, 12, "OK",     NULL);
    break;
    case 21:                                                                                
        setgadget(            10,  AMINETHEIGHT - 16,      AMINETWIDTH - 20, 12, "Menu",     NULL);
    break;
    case 31:
        setgadget(            10,   ACSE1HEIGHT - 16,       ACSE1WIDTH - 20, 12, "Menu",     NULL);
    break;
    case 32:
        if (certified)
            setgadget(        10,   ACSE2HEIGHT - 16,       ACSE2WIDTH - 20, 12, "OK",       NULL);
        else                                                                                 
            setgadget(        10,   ACSE2HEIGHT - 16,       ACSE2WIDTH - 20, 12, "Menu",     NULL);
    break;
    case 33:
        setgadget(            10,   ACSE3HEIGHT - 16,       ACSE3WIDTH - 20, 12, "Menu",     NULL);
    break;
    case 41:
        setgadget(            10, AUTODOCHEIGHT - 16,     AUTODOCWIDTH - 20, 12, "Menu",     NULL);
    break;
    case 51:
        setgadget(            10,  MANUF1HEIGHT - 16,      MANUF1WIDTH - 20, 12, "Menu",     NULL);
    break;
    case 61:
        setgadget(            10,    IFF1HEIGHT - 16,        IFF1WIDTH - 20, 12, "Menu",     NULL);
    break;
    case 71:
        setgadget(            10,    EOL1HEIGHT - 16,        EOL1WIDTH - 20, 12, "Menu",     NULL);
    break;
    case 81:
        if (ysize >= 512)
        {   setgadget(        10,           512 - 16,       SIZE1WIDTH - 20, 12, "Menu",     NULL);
        } else
        {   setgadget(        10,   SIZE1HEIGHT - 16,       SIZE1WIDTH - 20, 12, "Menu",     NULL);
        }
    break;
    case 91:
        setgadget(            10,   BATT1HEIGHT - 16,       BATT1WIDTH - 20, 12, "Menu",     NULL);
    break;
    case 101:
        setgadget(            10,  FILES1HEIGHT - 16,      FILES1WIDTH - 20, 12, "Menu",     NULL);
    break;
    case 111:
        setgadget(            10,    AGDBHEIGHT - 16,        AGDBWIDTH - 20, 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, 4096) == -1)
    /* the whole bug report must be < 4K */
    {   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 launcheditor(STRPTR pathname)
{   GT_SetGadgetAttrs
    (   BU99_Right,
        MainWindowPtr, NULL,
        GA_Disabled, TRUE,
        TAG_DONE
    );
    if (!react)
    {   ClearMenuStrip(MainWindowPtr);

        strcpy(string, shared.editor);
	strcat(string, " ");
        strcat(string, pathname);
	if (!Execute(string, NULL, NULL))
            rq("Can't launch editor!");
    } else
    {   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;
    STRPTR*            ToolArray;
    STRPTR             s;

    if ((*WBArg->wa_Name) && (DiskObject = GetDiskObject(WBArg->wa_Name)))
    {   ToolArray = (STRPTR *) DiskObject->do_ToolTypes;

        if (s = FindToolType((CONST_STRPTR *) ToolArray, "PAL"))
            pal = TRUE;
        if (s = FindToolType((CONST_STRPTR *) ToolArray, "GREY"))
            fillwindows = FALSE;
        if (s = FindToolType((CONST_STRPTR *) ToolArray, "EDITOR"))
        {   react = FALSE;
        }
        if (s = FindToolType((CONST_STRPTR *) ToolArray, "ICONTYPE"))
        {   if (MatchToolValue(s, "DISK"))
            {   icon.type = WBDISK - 1;
            } elif (MatchToolValue(s, "DRAWER"))
            {   icon.type = WBDRAWER - 1;
            } elif (MatchToolValue(s, "TOOL"))
            {   icon.type = WBTOOL - 1;
            } elif (MatchToolValue(s, "PROJECT"))
            {   icon.type = WBPROJECT - 1;
            } elif (MatchToolValue(s, "TRASHCAN"))
            {   icon.type = WBGARBAGE - 1;
            } elif (MatchToolValue(s, "DEVICE"))
            {   icon.type = WBDEVICE - 1;
            } elif (MatchToolValue(s, "KICKSTART"))
            {   icon.type = WBKICK - 1;
            } elif (MatchToolValue(s, "APPICON"))
            {   icon.type = WBAPPICON - 1;
        }   }
        if (s = FindToolType((CONST_STRPTR *) 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;
            elif (MatchToolValue(s, "11"))
            {   page = 111;
            } elif (MatchToolValue(s, "12"))
            {   page = 121;
        }   }
        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 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 (!(EADataPtr = AllocVec(2048, MEMF_CLEAR | MEMF_PUBLIC)))
    {   rq("Out of memory!");
}   }

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
    );
}
AGLOBAL void drawgadgets(WORD gadgets)
{   if (!PrevGadPtr)
        rq("Can't create GadTools gadgets!");
    AddGList(MainWindowPtr, BU99_Right, (UWORD) ~0, gadgets, NULL);
    RefreshGList(BU99_Right, MainWindowPtr, NULL, -1);
    GT_RefreshWindow(MainWindowPtr, NULL);
}

AGLOBAL void parse(STRPTR terminator)
{   ABOOL done = FALSE;
    ULONG suboffset;

    suboffset = offset;
    while (!done)
    {   string[offset - suboffset] = IOBuffer[offset];
        if (!(strncmp(&(IOBuffer[offset]), terminator, strlen(terminator))))
        {   string[offset - suboffset] = 0;
            offset += strlen(terminator);
            done = TRUE;
        } elif (offset > strlen(IOBuffer))
        {   /* failure */
            string[0] = 0;
            done = TRUE;
        } else offset++;
}   }

AGLOBAL void parsetoend(void)
{   ABOOL done      = FALSE;
    ULONG suboffset = 0;

    while (!done)
    {   string[suboffset] = IOBuffer[offset];
        if (offset > strlen(IOBuffer))
        {   /* EOF */
            string[suboffset] = 0;
            done = TRUE;
        } else
        {   offset++;
            suboffset++;
}   }   }

AGLOBAL ABOOL saveasl(STRPTR message)
{   struct FileRequester* ASLRqPtr;
    TEXT                  tempstring[VLONGFIELD + 1];
    ABOOL                 success;

    strcpy(tempstring, "Report+: ");
    strcat(tempstring, message);

    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, tempstring, ASL_FuncFlags, FILF_PATGAD | FILF_SAVE, 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!");
        success = TRUE;
    } else
    {   strcpy(asldir, "");
        strcpy(aslresult, "");
        success = FALSE;
    }
    if (ASLRqPtr) /* will always be true */
        FreeAslRequest(ASLRqPtr);
    return(success);
}

AGLOBAL void handlemenus(UWORD code)
{   /* struct MenuItem* ItemPtr; */
       BPTR             LockPtr;

    if (code != MENUNULL) /* while (code != MENUNULL) */
    {   /* ItemPtr = ItemAddress(MenuPtr, code); */
        switch (MENUNUM(code))
        {
        case MN_PROJECT:
            switch (ITEMNUM(code))
            {
            case IN_NEW:
                if (page == 11)
                    newreport(TRUE);
                elif (page == 21)
                    newaminet(TRUE);
                elif (page == 41)
                    newautodoc(TRUE);
                elif (page == 111)
                    newagdb(TRUE);
            break;
            case IN_OPEN:
                if (page == 11)
                    openreport();
                elif (page == 21)
                    openaminet();
                elif (page == 41)
                    openautodoc();
                elif (page == 91)
                {   batt_open();
                } elif (page == 111)
                    openagdb();
            break;
            case IN_SAVE:
                if (page == 11)
                    savereport(FALSE);
                elif (page == 21)
                    saveaminet(FALSE);
                elif (page == 41)
                    saveautodoc(FALSE);
                elif (page == 91)
                {   batt_save(FALSE);
                } elif (page == 111)
                    saveagdb(FALSE);
            break;
            case IN_SAVEAS:
                if (page == 11)
                    savereport(TRUE);
                elif (page == 21)
                    saveaminet(TRUE);
                elif (page == 41)
                    saveautodoc(TRUE);
                elif (page == 91)
                {   batt_save(TRUE);
                } elif (page == 111)
                    saveagdb(TRUE);
            break;
            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 = Lock("CON:", ACCESS_READ);
                if (SystemTags
                (   "SYS:Utilities/MultiView ReportPlus.guide",
                    SYS_Input,  (ULONG) LockPtr,
                    SYS_Output, NULL,
                    SYS_Asynch, TRUE,
                    TAG_DONE
                ) == -1)
                    DisplayBeep(ScreenPtr);
                elif (pal)
                    ScreenToFront(ScreenPtr);
                UnLock(LockPtr);
            break;
            default:
            break;
            }
        break;
        default:
        break;
        }
        /* Doing things the above way disables multi-selection,
        but prevents `endless selection'.
        code = ItemPtr->NextSelect; */
}   }

AGLOBAL void lockscreen(void)
{   if (!pal)
    {   if (!(ScreenPtr = LockPubScreen(NULL)))
            rq("Can't lock default public screen!");
}   }
AGLOBAL void unlockscreen(void)
{   if (!pal && ScreenPtr)
    {   UnlockPubScreen(NULL, ScreenPtr);
        ScreenPtr = NULL;
}   }

AGLOBAL void getfillcolour(void)
{   if (fillwindows)
    {   lockscreen();
        fillcolour = FindColor
        (   ScreenPtr->ViewPort.ColorMap,
            0x99999999, /* red */
            0x99999999, /* green */
            0xFFFFFFFF, /* blue */
           -1
        );
        unlockscreen();
    } else fillcolour = 0;
}

MODULE void eachwildcard(STRPTR subpattern)
{   struct AnchorPath* AnchorPathPtr;
    BPTR               OldDir;
    TEXT               dirbuffer[VLONGFIELD + 1];
    BOOL               result;
    ABOOL              done;

    dirbuffer[0] = NULL;
    if (!(AnchorPathPtr = AllocMem(sizeof(struct AnchorPath), MEMF_ANY | MEMF_PUBLIC)))
        return;

    AnchorPathPtr->ap_BreakBits = NULL;
    AnchorPathPtr->ap_Flags = NULL;
    AnchorPathPtr->ap_Strlen = 0;
    result = MatchFirst(subpattern, AnchorPathPtr);
    if (result == 0)
    {   OldDir = CurrentDir(AnchorPathPtr->ap_Current->an_Lock);
        if (!NameFromLock(AnchorPathPtr->ap_Current->an_Lock, dirbuffer, VLONGFIELD))
        {   MatchEnd(AnchorPathPtr);
            return;
        }
        if (!AddPart(dirbuffer, AnchorPathPtr->ap_Info.fib_FileName, VLONGFIELD))
        {   MatchEnd(AnchorPathPtr);
            return;
        }
        CurrentDir(OldDir);
        strcat(shared.finallist, "\"");
        strcat(shared.finallist, dirbuffer);
        strcat(shared.finallist, "\" ");
    } elif (result != ERROR_NO_MORE_ENTRIES)
    {   MatchEnd(AnchorPathPtr);
        return;
    }

    done = FALSE;
    while (!done)
    {   result = MatchNext(AnchorPathPtr);
        if (result == 0)
        {   OldDir = CurrentDir(AnchorPathPtr->ap_Current->an_Lock);
            if (!NameFromLock(AnchorPathPtr->ap_Current->an_Lock, dirbuffer, VLONGFIELD))
            {   MatchEnd(AnchorPathPtr);
                return;
            }
            if (!AddPart(dirbuffer, AnchorPathPtr->ap_Info.fib_FileName, VLONGFIELD))
            {   MatchEnd(AnchorPathPtr);
                return;
            }
            CurrentDir(OldDir);
            strcat(shared.finallist, "\"");
            strcat(shared.finallist, dirbuffer);
            strcat(shared.finallist, "\" ");
        } elif (result != ERROR_NO_MORE_ENTRIES)
        {   MatchEnd(AnchorPathPtr);
            return;
        } else done = TRUE;
    }
    MatchEnd(AnchorPathPtr);
    FreeMem(AnchorPathPtr, sizeof(struct AnchorPath));
}

AGLOBAL void multiasl(STRPTR pattern)
{   struct FileRequester* ASLRqPtr;
    ULONG                 i;
    TEXT                  quotestring[2];

    quotestring[0] = QUOTE;
    quotestring[1] = 0;

    /* It would also be good to correctly
    handle selection of directories. */

    if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, pattern, ASL_Window, MainWindowPtr, TAG_DONE)))
        rq("Can't create ASL request!");
    if (AslRequestTags(ASLRqPtr, ASL_Dir, asldir, ASL_Hail, "Report+ file multiselector", ASL_FuncFlags, FILF_PATGAD | FILF_MULTISELECT, TAG_DONE) && *(ASLRqPtr->rf_File) != 0)
    {   if (ASLRqPtr->rf_NumArgs)
        {   /* rf_ArgList is an array of WBArg structures. Each entry in
            this array corresponds to one of the files the user selected
            (in alphabetical order). The user multiselected; step through
            the list of selected files. */

            strcpy(asldir, ASLRqPtr->rf_Dir);
            strcpy(shared.pathname, quotestring);
            strcat(shared.pathname, ASLRqPtr->rf_Dir);
            if (!AddPart(shared.pathname, (ASLRqPtr->rf_ArgList)[0].wa_Name, VLONGFIELD))
                rq("Can't add filename to pathname!");
            strcat(shared.pathname, quotestring);
            strcat(shared.pathname, " ");
            for (i = 1; i < ASLRqPtr->rf_NumArgs; i++)
            {   strcat(shared.pathname, quotestring);
                strcat(shared.pathname, ASLRqPtr->rf_Dir);
                if (!AddPart(shared.pathname, (ASLRqPtr->rf_ArgList)[i].wa_Name, VLONGFIELD))
                   rq("Can't add filename to pathname!");
                strcat(shared.pathname, quotestring);
                if (i < ASLRqPtr->rf_NumArgs - 1)
                    strcat(shared.pathname, " ");
        }   }
        else
        {   /* The user didn't multiselect; use the normal way to get the
            filename. */

            strcpy(shared.pathname, quotestring);
            strcat(shared.pathname, ASLRqPtr->rf_Dir);
            if (!AddPart(shared.pathname, ASLRqPtr->rf_File, VLONGFIELD))
                rq("Can't add filename to pathname!");
            strcat(shared.pathname, quotestring);
    }   }
    if (ASLRqPtr)
        FreeAslRequest(ASLRqPtr);
}

AGLOBAL void checkabort(ABOOL gui)
{   struct Gadget*       addr;
    struct IntuiMessage* MsgPtr;
    ULONG                class, signals, gid, result;
    UWORD                code;

    /* OK, we've just finished operating on that file. Now before we */
    /* start on the next one, check whether the user still wants to... */
    signals = SetSignal(0L, 0L);
    if (signals & SIGBREAKF_CTRL_C)
    {   stop = TRUE;
        SetSignal(0L, SIGBREAKF_CTRL_C); /* clear the Ctrl-C signal */
        if (gui)
        {   if (page == 71)
            {   GT_SetGadgetAttrs
                (   TE71_Status,
                    MainWindowPtr, NULL,
                    GTTX_Text, "Aborted by user!",
                    TAG_DONE
                );
            } else
            {   /* assert(page == 121); */
                SetGadgetAttrs
                (   gadgets[GID_12_ST2], MainWindowPtr, NULL,
                    STRINGA_TextVal, "Aborted by user!",
                    TAG_DONE
                );
        }   }
        else
        {   Printf("Aborted by user!\n");
            Flush(Output());
    }   }

    if (page == 71)
    {
    while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
    {   class  = MsgPtr->Class;                       
        addr   = MsgPtr->IAddress;
        GT_ReplyIMsg(MsgPtr);
        switch(class)
        {
        case IDCMP_CLOSEWINDOW:
            cleanexit(EXIT_SUCCESS);
        break;
        case IDCMP_GADGETUP:
            /* assert(gui); */
            if (addr == BU99_Stop)
            {   GT_SetGadgetAttrs
                (   TE71_Status,
                    MainWindowPtr, NULL,
                    GTTX_Text, "Aborted by user!",
                    TAG_DONE
                );
                stop = TRUE;
            }
        break;
        default:
        break;
    }   }
    } else
    {   /* assert(page == 121); */
        while ((result = DoMethod((Object *) object, WM_HANDLEINPUT, &code)) != WMHI_LASTMSG)
        {   switch (result & WMHI_CLASSMASK)
            {
            case WMHI_MENUPICK:
                ; /* handlemenus(code); */
            break;
            case WMHI_CLOSEWINDOW:
                done = quit = TRUE;
            break;
            case WMHI_GADGETUP:
                gid = result & WMHI_GADGETMASK;
                if (gid == GID_12_BU4)
                {   stop = TRUE;
                }
            break;
            default:
            break;
}   }   }   }

AGLOBAL void convert(ABOOL gui)
{   ULONG i, j, length;
    ABOOL flag,   /* are we in letters (TRUE) or whitespace (FALSE)? */
          quoted; /* are we quoted (TRUE) or unquoted (FALSE)? */

    /* At this point we have a list of pathnames, separated by spaces and
    NULL-terminated. If they came from ASL, they will be quoted, otherwise,
    they may not.

    shared.pathname: the actual contents of the string gadget.
    shared.thatfile: each file that we pass to eachwildcard().
    shared.finallist: the final list produced, containing all pathnames.
    shared.thisfile: each file that we pass for conversion. */

    stop = flag = quoted = FALSE;
    length = strlen(shared.pathname);
    j = shared.finallist[0] = 0;
    for (i = 0; i < length; i++)
    {   if (shared.pathname[i] == ' ' && flag && !quoted)
        {   /* if we're unquoted and have a space */
            shared.thatfile[j] = 0; /* then NULL-terminate the pathname */
            eachwildcard(shared.thatfile);
            j = 0;
            flag = FALSE;
        } elif (shared.pathname[i] == QUOTE)
        {   if (!flag && !quoted)
            {   flag = TRUE; /* we're in letters */
                quoted = TRUE; /* it's a quote */
            } elif (flag && quoted)
            {   quoted = FALSE; /* it's an unquote */
        }   }
        else
        {   shared.thatfile[j++] = shared.pathname[i];
            flag = TRUE; /* we're in letters */
    }   }
    /* Now we are at the end. */
    if (flag) /* if we're in letters */
    {   shared.thatfile[j] = 0;
        /* then it is ended, quoted or not. Although we could */
        /* report an error condition if there are an odd */
        /* number of quotes (ie. a missing quote). */
        eachwildcard(shared.thatfile);
    }

    flag = quoted = FALSE;
    length = strlen(shared.finallist);
    j = 0;
    for (i = 0; i < length; i++)
    {   if (shared.finallist[i] == ' ' && flag && !quoted)
        {   /* if we're unquoted and have a space */
            shared.thisfile[j] = 0; /* then NULL-terminate the pathname */
            if (!stop)
            {   if (shared.function == 7 - 1)
                {   eolconvert(gui);
                } else
                {   /* assert(shared.function == 12 - 1); */
                    iconconvert(gui);
            }   }
            j = 0;
            flag = FALSE;
        } elif (shared.finallist[i] == QUOTE)
        {   if (!flag && !quoted)
            {   flag = TRUE; /* we're in letters */
                quoted = TRUE; /* it's a quote */
            } elif (flag && quoted)
            {   quoted = FALSE; /* it's an unquote */
        }   }
        else
        {   shared.thisfile[j++] = shared.finallist[i];
            flag = TRUE; /* we're in letters */
        }
        if (stop)
        {   return;
    }   }
    /* Now we are at the end. */
    if (flag) /* if we're in letters */
    {   shared.thisfile[j] = 0;
        /* then it is ended, quoted or not. Although we could */
        /* report an error condition if there are an odd */
        /* number of quotes (ie. a missing quote). */
        if (shared.function == 7 - 1)
        {   eolconvert(gui);
        } else
        {   /* assert(shared.function == 12 - 1); */
            iconconvert(gui);
}   }   }
