#import "ToyView.h"
#import <dpsclient/wraps.h>
#import <appkit/publicWraps.h>
#import <appkit/NXImage.h>
#import <appkit/NXBitmapImageRep.h>
#import <appkit/Application.h>
#import <stdlib.h>

@implementation ToyView

/* Local Method */
- setupInfo
{
	NXRect rect;
	NXImageRep *rep;
	int x;

	[image getSize: &origSize];
	if (origSize.width == 0 || origSize.height == 0)
		return nil;	/* maybe Filter error */
	rawmap = NULL;
	[image setScalable: YES];
	[image setDataRetained: YES];
	// [image setBackgroundColor: NX_COLORWHITE];
	rep = [image bestRepresentation];
	if ((x = [rep pixelsWide]) != NX_MATCHESDEVICE
			&& x != origSize.width) {
		origSize.width = x;
		origSize.height = [rep pixelsHigh];
		[image setSize: &origSize];
	}
	scaleFactor = 1.0;
	backgray = 1.0;		/* White */
	rect.size = curSize = origSize;
	rect.origin.x = rect.origin.y = 0;
	[self initFrame: &rect];

	comInfo = (commonInfo *)malloc(sizeof(commonInfo));
	comInfo->width	= origSize.width;
	comInfo->height	= origSize.height;
	comInfo->bits	= [rep bitsPerSample];
	comInfo->numcolors = [rep numColors]; /* without alpha */
	comInfo->alpha	= [rep hasAlpha];
	if ( [rep isKindOf:[NXBitmapImageRep class]] ) {
		comInfo->xbytes	= [(NXBitmapImageRep *)rep bytesPerRow];
		comInfo->cspace	= [(NXBitmapImageRep *)rep colorSpace];
		comInfo->isplanar = [(NXBitmapImageRep *)rep isPlanar];
		comInfo->type = Type_tiff;
	}else {
		comInfo->xbytes	= 0;
		//  comInfo->cspace	= 0;  DON'T CARE
		comInfo->alpha	= YES;
		comInfo->isplanar = YES;	/* maybe... */
		comInfo->type = Type_eps;
	}
	comInfo->palette = NULL;
	comInfo->palsteps = 0;
	comInfo->memo[0] = 0;

	selectRect.size.width = 0.0;
	selectRect.size.height = 0.0;

	return self;
}

- initFromFile:(const char *)filename
{
	if ((image = [[NXImage alloc] initFromFile: filename]) == nil)
		return nil;
	[ToyView cursor];
	return [self setupInfo];
}

- initFromStream:(NXStream *)stream
{
	if ((image = [[NXImage alloc] initFromStream: stream]) == nil)
		return nil;
	[ToyView cursor];
	return [self setupInfo];
}


- initDataPlanes:(unsigned char **)planes info:(commonInfo *)cinf
{
	NXRect frect;
	NXBitmapImageRep *imageRep;
	int spp;

	frect.origin.x = frect.origin.y = 0;
	origSize.width  = cinf->width;
	origSize.height = cinf->height;
	frect.size = curSize = origSize;
	scaleFactor = 1.0;
	backgray = 1.0;		/* White */
	rawmap = planes[0];
	comInfo = cinf;

	[self initFrame: &frect];
	spp = cinf->numcolors;
	if (cinf->alpha) spp++;
	imageRep = [[NXBitmapImageRep alloc] initDataPlanes: planes
		    pixelsWide: cinf->width	pixelsHigh: cinf->height
		    bitsPerSample: cinf->bits	samplesPerPixel: spp 
		    hasAlpha: cinf->alpha	isPlanar: YES 
		    colorSpace: cinf->cspace	bytesPerRow: cinf->xbytes 
		    bitsPerPixel: cinf->bits];
	if (imageRep == nil)
		return nil;
	if ((image = [[NXImage alloc] initSize:&origSize]) == nil) {
		[imageRep free];
		return nil;
	}
	[image setScalable: YES];
	[image setDataRetained: YES];
	[image useRepresentation:imageRep];
	// [image setBackgroundColor: NX_COLORWHITE]; NO NEED!!
	[ToyView cursor];
	return self;
}

- setCommText: (TextField *)text
{
	commText = text;
	return self;
}

- (NXSize *)originalSize
{
	return &origSize;
}

- (NXSize *)resize: (float)factor
{
	int wd = (int)(origSize.width * factor + 0.5);
	int ht = (int)(origSize.height * factor + 0.5);
	if (wd > MAXWidth || ht > MAXWidth || wd < 4 || ht < 4)
		return NULL;
	curSize.width = wd;
	curSize.height = ht;
	scaleFactor = factor;
	backgray = 1.0;		/* White */
	[self sizeTo: curSize.width : curSize.height];
	[window invalidateCursorRectsForView:self];
	[image setSize: &curSize];
	[self clearDraggedLine];
	return &curSize;
}

- free
{
	if (image != nil)
		[image free];
	if (rawmap) free((void *)rawmap);
	/* NXBitmapImageRep's Bug ??
		Method "initDataPlanes: planes ..." allocates inside
		an area of 20 bytes such as "unsigned char *planes[5]".
		This area is not freed and becomes a leak node.
	*/
	if (comInfo) {
		if (comInfo->palette) free((void *)comInfo->palette);
		free((void *)comInfo);
	}
	return [super free];
}

- (NXImage *)image
{
	return image;
}

- (commonInfo *)commonInfo
{
	return comInfo;
}

- (NXRect *)selectedRect
{
	return &selectRect;
}

- (NXRect *)selectedScaledRect
{
	static NXRect rct;

	if (scaleFactor == 1.0) return &selectRect;
	rct.size.width = (int)(selectRect.size.width / scaleFactor + 0.5);
	rct.size.height = (int)(selectRect.size.height / scaleFactor + 0.5);
	rct.origin.x = (int)(selectRect.origin.x / scaleFactor + 0.5);
	rct.origin.y = (int)(selectRect.origin.y / scaleFactor + 0.5);
	return &rct;
}

- (float)scaleFactor
{
	return scaleFactor;
}

/* Overload */
- beginPrologueBBox:(const NXRect *)boundingBox
	creationDate:(const char *)dateCreated
	createdBy:(const char *)anApplication
	fonts:(const char *)fontNames
	forWhom:(const char *)user
	pages:(int)numPages
	title:(const char *)aTitle
{
/* Not to use the title of the window as %%Title: of EPS file. */

	char buf[MAXFILENAMELEN];
	const char *p;
	int i, cc;

	p = aTitle;
	if (!p)
		p = [window title];
	for (i = 0; ; i++) {
		cc = p[i];
		if (cc == 0 || (cc > 0 && cc <= ' ')
		|| cc == '(' || cc == ')' ) break;
		buf[i] = cc;
	}
	buf[i] = 0;
	return [super beginPrologueBBox:boundingBox
		creationDate:dateCreated
		createdBy:anApplication
		fonts:fontNames
		forWhom:user
		pages:numPages
		title:(const char *)buf];
}

@end
