#import "RouteController.h"
#import <appkit/appkit.h>
#import "IcaoMap.h"
#import "MapController.h"
#import "soaring.h"
#import "router.h"
#import "geometry.h"

#ifdef HAVE_TRUE_ROUTEOBJECTS
#import <dbkit/DBTableView.h>
#endif

@implementation RouteController



- awakeFromNib
{
	NXRect	aRect;
	char		*ptr;
	
	[triangleBrowser setTarget:self];
	[triangleBrowser setAction:@selector(objectClicked:)];
	[triangleBrowser setDoubleAction:@selector(objectDoubleClicked:)];
	[triangleBrowser acceptArrowKeys:YES andSendActionMessages:YES];

	[[mapController mapWindow] getFrame:&aRect 
			andScreen: &autoRouteData.theScreen];
	ptr = alloca(strlen(NXGetDefaultValue(APPNAME, IPD_AUTOROUTE))+1);
	strcpy(ptr, NXGetDefaultValue(APPNAME, IPD_AUTOROUTE));
	ptr=strtok(ptr, " ");
	/* First x */
	autoRouteData.topLeft.x = atoi(ptr);
	ptr=strtok(NULL, " ");
	/* Second y */
	autoRouteData.topLeft.y = atoi(ptr);
	ptr=strtok(NULL, " ");
	/* ignore width */
	ptr=strtok(NULL, " ");
	/* add height */
 	autoRouteData.topLeft.y += atoi(ptr);
	
	ptr = (char *)NXGetDefaultValue(APPNAME, IPD_SUGGESTUNIT);
	if (ptr)
	{
		[[[suggestUnit target] itemList] selectCellWithTag:atoi(ptr)];
		[suggestUnit 
				setTitle:[[[[suggestUnit target] itemList] selectedCell] title]];
	}
	
	return self;
}

- setup
{
	return self;
}


- objectDoubleClicked:sender
{
	id scalePopup = [mapController scalePopup];
	[self objectClicked:self];
	[[mapController mapView] makeRouteFit:NO];
	[scalePopup setTitle:[[[[scalePopup target] itemList] 
			cellAt:scale:0] title]];
	[mapController displayMap];		
	return self;
}

char *noUnderline(char *inStrg)
{
#ifdef oliver
	int			j;
	
	for (j = 0; j < strlen(inStrg); j++)
		if (inStrg[j] == '_')
			inStrg[j] = ' ';
#endif
	return inStrg;	
}

- objectClicked:sender
{
	int					pos;
	char				*TO, *via1, *via2;

	pos = [[triangleBrowser matrixInColumn:0] selectedRow];
	
	if (pos != -1)
	{
		TO = noUnderline(strdup(takeOffObjc->name));
		via1 = noUnderline(strdup(turn1[pos]->name));
		via2 = noUnderline(strdup(turn2[pos]->name));
		
		/* don't initiate a Redraw if this is invoked by objectDoubleClicked */
		[mapController setNewRoute:(sender != self)
				TO:TO
				via:via1
				via:via2
				via:""
				dest:TO];
		
		free(TO);
		free(via1);
		free(via2);
	}
	return self;
}

- suggest:sender
{
	takeOffObjc = currentroute[FROM] = objectfromnamelist( objectThatMatches
			([takeOffField stringValue]));
	suggest([distanceField intValue]/UNIT_CHANGE(IPD_SUGGESTUNIT)*1.852);

	[triangleBrowser reloadColumn:0];
	return self;
}

- textDidGetKeys:textObject isEmpty:(BOOL)flag
{
	[suggestButton setEnabled:((strcmp([takeOffField stringValue], "") != 0)
			&& ([distanceField intValue] > 0))];
	return self;
}

- setNewTakeoff:(const char*)takeoff
{
	[takeOffField setStringValue:takeoff];
	[suggestButton setEnabled:((strcmp(takeoff, "") != 0)
			&& ([distanceField intValue] > 0))];
	return self;
}

- soaringPanel
{
	return soaringPanel;
}

