/* 
 * Phidget Hello World Program for all devices
 * (c) Phidgets 2012
 */

#import "HelloWorldAppDelegate.h"


// ========== Event Handling Setup Functions ==========
int gotAttach(CPhidgetHandle phid, void *context) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	
	//invokes the Deviceattach event method on the main thread and block the main thread until after the DeviceAttach method finishes
	//A bad access exception may occur if you set waitUntilDone to No
	[(id)context performSelectorOnMainThread:@selector(DeviceAttach:)
								  withObject:[NSValue valueWithPointer:phid]
                                  waitUntilDone:YES];
    [pool release];
    return 0;
 }

int gotDetach(CPhidgetHandle phid, void *context) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	//invokes the Deviceattach event method on the main thread and block the main thread until after the DeviceAttach method finishes
	//A bad access exception may occur if you set waitUntilDone to No
	[(id)context performSelectorOnMainThread:@selector(DeviceDetach:)
                                  withObject:[NSValue valueWithPointer:phid]
                                  waitUntilDone:YES];
    [pool release];
    return 0;
}

int gotError(CPhidgetManagerHandle phid, void *context, int Code, const char *Description) {
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	//invokes the ErrorChange event method on the main thread and  we do not have to block the main thread until after the ErrorChange method finishes
	[(id)context performSelectorOnMainThread:@selector(ErrorChange:)
								  withObject:[NSArray arrayWithObjects:[NSNumber numberWithInt:Code],[NSString stringWithFormat:@"%s", Description], nil]
                                  waitUntilDone:NO];
	[pool release];
	return 0;
}

@implementation HelloWorldAppDelegate

// ========== This error handler can handle any CPhidget function that returns an int ==========
- (void)LocalErrorCatcher:(int)errorCode
{
   //If the error code is 0, everything is okay
   if(errorCode != 0){
       //Otherwise, you can print specific messages or perform actions by error code.
    
       const char *errorDescription;
       CPhidget_getErrorDescription(errorCode, &errorDescription);

       //Append error to the NSTextView
       [OutputField setString: [[OutputField string] stringByAppendingString: [NSString stringWithFormat: @"Error: An error occured with code %d. The description for this error is: %@\n", errorCode,[NSString stringWithCString:errorDescription encoding:NSASCIIStringEncoding]]]];
       
    }
}

// ========== Event Handling Functions ==========
- (void)DeviceAttach:(NSValue *)phid{
    int phidgetSerial;
    const char * phidgetName;
    
    [self LocalErrorCatcher:CPhidget_getSerialNumber((CPhidgetHandle)[phid pointerValue], &phidgetSerial)];
    [self LocalErrorCatcher:CPhidget_getDeviceName((CPhidgetHandle)[phid pointerValue], &phidgetName)];
   
    //Append new device to the NSTextView
    [OutputField setString: [[OutputField string] stringByAppendingString: [NSString stringWithFormat: @"Hello Device %@, Serial Number: %d\n", [NSString stringWithCString:phidgetName encoding:NSASCIIStringEncoding], phidgetSerial]]];

    //auto scroll to the bottom of the NSTextView
    [OutputField scrollToEndOfDocument:self];
}

- (void)DeviceDetach:(NSValue *)phid{
    int phidgetSerial;
    const char * phidgetName;
    
    [self LocalErrorCatcher:CPhidget_getSerialNumber((CPhidgetHandle)[phid pointerValue], &phidgetSerial)];
    [self LocalErrorCatcher:CPhidget_getDeviceName((CPhidgetHandle)[phid pointerValue], &phidgetName)];

    //Append removed device to the NSTextView
    [OutputField setString: [[OutputField string] stringByAppendingString: [NSString stringWithFormat: @"Goodbye Device %@, Serial Number: %d\n", [NSString stringWithCString: phidgetName encoding:NSASCIIStringEncoding], phidgetSerial]]];
    
    //auto scroll to the bottom of the NSTextView
    [OutputField scrollToEndOfDocument:self];
}

- (void)ErrorChange:(NSArray *)errorData{
    
    NSString *str = [NSString stringWithFormat:@"Error Event: %d - %@", [errorData objectAtIndex:0], [errorData objectAtIndex:1]];
    [OutputField setString: [[OutputField string] stringByAppendingString: str]];

    //auto scroll to the bottom of the NSTextView
    [OutputField scrollToEndOfDocument:self];}

@synthesize window;

/*
 * This gets run when the GUI gets displayed
 */
- (void)awakeFromNib
{
    [self LocalErrorCatcher:CPhidgetManager_create(&manager)];
	/*
     * set up the phidget Manager - detects when phidgets are attached and removed
     */
	[self LocalErrorCatcher:CPhidgetManager_set_OnAttach_Handler(manager, gotAttach, self)];
	[self LocalErrorCatcher:CPhidgetManager_set_OnDetach_Handler(manager, gotDetach, self)];
	[self LocalErrorCatcher:CPhidgetManager_set_OnError_Handler(manager, gotError, self)];
	[self LocalErrorCatcher:CPhidgetManager_open(manager)];
}

- (void)windowWillClose:(NSNotification *)aNotification {
	[self LocalErrorCatcher:CPhidgetManager_close(manager)];
	[self LocalErrorCatcher:CPhidgetManager_delete(manager)];
	manager = NULL;
	[NSApp terminate:self];
}

@end