#include <sys/types.h>
#include <ansi/ctype.h>
#include <bsd/pwd.h>
#import "IcaoController.h"
#import <appkit/appkit.h>
#import "IcaoDefinitions.h"
#import "IcaoObjects.h"
#import "mapdraw.h"
#import "MapController.h"
#import "PrefController.h"
#import "MarginPageLayout.h"
#import "MailSpeaker.h"


@implementation IcaoController

+ initialize
{
	static NXDefaultsVector IcaoDefaults =
	{{IPD_RUNWAYUNIT, "2"},
	 {IPD_ELEVATIONUNIT, "1"},
	 {IPD_RANGEUNIT, "4"},
	 {IPD_AUTOLAUNCH, "0"},
	 {IPD_ONSTARTUP, "1"},
	 {IPD_STARTUPFILE, "/foo.iwp"},
	 {IPD_ONLOADING, "1"},
	 {IPD_PROJECTIONTYPE, "1"},
	 {IPD_OPTIMIZEMONO, "1"},
	 {IPD_RUBBERUNIT, "4"},
	 {IPD_AUTOUNIT, "4"},
	 {IPD_AUTOROUTE, "104 44 385 276 0 0 956 768 "},
	 {IPD_SUGGESTUNIT, "3"},
	 {NULL, NULL}};

	NXRegisterDefaults(APPNAME, IcaoDefaults);

	return self;
}

- (BOOL)setPort
{
	/* Should call this before any remote message to make sure Mail.app is
	/ running and mailSpeaker 's port is current.  Get named port ' Mail '.  
	/ This will launch Mail.app if not already.Get named port 'MailSendDemo'
  / (this is the one we will actually talk to).Set mailSpeaker 's port to be this one. 
	*/

	port_t              mailPort = NXPortFromName("Mail", NULL);

	if (mailPort == PORT_NULL)
	{
		(NXRunAlertPanel("Accessing Mail", "Unable to connect to Mail.app",
										 NULL, NULL, NULL));
		return NO;
	}

	mailPort = NXPortFromName("MailSendDemo", NULL);

	if (mailPort == PORT_NULL)
	{
		(NXRunAlertPanel("Accessing Mail", "Unable to connect to Mail.app",
										 NULL, NULL, NULL));
		return NO;
	}

	[mailSpeaker setSendPort:mailPort];
	return YES;
}

- (const char *)user
{
	static char        *username = (char *)0;
	struct passwd      *pwdentry;
	static char         ubuf[128];
	char               *pc;

	pwdentry = getpwnam(NXUserName());
	username = ((pwdentry) ? pwdentry->pw_gecos : "");

	/*
	 * extended GECOS field handling, Detlev Droege,
	 * droege@informatik.uni-koblenz.de, December 1991 
	 */
	if (pc = index(username, ','))
		*pc = 0;										/* strip ','-part of gecos field, clobbers
																 * pw_gecos !! */
	if (index(username, '&'))
	{
		/* do '&' expansion */
		pc = ubuf;
		while (*username)
		{
			if (*username == '&')
			{
				strcpy(pc, pwdentry->pw_name);
				*pc = toupper(*pc);
				while (*pc)
					pc++;									/* ==  pc += strlen(..->pw_name) */
			}
			else
				*pc++ = *username;
			username++;
		}
		*pc = 0;
		username = ubuf;
	}
	return (const char *)username;
}

- routeAdjust
{
	return routeAdjust;
}

- (BOOL)menuActive:menuCell
{
	BOOL                shouldBeEnabled;

	shouldBeEnabled = [[[NXApp mainWindow] delegate]
										 isKindOf:[MapController class]];

	if ([menuCell isEnabled] != shouldBeEnabled)
	{

		/*
		 * Menu cell is either enabled and shouldn't be, or it is not enabled and
		 * should be. In any event, set the correct state. 
		 */
		[menuCell setEnabled:shouldBeEnabled];
		return YES;									/* redisplay */
	}
	return NO;										/* no change */
}

