#import "MandleController.h"


@implementation MandleController


- (id)init

{

[super init];

xmin = -2.5;

xmax = 0.5;

ymin = -1.5;

ymax = 1.5;

xres = 500;

yres = 500;

maxiters = 1000;

span = 1.0;

bitImageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil 

  pixelsWide:500 

  pixelsHigh:500 

  bitsPerSample:8 

samplesPerPixel:3 

hasAlpha:NO 

isPlanar:NO 

  colorSpaceName:NSCalibratedRGBColorSpace 

bitmapFormat:NSAlphaFirstBitmapFormat 

bytesPerRow:1500 bitsPerPixel:24];

NSSize size;

size.height=500.0;

size.width=500.0;

image = [[NSImage alloc] initWithSize:size];

return self;

}


- (void)awakeFromNib

{

NSLog(@"Awake from Nib called.");

[[imageView window] setDelegate:self];

[xMinField setFloatValue:xmin];

[xMaxField setFloatValue:xmax];

[yMinField setFloatValue:ymin];

[yMaxField setFloatValue:ymax];

[maxIterField setIntValue:maxiters];

int x,y;

unsigned int pixel[3];

pixel[0]=0;

pixel[1]=0;

pixel[2]=0;

for (x=0; x<500; x++) {

for (y=0; y<500; y++) {

[bitImageRep setPixel:pixel atX:x y:y];

}

}

[image addRepresentation:bitImageRep];

[imageView setImage:image];

}


- (IBAction)go:(id)sender

{

xmin = [xMinField floatValue];

xmax = [xMaxField floatValue];

ymin = [yMinField floatValue];

ymax = [yMaxField floatValue];

maxiters = [maxIterField intValue];

int x,y;

unsigned int pixel[3];

for (x=0; x<500; x++) {

for (y=0; y<500; y++) {

[self setPixel:pixel atX:x atY:y];

[bitImageRep setPixel:pixel atX:x y:y];

}

}

[imageView setNeedsDisplay];

}


- (void)dealloc

{

if (bitImageRep != nil) [bitImageRep release];

[super dealloc];

}


- (unsigned int) mandle:(double) x atY:(double) y

{

double g,h,g2,h2,gt;

g = 0.0;

h = 0.0;

g2 = 0.0;

h2 = 0.0;

unsigned int iter;

for (iter = 0; iter< maxiters; iter++) {

gt = x + g2 - h2;

h = y + (2.0 * g * h);

g = gt;

g2 = g*g;

h2 = h*h;

if (g2 + h2 >= 4.0) return iter;

}

return maxiters;

}


- (void) setPixel:(unsigned int *)color atX:(unsigned int)x atY:(unsigned int)y

{

// Start with the scaling.

unsigned int result = [self mandle:(((xmax-xmin)*x)/(xres*1.0)) + xmin 

  atY:(((ymax-ymin)*y)/(yres*1.0)) + ymin];

if (result==maxiters) {

color[0]=0;

color[1]=0;

color[2]=0;

return;

}

if (result>maxiters-10) {

color[0]=255;

color[1]=0;

color[2]=0;

return;

} 

color[0]=0;

color[1]=(result % 64) * 4;

color[2]=0;

}


- (void) rescale:(NSPoint) point

{

span = span / 2.0;

// Convert point into coordinates in current system.

float centerX = (((xmax-xmin)*point.x)/(xres*1.0)) + xmin;

float centerY = (((ymax-ymin)*(yres-point.y))/(yres*1.0)) + ymin; // don't know how to "flip" appropriately yet.

xmin = centerX - span;

xmax = centerX + span;

ymin = centerY - span;

ymax = centerY + span;

[xMinField setFloatValue:xmin];

[xMaxField setFloatValue:xmax];

[yMinField setFloatValue:ymin];

[yMaxField setFloatValue:ymax];

[self go:nil];

}


@end