#import "PhidgetRFIDController.h"

CPhidgetRFIDHandle rfid=0;

@implementation PhidgetRFIDController

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

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

int gotError(CPhidgetHandle phid, void *context, int errcode, const char *error) {
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	[(id)context performSelectorOnMainThread:@selector(ErrorEvent:)
								  withObject:[NSArray arrayWithObjects:[NSNumber numberWithInt:errcode], [NSString stringWithUTF8String:error], nil]
							   waitUntilDone:NO];
	[pool release];
	return 0;
}

int gotTag(CPhidgetRFIDHandle phid, void *context, char *tag, CPhidgetRFID_Protocol proto) {
	[(id)context RFIDTag:tag];
	return 0;
}

int lostTag(CPhidgetRFIDHandle phid, void *context, char *tag, CPhidgetRFID_Protocol proto) {
	[(id)context RFIDTagLost];
	return 0;
}

- (void)phidgetAdded
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

	int serial, version;
	int numOutputs;
	const char *name;
	CPhidget_DeviceID devid;
	int heightChange;

	CPhidget_getSerialNumber((CPhidgetHandle)rfid, &serial);
	CPhidget_getDeviceVersion((CPhidgetHandle)rfid, &version);
	CPhidget_getDeviceName((CPhidgetHandle)rfid, &name);
	CPhidget_getDeviceID((CPhidgetHandle)rfid, &devid);
	CPhidgetRFID_getOutputCount(rfid, &numOutputs);
	
	[connectedField setStringValue:[NSString stringWithUTF8String:name]];
	[serialField setIntValue:serial];
	[versionField setIntValue:version];
	[numberOfOutputsField setIntValue:numOutputs];
	
	[antennaCheck setState:0];
	[externalLEDCheck setState:0];
	[fiveVCheck setState:0];
	[onboardLEDCheck setState:0];
	
	NSRect frame = [mainWindow frame];
	
	switch(devid)
	{
		case PHIDID_RFID_2OUTPUT:
			[settingsBox setHidden:FALSE];
			[writeBox setHidden:TRUE];
			heightChange = frame.size.height - 343;
			break;
		case PHIDID_RFID_2OUTPUT_READ_WRITE:
			[settingsBox setHidden:FALSE];
			[writeBox setHidden:FALSE];
			heightChange = frame.size.height - 440;
			break;
		case PHIDID_RFID:
			[settingsBox setHidden:TRUE];
			[writeBox setHidden:TRUE];
			heightChange = frame.size.height - 264;
			break;
		default:
			break;
	}
	
	CPhidgetRFID_setAntennaOn(rfid,1);
	[antennaCheck setState:true];
	
	[tagBox 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:@""];
	[numberOfOutputsField setStringValue:@""];
	
	[antennaCheck setState:0];
	[externalLEDCheck setState:0];
	[fiveVCheck setState:0];
	[onboardLEDCheck setState:0];
	
	[settingsBox setHidden:TRUE];
	[tagBox 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];
}

/*
* got a tag
*/
- (void)RFIDTag:(char *)tag
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	[tagField setStringValue:[NSString stringWithUTF8String:tag]];
	//[tagField setTitleWithMnemonic:[NSString stringWithFormat:@"%02x%02x%02x%02x%02x\n",tag[0],tag[1],tag[2],tag[3],tag[4]]];
	[pool release];
}

/*
* lost a tag
*/
- (void)RFIDTagLost
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	[tagField setStringValue:@""];
	[pool release];
}

- (IBAction)antennaChecked:(id)sender
{
	CPhidgetRFID_setAntennaOn(rfid,[sender state]);
}

- (IBAction)externalLEDChecked:(id)sender
{
	CPhidgetRFID_setOutputState(rfid, 1,[sender state]);
}

- (IBAction)fiveVChecked:(id)sender
{
	CPhidgetRFID_setOutputState(rfid, 0,[sender state]);
}

- (IBAction)onboardLEDChecked:(id)sender
{
	CPhidgetRFID_setLEDOn(rfid,[sender state]);
}

