// 14 august 2015
#import "uipriv_darwin.h"

// Text fields for entering text have no intrinsic width; we'll use the default Interface Builder width for them.
#define textfieldWidth 96

@interface libui_intrinsicWidthNSTextField : NSTextField
@end

@implementation libui_intrinsicWidthNSTextField

- (NSSize)intrinsicContentSize
{
	NSSize s;

	s = [super intrinsicContentSize];
	s.width = textfieldWidth;
	return s;
}

@end

struct uiEntry {
	uiDarwinControl c;
	NSTextField *textfield;
	void (*onChanged)(uiEntry *, void *);
	void *onChangedData;
};

@interface entryDelegateClass : NSObject<NSTextFieldDelegate> {
	NSMapTable *entries;
}
- (void)controlTextDidChange:(NSNotification *)note;
- (void)registerEntry:(uiEntry *)e;
- (void)unregisterEntry:(uiEntry *)e;
@end

@implementation entryDelegateClass

- (id)init
{
	self = [super init];
	if (self)
		self->entries = newMap();
	return self;
}

- (void)dealloc
{
	if ([self->entries count] != 0)
		complain("attempt to destroy shared entry delegate but entries are still registered to it");
	[self->entries release];
	[super dealloc];
}

- (void)controlTextDidChange:(NSNotification *)note
{
	uiEntry *e;

	e = (uiEntry *) mapGet(self->entries, [note object]);
	(*(e->onChanged))(e, e->onChangedData);
}

- (void)registerEntry:(uiEntry *)e
{
	mapSet(self->entries, e->textfield, e);
	[e->textfield setDelegate:self];
}

- (void)unregisterEntry:(uiEntry *)e
{
	[e->textfield setDelegate:nil];
	[self->entries removeObjectForKey:e->textfield];
}

@end

static entryDelegateClass *entryDelegate = nil;

uiDarwinDefineControlWithOnDestroy(
	uiEntry,								// type name
	uiEntryType,							// type function
	textfield,								// handle
	[entryDelegate unregisterEntry:this];			// on destroy
)

char *uiEntryText(uiEntry *e)
{
	return uiDarwinNSStringToText([e->textfield stringValue]);
}

void uiEntrySetText(uiEntry *e, const char *text)
{
	[e->textfield setStringValue:toNSString(text)];
	// don't queue the control for resize; entry sizes are independent of their contents
}

void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data)
{
	e->onChanged = f;
	e->onChangedData = data;
}

int uiEntryReadOnly(uiEntry *e)
{
	return [e->textfield isEditable] == NO;
}

void uiEntrySetReadOnly(uiEntry *e, int readonly)
{
	BOOL editable;

	editable = YES;
	if (readonly)
		editable = NO;
	[e->textfield setEditable:editable];
}

static void defaultOnChanged(uiEntry *e, void *data)
{
	// do nothing
}

// these are based on interface builder defaults; my comments in the old code weren't very good so I don't really know what talked about what, sorry :/
void finishNewTextField(NSTextField *t, BOOL isEntry)
{
	uiDarwinSetControlFont(t, NSRegularControlSize);

	// THE ORDER OF THESE CALLS IS IMPORTANT; CHANGE IT AND THE BORDERS WILL DISAPPEAR
	[t setBordered:NO];
	[t setBezelStyle:NSTextFieldSquareBezel];
	[t setBezeled:isEntry];

	// we don't need to worry about substitutions/autocorrect here; see window_darwin.m for details

	[[t cell] setLineBreakMode:NSLineBreakByClipping];
	[[t cell] setScrollable:YES];
}

NSTextField *newEditableTextField(void)
{
	NSTextField *tf;

	tf = [[libui_intrinsicWidthNSTextField alloc] initWithFrame:NSZeroRect];
	[tf setSelectable:YES];		// otherwise the setting is masked by the editable default of YES
	finishNewTextField(tf, YES);
	return tf;
}

uiEntry *uiNewEntry(void)
{
	uiEntry *e;

	e = (uiEntry *) uiNewControl(uiEntryType());

	e->textfield = newEditableTextField();

	if (entryDelegate == nil) {
		entryDelegate = [entryDelegateClass new];
		[delegates addObject:entryDelegate];
	}
	[entryDelegate registerEntry:e];
	uiEntryOnChanged(e, defaultOnChanged, NULL);

	uiDarwinFinishNewControl(e, uiEntry);

	return e;
}
