
/* Generated by Interface Builder */

#import "AnimView.h"
#import <appkit/NXImage.h>
#import <appkit/Control.h>
#import <appkit/Matrix.h>
#import <dpsclient/psops.h>

@implementation AnimView

- initFrame:(const NXRect *)frm	// initialize instance
{
	[super initFrame:frm];
	cycles = 0;
	frameShown = 0;
	position.y = 0.0;
	position.x = 0.0;
	return self;
}

- loadPix				// gameBrain calls this from appDidInit
{
	[super loadPix];
	runner = [NXImage findImageNamed:IMAGENAME];
	return self;
}

- autoUpdate:sender	// sent by timer
{
	int direction = GODIR;
	int move = MOVEINC;
	
	[super autoUpdate:sender];
	if (!(cycles % UPDATEFREQ)) {
		frameShown++;
		if (frameShown >= NUM_FRAMES) frameShown = 0;
		if (GORIGHT) {
			position.x = position.x + move;
			if (position.x > NX_WIDTH(&bounds) + move) position.x = 0.0;
		} else if (GOLEFT) {
			position.x = position.x - move;
			if (position.x < - (BLOCK_SIZE + move)) position.x = NX_WIDTH(&bounds);
		} else if (GOUP) {
			position.y = position.y + move;
			if (position.y > NX_HEIGHT(&bounds) + move) position.y = 0.0;
		} else if (GODOWN) {
			position.y = position.y - move;
			if (position.y < - (BLOCK_SIZE + move)) position.y = NX_HEIGHT(&bounds);
		} else {
		}
		[self updateSelf:&bounds :1]; 
	}
	return self;
}

- drawSelf:(NXRect *)rects :(int)rectCount  //used by internals for speed
{
	NXRect from = {{frameShown * BLOCK_SIZE, SERIES * BLOCK_SIZE},
		{BLOCK_SIZE, BLOCK_SIZE}};
	
	[super drawSelf:rects :rectCount];
	PSsetgray(0.333);
	NXRectFill(rects);
	[runner composite:NX_SOVER fromRect:&from toPoint:&position];
	return self;
}

- updateSelf:(NXRect *)rects :(int)rectCount  //used by internals for speed
{
	int move = MOVEINC;
	NXRect from = {{frameShown * BLOCK_SIZE, SERIES * BLOCK_SIZE},
		{BLOCK_SIZE, BLOCK_SIZE}};
	NXRect old = {{position.x  - move, position.y - move},
		{BLOCK_SIZE + move * 2, BLOCK_SIZE + move * 2}};
	
	[self lockFocus];
	[super drawSelf:rects :rectCount]; // very inefficient (GameView will splat the
	// whole background!)  Probably OK to comment it out.
	PSsetgray(0.333);
	NXRectFill(&old); // since there is only one object, the DirtPile is overkill and
	// I just use regular NEXTSTEP buffers- they'll flush to the screen the erased
	// area intersected with the newly composited area.  Quite simple, really.  The
	// DirtPile will do this intelligently if you have more objects than one.
	[runner composite:NX_SOVER fromRect:&from toPoint:&position];
	[self unlockFocus];
	[window flushWindow];
	NXPing();  // Only one ping per frame or you'll crawl!
	return self;
}

- changeDist:sender
{
	int val = [sender intValue];
	
	[distText setIntValue:val];
	if (sender != distSlider) [distSlider setIntValue:val];
	return self;
}

@end