- (IBAction)writeTag:(id)sender
{
	CPhidgetRFID_Protocol proto;
	if([[protocolCombo titleOfSelectedItem] isEqualToString:@"EM4100"])
		proto = PHIDGET_RFID_PROTOCOL_EM4100;
	else if([[protocolCombo titleOfSelectedItem] isEqualToString:@"ISO11785"])
		proto = PHIDGET_RFID_PROTOCOL_ISO11785_FDX_B;
	else if([[protocolCombo titleOfSelectedItem] isEqualToString:@"PHIDGETS"])
		proto = PHIDGET_RFID_PROTOCOL_PHIDGETS;
		
	CPhidgetRFID_write(rfid, (char *)[[writeTagString stringValue] UTF8String], proto, [lockCheck intValue]);
}

- (void)openCmdLine
{
	int serial = -1, remote = 0;
	NSArray *args = [[NSProcessInfo processInfo] arguments];
	if([args count] > 1)
	{
		if([[args objectAtIndex:1] isEqualToString:@"remote"])
			remote = 1;
		serial = [[args objectAtIndex:[args count]-1] intValue];
		if(serial == 0) serial = -1;
	}
	
	if(remote)
		CPhidget_openRemote((CPhidgetHandle)rfid, serial, NULL, [[passwordField stringValue] UTF8String]);
	else
		CPhidget_open((CPhidgetHandle)rfid, serial);
}

/*
* This gets run when the GUI gets displayed
*/
- (void)awakeFromNib
{
	[mainWindow setDelegate:self];
	
	[tagField setFont:[NSFont fontWithName:@"Courier New" size:14.0]];
	
	//CPhidget_enableLogging(PHIDGET_LOG_VERBOSE, NULL);
	CPhidgetRFID_create(&rfid);
	
	CPhidgetRFID_set_OnTag2_Handler(rfid, gotTag, self);
	CPhidgetRFID_set_OnTagLost2_Handler(rfid, lostTag, self);
	CPhidget_set_OnAttach_Handler((CPhidgetHandle)rfid, gotAttach, self);
	CPhidget_set_OnDetach_Handler((CPhidgetHandle)rfid, gotDetach, self);
	CPhidget_set_OnError_Handler((CPhidgetHandle)rfid, gotError, self);
	
	[self openCmdLine];
}

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

- (void)setPicture:(int)version:(CPhidget_DeviceID)devid
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSString *imgPath;
	
	switch(devid)
	{
		case PHIDID_RFID_2OUTPUT:
			imgPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"1023_1" ofType:@"icns"];
			break;
		case PHIDID_RFID:
		case PHIDID_RFID_2OUTPUT_READ_WRITE:
		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];
}

int errorCounter = 0;
- (void)ErrorEvent:(NSArray *)errorEventData
{
	int errorCode = [[errorEventData objectAtIndex:0] intValue];
	NSString *errorString = [errorEventData objectAtIndex:1];
	
	switch(errorCode)
	{
		case EEPHIDGET_BADPASSWORD:
			CPhidget_close((CPhidgetHandle)rfid);
			[NSApp runModalForWindow:passwordPanel];
			break;
		case EEPHIDGET_BADVERSION:
			CPhidget_close((CPhidgetHandle)rfid);
			NSRunAlertPanel(@"Version mismatch", [NSString stringWithFormat:@"%@\nApplication will now close.", errorString], nil, nil, nil);
			[NSApp terminate:self];
			break;
		default:
			errorCounter++;
			
			NSAttributedString *string = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@\n",errorString]];
			
			[[errorEventLog textStorage] beginEditing];
			[[errorEventLog textStorage] appendAttributedString:string];
			[[errorEventLog textStorage] endEditing];
			
			[errorEventLogCounter setIntValue:errorCounter];
			if(![errorEventLogWindow isVisible])
				[errorEventLogWindow setIsVisible:YES];
			break;
	}
}

- (IBAction)clearErrorLog:(id)sender
{
	[[errorEventLog textStorage] setAttributedString:[[NSAttributedString alloc] initWithString:@""]];
	[errorEventLogCounter setIntValue:0];
	errorCounter = 0;
}

- (IBAction)passwordOK:(id)sender
{
	[passwordPanel setIsVisible:NO];
	[NSApp stopModal];
	[self openCmdLine];
	[passwordField setStringValue:@""];
}

- (IBAction)passwordCancel:(id)sender
{
	[passwordPanel setIsVisible:NO];
	[NSApp stopModal];
	[NSApp terminate:self];
}
@end
