
/* Generated by Interface Builder */

#import "HenonController.h"
#import <appkit/appkit.h>
#import <musickit/musickit.h>


@implementation HenonController

- init
{
	[super init];
	[NXApp loadNibSection:"HenonControl.nib" owner:self withNames:NO];
	[thePanel makeKeyAndOrderFront:self];
	return self;
}

- closeUp
{
	[thePanel close];
	return self;
}

- setUp
{
	X = [sInitValueFields doubleValueAt:0]; 
	Y = [sInitValueFields doubleValueAt:1]; 
	speed = [sSpeedField floatValue];
	duration = [sDurationField floatValue];
	A = [sAField doubleValue];
	B = [sBField doubleValue];
	[self setSoundMode:DSP];
	axisMode = [sAxisButtons selectedTag];
	return self;
}

- setSoundMode:(int)mode
{
	switch (soundMode = mode) {
		case DSP:
			[[sFreqBox setTitle:"Frequency (Hz)"] display];
			[sFreqRangeSlider setMinValue:0.0];
			[sFreqRangeSlider setMaxValue:4000.0];
			[sFreqRangeSlider setFloatValue:500.0];
			[sFreqRangeField setFloatValue:500.0];
			[sFreqCenterSlider setMinValue:0.0];
			[sFreqCenterSlider setMaxValue:4000.0];
			[sFreqCenterSlider setFloatValue:500.0];
			[sFreqCenterField setFloatValue:500.0];
			freqRange = [sFreqRangeField floatValue];
			freqCenter = [sFreqCenterField floatValue];
			[[sAmpBox setTitle:"Amplitude (dB)"] display];
			[sAmpRangeSlider setMinValue:0.0];
			[sAmpRangeSlider setMaxValue:60.0];
			[sAmpRangeSlider setFloatValue:30.0];
			[sAmpRangeField setFloatValue:30.0];
			[sAmpCenterSlider setMinValue:-60.0];
			[sAmpCenterSlider setMaxValue:0.0];
			[sAmpCenterSlider setFloatValue:-20.0];
			[sAmpCenterField setFloatValue:-20.0];
			ampRange = [sAmpRangeField floatValue];
			ampCenter = [sAmpCenterField floatValue];
			break;
		case MIDI:
			[[sFreqBox setTitle:"Key"] display];
			[sFreqRangeSlider setMinValue:0.0];
			[sFreqRangeSlider setMaxValue:127.0];
			[sFreqRangeSlider setFloatValue:64.0];
			[sFreqRangeField setFloatValue:64.0];
			[sFreqCenterSlider setMinValue:0.0];
			[sFreqCenterSlider setMaxValue:127.0];
			[sFreqCenterSlider setFloatValue:64.0];
			[sFreqCenterField setFloatValue:64.0];
			freqRange = [sFreqRangeField floatValue];
			freqCenter = [sFreqCenterField floatValue];
			[[sAmpBox setTitle:"Velocity"] display];
			[sAmpRangeSlider setMinValue:0.0];
			[sAmpRangeSlider setMaxValue:127.0];
			[sAmpRangeSlider setFloatValue:64.0];
			[sAmpRangeField setFloatValue:64.0];
			[sAmpCenterSlider setMinValue:0.0];
			[sAmpCenterSlider setMaxValue:127.0];
			[sAmpCenterSlider setFloatValue:64.0];
			[sAmpCenterField setFloatValue:64.0];
			ampRange = [sAmpRangeField floatValue];
			ampCenter = [sAmpCenterField floatValue];
			break;
		default:
			break;
	}
	return self;
}

- changeInitValue:sender
{
	X = [sender doubleValueAt:0];
	Y = [sender doubleValueAt:1];
    return self;
}

- changeDurationField:sender
{
	duration = [sender floatValue];
	[sDurationSlider setFloatValue:duration];
    return self;
}

- changeSpeedField:sender
{
	speed = [sender floatValue];
	if (speed < 0.01) {
		speed = 0.01;
		[sender setFloatValue:speed];
	}
	[sSpeedSlider setFloatValue:speed];
    return self;
}

- changeFreqCenterField:sender
{
	freqCenter = [sender floatValue];
	[sFreqCenterSlider setFloatValue:freqCenter];
    return self;
}

- changeASlider:sender
{
	A = [sender doubleValue];
	[sAField setDoubleValue:A];
    return self;
}

- changeBSlider:sender
{
	B = [sender doubleValue];
	[sBField setDoubleValue:B];
    return self;
}

- changeFreqRangeField:sender
{
	freqRange = [sender floatValue];
	[sFreqRangeSlider setFloatValue:freqRange];
    return self;
}

- changeAmpCenterField:sender
{
	ampCenter = [sender floatValue];
	[sAmpCenterSlider setFloatValue:ampCenter];
    return self;
}

- changeAField:sender
{
	A = [sender doubleValue];
	[sASlider setDoubleValue:A];
    return self;
}

- changeBField:sender
{
	B = [sender doubleValue];
	[sBSlider setDoubleValue:B];
    return self;
}

- changeAmpRangeField:sender
{
	ampRange = [sender floatValue];
	[sAmpRangeSlider setFloatValue:ampRange];
    return self;
}

- changeAmpRangeSlider:sender
{
	ampRange = [sender floatValue];
	[sAmpRangeField setFloatValue:ampRange];
    return self;
}

- changeFreqRangeSlider:sender
{
	freqRange = [sender floatValue];
	[sFreqRangeField setFloatValue:freqRange];
    return self;
}

- changeAmpCenterSlider:sender
{
	ampCenter = [sender floatValue];
	[sAmpCenterField setIntValue:ampCenter];
    return self;
}

- changeSpeedSlider:sender
{
	speed = [sender floatValue];
	[sSpeedField setFloatValue:speed];
    return self;
}

- changeDurationSlider:sender
{
	duration = [sender floatValue];
	[sDurationField setFloatValue:duration];
    return self;
}

- changeFreqCenterSlider:sender
{
	freqCenter = [sender floatValue];
	[sFreqCenterField setFloatValue:freqCenter];
    return self;
}

- changeAxis:sender
{
	axisMode = [sender selectedTag];
    return self;
}


- iterateFreq:(float *)freq Amp:(float *)amp Dur:(float *)dur Next:(float *)next 
	X:(float *)xpos Y:(float *)ypos
{
	double newX;

	if ((fabs(X) > 3.0) || (fabs(Y) > 1.0)) {
		NXRunAlertPanel("KaBoom!", "Orbit escapes to infinity: resetting.", "OK", 0, 0);
		A = 1.4;
		B = 0.3;
		X = 0.0;
		Y = 0.0;
		[sAField setDoubleValue:A];
		[sASlider setDoubleValue:A];
		[sBField setDoubleValue:B];
		[sBSlider setDoubleValue:B];
		[sInitValueFields setDoubleValue:X at:0];
		[sInitValueFields setDoubleValue:Y at:0];
	}

	*xpos = (X + 1.5) / 3.0;
	*ypos = (Y + 0.5);

	switch (axisMode) {
		case XY:
			*freq = ((X / 3.0) * freqRange) + freqCenter;
			*amp = (Y * ampRange) + ampCenter;
			break;
		case YX:
			*freq = (Y * freqRange) + freqCenter;
			*amp = ((X / 3.0) * ampRange) + ampCenter;
			break;
	}
	*dur = duration;
	*next = speed;

	newX = Y + 1.0 - (A * X * X);
	Y = B * X;
	X = newX;

	return self;
}

@end

