#import "PhidgetMotorController.h"

CPhidgetMotorControlHandle motor;

@implementation PhidgetMotorController

- (IBAction)accel0:(id)sender
{
	CPhidgetMotorControl_setAcceleration(motor,0,[sender floatValue]);
	[setAccel0Field setStringValue:[NSString stringWithFormat:@"%0.1f", [sender floatValue]]];
}

- (IBAction)accel1:(id)sender
{
	CPhidgetMotorControl_setAcceleration(motor,1,[sender floatValue]);
	[setAccel1Field setStringValue:[NSString stringWithFormat:@"%0.1f", [sender floatValue]]];
}

- (IBAction)speed0:(id)sender
{
	CPhidgetMotorControl_setVelocity(motor,0,[sender floatValue]);
	[setSpeed0Field setStringValue:[NSString stringWithFormat:@"%0.1f", [sender floatValue]]];
}

- (IBAction)speed1:(id)sender
{
	CPhidgetMotorControl_setVelocity(motor,1,[sender floatValue]);
	[setSpeed1Field setStringValue:[NSString stringWithFormat:@"%0.1f", [sender floatValue]]];
}


int gotAttach(CPhidgetHandle phid, void *context) {
	[(id)context phidgetAdded];
	return 0;
}

int gotDetach(CPhidgetHandle phid, void *context) {
	[(id)context phidgetRemoved];
	return 0;
}

int gotInputChange(CPhidgetMotorControlHandle phid, void *context, int ind, int val) {
	[(id)context InputChange:ind:val];
	return 0;
}

int gotMotorChange(CPhidgetMotorControlHandle phid, void *context, int ind, double val) {
	[(id)context MotorChange:ind:val];
	return 0;
}

int gotCurrentChange(CPhidgetMotorControlHandle phid, void *context, int ind, double val) {
	[(id)context CurrentChange:ind:val];
	return 0;
}

- (void)phidgetAdded
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	
	int serial, version;
	int numMotors, numInputs;
	const char *name;
	CPhidget_DeviceID devid;
	int heightChange;
	double maxAccel, minAccel;
	
	CPhidget_getSerialNumber((CPhidgetHandle)motor, &serial);
	CPhidget_getDeviceVersion((CPhidgetHandle)motor, &version);
	CPhidget_getDeviceName((CPhidgetHandle)motor, &name);
	CPhidget_getDeviceID((CPhidgetHandle)motor, &devid);
	CPhidgetMotorControl_getInputCount(motor, &numInputs);
	CPhidgetMotorControl_getMotorCount(motor, &numMotors);
	CPhidgetMotorControl_getAccelerationMax(motor, 0, &maxAccel);
	CPhidgetMotorControl_getAccelerationMin(motor, 0, &minAccel);
	
	[connectedField setStringValue:[NSString stringWithCString:name]];
	[serialField setIntValue:serial];
	[versionField setIntValue:version];
	[numInputsField setIntValue:numInputs];
	[numMotorsField setIntValue:numMotors];
	
	[accel0Slider setMaxValue:maxAccel];
	[accel0Slider setMinValue:minAccel];
	[accel1Slider setMaxValue:maxAccel];
	[accel1Slider setMinValue:minAccel];
	
	NSRect frame = [mainWindow frame];
	
	switch(devid)
	{
		case PHIDID_MOTORCONTROL_HC_2MOTOR:
			heightChange = frame.size.height - 407;
			[inputBox setHidden:TRUE];
			[current0Field setHidden:FALSE];
			[current1Field setHidden:FALSE];
			[current0Slider setHidden:FALSE];
			[current1Slider setHidden:FALSE];
			[currentLabel setHidden:FALSE];
			break;
		case PHIDID_MOTORCONTROL_LV_2MOTOR_4INPUT:
			heightChange = frame.size.height - 471;
			[inputBox setHidden:FALSE];
			[current0Field setHidden:TRUE];
			[current1Field setHidden:TRUE];
			[current0Slider setHidden:TRUE];
			[current1Slider setHidden:TRUE];
			[currentLabel setHidden:TRUE];
			break;
		default:
			break;
	}
	
	[motorsetBox setHidden:FALSE];
	[motorstateBox setHidden:FALSE];
	
	frame.origin.y += heightChange;
	frame.size.height -= heightChange;
	[mainWindow setMinSize:frame.size];
	[mainWindow setFrame:frame display:YES animate:NO];
	
	[self setPicture:version:devid];
	[pool release];
	[mainWindow display];
}

