/* (c) 1992 Dirk Schwarzhans, Matthias Braun
   Use under the terms of the GNU General Public License */
   
#import "MainController.h"

#import "pageNumber.h"
#import "VTFontInit.h"

#import <appkit/Application.h>
#import <appkit/Pasteboard.h>
#import <appkit/PrintInfo.h>
#import <appkit/nextstd.h>
#import	<string.h>

@implementation MainController

- init
{
	[super init];
	inspector = nil;
	activeContainer = nil;
	windowList = [[HashTable alloc] initKeyDesc:@encode(Window *)
									valueDesc:@encode(WindowContainer *)];

	return self;
}

- free
{
	[windowList free];
	[savePanel free];
	
	return [super free];
}

//********************
// interne Methoden
//********************
- windowServices:(BOOL)mode
{
	[inspector setEnabled:mode];
//	[menuSave setEnabled:mode];
//	[menuSaveAs setEnabled:mode];
	[menuSaveEPS setEnabled:mode];
	[menuClose setEnabled:mode];
	[menuCut setEnabled:mode];
	[menuCopy setEnabled:mode];
	[menuPaste setEnabled:mode];
	[menuCopyEPS setEnabled:mode];
	[menuSelectAll setEnabled:mode];
	[menuPrint setEnabled:mode];
	
	return self;
}

- (Window *)createNewWindow
{
	Window			*window;
	VideoTextView	*view;
	NXRect			rect;
	
	if (activeContainer)
	{
		[[activeContainer window] getFrame:&rect];
		activeContainer = [[WindowContainer alloc] init];
		window = [activeContainer window];
		[window moveTo:rect.origin.x + 20.0 :rect.origin.y - 20.0];
	}
	else
	{
		activeContainer = [[WindowContainer alloc] init];
		window = [activeContainer window];
	}

	view = [activeContainer view];
	[view setFontSize:25];
	[view display];
	[view setDelegate:self];
	[windowList insertKey:window value:activeContainer];
	[window setDelegate:self];
	[window makeKeyAndOrderFront:self];
	[inspector inspectView:view];
	if ([windowList count] == 1)
		[self windowServices:YES];

	[pageSupplier setMainWindow:window];
		
	return window;
}


// ****************************************************************
// Hier folgen die Methoden, die durch Menöpunkte aufgerufen werden
// ****************************************************************
- inspectorRequested:sender
{
	BOOL mode;
	
	mode = ([windowList count] != 0);

	if (inspector == nil)
		{
		inspector = [[Inspector alloc] initAndEnable:mode];
		if (activeContainer != nil)
			[inspector inspectView:[activeContainer view]];
		[inspector setDelegate:self];
		}
	else
		[inspector makeKeyAndOrderFront:self];
	
    return self;
}

- openNewWindow:sender
{
	[self requestPage:100 subpage:0 forWindow:[self createNewWindow]];
	
	return self;
}

- createEPSFile:sender
{
    NXStream 		*stream;
	NXRect			rect;
	VideoTextView	*view;

	tag = [pageSupplier holdPage:YES];
	[savePanel setRequiredFileType:"eps"];	
	if([savePanel runModalForDirectory:NULL file:NULL])
	{
		stream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
		view = [activeContainer view];
		[view getBounds:&rect];
		[view copyPSCodeInside:&rect to:stream];
		NXSaveToFile(stream, [savePanel filename]);	
		NXCloseMemory(stream, NX_FREEBUFFER);
	}
	tag = [pageSupplier holdPage:[activeContainer isHeld]];
	
	return self;
}

- copyAsEPS:sender
{
	const char *types[] = {NXPostScriptPboardType, NULL};

	tag = [pageSupplier holdPage:YES];
	[[activeContainer view] writeSelectionToPasteboard:[Pasteboard new] types:types];
	tag = [pageSupplier holdPage:[activeContainer isHeld]];
	
	return self;
}

- print:sender
{
	tag = [pageSupplier holdPage:YES];
	[[activeContainer view] printPSCode:self];
	tag = [pageSupplier holdPage:[activeContainer isHeld]];

	return self;
}

- openTimePanel:sender
{
	[timePanel setDelegate:self];
	[timePanel makeKeyAndOrderFront:sender];
	[pageSupplier requestClockMessages:YES];

	return self;
}

// *****************************************
// Methoden als 'delegate' von VideoTextView
// *****************************************
- requestPage:(int)pageInt subpage:(int)subpageInt forWindow:(Window *)window
{
	VTPageNumber page;
	VTSubpageNumber subpage;
	char	title[100];

	if (window == nil)
		window = [self createNewWindow];		

	[inspector setRequestPage:pageInt];
	[inspector setRequestSubpage:subpageInt];
	if (subpageInt == 0)
		[inspector setCareSubpage:NO];
	else
		[inspector setCareSubpage:YES];
	
	VTNumbersFromInt(&page, &subpage, pageInt, subpageInt);

	if (subpageInt != 0)
	{
		sprintf(title, "Video-TeXT: %03d.%04d wird gesucht", pageInt, subpageInt);
		tag = [pageSupplier pageRequest:page subpage:subpage];
	}
	else
	{
		sprintf(title, "Video-TeXT: %03d wird gesucht", pageInt);
		tag = [pageSupplier pageRequest:page];
	}
	[window setTitle:title];
	[inspector setHoldPageSwitch:NO];
	[activeContainer setHeld:NO];
	
	return self;
}

