//
// SpheresView.m
//
// Matt Pharr- pharr@cs.yale.edu
//

#import "SpheresView.h"
#import "SpheresWrap.c"
#import <appkit/graphics.h>
#import <dpsclient/wraps.h>
#import <libc.h>
#import <stdlib.h>

#define MAXSIZE					125

@implementation SpheresView

- oneStep
{
  float red= 0.0, green= 0.0, blue= 0.0;
	float color= 0.0;
	NXPoint position;
	NXPoint hilight;
	int radius= 100;
	float dx= 0.0, dy= 0.0;
	float dcolor= 0.0;
	float dred= 0.0, dgreen= 0.0, dblue= 0.0;
	
	if (++nDrawn >= 75) {
		usleep(1000000);
		nDrawn= 0;
		PSsetgray(0.0);
		NXRectFill(&bounds);
	}
	
	// decide where to put the sphere after we draw it..
	position.x= (int)randBetween(bounds.origin.x - MAXSIZE / 2, 
															 bounds.origin.x + bounds.size.width - MAXSIZE/2);
	position.y= (int)randBetween(bounds.origin.y - MAXSIZE / 2, 
															 bounds.origin.y + bounds.size.height - MAXSIZE/2);

	radius= (int)randBetween(30, MAXSIZE);

	// where to put the hilight on the sphere- always in the same relative
	// place	
	hilight.x= .4 * radius;
	hilight.y= .6 * radius;

	// distance by which we need to move each time when drawing the big highlight.
	// basically what we do is start at the position of the hilight and draw a little
	// circle that is all white there. Then we move out away from there and draw
	// bigger and bigger circles that become darker and darker, until they hit the
	// color we pick for the sphere below. This gives us the 3-d shading effect.
	// Actually, though, we do the above in reverse, so as not to draw over the 
	// circles- we're actually drawing smaller and smaller concentric, filled circles.
	// N.B. there's probably a more efficient way to do this...
	
	dx= hilight.x / radius;
	dy= hilight.y / radius;

  if ([Window defaultDepthLimit] == NX_TwoBitGrayDepth) {
     // Black And White Machines
		 color= randBetween(0.0, .4);
		 dcolor= (1 - color) / radius;
  }
	
  else { 
		red= randBetween(0.0, .4);
		dred= (1 - red) / radius;
		
		green= randBetween(0.0, .4);
		dgreen= (1 - green) / radius;

		blue= randBetween(0.0, .4);
		dblue= (1 - blue) / radius;
 }

	NXRectClip(&bounds);					// need to do this for when it's done in a window...
	
	PStranslate(position.x, position.y);
		
	if ([Window defaultDepthLimit] == NX_TwoBitGrayDepth) {
		// draw a sphere in black and white...
		drawSphereBW(color, radius, dcolor, dx, dy, MAXSIZE);
	}
	else {
		// or in color...
		drawSphereCL(red, green, blue, radius, dred, dgreen, dblue, dx, dy, MAXSIZE);
	}
			
	PStranslate(-position.x, -position.y);

  return self;
}


- initFrame:(const NXRect *)frameRect
{
  [super initFrame:frameRect];
	
	nDrawn= 0;
	
	return self;
}


- drawSelf:(const NXRect *)rects :(int)rectCount
{
  if (!rects || !rectCount) {
    return self;
  }

  PSsetgray(0.0);
  NXRectFill(rects);

  return self;
}


- (const char *)windowTitle
{
	return "Spheres";
}


@end

