 
#import "PopupFormatter.h"

#define _delWill1	@selector(formatterWillChangeValueFor:at:sender:)
#define _delWill2	@selector(formatterWillChangeValueFor:at:to:sender:)
#define _delDid	@selector(formatterDidChangeValueFor:at:to:sender:)
#define String char*

char *unitOfMeasurement[] = {
	"barrels",
	"gallons",
	"litres",
	"inches",
	"centimeters",
	"kilometers" ,
	NULL
};

@implementation PopupFormatter

- init
{
	[super init];
    	newValue = [[DBValue allocFromZone:[self zone]] init];
    	return self;
}

- mouseDown:(NXEvent *)theEvent at:(int)row :(int)column
    inside:(NXRect *)frame inView:(View *) view
    withAttributes:(id <DBTableVectors >)rowAttrs
     :(id <DBTableVectors >)columnAttrs
    usePositions:(BOOL)useRowPos :(BOOL)useColumnPos
{
	String* strings;
	int	x;

	[self getValueAt:row :column withAttributes:rowAttrs :columnAttrs
		usePositions:useRowPos :useColumnPos];


	popupList = [[PopUpList alloc] init];


	for (strings = unitOfMeasurement; *strings; strings++)
	{
		[popupList addItem: *strings];
	}

	popupButton = NXCreatePopUpListButton(popupList);
	[popupButton setFrame: frame];

	for (x = 0; x < [[[popupButton target] itemList]cellCount]; x++)
	{
		if (!strcmp([[[[popupButton target] itemList] cellAt: x: 0] title], [value stringValue]))
			{
			[[[popupButton target] itemList] selectCellAt:x :0];
			[popupButton setTitle:[[[[popupButton target] itemList] selectedCell]title]];
			break;
			}
	}

	[view addSubview:popupButton];

	[popupList popUp: popupButton];

	[newValue setStringValue: [popupList selectedItem]];

	[popupButton removeFromSuperview];
	[popupList free];
	[popupButton free];

	[self setValueAt:row :column
		withAttributes:rowAttrs :columnAttrs
		usePositions:useRowPos :useColumnPos];
	
	/* Redraw the modified field */
	[self drawFieldAt:row :column
		inside:frame inView:view
		withAttributes:rowAttrs :columnAttrs
		usePositions:useRowPos :useColumnPos];

	[view display];

    return self;
}


- setValueAt:(int)row :(int)column
    withAttributes:(id <DBTableVectors >)rowAttrs
     :(id <DBTableVectors >)columnAttrs
    usePositions:(BOOL)useRowPos :(BOOL)useColumnPos
{
    BOOL                isChangeOk = YES;

 /* Ask delegate if we can change */
    if (useRowPos && !useColumnPos && delWill2)
	isChangeOk = [delegate formatterWillChangeValueFor:
		      [columnAttrs identifier]
		      at:row to:newValue sender:self];
    else if (useColumnPos && !useRowPos && delWill2)
	isChangeOk = [delegate formatterWillChangeValueFor:
		      [rowAttrs identifier]
		      at:column to:newValue sender:self];
    if (!isChangeOk)
	return nil;

 /* Tell dataSource our newValue */
    if (useRowPos && !useColumnPos)
	[dataSource setValueFor:[columnAttrs identifier] at:row
	 from:newValue];
    else if (useColumnPos && !useRowPos)
	[dataSource setValueFor:[rowAttrs identifier] at:column
	 from:newValue];
   
 /* Tell delegate we changed */
    if (useRowPos && !useColumnPos && delDid)
	[delegate formatterDidChangeValueFor:[columnAttrs identifier]
	 at:row to:newValue sender:self];
    else if (!useRowPos && useColumnPos && delDid)
	[delegate formatterDidChangeValueFor:[rowAttrs identifier]
	 at:column to:newValue sender:self];
    return self;
}

- setDelegateFlags
{
    delWill1 = delWill2 = delDid = NO;

    if ([delegate respondsTo:_delWill1])
	delWill1 = YES;
    if ([delegate respondsTo:_delWill2])
	delWill2 = YES;
    if ([delegate respondsTo:_delDid])
	delDid = YES;
    return self;
}

- setDelegate:newDelegate
{
    if (newDelegate == delegate)
	return self;
    else
	[super setDelegate:newDelegate];

    [self setDelegateFlags];

    return self;
}

@end