#import "PasswordFieldCell.h"

#import <appkit/appkit.h>
#import <stdio.h>

@implementation PasswordFieldCell

static PasswordFieldCell *activeCell;
			
/*
typedef struct _NXLayInfo {
	NXRect rect;
	NXCoord descent;
	NXCoord width;
	NXCoord left;
	NXCoord right;
	NXCoord rightIndent;
	NXLayArray *lays;
	NXWidthArray *widths;
	NXCharArray *chars;
	NXTextCache cache;
	NXRect *textClipRect;
	struct _lFlags {
		unsigned int horizCanGrow:1;
		unsigned int vertCanGrow:1;
		unsigned int erase:1;
		unsigned int ping:1;
		unsigned int endsParagraph:1;
		unsigned int resetCache:1;
	} lFlags;
} NXLayInfo;

typedef struct _NXSelPt {
	int cp;		// Character position
	int line;	// Offset of LineDesc in break table
	NXCoord x;	// x coordinate
	NXCoord y;	// y coordinate
	int c1st;	// Character position of first character on the line
	NXCoord ht;	// Line height
} NXSelPt;

*/
int DrawALine(Text *textObj, NXLayInfo *layInfo)
{
Font *fontObj;
int c, charCount;
const NXRect *rect = &layInfo->rect;
NXSelPt start, end;

	PSsetgray([textObj backgroundGray]);
	NXRectFill(rect);
	if( [activeCell isVisible] == YES )
		return NXDrawALine(textObj, layInfo);
	charCount = layInfo->lays[0].lays[0].chars;
	if( charCount == 1 )
		if( layInfo->chars->text[0] == '\n' )
			charCount = 0;

	// Draw a string of charCount of the hiddenChar
	if( charCount > 0 )
	{
	char buffer[charCount], hiddenChar;
		fontObj = [textObj font];
		[fontObj set];
		PSsetgray([textObj textGray]);
		PSmoveto(layInfo->rect.origin.x, layInfo->rect.size.height);
		hiddenChar = [activeCell hiddenChar];
		for(c = 0; c < charCount; c ++)
			buffer[c] = hiddenChar;
		buffer[c] = 0;
		PSshow(buffer);
	}
	[textObj getSel: &start : &end];
	if( end.cp > start.cp )
	{	// Calc highlight area
	NXRect hrect;
		hrect.origin.x = start.x;
		hrect.origin.y = start.y;
		hrect.size.width = end.x - start.x;
		hrect.size.height = start.ht;
		NXHighlightRect(&hrect);
	}

	return 0;
}

- initTextCell:(const char *) aString
{
	[super initTextCell: aString];
	[super setScrollable: YES];
	[super setWrap: NO];
	password[0] = 0;
	if( aString != 0 )
		strcpy(password, aString);
	hiddenChar = '*';
	[self setIsVisible: NO];
	editor = nil;

	return self;
}

- (const char *) stringValue
{
//fprintf(stderr, "%s: stringValue<%s>\n", [self name], password);
	if( password[0] == 0 )
		return 0;
	return password;
}

- setStringValue:(const char *) aString
{
//fprintf(stderr, "%s: setStringValue<%s>\n", [self name], aString);
	password[0] = 0;
	if( aString != 0 )
		strcpy(password, aString);
	if( isVisible == NO )
		[self setStringValueNoCopy: [self hiddenString] shouldFree: NO];
	else
		[self setStringValueNoCopy: password shouldFree: NO];
	return self;
}
- setIsVisible:(BOOL) flag
{
//fprintf(stderr, "%s: setIsVisible<%d>, pw=%s\n", [self name],
//	flag, password);
	isVisible = flag;
	if( isVisible == NO )
		contents = [self hiddenString];
	else
		contents = password;
	return self;
}
- (BOOL) isVisible
{
	return isVisible;
}
- editor
{
	return editor;
}

- setHiddenChar:(unsigned short) value
{
	hiddenChar = value;
	return self;
}

- (const char *) hiddenString
{
static char buffer[128];
int c, charCount;

	charCount = strlen(password);
	for(c = 0; c < charCount; c ++)
		buffer[c] = hiddenChar;
	buffer[c] = 0;
	return buffer;
}
- (unsigned short) hiddenChar
{
	return hiddenChar;
}

- edit:(const NXRect *)aRect inView:controlView editor: textObj delegate:anObject event:(NXEvent *)theEvent
{
id ret;

//fprintf(stderr, "%s: edit\n", [self name]);
	editor = textObj;
	prevDrawFunc = [editor drawFunc];
	activeCell = self;
	contents = password;
	[editor setDrawFunc:(NXTextFunc)DrawALine];
	ret = [super edit: aRect inView: controlView editor: textObj
		delegate: anObject event: theEvent];
	return ret;
}

- select:(const NXRect *)aRect inView: aView editor: textObj
	delegate: anObject start:(int) selStart length:(int) selLength
{
id ret;

//fprintf(stderr, "%s: select\n", [self name]);
	editor = textObj;
	prevDrawFunc = [editor drawFunc];
	[editor setDrawFunc:(NXTextFunc)DrawALine];
	activeCell = self;
	contents = password;
	ret = [super select: aRect inView: aView editor: textObj
		delegate: anObject start: selStart length: selLength];
	return ret;
}

- endEditing: textObject
{
id ret;
//fprintf(stderr, "%s: endEditing\n", [self name]);
	ret = [super endEditing: textObject];
	[textObject setDrawFunc: prevDrawFunc];
	editor = nil;
	activeCell = nil;

	return ret;
}

@end
