#import "PhidgetServoController.h"
	
CPhidgetAdvancedServoHandle servo;

@implementation PhidgetServoController

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

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

int gotPositionChange(CPhidgetAdvancedServoHandle phid, void *context, int index, double position) {
	[(id)context positionChange:index:position];
	return 0;
}

int gotCurrentChange(CPhidgetAdvancedServoHandle phid, void *context, int index, double current) {
	[(id)context currentChange:index:current];
	return 0;
}

int gotVelocityChange(CPhidgetAdvancedServoHandle phid, void *context, int index, double velocity) {
	[(id)context velocityChange:index:velocity];
	return 0;
}

- (void)phidgetAdded
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	int serial, version;
	int numMotors;
	
	double posn;
	int engaged, speedramping, i, stopped;
	
	CPhidget_getSerialNumber((CPhidgetHandle)servo, &serial);
	CPhidget_getDeviceVersion((CPhidgetHandle)servo, &version);
	CPhidgetAdvancedServo_getMotorCount(servo,&numMotors);
	
	[connectedField setTitleWithMnemonic:@"PhidgetServo Connected"];
	[serialField setTitleWithMnemonic:[NSString stringWithFormat:@"%d", serial]];
	[versionField setTitleWithMnemonic:[NSString stringWithFormat:@"%d", version]];
	[numberOfServosField setTitleWithMnemonic:[NSString stringWithFormat:@"%i", numMotors]];
	
	[scroll1 setEnabled:true];
	if(numMotors==4) {
		[scroll2 setEnabled:true];
		[scroll3 setEnabled:true];
		[scroll4 setEnabled:true];
		[scroll5 setEnabled:false];
		[scroll6 setEnabled:false];
		[scroll7 setEnabled:false];
		[scroll8 setEnabled:false];
		[scrollAll setEnabled:true];
	}
	else if(numMotors==8) {
		[scroll2 setEnabled:true];
		[scroll3 setEnabled:true];
		[scroll4 setEnabled:true];
		[scroll5 setEnabled:true];
		[scroll6 setEnabled:true];
		[scroll7 setEnabled:true];
		[scroll8 setEnabled:true];
		[scrollAll setEnabled:true];
	}
	else {			
		[scroll2 setEnabled:false];
		[scroll3 setEnabled:false];
		[scroll4 setEnabled:false];
		[scroll5 setEnabled:false];
		[scroll6 setEnabled:false];
		[scroll7 setEnabled:false];
		[scroll8 setEnabled:false];
		[scrollAll setEnabled:true];
	}
	
	if(CPhidgetAdvancedServo_getPosition(servo,0,&posn)) posn = 105.0;
	[scroll1 setFloatValue:posn];
	if(CPhidgetAdvancedServo_getPosition(servo,1,&posn)) posn = 105.0;
	[scroll2 setFloatValue:posn];
	if(CPhidgetAdvancedServo_getPosition(servo,2,&posn)) posn = 105.0;
	[scroll3 setFloatValue:posn];
	if(CPhidgetAdvancedServo_getPosition(servo,3,&posn)) posn = 105.0;
	[scroll4 setFloatValue:posn];
	if(CPhidgetAdvancedServo_getPosition(servo,4,&posn)) posn = 105.0;
	[scroll5 setFloatValue:posn];
	if(CPhidgetAdvancedServo_getPosition(servo,5,&posn)) posn = 105.0;
	[scroll6 setFloatValue:posn];
	if(CPhidgetAdvancedServo_getPosition(servo,6,&posn)) posn = 105.0;
	[scroll7 setFloatValue:posn];
	if(CPhidgetAdvancedServo_getPosition(servo,7,&posn)) posn = 105.0;
	[scroll8 setFloatValue:posn];
	[scrollAll setFloatValue:105.0];
	
	for(i = 0;i<numMotors;i++)
	{
		if(CPhidgetAdvancedServo_getEngaged(servo,i,&engaged))
		{
			engaged = 0;
		}
		if(!engaged)
		{
			[[stopButtons cellWithTag:i] setTitle:@"Off"];
			[[setPositions cellWithTag:i] setTitleWithMnemonic:@"Unknown"];
		}
		else
		{
			CPhidgetAdvancedServo_getPosition(servo,i,&posn);
			[[setPositions cellWithTag:i] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", posn]];
			[[stopButtons cellWithTag:i] setTitle:@"On"];
		}
		CPhidgetAdvancedServo_getStopped(servo, i, &stopped);
		[[stoppedCheckBoxes cellWithTag:i] setState:stopped];
		CPhidgetAdvancedServo_getSpeedRampingOn(servo, i, &speedramping);
		if(!speedramping)
			[[speedRampingButtons cellWithTag:i] setTitle:@"Off"];
		else
			[[speedRampingButtons cellWithTag:i] setTitle:@"On"];
	}
	
	[pool release];
}

