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

#include <intuition/intuition.h>
#include <intuition/screens.h>

#include <graphics/gfx.h>
#include <dos/dos.h>

#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/alib_protos.h>

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

#define STEP_DIVS pP->Divisions
#define STEP_DELAY pP->Delay

struct ModulePrefs
{
	LONG Horiz;
	LONG Vert;
	LONG Divisions;
	LONG Delay;
};

typedef struct _mPoint
{
	LONG x;
	LONG y;
} mPoint;

extern struct ModulePrefs nP;

#define UP	0
#define DOWN	1
#define LEFT	2
#define RIGHT	3

#define BLANKMOUSE
#define CLONETOPSCREEN
#include "/utility.c"

LONG getNewDir( LONG x, LONG y, LONG xmax, LONG ymax, LONG olddir )
{
	LONG dir, a1[] = { UP, DOWN, LEFT, RIGHT }, a2[] = { DOWN, UP, RIGHT, LEFT };
	
	do
	{
		dir = RangeRand(4 );
		if( !x && dir == RIGHT )
			dir = LEFT;
		if( !y && dir == DOWN )
			dir = UP;
		if( x > xmax && dir == LEFT )
			dir = RIGHT;
		if( y > ymax && dir == UP )
			dir = DOWN;
	}
	while( a1[dir] == a2[olddir] );
	
	return dir;
}

LONG Blank( VOID *Prefs )
{
	struct ModulePrefs *pP;
	struct Screen *PScr;
	struct RastPort *Rast;
	mPoint c = { 0, 0 }, n = { 0, 0 }, t;
	LONG i, dir = UP, xmax, ymax, wid, hei, Width, Height, RetVal = OK, ToFrontCount = 0;
	
	if( PuzzleWnd )
		pP = &nP;
	else
		pP = ( struct ModulePrefs * )Prefs;
	
	if( PScr = cloneTopScreen( FALSE ))
	{
		Rast = &( PScr->RastPort );
		Width = PScr->Width;
		Height = PScr->Height;
		wid = Width / pP->Horiz;
		hei = Height / pP->Vert;
		
		SetAPen( Rast, 2 );
		for( i = 0; i < Width; i += wid )
		{
			Move( Rast, i, 0 );
			Draw( Rast, i, Height-1 );
		}
		for( i = 0; i < Height; i += hei )
		{
			Move( Rast, 0, i );
			Draw( Rast, Width-1, i );
		}
		
		SetAPen( Rast, 1 );
		for( i = wid-1; i < Width; i += wid )
		{
			Move( Rast, i, 0 );
			Draw( Rast, i, Height-1 );
		}
		for( i = hei-1; i < Height; i += hei )
		{
			Move( Rast, 0, i );
			Draw( Rast, Width-1, i );
		}
		
		xmax = Width - 2 * wid;
		ymax = Height - 2 * hei;
		
		SetAPen( Rast, 3 );
		
		BlankMousePointer( PScr );
		
		while( RetVal == OK )
		{
			LONG step, i;

			if(!( ++ToFrontCount % 60 ))
				ScreenToFront( PScr );
			
			switch( dir = getNewDir( c.x, c.y, xmax, ymax, dir ))
			{
			case UP:
				n.y += hei;
				t = n;
				step = ( n.y - c.y ) / STEP_DIVS;
				do
				{
					if( step > t.y - c.y )
						step = t.y - c.y;
					t.y -= step;
					for( i = 0; i < STEP_DELAY; i++ )
						WaitTOF();
					BltBitMap( Rast->BitMap, t.x, t.y + step, Rast->BitMap, t.x, t.y, wid, hei,
							  0xC0, 0xFF, 0L );
					RectFill( Rast, t.x, t.y + hei, t.x + wid - 1, t.y + hei + step - 1 );
					if(( RetVal = ContinueBlanking() ) != OK )
						break;
				}
				while( t.y > c.y );
				break;
			case DOWN:
				n.y -= hei;
				t = n;
				step = ( c.y - n.y ) / STEP_DIVS;
				do
				{
					if( step > c.y - t.y )
						step = c.y - t.y;
					t.y += step;
					for( i = 0; i < STEP_DELAY; i++ )
						WaitTOF();
					BltBitMap( Rast->BitMap, t.x, t.y - step, Rast->BitMap, t.x, t.y, wid, hei,
							  0xC0, 0xFF, 0L );
					RectFill( Rast, t.x, t.y - step, t.x + wid - 1, t.y - 1 );
					if(( RetVal = ContinueBlanking() ) != OK )
						break;
				}
				while( t.y < c.y );
				break;
			case LEFT:
				n.x += wid;
				t = n;
				step = ( n.x - c.x ) / STEP_DIVS;
				do
				{
					if( step > t.x - c.x )
						step = t.x - c.x;
					t.x -= step;
					for( i = 0; i < STEP_DELAY; i++ )
						WaitTOF();
					BltBitMap( Rast->BitMap, t.x + step, t.y, Rast->BitMap, t.x, t.y, wid, hei,
							  0xC0, 0xFF, 0L );
					RectFill( Rast, t.x + wid, t.y, t.x + wid + step - 1, t.y + hei - 1 );
					if(( RetVal = ContinueBlanking() ) != OK )
						break;
				}
				while( t.x > c.x );
				break;
			case RIGHT:
				n.x -= wid;
				t = n;
				step = ( c.x - n.x ) / STEP_DIVS;
				do
				{
					if( step > c.x - t.x )
						step = c.x - t.x;
					t.x += step;
					for( i = 0; i < STEP_DELAY; i++ )
						WaitTOF();
					BltBitMap( Rast->BitMap, t.x - step, t.y, Rast->BitMap, t.x, t.y, wid, hei,
							  0xC0, 0xFF, 0L );
					RectFill( Rast, t.x - step, t.y, t.x - 1, t.y + hei - 1 );
					if(( RetVal = ContinueBlanking() ) != OK )
						break;
				}
				while( t.x < c.x );
				break;
			}

			c = n;

			if( RetVal == OK )
				RetVal = ContinueBlanking();
			WaitTOF();
		}
		
		UnblankMousePointer();
		closeTopScreen( PScr );
	}
	else
		RetVal = FAILED;
		
	return RetVal;
}
