#define DEBUG

/*
              MAND.H -- The Constants and Definitions
             Mandelbrot Self-Squared Dragon Generator
                    For the Commodore Amiga
                         Version 2.01

                      Accompanied MAND.C

             Copyright (c) 1985, Robert S. French
                  Placed in the Public Domain

              Vastly Enhanced by =RJ Mical=  1985
                Manxified by Olaf Seibert  1987

This program may be distributed free of charge as long as the above
notice is retained.

*/


/*-------------------*/
/* Lots of includes! */

#include <exec/types.h>
#include <exec/memory.h>
/* #include <exec/tasks.h> */
/* #include <exec/libraries.h> */
/* #include <exec/devices.h> */
/* #include <devices/keymap.h> */
/* #include <graphics/copper.h> */
/* #include <graphics/display.h> */
/* #include <graphics/gfxbase.h> */
/* #include <graphics/text.h> */
/* #include <graphics/view.h> */
/* #include <graphics/gels.h> */
/* #include <graphics/regions.h> */
/* #include <hardware/blit.h> */
#include <intuition/intuition.h>
/* #include <intuition/intuitionbase.h> */
#ifdef DEBUG
#  include <stdio.h>
#  undef STATIC	/* Empty string */
#  define STATIC
#endif

/* #include <libraries/dos.h> */

/* #include <workbench/workbench.h> */

#include "mandel.h"

/*---------------------------------*/
#define NOT	!
#define FOREVER	for(;;)

/* === the definitions for the ColorWindow =============================== */
#define COLOR_KNOB_BODY		0x1000	/* 0x1111 */

#define COLORWINDOW_WIDTH	208
#define COLORWINDOW_HEIGHT	101		/* 91 */

#define DEFAULT_WINDOW_LEFT	(320 - COLORWINDOW_WIDTH)
#define DEFAULT_WINDOW_TOP	(200 - COLORWINDOW_HEIGHT)

#define CHARACTER_WIDTH		8
#define CHARACTER_HEIGHT	8

#define COLOR_BOX_LEFT		7
#define COLOR_BOX_TOP		16		/* 6 */
#define COLOR_BOX_RIGHT		(COLOR_BOX_LEFT + 15)
#define COLOR_BOX_BOTTOM	(COLOR_BOX_TOP + 29)
#define COLOR_COLOR_TOP		55		/* 45 */
#define COLOR_COLOR_WIDTH	15
#define COLOR_COLOR_HEIGHT	10
#define COLOR_PROP_LEFT		38
#define COLOR_PROP_TOP		14		/* 4 */
#define COLOR_PROP_WIDTH	165
#define COLOR_PROP_HEIGHT	10
#define COLOR_CLUSTER_LEFT	141
#define COLOR_CLUSTER_TOP	51		/* 41 */
#define COLOR_CLUSTER_WIDTH	(CHARACTER_WIDTH * 6 + 4)
#define COLOR_CLUSTER_HEIGHT	9
#define COLOR_AIN_TOP		(COLOR_BOX_TOP - 2)
#define COLOR_AIN_LEFT		(COLOR_BOX_RIGHT + 3)

/* GREEN and RED are out of order.  Do you wonder why?  Some day I'll 
 * tell you.  =RJ=
 */
#define COLOR_COPY		MAXCOL
#define COLOR_RANGE		MAXCOL+1
#define COLOR_OK		MAXCOL+2
#define COLOR_CANCEL	MAXCOL+3
#define COLOR_GREEN		MAXCOL+4
#define COLOR_RED		MAXCOL+5
#define COLOR_BLUE		MAXCOL+6
#define COLOR_AIN_RGB	MAXCOL+7
#define COLOR_GADGETS_COUNT	MAXCOL+8

#define RAIN_MAX_DISTANCE	(MaxColor - 2)
#define RAIN_MIN_DISTANCE	1

#define ONE_HALF		(0x8000L)

#define SafeFont	Topaz80

/****************************************************************************
 *                  MAND6.C - Color Window Data
 *             Mandelbrot Self-Squared Dragon Generator
 *                    For the Commodore Amiga
 *                         Version 2.01
 *
 *             Copyright (C) 1986, =Robert J. Mical=
 *                  Placed in the Public Domain
 *
 *  This program may be distributed free of charge as long as the above
 *  notice is retained.  You may extract any or all information contained
 *  in this file for use in your own programs
 *
 ***************************************************************************/


/****************************************************************************
 *
 * Color window template initialization and routines, 
 * for colorwindow and cyclewindow
 *
 * Throughout this file, the COLOR_RED and COLOR_GREEN gadgets are in the
 * opposite order you would expect.  
 *
 ***************************************************************************/

STATIC USHORT RGBData[] =
{
	0x0000, 0xFC00, 0x6600, 0x6600, 0x7C00, 0x6C00, 0x6600, 0xE300,
	0x0000, 0x0000, 0x0000, 0x0000, 0x3C00, 0x6600, 0xC000, 0xCE00,
	0xC600, 0x6600, 0x3E00, 0x0000, 0x0000, 0x0000, 0x0000, 0xFC00,
	0x6600, 0x6600, 0x7C00, 0x6600, 0x6600, 0xFC00, 0x0000,
	/* The rest is for the Rainbow Image */
	~0x0000, ~0xFC00, ~0x6600, ~0x6600, ~0x7C00, ~0x6C00, ~0x6600, ~0xE300,
	~0x0000, ~0x0000, ~0x0000, ~0x0000, ~0x3C00, ~0x6600, ~0xC000, ~0xCE00,
	~0xC600, ~0x6600, ~0x3E00, ~0x0000, ~0x0000, ~0x0000, ~0x0000, ~0xFC00,
	~0x6600, ~0x6600, ~0x7C00, ~0x6600, ~0x6600, ~0xFC00, ~0x0000
};

