#import  "TVController.h"
#import  <dpsclient/dpsNeXT.h>	// for TimedEntry
#import  <appkit/Application.h>
#import  <appkit/publicWraps.h>
#import  <appkit/Control.h>
#import  <appkit/MenuCell.h>
#import  <appkit/workspaceRequest.h>
#import  <objc/NXBundle.h>	/* LocalizedString */
#import  <defaults/defaults.h>
#import  <stdio.h>
#import  <stdlib.h>
#import  <string.h>
#import  <objc/zone.h>
#import  <bsd/libc.h>
#import  <mach/mach_init.h>
#import  "ToyWin.h"
#import  "ToyView.h"
#import  "ImageOpCtr.h"
#import  "ImageSave.h"
#import  "common.h"
#import  "strfunc.h"

#define	 MAXWindows	80

@implementation TVController (WindowManager)

static int winp = 0, showp = 0;
static ToyWin *wintab[MAXWindows];
static DPSTimedEntry teNum;

- newWindow: (ToyWin *)win
{
	if (winp < MAXWindows)
		wintab[winp++] = win;
	return self;
}

- checkWindow: (ToyWin *)win delete:(BOOL)delflag;
{
	/* Return Value:  nil: No such window,  self: Success */
	int i, j;

	j = -1;
	for (i = 0; i < winp; i++)
		if (wintab[i] == win) {
			j = i;
			break;
		}
	if (j < 0) return nil;
	if (delflag) {
		--winp;
		for (i = j; i < winp; i++)
			wintab[i] = wintab[i + 1];
	}
	return self;
}

- deleteAllWindow: sender
{
	int i, n;

	n = winp, winp = 0;
	for (i = 0; i < n; i++)
		[[wintab[i] window] performClose: sender];
	return self;
}


static void wakeup(DPSTimedEntry te, double now, void *data)
{
	if (showp >= winp) {
		DPSRemoveTimedEntry(teNum);
		showp = 0;
	}else
		[[wintab[showp++] window] orderFront: (id)data];
}

- showAllWindow: sender
{
	if (winp <= 0) return self;
	if (showp > 0) {
		DPSRemoveTimedEntry(teNum);
		showp = 0;
	}else {
		[[wintab[0] window] orderFront: sender];
		teNum = DPSAddTimedEntry(0.8, &wakeup, self, NX_BASETHRESHOLD);
		showp = 1;
	}
	return self;
}

- keyWindow
{
	int i;

	for (i = 0; i < winp; i++)
		if ([[wintab[i] window] isMainWindow])
			return wintab[i];
	return (winp > 0) ? wintab[winp - 1] : nil;
}

- (BOOL)isOpened: (const char *)newfile
{
	int i;

	for (i = 0; i < winp; i++)
		if (strcmp(newfile, [wintab[i] filename]) == 0) {
			[[wintab[i] window] makeKeyAndOrderFront: self];
			return YES;
		}
	return NO;
}

- (BOOL)isOpenedID: (ToyWin *)win
{
	int i;

	for (i = 0; i < winp; i++)
		if (wintab[i] == win)
			return YES;
	return NO;
}


/****** Print *****************************/

- print: sender
{
	id	tw;

	if ((tw = [self keyWindow]) == nil)
		NXBeep();
	else
		[tw print:sender];
	return self;
}

/****** SaveAs... *************************/

/* Local Method */
- allocImageSave
{
	static id classImgSv = nil;

	if (classImgSv == nil) {
		char bdir[MAXFILENAMELEN];
		id bundle;
		int n;

		n = dircopy(bdir, NXArgv[0], YES);
		strcpy(&bdir[n], "ImageSave.bundle");
		bundle = [[NXBundle alloc] initForDirectory: bdir];
		if (bundle == nil) /* ERROR */
			return nil;
		classImgSv = [bundle classNamed:"ImageSave"];
		if (classImgSv == nil) /* ERROR */
			return nil;
	}
	return [classImgSv alloc];
}

- saveAs: sender
{
	ToyWin	*tw;
	id	imgsv;
	commonInfo	*cinf;
	char *p;

	if ((tw = (ToyWin *)[self keyWindow]) == nil) {
		NXBeep();
		return self;
	}
	imgsv = [[self allocImageSave] initWithWin: tw];

	switch ([sender selectedTag]) {
	case 0: [imgsv saveAsTiff: sender];
		break;
	case 1: [imgsv saveAsEPS: sender];
		break;
	case 2: [imgsv saveAsType: Type_bmp];
		break;
	case 3:
		if ((p = [imgsv saveAsGif: NULL]) != NULL) {
			[imgsv free];
			cinf = [[tw toyView] commonInfo];
			if (cinf->type == Type_eps)
				[imageOpCtr newBitmap: self];
			[imageOpCtr reduce: self];
			tw = (ToyWin *)[self keyWindow];
			imgsv = [[self allocImageSave] initWithWin: tw];
			(void)[imgsv saveAsGif: p];
		}
		break;
	case 4: [imgsv saveAsType: Type_jpg];
		break;
	case 5: [imgsv saveAsType: Type_jbg];
		break;
	case 6: [imgsv saveAsType: Type_ppm];
		break;
	case 7: [imgsv saveAsXBM: sender];
		break;
	case 8: [imgsv saveAsPng: sender];
		break;
	}
	[imgsv free];
	return self;
}

/****** Info.Panel attraction *************************/

- attraction: sender
{
	static int	cnt = 0;

	if ((++cnt & 0x7) == 0) {
		[sender setType: NX_TOGGLE];
		[sender setState: 1];
	}else {
		[sender setType: NX_MOMENTARYPUSH];
		[sender setState: 0];
	}
	return self;
}

#ifdef  ToyViewer2_5
- attraction: sender
{
	NXRect	wrct, brct;
	NXPoint pnt[2];
	NXImage *img;
	id	ws, win;

	img = [sender image];
	[sender getFrame:&brct];
	[(win = [sender window]) getFrame:&wrct];
	pnt[0].x = wrct.origin.x + brct.origin.x + 4;
	pnt[0].y = wrct.origin.y + brct.origin.y + 4;
	[[NXApp appIcon] getFrame:&wrct];
	pnt[1].x = wrct.origin.x + 8;
	pnt[1].y = wrct.origin.y + 8;
	ws = [Application workspace];
	[win performClose: self];
	[ws slideImage:img from:&pnt[0] to:&pnt[1]];
	sleep(1);
	[ws slideImage:img from:&pnt[1] to:&pnt[0]];
	[win makeKeyAndOrderFront: self];
	return self;
}
#endif

@end
