/*
 * IEEE488 Driver Inspector implementation
 * Copyright (C) 1995  W. Eric Norum
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * 
 * W. Eric Norum
 * Saskatchewan Accelerator Laboratory
 * University of Saskatchewan
 * 107 North Road
 * Saskatoon, Saskatchewan, CANADA
 * S7N 5C6
 * 
 * eric@skatter.usask.ca
 */

#import "IEEE488Inspector.h"

#define DRIVERNAME_KEY	"Driver Name"
#define CONTROLLER_KEY	"Controller GPIB Address"
#define TIMECODE_KEY	"Time Limit Code"

@implementation IEEE488Inspector

- init
{
	char      buffer[MAXPATHLEN];
	NXBundle *myBundle = [NXBundle bundleForClass:[self class]];

	[super init];
	if (![myBundle getPath:buffer forResource:"IEEE488" ofType:"nib"]) {
		[self free];
		return nil;
	}
	if (![NXApp loadNibFile:buffer owner:self withNames:NO]) {
		[self free];
		return nil;
	}
	return self;
}

- (BOOL)getDriverIntValue:(unsigned int *)value withKey:(const char *)key
{
	IOReturn r;
	unsigned int count;
	unsigned int i;

	count = 1;
	r = [deviceMaster getIntValues:&i
								forParameter:(char *)key
								objectNumber:deviceObjectNumber
								count:&count];
	if ((r != IO_R_SUCCESS) || (count != 1))
		return NO;
	*value = i;
	return YES;
}

- (BOOL)loadParametersFromDriver
{
	if (![self getDriverIntValue:&gpibController withKey:CONTROLLER_KEY])
		return NO;
	if (![self getDriverIntValue:&timeLimitCode withKey:TIMECODE_KEY])
		return NO;
	return YES;
}

- (BOOL)getTableIntValue:(unsigned int *)value withKey:(const char *)key
{
	const char *cp;
	unsigned int i;

	cp = [table valueForStringKey:key];
	if ((cp == NULL) || (sscanf (cp, "%u", &i) != 1))
		return NO;
	*value = i;
	return YES;
}

- (BOOL)loadParametersFromTable
{
	if (![self getTableIntValue:&gpibController withKey:CONTROLLER_KEY])
		return NO;
	if (![self getTableIntValue:&timeLimitCode withKey:TIMECODE_KEY])
		return NO;
	return YES;
}

- (void)loadDefaultParameters
{
	gpibController = [[gpibControllerSelector selectedCell] tag];
	timeLimitCode = [timeLimitSelector tag];
}

- (void)setButton:button to:(int)tag
{
	id items = [[button target] itemList];
	[items selectCellWithTag:tag];
	[button setTitle:[[items selectedCell] title]];
}

- (void)updateIEEE488View
{
	[gpibControllerSelector selectCellWithTag:gpibController];
	[self setButton:timeLimitSelector to:timeLimitCode];
}

- setTable:(NXStringTable *)anObject
{
	const char *name;
	IOReturn r;
	IOString kind;

	[super setTable:anObject];

	/*
	 * Try to connect to driver
	 */
	name = [table valueForStringKey:DRIVERNAME_KEY];
	if (name != NULL) {
		deviceMaster = [IODeviceMaster new];
		r = [deviceMaster lookUpByDeviceName:(char *)name
								objectNumber:&deviceObjectNumber
								deviceKind:&kind];
		if (r != IO_R_SUCCESS)
			deviceMaster = nil;
	}

	/*
	 * Load the values
	 */
	if ((deviceMaster == nil) || ![self loadParametersFromDriver])
		if (![self loadParametersFromTable])
			[self loadDefaultParameters];
	[self updateIEEE488View];
	[self setAccessoryView:ieee488View];
	return self;
}

- (void)setDriverIntValue:(unsigned int)value forKey:(char *)key
{
	if (deviceMaster)
		[deviceMaster setIntValues:&value
								forParameter:key
								objectNumber:deviceObjectNumber
								count:1];
}

- gpibControllerChanged:sender
{
	unsigned int i = [[sender selectedCell] tag];

	sprintf (gpibControllerString, "%d", i);
	[table insertKey:CONTROLLER_KEY value:gpibControllerString];
	return self;
}

- timeLimitChanged:sender
{
	unsigned int i = [[sender selectedCell] tag];

	sprintf (timeLimitString, "%d", i);
	[table insertKey:TIMECODE_KEY value:timeLimitString];
	[self setDriverIntValue:i forKey:TIMECODE_KEY];
	return self;
}

@end