- (void)phidgetRemoved
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	[connectedField setTitleWithMnemonic:@"PhidgetServo Removed"];
	[serialField setTitleWithMnemonic:@""];
	[versionField setTitleWithMnemonic:@""];
	[numberOfServosField setTitleWithMnemonic:@""];
	[scroll1 setEnabled:false];
	[scroll2 setEnabled:false];
	[scroll3 setEnabled:false];
	[scroll4 setEnabled:false];
	[scroll5 setEnabled:false];
	[scroll6 setEnabled:false];
	[scroll7 setEnabled:false];
	[scroll8 setEnabled:false];
	[scrollAll setEnabled:false];
	[pool release];
}

- (void)positionChange:(int)Index:(double)Value
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	int stopped;
	CPhidgetAdvancedServo_getStopped(servo, Index, &stopped);
	[[currentPositions cellWithTag:Index] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", Value]];
	[[currentPositionSliders cellWithTag:Index] setIntValue:(int)Value];
	[[stoppedCheckBoxes cellWithTag:Index] setState:stopped];
	[pool release];
}

- (void)velocityChange:(int)Index:(double)Value
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	int stopped;
	CPhidgetAdvancedServo_getStopped(servo, Index, &stopped);
	[[currentVelocities cellWithTag:Index] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", Value]];
	[[stoppedCheckBoxes cellWithTag:Index] setState:stopped];
	[pool release];
}

- (void)currentChange:(int)Index:(double)Value
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	[[currentCurrents cellWithTag:Index] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", Value]];
	[[currentCurrentSliders cellWithTag:Index] setFloatValue:Value];
	[pool release];
}

