/* ScreenShift 1.0
 * Anson Mah
 * June 4, 1987
 * Completely in the Public Domain
 * Written for Lattice C
 */

/* #define DEBUG */

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>

#ifdef DEBUG
#include <stdio.h>
#endif

#define PROPGADWIDTH	200	/* gadget proportions */
#define PROPGADHEIGHT	50
#define XJUMP	512		/* add to Vert/HorizPot when */
#define YJUMP	1024		/*   moving with cursor keys */
#define UP	0x4c		/* cursor key RAWKEYS */
#define DOWN	0x4d		/* also defined in intuition.h, */
#define LEFT	0x4f		/*   but included for clarity */
#define RIGHT	0x4e
#define CR	0x44		/* RETURN key */

extern UWORD xoffset(), yoffset();	/* the math.s routines */
extern BYTE xpot(), ypot();

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase = NULL;
struct Preferences *pref = NULL;
struct Window *pwin = NULL;

UWORD pimagedata[] = {
	0x0000,0x0000,0x0000,	/* bit plane 0 */
	0x7FFF,0xFFFF,0xFE00,
	0x7FFE,0x3F1F,0xFE00,
	0x7FF9,0x9CCF,0xFE00,
	0x7FF9,0xFCFF,0xFE00,
	0x7FFE,0x7F3F,0xFE00,
	0x7FE6,0x733F,0xFE00,
	0x7FF0,0xF87F,0xFE00,
	0x7FFF,0xFFFF,0xFE00,
	0x0000,0x0000,0x0000,
	0xFFFF,0xFFFF,0xFF00,	/* bit plane 1 */
	0xFFFF,0xFFFF,0xFF00,
	0xFFFF,0xFFFF,0xFF00,
	0xFFFF,0xFFFF,0xFF00,
	0xFFFF,0xFFFF,0xFF00,
	0xFFFF,0xFFFF,0xFF00,
	0xFFFF,0xFFFF,0xFF00,
	0xFFFF,0xFFFF,0xFF00,
	0xFFFF,0xFFFF,0xFF00,
	0xFFFF,0xFFFF,0xFF00
};

struct Image pimage = { 0, 0, 40, 10, 2, &pimagedata[0], 0x03, 0x00, NULL };

struct PropInfo pinfo = { FREEVERT | FREEHORIZ, 0,0, MAXBODY/5,MAXBODY/5, 0,0,0,0,0 };

struct Gadget pgadget = {
	NULL, 0, 10, PROPGADWIDTH, PROPGADHEIGHT, GADGIMAGE, FOLLOWMOUSE,
	PROPGADGET, (APTR)&pimage, NULL, NULL, 0, (APTR)&pinfo,
	0, NULL
};

struct NewWindow pwindef = {
	220, 70,
	PROPGADWIDTH, PROPGADHEIGHT + 10,
	0, 3,
	CLOSEWINDOW | MOUSEMOVE | RAWKEY,
	WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG | ACTIVATE | SMART_REFRESH | RMBTRAP,
	&pgadget,
	NULL,
	"ScreenShift",
	NULL, NULL,
	0,0, 0,0,
	WBENCHSCREEN
};

void closestuff()
{
	if (pref)		FreeMem(pref, sizeof(struct Preferences));
	if (pwin)		CloseWindow(pwin);
	if (GfxBase)		CloseLibrary(GfxBase);
	if (IntuitionBase)	CloseLibrary(IntuitionBase);
#ifdef DEBUG
	exit(0);
#else
	XCEXIT(0);
#endif
}

void openstuff()
{
	IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 33);
	GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 33);

	if (IntuitionBase == NULL || GfxBase == NULL)
		closestuff();

	if (!(pref = (struct Preferences *)AllocMem(sizeof(struct Preferences),
		MEMF_PUBLIC)))
		closestuff();

	/* get current preference setting */
	(void)GetPrefs(pref, sizeof(struct Preferences));
	/* set up prop gadget with current View settings */
	pinfo.HorizPot = xoffset(pref->ViewXOffset);
	pinfo.VertPot = yoffset(pref->ViewYOffset);
#ifdef DEBUG
	printf("x: %d  y: %d\n", pref->ViewXOffset, pref->ViewYOffset);
	printf("x: %d  y: %d\n", pinfo.HorizPot, pinfo.VertPot);
#endif
	if (!(pwin = (struct Window *)OpenWindow(&pwindef)))
		closestuff();	/* couldn't open window */
}

#ifdef DEBUG
void main()
#else
void _main()
#endif
{
	struct IntuiMessage *msg;
	ULONG class, code;
	BYTE xoffset, yoffset;

	openstuff();

	for (;;) {
		WaitPort(pwin->UserPort);
		msg = (struct IntuiMessage *)GetMsg(pwin->UserPort);
		class = msg->Class;
		code = msg->Code;
		ReplyMsg(msg);

		switch (class) {
			case CLOSEWINDOW:
				closestuff();
				break;
			case RAWKEY:
			  switch (code) {
				case UP:
					if (pinfo.VertPot >= YJUMP)
						pinfo.VertPot -= YJUMP;
					else	pinfo.VertPot = 0;
					break;
				case DOWN:
					if (pinfo.VertPot < MAXBODY - YJUMP)
						pinfo.VertPot += YJUMP;
					else	pinfo.VertPot = MAXBODY;
					break;
				case LEFT:
					if (pinfo.HorizPot >= XJUMP)
						pinfo.HorizPot -= XJUMP;
					else	pinfo.HorizPot = 0;
					break;
				case RIGHT:
					if (pinfo.HorizPot < MAXBODY - XJUMP)
						pinfo.HorizPot += XJUMP;
					else	pinfo.HorizPot = MAXBODY;
					break;
				case CR:	/* carriage return */
					closestuff();	/* quit */
					break;
			  }
			  RefreshGadgets(&pgadget, pwin, NULL);
			  /* fall through */
			case MOUSEMOVE:
				xoffset = xpot(pinfo.HorizPot);
				yoffset = ypot(pinfo.VertPot);
				if (pref->ViewXOffset != xoffset || pref->ViewYOffset != yoffset) {
					pref->ViewXOffset = xoffset;
					pref->ViewYOffset = yoffset;
					(void)SetPrefs(pref, sizeof(struct Preferences), FALSE);
#ifdef DEBUG
	printf("x: %d  y: %d\n", pref->ViewXOffset, pref->ViewYOffset);
	printf("x: %d  y: %d\n", pinfo.HorizPot, pinfo.VertPot);
#endif
				}
				break;
		}
	}
}

void MemCleanup() {}	/* stub for Lattice */
