#include <exec/memory.h>
#include <dos/dos.h>
#include <intuition/intuition.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/alib_protos.h>

#include "Species.h"
#include "//defs.h"
#include "/main.h"

struct ModulePrefs
{
	LONG Mode;
	LONG Size;
};

extern __far WORD RangeSeed;
extern struct ModulePrefs nP;

UWORD Table4[] = {
	0x0000, 0x0B06, 0x0909, 0x060B,
	0x030E, 0x003E, 0x006B, 0x0099,
	0x00B6, 0x00E3, 0x03E0, 0x06B0,
	0x0990, 0x0B60, 0x0E30, 0x0E03
	};

#ifndef min
#define min( x, y ) ( x < y ? x : y )
#endif

#define BLANKMOUSE
#include "/utility.c"

LONG Blank( VOID *Prefs )
{
	LONG i, j, hei, wid, size, stable, side, offx, offy, iter = 0;
	LONG *Phase[2], Cur = 0, Pos, Species, Parent, Width, Height, RetVal = OK;
	struct ModulePrefs *mP;
	struct Screen *Scr;
	
	if( SpeciesWnd )
		mP = &nP;
	else
		mP = ( struct ModulePrefs * )Prefs;

	CurrentTime(( ULONG * )&offx, ( ULONG * )&offy );
	RangeSeed = ( WORD )( offx + offy );

	Scr = OpenScreenTags( 0L, SA_DisplayID, mP->Mode, SA_Depth, 4, SA_Overscan, OSCAN_STANDARD,
						 SA_Quiet, TRUE, TAG_DONE );
	if( Scr )
	{
		LoadRGB4( &Scr->ViewPort, Table4, 16 );
		Width = Scr->Width;
		Height = Scr->Height;
		hei = Height / mP->Size;
		wid = Width / mP->Size;
		size = wid * hei;
		side = Height / hei;
		offx = ( Width - side * wid ) / 2;
		offy = ( Height - side * hei ) / 2;

		Phase[0] = AllocVec( sizeof( LONG ) * size, MEMF_ANY );
		Phase[1] = AllocVec( sizeof( LONG ) * size, MEMF_ANY );

		if( Phase[0] && Phase[1] )
		{
			BlankMousePointer( Scr );
			ScreenToFront( Scr );

			while( RetVal == OK )
			{
				for( j = 0; ( j < hei )&&( RetVal == OK ); j++ )
				{
					for( i = 0; i < wid; i++ )
					{
						Pos = j * hei + i;
						Phase[1-Cur][Pos] = Phase[Cur][Pos] = RangeRand( 15 ) + 1;
						SetAPen( &Scr->RastPort, Phase[Cur][Pos] );
						RectFill( &Scr->RastPort, offx + side * i, offy + side * j,
								 offx + side * i + side - 2, offy + side * j + side - 2 );
						if(!( Pos % 200 ))
							if(( RetVal = ContinueBlanking()) != OK )
								break;
					}
				}	
				stable = FALSE;
				while( !stable &&( RetVal == OK ))
				{
					stable = TRUE;
					CopyMemQuick( Phase[Cur], Phase[1-Cur], size );
					for( j = 0; ( j < hei )&&( RetVal == OK ); j++ )
					{
						for( i = 0; i < wid; i++ )
						{
							Pos = j * hei + i;
							Species = Phase[Cur][Pos];
							if( Species == 15 )
								Parent = 1;
							else
								Parent = Species + 1;
							if(( Phase[Cur][j*hei+((i+wid-1)%wid)] == Parent )||  /*  Left */
							   ( Phase[Cur][j*hei+((i+1)%wid)] == Parent )||      /* Right */
							   ( Phase[Cur][((j+hei-1)%hei)*hei+i] == Parent )||  /*    Up */
							   ( Phase[Cur][((j+1)%hei)*hei+i] == Parent ))       /*  Down */
							{
								SetAPen( &Scr->RastPort, Phase[1-Cur][Pos] = Parent );
								RectFill( &Scr->RastPort, offx + side * i, offy + side * j,
										 offx + side * i + side - 2, offy + side * j + side - 2 );
								stable = FALSE;
							}
							if(!( Pos % 200 ))
								if(( RetVal = ContinueBlanking()) != OK )
									break;
						}
					}
					Cur = 1 - Cur;
					if(!( ++iter % (size/4) ))
						stable = TRUE;
				}
			}
			UnblankMousePointer();
		}
		else
			RetVal = FAILED;

		if( Phase[0] )
			FreeVec( Phase[0] );
		if( Phase[1] )
			FreeVec( Phase[1] );	
		CloseScreen( Scr );
	}
	else
		RetVal = FAILED;

	return RetVal;
}