- (IBAction)moveServo:(id)sender
{
	int i=0;
	if([sender tag] < 8)
	{
		CPhidgetAdvancedServo_setPosition(servo, [sender tag], [sender floatValue]);
		[[setPositions cellWithTag:[sender tag]] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", [sender floatValue]]];
	}
	else
	{
		for(i=0;i<8;i++)
		{
			CPhidgetAdvancedServo_setPosition(servo, i, [sender floatValue]);
			[[setPositions cellWithTag:i] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", [sender floatValue]]];
		}
		[[setPositions cellWithTag:[sender tag]] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", [sender floatValue]]];
		[scroll1 setFloatValue:[sender floatValue]];
		[scroll2 setFloatValue:[sender floatValue]];
		[scroll3 setFloatValue:[sender floatValue]];
		[scroll4 setFloatValue:[sender floatValue]];
		[scroll5 setFloatValue:[sender floatValue]];
		[scroll6 setFloatValue:[sender floatValue]];
		[scroll7 setFloatValue:[sender floatValue]];
		[scroll8 setFloatValue:[sender floatValue]];
	}
}
- (IBAction)accelServo:(id)sender
{
	int i=0;
	if([sender tag] < 8)
	{
			CPhidgetAdvancedServo_setAcceleration(servo, [sender tag], [sender floatValue]);
	[[setAccelerations cellWithTag:[sender tag]] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", [sender floatValue]]];
	}
	else
	{
		for(i=0;i<8;i++)
		{
			CPhidgetAdvancedServo_setAcceleration(servo, i, [sender floatValue]);
			[[setAccelerations cellWithTag:i] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", [sender floatValue]]];
		}
	}
}
- (IBAction)velocityServo:(id)sender
{
	int i=0;
	if([sender tag] < 8)
	{
		CPhidgetAdvancedServo_setVelocityLimit(servo, [sender tag], [sender floatValue]);
		[[setVelocities cellWithTag:[sender tag]] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", [sender floatValue]]];
	}
	else
	{
		for(i=0;i<8;i++)
		{
			CPhidgetAdvancedServo_setVelocityLimit(servo, i, [sender floatValue]);
			[[setVelocities cellWithTag:i] setTitleWithMnemonic:[NSString stringWithFormat:@"%lf", [sender floatValue]]];
		}
	}
}

- (IBAction)stopServo:(id)sender
{
	int i=0;
	if([[sender selectedCell]tag] < 8)
	{
		if([[[sender selectedCell] title] isEqualToString:@"On"])
		{
			CPhidgetAdvancedServo_setEngaged(servo, [[sender selectedCell]tag], 0);
			[[sender selectedCell] setTitle:@"Off"];
		}
		else
		{
			CPhidgetAdvancedServo_setEngaged(servo, [[sender selectedCell]tag], 1);
			[[sender selectedCell] setTitle:@"On"];
		}
	}
	else
	{
		if([[[sender selectedCell] title] isEqualToString:@"On"])
		{
			for(i=0;i<8;i++)
			{
				CPhidgetAdvancedServo_setEngaged(servo, i, 0);
				[[stopButtons cellWithTag:i] setTitle:@"Off"];
			}
			[[sender selectedCell] setTitle:@"Off"];
		}
		else
		{
			for(i=0;i<8;i++)
			{
				CPhidgetAdvancedServo_setEngaged(servo, i, 1);
				[[stopButtons cellWithTag:i] setTitle:@"On"];
			}
			[[sender selectedCell] setTitle:@"On"];
		}
	}
}

- (IBAction)setSpeedRamping:(id)sender
{
	int i=0;
	if([[sender selectedCell]tag] < 8)
	{
		if([[[sender selectedCell] title] isEqualToString:@"On"])
		{
			CPhidgetAdvancedServo_setSpeedRampingOn(servo, [[sender selectedCell]tag], 0);
			[[sender selectedCell] setTitle:@"Off"];
		}
		else
		{
			CPhidgetAdvancedServo_setSpeedRampingOn(servo, [[sender selectedCell]tag], 1);
			[[sender selectedCell] setTitle:@"On"];
		}
	}
	else
	{
		if([[[sender selectedCell] title] isEqualToString:@"On"])
		{
			for(i=0;i<8;i++)
			{
				CPhidgetAdvancedServo_setSpeedRampingOn(servo, i, 0);
				[[speedRampingButtons cellWithTag:i] setTitle:@"Off"];
			}
			[[sender selectedCell] setTitle:@"Off"];
		}
		else
		{
			for(i=0;i<8;i++)
			{
				CPhidgetAdvancedServo_setSpeedRampingOn(servo, i, 1);
				[[speedRampingButtons cellWithTag:i] setTitle:@"On"];
			}
			[[sender selectedCell] setTitle:@"On"];
		}
	}
}

- (IBAction)setMaxAngle:(id)sender
{
	int i;
	for(i=0;i<8;i++)
	{
		CPhidgetAdvancedServo_setPositionMax(servo, i, [sender floatValue]);
	}
    [scroll1 setMaxValue:[sender floatValue]];
    [scroll2 setMaxValue:[sender floatValue]];
    [scroll3 setMaxValue:[sender floatValue]];
    [scroll4 setMaxValue:[sender floatValue]];
    [scroll5 setMaxValue:[sender floatValue]];
    [scroll6 setMaxValue:[sender floatValue]];
    [scroll7 setMaxValue:[sender floatValue]];
    [scroll8 setMaxValue:[sender floatValue]];
    [scrollAll setMaxValue:[sender floatValue]];
}

- (IBAction)setMinAngle:(id)sender
{
	int i;
	for(i=0;i<8;i++)
	{
		CPhidgetAdvancedServo_setPositionMin(servo, i, [sender floatValue]);
	}
    [scroll1 setMinValue:[sender floatValue]];
    [scroll2 setMinValue:[sender floatValue]];
    [scroll3 setMinValue:[sender floatValue]];
    [scroll4 setMinValue:[sender floatValue]];
    [scroll5 setMinValue:[sender floatValue]];
    [scroll6 setMinValue:[sender floatValue]];
    [scroll7 setMinValue:[sender floatValue]];
    [scroll8 setMinValue:[sender floatValue]];
    [scrollAll setMinValue:[sender floatValue]];
}

/*
* 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];
	
	CPhidget_enableLogging(PHIDGET_LOG_VERBOSE, NULL);
	
	CPhidgetAdvancedServo_create(&servo);
	
	CPhidget_set_OnAttach_Handler((CPhidgetHandle)servo, gotAttach, self);
	CPhidget_set_OnDetach_Handler((CPhidgetHandle)servo, gotDetach, self);
	CPhidgetAdvancedServo_set_OnPositionChange_Handler(servo, gotPositionChange, self);
	CPhidgetAdvancedServo_set_OnVelocityChange_Handler(servo, gotVelocityChange, self);
	CPhidgetAdvancedServo_set_OnCurrentChange_Handler(servo, gotCurrentChange, self);
	
	if(remote)
		CPhidget_openRemote((CPhidgetHandle)servo, serial, NULL, NULL);
	else
		CPhidget_open((CPhidgetHandle)servo, serial);
}

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

@end