- (BOOL)switchAutorouteMenu:menuCell
{
	BOOL                shouldBeEnabled;

	shouldBeEnabled = [[[NXApp mainWindow] delegate]
										 isKindOf:[MapController class]];

	if (shouldBeEnabled)
		shouldBeEnabled = [[[NXApp mainWindow] delegate] canAutoroute];

	if ([menuCell isEnabled] != shouldBeEnabled)
	{

		/*
		 * Menu cell is either enabled and shouldn't be, or it is not enabled and
		 * should be. In any event, set the correct state. 
		 */
		[menuCell setEnabled:shouldBeEnabled];
		return YES;									/* redisplay */
	}
	return NO;										/* no change */
}


- showPreferencesPanel:sender
{
	if (!prefPanel)
	{
		if ([NXApp loadNibSection:"Preferences.nib" owner:self] == nil)
			return nil;
	}

	[prefPanel makeKeyAndOrderFront:sender];
	return self;
}

- showInfoPanel:sender
{
	if (!infoPanel)
	{
		if ([NXApp loadNibSection:"Info.nib" owner:self] == nil)
			return nil;
	}

	[self updateInfoPanel];
	[infoPanel makeKeyAndOrderFront:sender];

	return self;
}


- updateInfoPanel;
{
	char                infoText[256];

	if (infoPanel)
	{
		sprintf(infoText, NXLS("Currently %i objects in database,\nof which %i are currently visible."), objectno + 1, db_visible);
		[howManyObjects setStringValue:infoText];
	}
	return self;
}


- mapChanged:sender;
{
	//[[[mapWindow delegate] displayButton] setEnabled:NO];
	[self updateInfoPanel];
	return self;
}

- showLegalPanel:sender
{
	if (!legalPanel)
		if ([NXApp loadNibSection:"Legal.nib" owner:self] == nil)
			return nil;

	[legalPanel makeKeyAndOrderFront:sender];

	return self;
}


- sendComments:sender
{
	char                body[4096];
	int                 winNum;

	if ([self setPort])
	{
		sprintf(body, (const char *)NXLS("msg_comments"), VERSION,[self user]);
		[mailSpeaker openSend:&winNum];
		[mailSpeaker setTo:NXLS("to_address") inWindow :winNum];
		[mailSpeaker setCc:NXLS("cc_address") inWindow :winNum];
		[mailSpeaker setSubject:NXLS("msg_icaocom") inWindow :winNum];
		[mailSpeaker setBody:(const char *)body inWindow:winNum];
	}
	return self;
}

- openMapWindow:sender
{
	id                  openPanel;
	char               *types[3] = {"worldpart", "iwp", NULL};

	openPanel = [OpenPanel new];
	[openPanel allowMultipleFiles:NO];
	[openPanel chooseDirectories:NO];
	if ([openPanel runModalForTypes:types])
	{
		[self openMapWindowFromFile:[openPanel filename]];
		if (mapWindow)
			[mapWindow makeKeyAndOrderFront:self];
	}

	return self;
}

- openMapWindowFromFile:(const char *)filename
{
	if ([NXApp loadNibSection:"MapWindow.nib" owner:self] == nil)
		return nil;

	if ([[mapWindow delegate] setupFromFile:filename])
	{
		[mapWindow setTitleAsFilename:filename];
	}
	else
	{
		[mapWindow performClose:self];
		mapWindow = nil;
	}

	return self;
}

@end


@implementation IcaoController(ApplicationDelegate)