- (void)phidgetRemoved
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	[connectedField setStringValue:@"Nothing"];
	[serialField setStringValue:@""];
	[versionField setStringValue:@""];
	[numInputsField setStringValue:@""];
	[numMotorsField setStringValue:@""];
	
	[inputBox setHidden:TRUE];
	[motorsetBox setHidden:TRUE];
	[motorstateBox setHidden:TRUE];
	
	NSRect frame = [mainWindow frame];
	int heightChange = frame.size.height - 195;
	frame.origin.y += heightChange;
	frame.size.height -= heightChange;
	[mainWindow setMinSize:frame.size];
	[mainWindow setFrame:frame display:YES animate:NO];
	
	[self setPicture:0:0];
	
	[pool release];
	[mainWindow display];
}

- (void)InputChange:(int)Index:(int)State
{
	[[inputs cellWithTag:Index] setState:State];
}

- (void)MotorChange:(int)Index:(double)Value
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	switch(Index) {
		case 0:
			[speed0Field setStringValue:[NSString stringWithFormat:@"%0.1f", Value]];
			[speed0Slider setFloatValue:Value];
			break;
		case 1:
			[speed1Field setStringValue:[NSString stringWithFormat:@"%0.1f", Value]];
			[speed1Slider setFloatValue:Value];
			break;
	}
	[pool release];
}

- (void)CurrentChange:(int)Index:(double)Value
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	switch(Index) {
		case 0:
			[current0Field setStringValue:[NSString stringWithFormat:@"%0.3f", Value]];
			[current0Slider setFloatValue:Value];
			break;
		case 1:
			[current1Field setStringValue:[NSString stringWithFormat:@"%0.3f", Value]];
			[current1Slider setFloatValue:Value];
			break;
	}
	[pool release];
}

/*
* This gets run when the GUI gets displayed
*/
- (void)awakeFromNib
{
	int serial = -1, remote = 0;
	NSArray *args = [[NSProcessInfo processInfo] arguments];
	if([args count] > 1)
	{
		if([[args objectAtIndex:1] isEqualToString:@"remote"])
			remote = 1;
		serial = strtol([[args objectAtIndex:[args count]-1] UTF8String], NULL, 10);
		if(serial == 0) serial = -1;
	}
	
	[mainWindow setDelegate:self];
	
	CPhidgetMotorControl_create(&motor);
	
	CPhidgetMotorControl_set_OnInputChange_Handler(motor, &gotInputChange, self);
	CPhidgetMotorControl_set_OnVelocityChange_Handler(motor, &gotMotorChange, self);
	CPhidgetMotorControl_set_OnCurrentChange_Handler(motor, &gotCurrentChange, self);
	CPhidget_set_OnAttach_Handler((CPhidgetHandle)motor, gotAttach, self);
	CPhidget_set_OnDetach_Handler((CPhidgetHandle)motor, gotDetach, self);
	
	if(remote)
		CPhidget_openRemote((CPhidgetHandle)motor, serial, NULL, NULL);
	else
		CPhidget_open((CPhidgetHandle)motor, serial);
}

- (void)windowWillClose:(NSNotification *)aNotification {
	CPhidget_close((CPhidgetHandle)motor);
	CPhidget_delete((CPhidgetHandle)motor);
	motor = NULL;
	[NSApp terminate:self];
}

- (void)setPicture:(int)version:(CPhidget_DeviceID)devid
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSString *imgPath;
	
	switch(devid)
	{
		case PHIDID_MOTORCONTROL_HC_2MOTOR:
			imgPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"1064_0" ofType:@"icns"];
			break;
		case PHIDID_MOTORCONTROL_LV_2MOTOR_4INPUT:
			imgPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"1060_0" ofType:@"icns"];
			break;
		default:
			imgPath = nil;
			break;
	}
	
	NSImage *img = [[NSImage alloc]  initByReferencingFile:imgPath];
	
	//otherwise the images are just painted over each other - and the transparency causes trouble
	[pictureBox setImage:nil];
	[pictureBox display];
	if(imgPath!=nil)
		[NSApp setApplicationIconImage: img];
	[pictureBox setImage:img];
	[pictureBox display];
	
	[pool release];
}
@end