#define MID_RGB_AIN (sizeof(RGBData)/sizeof(RGBData[0])/2)


STATIC struct Image ColorRGBImage =
{
	3, 0,
	8, 
	31,
	1,
	&RGBData[0],
	0x1, 0x0,
	NULL,
};

STATIC struct Image ColorRAINImage =
{
	3, 0,
	8, 
	31,
	1,
	&RGBData[MID_RGB_AIN],
	0x1, 0x0,
	NULL,
};

STATIC SHORT ClusterBorderVectors[] =
{
	-1, -1,
	-1, COLOR_CLUSTER_HEIGHT,
	COLOR_CLUSTER_WIDTH, COLOR_CLUSTER_HEIGHT,
	COLOR_CLUSTER_WIDTH, -1,
	-1, -1,
};


STATIC struct Border ColorClusterBorder =
{
	0, 0, 
	1, 0,
	JAM1,
	5,
	&ClusterBorderVectors[0],
	NULL,
};

STATIC struct IntuiText ColorClusterText[4] =
{	/* "COPY" */
	{
		1, 0,
		JAM2,
		2 + CHARACTER_WIDTH, 1, 
		&SafeFont,
		(UBYTE *) "COPY",
		NULL,
	}, /* "RANGE" */
	{
		1, 0, 
		JAM2,
		2 + (CHARACTER_WIDTH >> 1), 1, 
		&SafeFont,
		(UBYTE *) "RANGE",
		NULL,
	}, /* "OK" */
	{
		1, 0, 
		JAM2,
		2 + (CHARACTER_WIDTH << 1), 1, 
		&SafeFont,
		(UBYTE *) "OK",
		NULL,
	}, /* "CANCEL" */
	{
		1, 0, 
		JAM2,
		2, 1, 
		&SafeFont,
		(UBYTE *) "CANCEL",
		NULL,
	},
};

STATIC struct IntuiText LessMoreText =
/* "COPY" "<>" */
{
	1, 0,
	JAM2,
	2 + (CHARACTER_WIDTH >> 1), 1, 
	&SafeFont,
	(UBYTE *) " <-> ",
	NULL,
};
STATIC struct IntuiText MoreLessText =
{ /* "RANGE" "><" */
	1, 0, 
	JAM2,
	2 + (CHARACTER_WIDTH >> 1), 1, 
	&SafeFont,
	(UBYTE *) " >-< ",
	NULL,
};

/* ======================================================================= */
/* ======================================================================= */
/* ======================================================================= */

/* RJM anchor */
STATIC struct Image ColorPropsImages[3];
STATIC struct Image SuperColorImages[MAXCOL];


STATIC struct PropInfo ColorPropsInfos[3] = 
{
	{ /* COLOR_GREEN */
		AUTOKNOB | FREEHORIZ,
		0,
		0,
		COLOR_KNOB_BODY,
		0,
		0, 0, 0, 0, 0, 0,
	},
	{ /* COLOR_RED */
		AUTOKNOB | FREEHORIZ,
		0,
		0,
		COLOR_KNOB_BODY,
		0,
		0, 0, 0, 0, 0, 0,
	},
	{ /* COLOR_BLUE */
		AUTOKNOB | FREEHORIZ,
		0,
		0,
		COLOR_KNOB_BODY,
		0,
		0, 0, 0, 0, 0, 0,
	}
};


