#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;
SHORT RRMax = -1, RGMax = -1, RBMax = -1;


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

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

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

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

    if (ColorWindow) {
	WindowToFront(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 = (w->WScreen->Width-ColorNewWindow.Width) / 2;
    }
    if (ColorNewWindow.TopEdge+ColorNewWindow.Height > w->WScreen->Height) {
	ColorNewWindow.TopEdge = (w->WScreen->Height-ColorNewWindow.Height) / 2;
    }
    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;
}


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);
}


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;
}

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);
}

#ifdef notdef

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;
	    }
	}
    }
}

#else

void HandleColorWindow(message)
struct IntuiMessage *message;
{
    ULONG class;
    struct Gadget *gadget;

    class = message->Class;
    gadget = (struct Gadget *)(message->IAddress);
    ReplyMsg(message);

    if (ColorWindow == NULL)
	return;

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

#endif

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;
    }
}