- appDidInit:sender
{
	id                  toolsMenu = [toolsSubmenuCell target];
	int                 val;
	const char         *name;
	int                 sendIt = NO;

	/* Setting the AutoUpdate Messages for the MenuCells */
	[printCell setUpdateAction:@selector(menuActive:) forMenu :[NXApp mainMenu]];
	[visibleObjectsCell setUpdateAction:@selector(menuActive:)
	 forMenu :toolsMenu];
	[autoRouterCell setUpdateAction:@selector(switchAutorouteMenu:)
	 forMenu :toolsMenu];
	[suggestTriangleCell setUpdateAction:@selector(menuActive:)
	 forMenu :toolsMenu];

	[NXApp setAutoupdate:YES];

	[NXApp loadNibSection:"PageLayoutAccessory.nib"
	 owner:[MarginPageLayout new]];

	val = atoi(NXGetDefaultValue(APPNAME, IPD_ONSTARTUP));
	switch (val)
	{
	case 1:
		name = NXGetDefaultValue(APPNAME, IPD_STARTUPFILE);
		if (name)
			[self openMapWindowFromFile:name];
		break;
	case 2:
		break;
	}

	[[PrintPanel new] setAccessoryView:routeAdjust];

	/* Set routeAdjust to the PopupButton */
	routeAdjust = [[[[[[routeAdjust contentView] subviews] objectAt:0]
									 contentView] subviews] objectAt:0];

	if (!strcmp(NXGetDefaultValue([NXApp appName], "NXAutoLaunch"), "YES")
			&& atoi(NXGetDefaultValue(APPNAME, IPD_AUTOLAUNCH)))
		[NXApp hide:self];
	else
	if (mapWindow)
		[mapWindow makeKeyAndOrderFront:self];

	if (!(NXGetDefaultValue(APPNAME, IPD_NEWUSER)))
	{
		if (!NXReadDefault("Icao", "Default Mapfile"))
		{
			switch (NXRunAlertPanel(MSG_TITLE, MSG_INFO, MSG_OK, MSG_NOTYET, MSG_NO))
			{
			case NX_ALERTDEFAULT:
				sendIt = YES;
			case NX_ALERTOTHER:
				NXWriteDefault(APPNAME, IPD_NEWUSER, VERSION);
				break;
			case NX_ALERTALTERNATE:
				NXWriteDefault(APPNAME, IPD_NEWUSER, KIND_OF);
				break;
			}
		}
		else												/* this is for the 0.6 to 0.7 update only. */
		{
			switch (NXRunAlertPanel(MSG_TITLE, MSG_UPDATE, NXLS("Yes"), NXLS("No"), NULL
															,0.6, VERSION, NXLS("new_in_0.7")))
			{
			case NX_ALERTDEFAULT:
				sendIt = YES;
			case NX_ALERTALTERNATE:
				NXWriteDefault(APPNAME, IPD_NEWUSER, VERSION);
				break;
			}
		}
	}
	else
	{
		if (strcmp(NXGetDefaultValue(APPNAME, IPD_NEWUSER), KIND_OF) == 0)
		{
			switch (NXRunAlertPanel(MSG_TITLE, MSG_LATER, NXLS("Yes"), NXLS("No"), NULL))
			{
			case NX_ALERTDEFAULT:
				sendIt = YES;
			case NX_ALERTALTERNATE:
				NXWriteDefault(APPNAME, IPD_NEWUSER, VERSION);
				break;
			}
		}
		else												/* general update... to be rewritten. */
		{
			float               former_version = atof(NXGetDefaultValue(APPNAME, IPD_NEWUSER));

			if (former_version < (float)atof(VERSION))
			{
				switch (NXRunAlertPanel(MSG_TITLE, MSG_UPDATE, NXLS("Yes"), NXLS("No"), NULL
															,former_version, VERSION, NXLS("new_in_0.7")))
				{
				case NX_ALERTDEFAULT:
					sendIt = YES;
				case NX_ALERTALTERNATE:
					NXWriteDefault(APPNAME, IPD_NEWUSER, VERSION);
					break;
				}
			}
		}
	}
	if (sendIt)
	{
		char                body[4096];
		int                 winNum;

		if ([self setPort])
		{
			sprintf(body, (const char *)NXLS("msg_response"), VERSION,[self user]);
			[mailSpeaker openSend:&winNum];
			[mailSpeaker setTo:NXLS("to_address") inWindow :winNum];
			[mailSpeaker setCc:NXLS("cc_address") inWindow :winNum];
			[mailSpeaker setSubject:NXLS("msg_i_use_it") inWindow :winNum];
			[mailSpeaker setBody:(const char *)body inWindow:winNum];
		}
	}

	return self;
}


- (BOOL)appAcceptsAnotherFile:sender
{
	return YES;
}


- (int)appOpenFile:(const char *)filename type:(const char *)aType
{
	[self openMapWindowFromFile:filename];
	return YES;
}


- appWillTerminate:sender
{
	List               *windowList = [NXApp windowList];
	int                 i;
	id                  currentObject;

	for (i = 0; i < [windowList count]; i++)
	{
		currentObject = [[windowList objectAt:i] delegate];
		if ([currentObject isKindOfClassNamed:"MapController"])
			[currentObject appWillTerminate:sender];
	}
	return self;
}