- dontDisturb:(BOOL)mode
{
	tag = [pageSupplier holdPage:mode];
	[activeContainer setHeld:mode];
	[inspector setHoldPageSwitch:mode];

	return self;
}

// *************************************
// Methoden als 'delegate' von Inspector
// *************************************
- subpageBrowse:(int)direction
{
	VTSubpageNumber subpage;

	if (direction > 0)
		tag = [pageSupplier nextSubpage:&subpage];
	else
		tag = [pageSupplier previousSubpage:&subpage];

	[inspector setCareSubpage:YES];
	[inspector setRequestSubpage:intFromVTSubpageNumber(subpage)];

	return self;
}

- clearPageMemoryRequested
{
	tag = [pageSupplier forgetAll];
	[activeContainer setHeld:NO];
	[inspector setHoldPageSwitch:NO];
	[self requestPage:100 subpage:0 forWindow:[activeContainer window]];

	return self;
}

- holdPage:(BOOL)mode;
{
	tag = [pageSupplier holdPage:mode];
	[activeContainer setHeld:mode];

	return self;	
}

- setIVTRegisters:(unsigned char)mode :(unsigned char)normDispCtrl 
  :(unsigned char)newsDispCtrl :(unsigned char)dispMode
{
	[pageSupplier writeModeRegister:mode];
	[pageSupplier writeDisplayControlRegisters:normDispCtrl :newsDispCtrl];
	[pageSupplier writeDisplayModeRegister:dispMode];
	
	return self;
}
// ****************************************
// Methoden als 'delegate' von Listener
// ****************************************
-(int)updateClock:(char *)time size:(int)bytes return:(int *)dummy
{
	*dummy = 0;
	[timeText setStringValue:time];

	return 0;
}

-(int)updateRollingHeader:(char *)pageNumber size:(int)bytes return:(int *)dummy
{
	*dummy = 0;
	[inspector setIncomingPage:pageNumber];
	
	return 0;
}

-(int)updatePageData:(char *)pageInfo size:(int)bytes return:(int *)dummy
{
	VTPageNumber	pageNumber;
	VTSubpageNumber	subpageNumber;
	PagePacket		*packet;
	WindowContainer	*container;
	char			title[100], number[5];
		
	*dummy = 0;
	packet = (PagePacket *)pageInfo;

	if (packet->tag == tag)
	{
		container = [windowList valueForKey:packet->window];
		[[container view] setPageData:packet->data];

		strcpy(title,"Video-TeXT: ");
		VTNumbersFromPageData(&pageNumber, &subpageNumber, packet->data);
		stringFromVTPageNumber(number, pageNumber);
		strcat(title, number);
		strcat(title, ".");
		stringFromVTsubpageNumber(number, subpageNumber);
		strcat(title, number);
		[packet->window setTitle:title];
	}
	
	return 0;
}

-(int)printError : (char *) message
{
	NXLogError(message);

	return 0;
}

// **********************************
// Methoden als 'delegate' von Window
// **********************************
- windowWillClose:sender
{
	if (sender == timePanel)
	{
		[pageSupplier requestClockMessages:NO];
		return self;
	}
	
	activeContainer = nil;

	[windowList removeKey:sender];
	if ([windowList count] == 0)
		[self windowServices:NO];

	tag = [pageSupplier windowClosed:sender];
	
	return self;
}

- windowDidBecomeMain:sender
{
	activeContainer = (WindowContainer *)[windowList valueForKey:sender];
	[inspector inspectView:[activeContainer view]];
	[inspector setHoldPageSwitch:[activeContainer isHeld]];
	tag = [pageSupplier setMainWindow:sender];
	
	return self;
}

// ***************************************
// Methoden als 'delegate' von Application
// ***************************************
- appDidInit:sender
{
	PrintInfo *info;
	const char * const sendTypes[] = {NXAsciiPboardType, NXPostScriptPboardType, NULL};
	
	// bevorzugte Parameter för das Drucken einstellen	
	info = [NXApp printInfo];
	[info setOrientation:NX_LANDSCAPE andAdjust:YES];
	[info setMarginLeft:57 right:57 top:35 bottom:20];
	[info setVertPagination:NX_FITPAGINATION];
	[info setHorizPagination:NX_FITPAGINATION];

	// Video-Text-ZeichensÙtze definieren
	PSWVTFont1Init();	// Der PostScript-Kontext ist global för die Applikation...
	PSWVTFont2Init();	// ...deshalb gelten diese Definitionen för alle Views.

	
	listener = [[VTListener alloc] init];
	[listener usePrivatePort];
	[listener setDelegate:self];
	[listener setPriority:NX_MODALRESPTHRESHOLD];
	[listener addPort];
	
	if ((pageSupplier = [[PageSupplier alloc] initPort:[listener listenPort]]) == nil)
		[NXApp terminate:self];
	
	tag = 0;

	savePanel = [SavePanel new];
	[NXApp registerServicesMenuSendTypes:sendTypes andReturnTypes:NULL];
	
	[self requestPage:100 subpage:0 forWindow:[self createNewWindow]];
	[self inspectorRequested:self];

	return self;
}


@end