- tryToAutoroute:sender
{
	OBJECT	*route[5];
	char	*wholetext = NXZoneMalloc(theZone, MC_MAXLINES*MC_MAXLEN); 
	int	i, k;
	TextField	*aTextField;
	NXRect	aRect = {0, 0, 10, 10};
	
	/* Set the Objects we can navigate to */
	router_radionav();
	
	for (i=0, k=0; i< 5; i++)
	{
		route[i] = NULL;
		if (strlen([[[mapController routeVia] cellAt:i:0] stringValue]))
			route[k++] = objectfromnamelist(objectThatMatches([
					[[mapController routeVia] cellAt:i:0] stringValue]));
	}
	
	/* The Routine expects the array to be "continous" */
	if (k!=5)
	{
		route[4] = route[k-1];
		route[k-1] = NULL;
	}
	
	/* in case next_findroute first appends */
	wholetext[0] = '\000';
	next_findroute(wholetext, route[0], route[1], route[2], route[3], route[4]);

	/* if it didn't work. */	
	if (!strlen(wholetext))
	{
		NXBeep();
		return nil;
	}	
	
	if (autoRouteData.window)
	{
		[autoRouteData.window getFrame:&aRect
		 		andScreen:&autoRouteData.theScreen];
		autoRouteData.topLeft.x = NX_X(&aRect);
		autoRouteData.topLeft.y = NX_MAXY(&aRect);
		[autoRouteData.window close];
	}
		
	aTextField = [[TextField alloc] initFrame:&aRect];
	
	[aTextField setSelectable:YES];
	[aTextField setBordered:NO];
	[aTextField setBackgroundGray:NX_LTGRAY];
	[aTextField setBackgroundColor:NX_COLORLTGRAY];
	[aTextField setStringValue:wholetext];
	[aTextField setFont:[Font newFont:"Ohlfs" size:10
			matrix:NX_FLIPPEDMATRIX]];
	
	[aTextField sizeToFit];
	[aTextField getFrame:&aRect];
	
	autoRouteData.window = [[Panel alloc] initContent: &aRect
			style: NX_TITLEDSTYLE
			backing: NX_BUFFERED
			buttonMask: NX_CLOSEBUTTONMASK | NX_MINIATURIZEBUTTONMASK
			defer: YES];
	
	[autoRouteData.window setContentView: aTextField];
	[autoRouteData.window setTitle:"Auto Route"];
	[autoRouteData.window setDelegate:self];
	[autoRouteData.window moveTopLeftTo:autoRouteData.topLeft.x
			: autoRouteData.topLeft.y	screen: autoRouteData.theScreen];
	[autoRouteData.window orderFront:self];

	[[mapController mapView] setDrawInternalRoute:YES];

	free(wholetext);
	
#ifdef HAVE_TRUE_ROUTEOBJECTS
	/* This is in a complete test state! */
	if (!autoWindow)
		if ([NXApp loadNibSection:"Autoroute.nib" owner:self])
		{
			[tableView setDataSource:self];
			[inboundVec setIdentifier:inboundVec];
			[outboundVec setIdentifier:outboundVec];
			[waypointVec setIdentifier:waypointVec];
			[nmVec setIdentifier:nmVec];
			[autoWindow orderFront:self];
		}
#endif	
	
	return self;
}

- (BOOL)canAutoroute
{
	Matrix	*selectedRoute = [mapController routeVia];
	int	i;
	int	lastPos, actualPos;
	
	if (!strlen([[selectedRoute cellAt:0:0] stringValue]))
		return NO; // no TakeOff
	if (!strlen([[selectedRoute cellAt:4:0] stringValue]))
		return NO; // no Dest
		
	lastPos = objectThatMatches([[selectedRoute cellAt:0:0] stringValue]);
	for (i=1; i<5; i++)
	{
		actualPos = objectThatMatches([[selectedRoute cellAt:i:0] stringValue]);
		if (actualPos)
			if (actualPos != lastPos)
				return YES;
			else
				lastPos = actualPos;
	}
	return NO;
}

- takeSuggestUnitFrom:sender
{
	char strg[10];
	
	sprintf(strg, "%i", [[sender selectedCell] tag]);
	NXWriteDefault(APPNAME, IPD_SUGGESTUNIT, strg);
	
	[triangleBrowser reloadColumn:0];
	
	return self;
}

- appWillTerminate:sender
{
	if (autoRouteData.window)
	{
		[autoRouteData.window saveFrameUsingName:RCD_AUTOROUTE];
	}
	return self;
}

@end


@implementation RouteController(BrowserDelegate)

- (int)browser:sender getNumRowsInColumn:(int)column
{
	return numberofroutes;
}

- browser:sender loadCell:cell atRow:(int)row inColumn:(int)column
{
	double				tempdist;
	static char		temp[1024];
	int						j, i=row;
	
	tempdist = distance(takeOffObjc->location, turn1[i]->location) +
		distance(turn1[i]->location, turn2[i]->location) +
		distance(turn2[i]->location, takeOffObjc->location);

	sprintf(temp, "%4.0f %s: %s - %s - %s"
			, UNIT_CHANGE(IPD_SUGGESTUNIT) * tempdist
			, UNIT_NAME(IPD_SUGGESTUNIT)
			,	takeOffObjc->name
			, turn1[i]->name
			,	turn2[i]->name);

	for (j = 0; j < strlen(temp); j++)
		if (temp[j] == '_')
			temp[j] = ' ';

	[cell setStringValue:temp];
	[cell setLeaf:YES];
	[cell setLoaded:YES];
	return self;
}

@end

@implementation RouteController(WindowDelegate)

- windowWillClose:sender
{
	if ([sender isEqual:autoRouteData.window])
	{
		[autoRouteData.window saveFrameUsingName:RCD_AUTOROUTE];
		[[mapController mapView] setDrawInternalRoute:NO];
		autoRouteData.window = nil;
	}
	return self;
}

@end

#ifdef HAVE_TRUE_ROUTEOBJECTS
@implementation RouteController(DBTableDataSources)

- (unsigned int) rowCount
{
	return 3;
}

- getValueFor:identifier at:(unsigned int) aPosition into:aValue
{
	if (identifier == inboundVec)
		[aValue setFloatValue:(float)aPosition];
	else if (identifier == outboundVec)
		[aValue setFloatValue:-(float)aPosition];
	else if (identifier == waypointVec)
		[aValue setStringValue:"Dies ist ein Waypoint"];
	else if (identifier == nmVec)
		[aValue setIntValue:aPosition];
	else
		[aValue setIntValue:0];	
	return self;
}

@end
#endif