STATIC struct Gadget ColorTemplateGadgets[COLOR_GADGETS_COUNT] =
{
	{ /* COLOR_00 */
		NULL,
		COLOR_BOX_LEFT + ((00 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((00 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[00],
		(APTR)&SuperColorImages[00],
		NULL,
		NULL,
		NULL,
		00,
		NULL,
	}, 
	{ /* COLOR_01 */
		&ColorTemplateGadgets[00],
		COLOR_BOX_LEFT + ((01 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((01 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[01],
		(APTR)&SuperColorImages[01],
		NULL,
		NULL,
		NULL,
		01,
		NULL,
	},
	{ /* COLOR_02 */
		&ColorTemplateGadgets[01],
		COLOR_BOX_LEFT + ((02 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((02 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[02],
		(APTR)&SuperColorImages[02],
		NULL,
		NULL,
		NULL,
		02,
		NULL,
	},
	{ /* COLOR_03 */
		&ColorTemplateGadgets[02],
		COLOR_BOX_LEFT + ((03 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((03 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[03],
		(APTR)&SuperColorImages[03],
		NULL,
		NULL,
		NULL,
		03,
		NULL,
	}, 
	{ /* COLOR_04 */
		&ColorTemplateGadgets[03],
		COLOR_BOX_LEFT + ((04 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((04 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[04],
		(APTR)&SuperColorImages[04],
		NULL,
		NULL,
		NULL,
		04,
		NULL,
	},
	{ /* COLOR_05 */
		&ColorTemplateGadgets[04],
		COLOR_BOX_LEFT + ((05 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((05 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[05],
		(APTR)&SuperColorImages[05],
		NULL,
		NULL,
		NULL,
		05,
		NULL,
	},
	{ /* COLOR_06 */
		&ColorTemplateGadgets[05],
		COLOR_BOX_LEFT + ((06 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((06 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[06],
		(APTR)&SuperColorImages[06],
		NULL,
		NULL,
		NULL,
		06,
		NULL,
	},
	{ /* COLOR_07 */
		&ColorTemplateGadgets[06],
		COLOR_BOX_LEFT + ((07 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((07 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[07],
		(APTR)&SuperColorImages[07],
		NULL,
		NULL,
		NULL,
		07,
		NULL,
	},
	{ /* COLOR_08 */
		&ColorTemplateGadgets[07],
		COLOR_BOX_LEFT + ((8 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((8 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[8],
		(APTR)&SuperColorImages[8],
		NULL,
		NULL,
		NULL,
		8,
		NULL,
	},
	{ /* COLOR_09 */
		&ColorTemplateGadgets[8],
		COLOR_BOX_LEFT + ((9 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((9 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[9],
		(APTR)&SuperColorImages[9],
		NULL,
		NULL,
		NULL,
		9,
		NULL,
	},
	{ /* COLOR_10 */
		&ColorTemplateGadgets[9],
		COLOR_BOX_LEFT + ((10 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((10 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[10],
		(APTR)&SuperColorImages[10],
		NULL,
		NULL,
		NULL,
		10,
		NULL,
	},
	{ /* COLOR_11 */
		&ColorTemplateGadgets[10],
		COLOR_BOX_LEFT + ((11 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((11 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[11],
		(APTR)&SuperColorImages[11],
		NULL,
		NULL,
		NULL,
		11,
		NULL,
	}, 
	{ /* COLOR_12 */
		&ColorTemplateGadgets[11],
		COLOR_BOX_LEFT + ((12 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((12 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[12],
		(APTR)&SuperColorImages[12],
		NULL,
		NULL,
		NULL,
		12,
		NULL,
	}, 
	{ /* COLOR_13 */
		&ColorTemplateGadgets[12],
		COLOR_BOX_LEFT + ((13 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((13 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[13],
		(APTR)&SuperColorImages[13],
		NULL,
		NULL,
		NULL,
		13,
		NULL,
	}, 
	{ /* COLOR_14 */
		&ColorTemplateGadgets[13],
		COLOR_BOX_LEFT + ((14 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((14 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[14],
		(APTR)&SuperColorImages[14],
		NULL,
		NULL,
		NULL,
		14,
		NULL,
	}, 
	{ /* COLOR_15 */
		&ColorTemplateGadgets[14],
		COLOR_BOX_LEFT + ((15 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((15 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[15],
		(APTR)&SuperColorImages[15],
		NULL,
		NULL,
		NULL,
		15,
		NULL,
	}, 
	{ /* COLOR_16 */
		&ColorTemplateGadgets[15],
		COLOR_BOX_LEFT + ((16 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((16 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[16],
		(APTR)&SuperColorImages[16],
		NULL,
		NULL,
		NULL,
		16,
		NULL,
	}, 
	{ /* COLOR_17 */
		&ColorTemplateGadgets[16],
		COLOR_BOX_LEFT + ((17 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((17 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[17],
		(APTR)&SuperColorImages[17],
		NULL,
		NULL,
		NULL,
		17,
		NULL,
	}, 
	{ /* COLOR_18 */
		&ColorTemplateGadgets[17],
		COLOR_BOX_LEFT + ((18 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((18 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[18],
		(APTR)&SuperColorImages[18],
		NULL,
		NULL,
		NULL,
		18,
		NULL,
	}, 
	{ /* COLOR_19 */
		&ColorTemplateGadgets[18],
		COLOR_BOX_LEFT + ((19 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((19 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[19],
		(APTR)&SuperColorImages[19],
		NULL,
		NULL,
		NULL,
		19,
		NULL,
	}, 
	{ /* COLOR_20 */
		&ColorTemplateGadgets[19],
		COLOR_BOX_LEFT + ((20 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((20 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[20],
		(APTR)&SuperColorImages[20],
		NULL,
		NULL,
		NULL,
		20,
		NULL,
	}, 
	{ /* COLOR_21 */
		&ColorTemplateGadgets[20],
		COLOR_BOX_LEFT + ((21 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((21 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[21],
		(APTR)&SuperColorImages[21],
		NULL,
		NULL,
		NULL,
		21,
		NULL,
	}, 
	{ /* COLOR_22 */
		&ColorTemplateGadgets[21],
		COLOR_BOX_LEFT + ((22 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((22 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[22],
		(APTR)&SuperColorImages[22],
		NULL,
		NULL,
		NULL,
		22,
		NULL,
	}, 
	{ /* COLOR_23 */
		&ColorTemplateGadgets[22],
		COLOR_BOX_LEFT + ((23 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((23 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[23],
		(APTR)&SuperColorImages[23],
		NULL,
		NULL,
		NULL,
		23,
		NULL,
	}, 
	{ /* COLOR_24 */
		&ColorTemplateGadgets[23],
		COLOR_BOX_LEFT + ((24 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((24 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[24],
		(APTR)&SuperColorImages[24],
		NULL,
		NULL,
		NULL,
		24,
		NULL,
	}, 
	{ /* COLOR_25 */
		&ColorTemplateGadgets[24],
		COLOR_BOX_LEFT + ((25 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((25 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[25],
		(APTR)&SuperColorImages[25],
		NULL,
		NULL,
		NULL,
		25,
		NULL,
	},
	{ /* COLOR_26 */
		&ColorTemplateGadgets[25],
		COLOR_BOX_LEFT + ((26 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((26 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[26],
		(APTR)&SuperColorImages[26],
		NULL,
		NULL,
		NULL,
		26,
		NULL,
	}, 
	{ /* COLOR_27 */
		&ColorTemplateGadgets[26],
		COLOR_BOX_LEFT + ((27 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((27 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[27],
		(APTR)&SuperColorImages[27],
		NULL,
		NULL,
		NULL,
		27,
		NULL,
	},
	{ /* COLOR_28 */
		&ColorTemplateGadgets[27],
		COLOR_BOX_LEFT + ((28 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((28 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[28],
		(APTR)&SuperColorImages[28],
		NULL,
		NULL,
		NULL,
		28,
		NULL,
	},
	{ /* COLOR_29 */
		&ColorTemplateGadgets[28],
		COLOR_BOX_LEFT + ((29 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((29 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[29],
		(APTR)&SuperColorImages[29],
		NULL,
		NULL,
		NULL,
		29,
		NULL,
	},
	{ /* COLOR_30 */
		&ColorTemplateGadgets[29],
		COLOR_BOX_LEFT + ((30 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((30 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[30],
		(APTR)&SuperColorImages[30],
		NULL,
		NULL,
		NULL,
		30,
		NULL,
	},
	{ /* COLOR_31 */
		&ColorTemplateGadgets[30],
		COLOR_BOX_LEFT + ((31 & 0x7) * COLOR_COLOR_WIDTH),
		COLOR_COLOR_TOP + ((31 >> 3) * COLOR_COLOR_HEIGHT),
		COLOR_COLOR_WIDTH,
		COLOR_COLOR_HEIGHT,
		GADGIMAGE | GADGHNONE,
		GADGIMMEDIATE,
		BOOLGADGET,
		(APTR)&SuperColorImages[31],
		(APTR)&SuperColorImages[31],
		NULL,
		NULL,
		NULL,
		31,
		NULL,
	},
	{ /* COLOR_COPY */
		&ColorTemplateGadgets[31],
		COLOR_CLUSTER_LEFT,
		COLOR_CLUSTER_TOP + (00 * (COLOR_CLUSTER_HEIGHT + 3)),
		COLOR_CLUSTER_WIDTH,
		COLOR_CLUSTER_HEIGHT,
		GADGHCOMP,
		RELVERIFY,
		BOOLGADGET,
		(APTR)&ColorClusterBorder,
		NULL,
		&ColorClusterText[00],
		NULL,
		NULL,
		COLOR_COPY,
		NULL,
	},
	{ /* COLOR_RANGE */
		&ColorTemplateGadgets[COLOR_COPY],
		COLOR_CLUSTER_LEFT,
		COLOR_CLUSTER_TOP + (01 * (COLOR_CLUSTER_HEIGHT + 3)),
		COLOR_CLUSTER_WIDTH,
		COLOR_CLUSTER_HEIGHT,
		GADGHCOMP,
		RELVERIFY,
		BOOLGADGET,
		(APTR)&ColorClusterBorder,
		NULL,
		&ColorClusterText[01],
		NULL,
		NULL,
		COLOR_RANGE,
		NULL,
	},
	{ /* COLOR_OK */
		&ColorTemplateGadgets[COLOR_RANGE],
		COLOR_CLUSTER_LEFT,
		COLOR_CLUSTER_TOP + (02 * (COLOR_CLUSTER_HEIGHT + 3)),
		COLOR_CLUSTER_WIDTH,
		COLOR_CLUSTER_HEIGHT,
		GADGHCOMP,
		RELVERIFY,
		BOOLGADGET,
		(APTR)&ColorClusterBorder,
		NULL,
		&ColorClusterText[02],
		NULL,
		NULL,
		COLOR_OK,
		NULL,
	},
	{ /* COLOR_CANCEL */
		&ColorTemplateGadgets[COLOR_OK],
		COLOR_CLUSTER_LEFT,
		COLOR_CLUSTER_TOP + (03 * (COLOR_CLUSTER_HEIGHT + 3)),
		COLOR_CLUSTER_WIDTH,
		COLOR_CLUSTER_HEIGHT,
		GADGHCOMP,
		RELVERIFY,
		BOOLGADGET,
		(APTR)&ColorClusterBorder,
		NULL,
		&ColorClusterText[03],
		NULL,
		NULL,
		COLOR_CANCEL,
		NULL,
	},
	{ /* COLOR_GREEN */
		&ColorTemplateGadgets[COLOR_CANCEL],
		COLOR_PROP_LEFT,
		COLOR_PROP_TOP + (01 * (COLOR_PROP_HEIGHT + 1)),
		COLOR_PROP_WIDTH,
		COLOR_PROP_HEIGHT,
		GADGIMAGE | GADGHNONE,	/* GADGHNONE doesn't seem to work! */
		FOLLOWMOUSE,			/* The knob still reverses when selected */
		PROPGADGET,				/* even if I GADGHIMAGE with 2 of the */
		(APTR)&ColorPropsImages[01],	/* same ColorPropsImages */
		NULL,
		NULL,
		NULL,
		(APTR)&ColorPropsInfos[01],
		COLOR_GREEN,
		NULL,
	},
	{ /* COLOR_RED */
		&ColorTemplateGadgets[COLOR_GREEN],
		COLOR_PROP_LEFT,
		COLOR_PROP_TOP + (00 * (COLOR_PROP_HEIGHT + 1)),
		COLOR_PROP_WIDTH,
		COLOR_PROP_HEIGHT,
		GADGIMAGE | GADGHNONE,
		FOLLOWMOUSE,
		PROPGADGET,
		(APTR)&ColorPropsImages[00],
		NULL,
		NULL,
		NULL,
		(APTR)&ColorPropsInfos[00],
		COLOR_RED,
		NULL,
	},
	{ /* COLOR_BLUE */
		&ColorTemplateGadgets[COLOR_RED],
		COLOR_PROP_LEFT,
		COLOR_PROP_TOP + (02 * (COLOR_PROP_HEIGHT + 1)),
		COLOR_PROP_WIDTH,
		COLOR_PROP_HEIGHT,
		GADGIMAGE | GADGHNONE,
		FOLLOWMOUSE,
		PROPGADGET,
		(APTR)&ColorPropsImages[02],
		NULL,
		NULL,
		NULL,
		(APTR)&ColorPropsInfos[02],
		COLOR_BLUE,
		NULL,
	},
	{ /* COLOR_AIN_RGB */
		&ColorTemplateGadgets[COLOR_BLUE],
		COLOR_AIN_LEFT,
		COLOR_AIN_TOP,
		CHARACTER_WIDTH + 5,
		COLOR_BOX_BOTTOM - COLOR_BOX_TOP + 1,
		GADGHIMAGE | GADGIMAGE /*| SELECTED*/,
		TOGGLESELECT | RELVERIFY,
		BOOLGADGET,
		(APTR)&ColorRGBImage,
		(APTR)&ColorRAINImage,
		NULL,
		NULL,
		NULL,
		COLOR_AIN_RGB,
		NULL,
	}
};



/****************************************************************************
 *                     MAND5.C - Color Window
 *             Mandelbrot Self-Squared Dragon Generator
 *                    For the Commodore Amiga
 *                         Version 2.01
 *
 *             Copyright (C) 1986, =Robert J. Mical=
 *                  Placed in the Public Domain
 *
 *  This program may be distributed free of charge as long as the above
 *  notice is retained.  You may extract any or all information contained
 *  in this file for use in your own programs
 *
 ***************************************************************************/


/****************************************************************************
 *
 * Color initialization and routines
 *
 ***************************************************************************/

#define COPYCOLOR    1
#define RANGE_FIRST  2
#define RANGE_SECOND 3
STATIC USHORT ColorMode;

STATIC USHORT SavePalette[MAXCOL];

#define COLOR_IDCMP_FLAGS (GADGETDOWN | GADGETUP | MOUSEMOVE)

#define MIN(x,y)	(x<y ? x : y)


STATIC struct NewWindow ColorNewWindow =
{
/*  SHORT LeftEdge, TopEdge;        /* screen dimensions of window */
/*  SHORT Width, Height;            /* screen dimensions of window */
	DEFAULT_WINDOW_LEFT, DEFAULT_WINDOW_TOP,
	COLORWINDOW_WIDTH, COLORWINDOW_HEIGHT,

/*  UBYTE DetailPen, BlockPen;      /* for bar/border/gadget rendering */
	-1, -1,

/*  ULONG IDCMPFlags;               /* User-selected IDCMP flags */
	NULL,

/*  ULONG Flags;                    /* see Window struct for defines */
	SMART_REFRESH | NOCAREREFRESH | WINDOWDRAG | WINDOWDEPTH | ACTIVATE,

/*  struct Gadget *FirstGadget;*/
	NULL,

/*  struct Image *CheckMark;*/
	NULL,

/*  UBYTE *Title;						/* the title text for this window */
	(UBYTE *)"Palette \xE0 la =RJ=",	/* a` \340 */

/*  struct Screen *Screen;*/
	NULL,

/*  struct BitMap *BitMap;*/
	NULL,

/*  SHORT MinWidth, MinHeight;			/* minimums */
	0, 0,
/*  SHORT MaxWidth, MaxHeight;			/* maximums */
	0, 0,

/*  USHORT Type;*/
	CUSTOMSCREEN,
};

STATIC SHORT CurrentColor;
STATIC SHORT RangeFirst;   /* the first selection of the range-color pair */
STATIC SHORT MaxColor;
STATIC BOOL  RainbowMode = FALSE;
SHORT RainbowDistance = 0;
SHORT RainbowRMax = 1000;
SHORT RainbowGMax = 1000;
SHORT RainbowBMax = 1000;
STATIC SHORT RRMax = -1, RGMax = -1, RBMax = -1;


STATIC struct Window *ColorWindow = NULL;
STATIC struct ViewPort *vp;

/* ======================================================================= */
/* ======================================================================= */
/* ======================================================================= */

STATIC BOOL OpenColorWindow(w)
register struct Window *w;
{
	register LONG i;
	extern LONG TypeOfMem();

	vp = &w->WScreen->ViewPort;
	ColorMode = NULL;

	if (ColorWindow) return TRUE;

	MaxColor = (1 << w->WScreen->BitMap.Depth) - 1;
	if (MaxColor > MAXCOL-1) MaxColor = MAXCOL-1;
	for (i = 0; i < MAXCOL; i++) SavePalette[i] = GetRGB4(vp->ColorMap, i);

	/* In case we have uninitialised or dumb values */
	if (RainbowDistance < RAIN_MIN_DISTANCE ||
		RainbowDistance > RAIN_MAX_DISTANCE) {
		RainbowDistance = 1 + MaxColor / 3;
		goto defaults;
	}
	if (RainbowRMax > MaxColor ||
		RainbowGMax > MaxColor ||
		RainbowBMax > MaxColor) {
defaults:
		RainbowRMax = 0;
		RainbowGMax = (MaxColor+2) / 3;
		RainbowBMax = 2 * (MaxColor+2) / 3;
	}

	ColorTemplateGadgets[COLOR_AIN_RGB].Flags &= ~SELECTED;
	RainbowMode = FALSE;
	ColorTemplateGadgets[COLOR_COPY].GadgetText = &ColorClusterText[0];
	ColorTemplateGadgets[COLOR_RANGE].GadgetText = &ColorClusterText[1];

	/* Make sure the image data is in CHIP memory */
	if (TypeOfMem(&RGBData[61]) & MEMF_CHIP) {
		ColorRGBImage.ImageData = &RGBData[0];
		ColorRAINImage.ImageData = &RGBData[MID_RGB_AIN];
	} else {
#ifdef DEBUG2
		fprintf(stderr, "Allocate CHIP memory (%d bytes) for RGBData\n", 
			sizeof(RGBData));
#endif
		if ((ColorRGBImage.ImageData = AllocMem((ULONG)sizeof(RGBData), MEMF_CHIP))
				== NULL) return FALSE;
		ColorRAINImage.ImageData = ColorRGBImage.ImageData + MID_RGB_AIN;
		/* Copy the data */
		for (i=0; i< sizeof(RGBData)/sizeof(RGBData[0]); i++)
			ColorRGBImage.ImageData[i] = RGBData[i];
	}

	ColorNewWindow.Screen = w->WScreen;
	ColorNewWindow.Type = w->WScreen->Flags & SCREENTYPE;
	ColorNewWindow.IDCMPFlags = NULL;
	ColorNewWindow.FirstGadget
	    = &ColorTemplateGadgets[COLOR_GADGETS_COUNT - 1];
	ColorTemplateGadgets[COLOR_COPY].NextGadget = 
		&ColorTemplateGadgets[MaxColor];

	if (ColorNewWindow.LeftEdge+ColorNewWindow.Width > w->WScreen->Width) {
		ColorNewWindow.LeftEdge = DEFAULT_WINDOW_LEFT;
	}
	if (ColorNewWindow.TopEdge+ColorNewWindow.Height > w->WScreen->Height) {
		ColorNewWindow.TopEdge = DEFAULT_WINDOW_TOP;
	}
	CurrentColor = 0;
	SetColorProps();
	InitSuperColors();

	if ((ColorWindow = (struct Window *)OpenWindow(&ColorNewWindow)) == NULL) {
		/* fputs("no memory!\n", console); */
		return FALSE;
	}
	ColorWindow->UserPort = w->UserPort;
	ModifyIDCMP(ColorWindow, COLOR_IDCMP_FLAGS);

	DrawColorWindow();

	return TRUE;
}


STATIC VOID CloseColorWindow(accept)
BOOL accept;
{
	/* register LONG i; */

	if (ColorWindow == NULL) return;

	/* ClearMenuStrip(ColorWindow); */
	ColorNewWindow.LeftEdge = ColorWindow->LeftEdge;
	ColorNewWindow.TopEdge = ColorWindow->TopEdge;

	/* ColorWindow->UserPort = NULL; */
	/* CloseWindow(ColorWindow); */
	CloseWindowSafely(ColorWindow);
	ColorWindow = NULL;

	/* Return the allocated CHIP memory */
	if (ColorRGBImage.ImageData != &RGBData) {
#ifdef DEBUG2
		fprintf(stderr,"Freeing CHIP mem of RGBData\n");
#endif
		FreeMem(ColorRGBImage.ImageData, (ULONG)sizeof(RGBData));
	}

	if (NOT accept) LoadRGB4(vp, &SavePalette[0], MaxColor + 1L);
	else
	{
	/*  color_set = 2;
	 *	Color0 = GetRGB4(vp->ColorMap, 0L);
	 *	Color1 = GetRGB4(vp->ColorMap, 1L);
	 *	Color2 = GetRGB4(vp->ColorMap, 2L);
	 *	for (i = 2; i < NUMCOL; i++)
	 *	{
	 *		if (i == 2) *(color_table) = GetRGB4(vp->ColorMap, 2L);
	 *		else *(color_table + color_offset + (i - 2) * color_inc) 
	 *		    = GetRGB4(vp->ColorMap, i);
	 *	}
	 */
	}
}


STATIC VOID ColorRange(first, last)
SHORT first, last;
{
	USHORT i;
	LONG whole, redfraction, greenfraction, bluefraction;
	USHORT rgb;
	SHORT firstred, firstgreen, firstblue;
	SHORT lastred, lastgreen, lastblue;
	SHORT workred, workgreen, workblue;

	if (first > last) {
		i = first;
		first = last;
		last = i;
	}

	/* I need to see a spread of at least two, where there's at least one
     * spot between the endpoints, else there's no work to do so I
     * might as well just return now.
     */
	if (first >= last - 1) return;

	rgb = GetRGB4(vp->ColorMap, (ULONG) first);
	firstred = (rgb >> 8) & 0xF;
	firstgreen = (rgb >> 4) & 0xF;
	firstblue = (rgb >> 0) & 0xF;

	rgb = GetRGB4(vp->ColorMap, (ULONG) last);
	lastred = (rgb >> 8) & 0xF;
	lastgreen = (rgb >> 4) & 0xF;
	lastblue = (rgb >> 0) & 0xF;

	whole = ((LONG) lastred - firstred) << 16;
	redfraction = whole / (last - first);
	whole = ((LONG) lastgreen - firstgreen) << 16;
	greenfraction = whole / (last - first);
	whole = ((LONG) lastblue - firstblue) << 16;
	bluefraction = whole / (last - first);

	for (i = first + 1; i < last; i++) {
		lastred = (redfraction * (i - first) + ONE_HALF) >> 16;
		workred = firstred + lastred;
		lastgreen = (greenfraction * (i - first) + ONE_HALF) >> 16;
		workgreen = firstgreen + lastgreen;
		lastblue = (bluefraction * (i - first) + ONE_HALF) >> 16;
		workblue = firstblue + lastblue;
		SetRGB4(vp, (ULONG) i, (ULONG) workred, (ULONG) workgreen,
			(ULONG) workblue);
	}
}


STATIC BOOL ColorGadgetGotten(gadget)
struct Gadget *gadget;
{
	ULONG rgb, pen;
	struct RastPort *RPort;
	SHORT green, red, blue;

	RPort = ColorWindow->RPort;

	/* Have we got a color specifier? */
	if (NOT RainbowMode && gadget->GadgetID <= MaxColor) {
		/* Yes, it's a color gadget.  Set this pen number */
		pen = gadget->GadgetID;
		/* First, were we in COPY COLOR mode? */
		if (ColorMode == COPYCOLOR) {
			/* Ok, copy old color here first! */
			rgb = GetRGB4(vp->ColorMap, (ULONG) CurrentColor);
			SetRGB4(vp, pen, rgb >> 8, rgb >> 4, rgb);
			ColorMode = NULL;
		}
		else if (ColorMode == RANGE_FIRST) {
			ColorMode = RANGE_SECOND;
			RangeFirst = pen;
		}
		else if (ColorMode == RANGE_SECOND) {
			ColorMode = NULL;
			ColorRange(RangeFirst, (SHORT) pen);
		}
		CurrentColor = pen;
		ColorRectFill(RPort, (SHORT) pen);

		red = RemoveGadget(ColorWindow, &ColorTemplateGadgets[COLOR_RED]);
		green = RemoveGadget(ColorWindow,&ColorTemplateGadgets[COLOR_GREEN]);
		blue = RemoveGadget(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE]);
		SetColorProps();
		AddGadget(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE], 
			(LONG) blue);
		AddGadget(ColorWindow, &ColorTemplateGadgets[COLOR_GREEN], 
			(LONG) green);
		AddGadget(ColorWindow, &ColorTemplateGadgets[COLOR_RED], 
			(LONG) red);
		RefreshGadgets(&ColorTemplateGadgets[COLOR_GADGETS_COUNT - 1], 
			ColorWindow);
	}

	else if (RainbowMode && gadget->GadgetID <= MaxColor) {
		/* Yes, it's a color gadget.  Get its old color back. */
		pen = gadget->GadgetID;
		red   = (SavePalette[pen] & 0xF00) >> 8;
		green = (SavePalette[pen] & 0x0F0) >> 4;
		blue  = (SavePalette[pen] & 0x00F) >> 0;
		SetRGB4(vp, pen, (LONG) red, (LONG) green, (LONG) blue);
	}

	else switch (gadget->GadgetID) {
	case COLOR_OK:
		CloseColorWindow((BOOL) TRUE);
		return FALSE;
		break;
	case COLOR_CANCEL:
		CloseColorWindow((BOOL) FALSE);
		return FALSE;
		break;
	case COLOR_COPY:
		if (RainbowMode) { /* Gadget now has an alternate meaning */
			if (++RainbowDistance > RAIN_MAX_DISTANCE)
				RainbowDistance = RAIN_MAX_DISTANCE;
			RRMax = -2;		/* Force color updating */
			ModifyColors();
		}
		else ColorMode = COPYCOLOR;
		break;
	case COLOR_RANGE:
		if (RainbowMode) {
			if (--RainbowDistance < RAIN_MIN_DISTANCE)
				RainbowDistance = RAIN_MIN_DISTANCE;
			RRMax = -3;		/* Force color updating */
			ModifyColors();
		}
		else ColorMode = RANGE_FIRST;
		break;
	case COLOR_AIN_RGB:
		/* blue = RemoveGList(ColorWindow,
			&ColorTemplateGadgets[COLOR_BLUE], 3L); */
		red = RemoveGadget(ColorWindow, &ColorTemplateGadgets[COLOR_RED]);
		green = RemoveGadget(ColorWindow,&ColorTemplateGadgets[COLOR_GREEN]);
		blue = RemoveGadget(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE]);
		if (gadget->Flags & SELECTED) { /* We want Rainbow Mode */
			RainbowMode = TRUE;
			ColorTemplateGadgets[COLOR_COPY].GadgetText = &LessMoreText;
			ColorTemplateGadgets[COLOR_RANGE].GadgetText = &MoreLessText;
			RRMax = -4;		/* Force color updating */
			SetColorProps();
			ModifyColors();
		} else { /* We want our normal RGB mode back */
			RainbowMode = FALSE;
			ColorTemplateGadgets[COLOR_COPY].GadgetText =
				&ColorClusterText[0];
			ColorTemplateGadgets[COLOR_RANGE].GadgetText =
				&ColorClusterText[1];
			SetColorProps();
		}
		/* AddGList(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE], 
			(LONG) blue, 3L, NULL); */
		AddGadget(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE], 
			(LONG) blue);
		AddGadget(ColorWindow, &ColorTemplateGadgets[COLOR_GREEN], 
			(LONG) green);
		AddGadget(ColorWindow, &ColorTemplateGadgets[COLOR_RED], 
			(LONG) red);
		RefreshGadgets(&ColorTemplateGadgets[COLOR_GADGETS_COUNT - 1], 
			ColorWindow);
		break;

	}
	return TRUE;
}

SHORT mod(a,b)
SHORT a,b;
{
	if (a < 0) 	return a+b;
	if (a >= b)	return a-b;
	return a;
}

STATIC ModifyColors()
{
	ULONG newred, newgreen, newblue;

	newred = ((struct PropInfo *)
		ColorTemplateGadgets[COLOR_RED].SpecialInfo)->HorizPot;
	newgreen = ((struct PropInfo *)
		ColorTemplateGadgets[COLOR_GREEN].SpecialInfo)->HorizPot;
	newblue = ((struct PropInfo *)
		ColorTemplateGadgets[COLOR_BLUE].SpecialInfo)->HorizPot;

	if (RainbowMode) {
		USHORT NewPalette[MAXCOL];
		SHORT i;
		SHORT distance;

		for (i=0; i<MAXCOL; i++)	NewPalette[i] = 0;
		NewPalette[0] = GetRGB4(vp->ColorMap, 0L);
		RainbowRMax = (newred * MaxColor + ONE_HALF) >> 16;
		RainbowGMax = (newgreen * MaxColor + ONE_HALF) >> 16;
		RainbowBMax = (newblue * MaxColor + ONE_HALF) >> 16;

		if (RainbowRMax == RRMax && RainbowGMax == RGMax && 
				RainbowBMax == RBMax) return;

#ifdef DEBUG2
		fprintf(stderr, "ModifyColors: d/r/g/b = %d %d %d %d\n",
			RainbowDistance,
			RainbowRMax,
			RainbowGMax,
			RainbowBMax);
#endif

		RRMax = RainbowRMax;
		RGMax = RainbowGMax;
		RBMax = RainbowBMax;

		for (distance=0; distance < RainbowDistance; distance++) {
			i = 15 - (16.0 * ((float) distance / RainbowDistance)) + 0.5;
			/* i = 15 - ((distance<<16)/RainbowDistance + (1<<11)) >> 12; */
			if (i < 0)	i = 0;

			NewPalette[1 + mod(RainbowBMax + distance, MaxColor)] |= i;
			NewPalette[1 + mod(RainbowBMax - distance, MaxColor)] |= i;
			i <<= 4;
			NewPalette[1 + mod(RainbowGMax + distance, MaxColor)] |= i;
			NewPalette[1 + mod(RainbowGMax - distance, MaxColor)] |= i;
			i <<= 4;
			NewPalette[1 + mod(RainbowRMax + distance, MaxColor)] |= i;
			NewPalette[1 + mod(RainbowRMax - distance, MaxColor)] |= i;
		}

		LoadRGB4(vp, &NewPalette[0], MaxColor + 1L);
	} else { /* Normal RGB mode */
		SetRGB4(vp, (ULONG) CurrentColor, newred >> 12, newgreen >> 12,
			newblue >> 12);
	}
}



STATIC DrawColorWindow()
{
	struct RastPort *RPort;

	RPort = ColorWindow->RPort;

	ColorRectFill(RPort, CurrentColor);
	SetAPen(RPort, 1L);
	SetDrMd(RPort, JAM1);

	/* Border around ColorBox */
	RectDraw(RPort, (SHORT) (COLOR_BOX_LEFT-2), (SHORT) (COLOR_BOX_TOP-2), 
		(SHORT) (COLOR_BOX_RIGHT+2), (SHORT) (COLOR_BOX_BOTTOM+2));
	/* Border around ColorTemplateGadgets */
	RectDraw(RPort, (SHORT) (COLOR_BOX_LEFT-2), (SHORT) (COLOR_COLOR_TOP-2), 
		(SHORT) (COLOR_BOX_LEFT+((MIN(MaxColor+1,8)*COLOR_COLOR_WIDTH)+1)),
		(SHORT) (COLOR_COLOR_TOP+(((MaxColor+8)/8)*COLOR_COLOR_HEIGHT)+1));
}



STATIC SetColorProps()
{
	ULONG rgb, red, green, blue;

	if (RainbowMode) {
		red   = ((ULONG) RainbowRMax << 16) / MaxColor;
		green = ((ULONG) RainbowGMax << 16) / MaxColor;
		blue  = ((ULONG) RainbowBMax << 16) / MaxColor;
	} else {
		rgb = GetRGB4(vp->ColorMap, (ULONG) CurrentColor);
		red   = (rgb & 0xF00) << 4  | (rgb & 0xF00) << 0;
		green = (rgb & 0x0F0) << 8  | (rgb & 0x0F0) << 4;
		blue  = (rgb & 0x00F) << 12 | (rgb & 0x00F) << 8;
	}

	((struct PropInfo *)ColorTemplateGadgets[COLOR_RED]
	    .SpecialInfo)->HorizPot
	    = red;
	((struct PropInfo *)ColorTemplateGadgets[COLOR_GREEN]
	    .SpecialInfo)->HorizPot
	    = green;
	((struct PropInfo *)ColorTemplateGadgets[COLOR_BLUE]
	    .SpecialInfo)->HorizPot
	    = blue;
}


STATIC ColorRectFill(RPort, pen)
struct RastPort *RPort;
SHORT pen;
{
	SetAPen(RPort, (ULONG) pen);
	SetDrMd(RPort, (ULONG) JAM2);
	WaitBOVP(vp);
	RectFill(RPort, (ULONG) COLOR_BOX_LEFT, (ULONG) COLOR_BOX_TOP, 
		(ULONG) COLOR_BOX_RIGHT, (ULONG) COLOR_BOX_BOTTOM);
}


void Palette(w) /* DoColorWindow() */
struct Window *w;
{
	struct IntuiMessage *message;
	ULONG class;
	struct Gadget *gadget;

	if (NOT OpenColorWindow(w)) return;

	FOREVER {
		Wait( 1L << ColorWindow->UserPort->mp_SigBit );
		while (message = (struct IntuiMessage *)
			GetMsg(ColorWindow->UserPort)) {
			class = message->Class;
			gadget = (struct Gadget *)(message->IAddress);
			ReplyMsg(message);

			switch (class) {
			case GADGETDOWN:
			case GADGETUP:
				if (ColorGadgetGotten(gadget) == FALSE) return; 
				break;
			case MOUSEMOVE:
				ModifyColors();
				break;
			}
		}
	}
}


STATIC InitSuperColors()
{
	SHORT i;

	/* OK, initialize those Super Color Gadgets! */
	for (i = 0; i < MAXCOL; i++)
	{
		SuperColorImages[i].LeftEdge = 0;
		SuperColorImages[i].TopEdge = 0;
		SuperColorImages[i].Width = COLOR_COLOR_WIDTH;
		SuperColorImages[i].Height = 10;
		SuperColorImages[i].Depth = 0;
		SuperColorImages[i].ImageData = NULL;
		SuperColorImages[i].PlanePick = 0;
		SuperColorImages[i].PlaneOnOff = i;
		SuperColorImages[i].NextImage = NULL;
	}
}
