/* Menus and commands for the Mac interface to Xconq.
   Copyright (C) 1992-1998 Stanley T. Shebs.

Xconq is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.  See the file COPYING.  */

#include "conq.h"
#include "ai.h"
#include "print.h"
#include "kpublic.h"
#include "macconq.h"

#ifdef THINK_C
#include <profile.h>
#endif

#ifdef DESIGNERS
#define side_may_select(unit) (in_play(unit) && ((unit)->side == dside || dside->designer))
#define valid_selection(unit) (in_play(unit) && ((unit)->side == dside || dside->designer))
#define menus_tweakable() ((!beforestart && !endofgame) || (gameinited && dside->designer))
#else /* n DESIGNERS */
#define side_may_select(unit) (in_play(unit) && ((unit)->side == dside))
#define valid_selection(unit) (in_play(unit) && ((unit)->side == dside))
#define menus_tweakable() ((!beforestart && !endofgame) || (gameinited))
#endif /* DESIGNERS */

#define MAXWINDOWS 100

extern void enable_commands_for_unit(MenuHandle menu, MenuHandle menu2, Unit *unit);
extern void global_advance_dialog(Side *side, Unit *unit, int advance);
extern void city_dialog(Map *map, Unit *unit);
extern void do_closeup_mi(void);				/* Needed in macmouse.c. */			

extern int do_down_command(void);
extern int do_up_command(void);
extern int num_sides_allowed PARAMS ((int u));
extern int do_one_give(Unit *unit);
extern int do_one_take(Unit *unit);
extern int do_one_detonate(Unit *unit);
extern int do_one_give_unit(Unit *unit);
extern int do_one_dir_move(Unit *unit);
extern int do_one_dir_multiple_move(Unit *unit);
extern int do_one_set_name(Unit *unit);

static void do_city_dialog_mi(void);
static void resign_the_game(int forced);
static void te_cut(TEHandle hdl);
static void te_copy(TEHandle hdl);
static void te_paste(TEHandle hdl);
static void do_page_setup_mi(void);
static void do_print_mi(void);
static void do_select_all_mi(void);
static void do_find_previous_mi(void);
static void do_find_next_mi(void);
static void do_find_location_mi(void);
static void do_find_unit_by_name_mi(void);
static void do_find_selected_mi(void);
static void do_overrun_mi(void);
static void do_take_mi(void);
static void do_detonate_mi(void);
static void do_give_unit_mi(int mi);
static void do_plan_type_mi(void);
static void moveonclick_mi(void);
static void autoselect_mi(void);
static void adjust_menu_item(MenuHandle menu, int item, int value);

static int do_one_plan_type(Unit *unit);
static int worldmap_dialog(void);
static int find_location_dialog(int *xp, int *yp);
static int find_unit_dialog(Unit **unitp);
static int find_something(Side *side, char *str, int findunit, int *xp, int *yp, Unit **unitp);

/* This permits more AIs to be dynamically added to the menu. */
extern AI_ops **all_ai_ops;

Side *tmpcmdside;

int numwindows = 0;

int tmp_plan_type;

int forcedtoresign;

int modal_construction = FALSE;

int Profile = FALSE;

int feature_menu_size;

short *feature_menu_fids;

char *cursavename = NULL;

MenuHandle mapviewmenu = nil;
MenuHandle listviewmenu = nil;
MenuHandle closeupviewmenu = nil;
MenuHandle colorsmenu = nil;
MenuHandle utypemenu = nil;
MenuHandle ttypemenu = nil;
MenuHandle mtypemenu = nil;
MenuHandle sidemenu = nil;
MenuHandle aitypemenu = nil;
MenuHandle featuremenu = nil;
MenuHandle optterrmenu = nil;

/* This is the array of windows that the Windows menu references. */
WindowPtr *winmenuwins;

WindowPtr window_behind_construction;

WindowPtr worldmapwin = nil;

Map *worldmap = NULL;

void
query_position_modally(int mode)
{
	if (map_modal == NO_MODAL) {

		/* Since we now allow selection of enemy units it is important to unselect 
		them before any modal commands are executed for the list of selected units. 
		The totalselections and unselected stuff is needed because both selections[i] 
		and numselections change within the loop. */
		int	totalselections;
		int	i, unselected = 0;
		Unit	*unit;
		
		if (frontmap) {
			totalselections = frontmap->numselections;
			for (i = 0; i < totalselections; ++i) {
				unit = frontmap->selections[i - unselected];
				if (!side_controls_unit(dside, unit)) {
					unselect_unit_on_map(frontmap, unit);
					update_cell(frontmap, unit->x, unit->y);
					unselected++;
				}
			}
		}
		/* Note: attempts to execute menu commands for non-controlled units
		are also intercepted in apply_to_all_selected_units. Still, unselecting
		non-controlled units here is a good idea since it reveals exactly which 
		units on the map will be affected by the command. */

		map_modal = mode;
	} else {
		beep();
	}
}

void
set_position_modally()
{
	modal_map = frontmap;
	GetMouse(&modal_point);
	position_set_modally = TRUE;
}

/* Set up all the menus, at least in their basic form. */

void
init_menus()
{
	int i;
	Handle menubar;
	MenuHandle menu;

	menubar = GetNewMBar(mbMain);
	SetMenuBar(menubar);
	/* Add the DAs etc as usual. */
	menu = GetMHandle(mApple);
	if (menu != nil)
	  AddResMenu(menu, 'DRVR');
	/* Get the different versions of the view menu. */
	mapviewmenu = GetMenu(mViewMap);
	listviewmenu = GetMenu(mViewList);
	closeupviewmenu = GetMenu(mViewCloseup);
	/* Init submenus and popups. */
	colorsmenu = GetMenu(mColors);
	if (colorsmenu != nil)
	  InsertMenu(colorsmenu, -1);
	menu = GetMenu(mMagnifications);
	if (menu != nil)
	  InsertMenu(menu, -1);
	menu = GetMenu(mViewWeather);
	if (menu != nil)
	  InsertMenu(menu, -1);
	menu = GetMenu(mViewAngles);
	if (menu != nil)
	  InsertMenu(menu, -1);
	menu = GetMenu(mPlanTypes);
	if (menu != nil)
	  InsertMenu(menu, -1);
	menu = GetMenu(mViewText);
	if (menu != nil)
	  InsertMenu(menu, -1);

	menu = GetMenu(mViewGrids);
	if (menu != nil)
	  InsertMenu(menu, -1);

	menu = GetMenu(mViewColors);
	if (menu != nil)
	  InsertMenu(menu, -1);

	menu = GetMenu(mViewBorders);
	if (menu != nil)
	  InsertMenu(menu, -1);

	sidemenu = GetMenu(mSides);
	if (sidemenu != nil)
	  InsertMenu(sidemenu, -1);
	utypemenu = GetMenu(mUnitTypes);
	if (utypemenu != nil)
	  InsertMenu(utypemenu, -1);
	mtypemenu = GetMenu(mMaterialTypes);
	if (mtypemenu != nil)
	  InsertMenu(mtypemenu, -1);
	ttypemenu = GetMenu(mTerrainTypes);
	if (ttypemenu != nil)
	  InsertMenu(ttypemenu, -1);
	aitypemenu = GetMenu(mAITypes);
	if (aitypemenu != nil)
	  InsertMenu(aitypemenu, -1);
	featuremenu = GetMenu(mFeatures);
	if (featuremenu != nil)
	  InsertMenu(featuremenu, -1);
	optterrmenu = GetMenu(mOptTerrainTypes);
	if (optterrmenu != nil)
	  InsertMenu(optterrmenu, -1);
	/* Init the support for the Windows menu. */
	winmenuwins = (WindowPtr *) xmalloc(MAXWINDOWS * sizeof(WindowPtr));
	for (i = 0; i < MAXWINDOWS; ++i)
	  winmenuwins[i] = nil;
	numwindows = 0;
	/* Done fiddling with menus, draw them. */
	DrawMenuBar();
}

/* Add a menu item that can be used to go to the given window.  Set the window title
   here too, ensures that the two match. */

void
add_window_menu_item(char *name, WindowPtr win)
{
	MenuHandle menu;
	Str255 tmpstr;

	if (numwindows < MAXWINDOWS) {
		c2p(name, tmpstr);
		SetWTitle(win, tmpstr);
		winmenuwins[numwindows++] = win;
		menu = GetMHandle(mWindows);
		if (menu != nil)
	  	    AppendMenu(menu, tmpstr);
	}
}

/* Remove the menu item that can be used to select a given window. */

void
remove_window_menu_item(WindowPtr win)
{
	int i, found = FALSE, next = 0;
	Str255 tmpstr;
	MenuHandle menu;

	/* Search for the window and remove it from the array of windows
	   that have menu items. */
	for (i = 0; i < numwindows; ++i) {
		if (!found && winmenuwins[i] == win) {
			found = TRUE;
		}
		if (found && i < numwindows - 1) {
			/* Shift the other windows down. */
			winmenuwins[i] = winmenuwins[i + 1];
		}
	}
	/* This routine gets called for all windows, so get out of here
	   if this window is not one of those in the menu. */
	if (!found)
	  return;
	--numwindows;
	/* Trash the existing window menu. */
	menu = GetMHandle(mWindows);
	if (menu != nil) {
		DeleteMenu(mWindows);
		ReleaseResource((Handle) menu);
	}
	/* Build a new version starting with the resource. */
	menu = GetMenu(mWindows);
	if (menu != nil) {
		for (i = 0; i < numwindows; ++i) {
			GetWTitle(winmenuwins[i], tmpstr);
			AppendMenu(menu, tmpstr);
		}
		/* Glue a view menu on after the windows menu. */
		if (GetMHandle(mViewMap) != nil)
		  next = mViewMap;
		if (GetMHandle(mViewList) != nil)
		  next = mViewList;
		InsertMenu(menu, next);
	}
	DrawMenuBar();
}

/* Fill up the side menu. */

void
build_side_menu()
{
	char *title;
	Side *side2;
	Str255 tmpstr;

	if (sidemenu != nil && CountMItems(sidemenu) < 1) {
		for_all_sides(side2) {
			title = shortest_side_title(side2, spbuf);
			sanitize_for_menu(title, tmpstr);
			AppendMenu(sidemenu, tmpstr);
			EnableItem(sidemenu, side_number(side2));
		}
		if (1 /* independent units possible in this game */) {
			AppendMenu(sidemenu, "\pindependent");
		}
	}
}

void
update_side_menu(Side *side2)
{
	char *title;
	Str255 tmpstr;

	title = shortest_side_title(side2, spbuf);
	sanitize_for_menu(title, tmpstr);
	SetMenuItemText(sidemenu, side_number(side2), tmpstr);
}

void
build_unit_type_menu()
{
	int u;
	Str255 tmpstr;

	if (utypemenu != nil && CountMItems(utypemenu) < 1) {
		for_all_unit_types(u) {
			sanitize_for_menu(u_type_name(u), tmpstr);
			AppendMenu(utypemenu, tmpstr);
			EnableItem(utypemenu, u + 1);
		}
	}
}

void
build_material_type_menu()
{
	int m;
	Str255 tmpstr;

	if (mtypemenu != nil && CountMItems(mtypemenu) < 1 && nummtypes > 0) {
		for_all_material_types(m) {
			sanitize_for_menu(m_type_name(m), tmpstr);
			AppendMenu(mtypemenu, tmpstr);
			EnableItem(mtypemenu, m + 1);
		}
	}
}

void
build_terrain_type_menu()
{
	int t;
	Str255 tmpstr;

	if (ttypemenu != nil && CountMItems(ttypemenu) < 1) {
		for_all_terrain_types(t) {
			sanitize_for_menu(t_type_name(t), tmpstr);
			AppendMenu(ttypemenu, tmpstr);
			EnableItem(ttypemenu, t);
		}
	}
}

void
build_ai_type_menu()
{
	/* Permit AIs to be dynamically added to the menu. */
	if (aitypemenu != nil && CountMItems(aitypemenu) < 1) {

		Str255	pname;
		int		i;

		AppendMenu(aitypemenu, "\pNone");
		EnableItem(aitypemenu, 1);
		for (i = 1; i < numaitypes; i++) {
			c2p(all_ai_ops[i]->name, pname);
			AppendMenu(aitypemenu, pname);
			EnableItem(aitypemenu, i + 1);
		}
	}
}

void
build_feature_menu()
{
	int i, newsize;
	char *name;
	Str255 tmpstr;
	Feature *feature;
	MenuHandle oldmenu, newmenu = nil;

	if (featuremenu != nil) {
		if (CountMItems(featuremenu) >= 1) {
			/* Trash the existing feature menu. */
			oldmenu = GetMHandle(mFeatures);
			if (oldmenu != nil) {
				DeleteMenu(mFeatures);
				ReleaseResource((Handle) oldmenu);
				/* Build a new version starting with the resource. */
				if ((newmenu = GetMenu(mFeatures)) != nil) {
					featuremenu = newmenu;
				}
			}
		}
		/* Allocate the lookup array that maps menu items to actual feature ids. */
		newsize = 1;
		for_all_features(feature) {
			++newsize;
		}
		if (newsize != feature_menu_size) {
			if (feature_menu_size > 0)
			  free(feature_menu_fids);
			feature_menu_size = newsize;
			feature_menu_fids =
			  (short *) xmalloc(feature_menu_size * sizeof(short));
		}
		i = 0;
		/* The first item is used to clear features. */
		AppendMenu(featuremenu, "\pNo Feature");
		EnableItem(featuremenu, i + 1);
		feature_menu_fids[i++] = 0;
		for_all_features(feature) {
			name = feature_desc(feature, spbuf);
			sanitize_for_menu(name, tmpstr);
			AppendMenu(featuremenu, tmpstr);
			EnableItem(featuremenu, i + 1);
			feature_menu_fids[i++] = feature->id;
		}
		if (newmenu != nil) {
			InsertMenu(featuremenu, -1);
		}
	}
}

void
build_optional_terrain_type_menu()
{
	int t;
	Str255 tmpstr;

	if (optterrmenu != nil && CountMItems(optterrmenu) < 1) {
		for_all_terrain_types(t) {
			if (!t_is_cell(t)) {
				sanitize_for_menu(t_type_name(t), tmpstr);
				AppendMenu(optterrmenu, tmpstr);
				EnableItem(optterrmenu, t);
			}
		}
		if (CountMItems(optterrmenu) < 1)
		  optterrmenu = nil;
	}
}

/* This removes chars that are specially recognized by the Menu Manager.
   Has to be done so that strange game-defined names don't scramble the
   menus; innocuous because this affects only the appearance in the menu. */

extern void
sanitize_for_menu(char *str, Str255 outstr)
{
	int i = 0;

	/* Replace special chars with blanks. */
	for (i = 0; str[i] != '\0' && i < 255; ++i) {
		switch (str[i]) {
			case ';':
			case '!':
			case '<':
			case '/':
			case '(':
			/* I don't think closing parens are special, but since the
			   (presumed) matching open paren is gone, might as well get
			   rid of the close also. */
			case ')':
				outstr[i + 1] = ' ';
				break;
			default:
				outstr[i + 1] = str[i];
				break;
		}
	}
	outstr[i + 1] = '\0';
	/* Replace a leading hyphen with an underscore. */
	if (outstr[1] == '-')
	  outstr[1] = '_';
	outstr[0] = i;
}

/* Decipher and do a menu command. */

/* Note: do_menu_command and most do_something_mi now use frontmap instead 
of FrontWindow (or topWindow) and will therefore work also when the frontmap
is in a background window. However, the menu commands are not accesible in that
case since adjust_menus still works with the topWindow. */

void
do_menu_command(long which)
{
	short menuid, menuitem, daRefNum;
	unsigned char keyMap[16];
	int optionKey;
	Str255 daname;
	WindowPtr win;
	Map *map;

	menuid = HiWord(which);
	menuitem = LoWord(which);
	DGprintf("menu %d, item %d\n", menuid, menuitem);

	/* Access world map if control key is down. */	
	GetKeys((unsigned long *) keyMap);
	optionKey = keyMap[0x3A >> 3] >> (0x3A & 7) & 1;
	if (optionKey && worldmap)
		map = worldmap;
	else	map = frontmap;	

	switch (menuid) {
		case mApple:
			switch (menuitem) {
				case miAppleAbout:
					do_about_box();
					break;
				case miAppleHelp:
					show_help_window(NULL);
					break;
				case miAppleInstructions:
					show_instructions_window();
					break;
				default:
					GetItem(GetMHandle(mApple), menuitem, daname);
					daRefNum = OpenDeskAcc(daname);
			}
			break;
		case mFile:
			switch (menuitem) {
				case miFileNew:
					/* (should reset state of everything first) */
					new_game_dialog();
					break;
				case miFileOpen:
					/* (should reset state of everything first) */
					open_game_dialog();
					break;
				case miFileConnect:
					connect_game_dialog();
					break;
				case miFileClose:
					close_window(topWindow);
					break;
				case miFileSave:
					save_the_game(FALSE, FALSE);
					break;
				case miFileSaveAs:	
					save_the_game(TRUE, FALSE);
					break;
				case miFilePreferences:
					set_preferences();
					break;
				case miFilePageSetup:
					do_page_setup_mi();
					break;
				case miFilePrintWindow:
					do_print_mi();
					break;
				case miFileResign:
					do_resign(dside);
					break;
				case miFileQuit:
					quit_the_game();
					break;
			}
			break;
		case mEdit:
			if (SystemEdit(menuitem - 1))
			  break;
			switch (menuitem)  {
				case miEditCut:
					if (topWindow == commandwin) {
						te_cut(command_text);
					} else if(topWindow == constructionwin) {
						te_cut(run_length_text);
					}
					break;
				case miEditCopy:
					if (topWindow == commandwin) {
						te_copy(command_text);
					} else if(topWindow == constructionwin) {
						te_copy(run_length_text);
					}
					break;
				case miEditPaste:
					if (topWindow == commandwin) {
						te_paste(command_text);
					} else if (topWindow == constructionwin) {
						te_paste(run_length_text);
					}
					break;
				case miEditClear:
					if (topWindow == commandwin) {
						TEDelete(command_text);						
					} else if (topWindow == constructionwin) {
						TEDelete(run_length_text);						
					}
					break;
				case miEditSelectAll:
					do_select_all_mi();
					break;
#ifdef DESIGNERS
				case miEditDesign:
					do_design(dside);
					break;
#endif
			}
			break;
		case mFind:
			switch (menuitem) {
				case miFindPrevious:
					do_find_previous_mi();
					break;
				case miFindNext:
					do_find_next_mi();
					break;
				case miFindNextOccupant:
					do_occupant(dside);
					break;
				case miFindLocation:
					do_find_location_mi();
					break;
				case miFindUnitByName:
					do_find_unit_by_name_mi();
					break;
				case miFindDistance:
					do_distance(dside);
					break;
				case miFindSelected:
					do_find_selected_mi();
					break;
			}
			break;
		case mPlay:
			switch (menuitem) {
				case miPlayCloseup:
					do_closeup_mi();
					break;
				case miPlayCityDialog:
					do_city_dialog_mi();
					break;
				case miPlayMove:
					query_position_modally(MOVE_TO_MODAL);
					break;
				case miPlaySetFormation:
					query_position_modally(SET_FORMATION_MODAL);
					break;
				case miPlayReturn:
					do_return(dside);
					break;
				case miPlayWake:
					do_wake(dside);
					break;
				case miPlaySleep:
					do_sleep(dside);
					break;
				case miPlayReserve:
					do_reserve(dside);
					break;
				case miPlayBuild:
					do_build(dside);
					break;
				case miPlayRepair:
					do_repair(dside);
					break;
				case miPlayAttack:
					query_position_modally(ATTACK_MODAL);
					break;
				case miPlayOverrun:
					do_overrun_mi();
					break;
				case miPlayFire:
					query_position_modally(FIRE_MODAL);
					break;
				case miPlayFireInto:
					query_position_modally(FIRE_INTO_MODAL);
					break;
				case miPlayDetonate:
					do_detonate_mi();
					break;
			}
			break;
		case mMore:
			switch (menuitem) {
				case miMoreTake:
					do_take_mi();
					break;
				case miMoreGive:
					beep();
					break;
				case miMoreEmbark:
					do_embark(dside);
					break;
				case miMoreDisembark:
					do_disembark(dside);
					break;
				case miMoreDrop:
					beep();
					break;
				case miMoreGiveUnit:
					/* has submenu mSides */
					break;
				case miMoreDetach:
					do_detach(dside);
					break;
				case miMoreDisband:
					do_disband(dside);
					break;
				case miMoreAddTerrain:
					query_position_modally(ADD_TERRAIN_MODAL);
					break;
				case miMoreRemoveTerrain:
					query_position_modally(REMOVE_TERRAIN_MODAL);
					break;
				case miMoreRename:
					do_name(dside);
					break;
				case miMoreAIControl:
					do_auto(dside);
					break;
			}
			break;
		case mSides:
			do_give_unit_mi(menuitem);
			break;
		case mSide:
			switch (menuitem) {
				case miSideCloseup:
					break;
				case miSideFinishedTurn:
					net_finish_turn(dside);
					break;
				case miSideMoveOnClick:
					moveonclick_mi();
					break;
				case miSideAutoSelect:
					autoselect_mi();
					break;
				case miSideAutoFinish:
					/* Toggle auto-finish for turns. */
					net_set_autofinish(dside, !dside->autofinish);
					break;
				case miSideSound:
					playsounds = !playsounds;
					ui_update_state();
					save_preferences();
					break;
				case miSideSendMessage:
					do_message(dside);
					break;
				case miSideRename:
					side_rename_dialog(dside);
					break;
			}
			break;
		case 	mColors:
			if (menuitem <= numsides + 1) {
				set_side_colors(menuitem - 1);
			/* - 2 because of Independents and separator line */
			} else if (menuitem <= numsides + FEATURES + 2) {
				 set_feature_color(menuitem - numsides - 3);
			} else {
			/* Pass terrain by sanitized name instead of number */
				GetItem(GetMenu(mColors), menuitem, daname);
				set_terrain_color(daname);
			}			
			force_overall_update();
			break;
		case mWindows:
			switch (menuitem) {
				case miWindowsGame:
					show_game_window();
					break;
				case miWindowsNotices:
					show_notice_window();
					break;
				case miWindowsHistory:
					show_history_window();
					break;
				case miWindowsConstruction:					
					show_construction_window();
					break;
				case miWindowsCommand:
					show_command_window();
					break;
				case miWindowsResearch:
					global_advance_dialog(dside, NULL, -1);
					break;
				case miWindowsScores:
					show_scores_window();
					break;
#ifdef DESIGNERS
				case miWindowsDesign:
					show_design_window();
					break;
#endif
				/* should have agreements list etc handling here also */
				case miWindowsWorldMap:
					/* Create a new World Map if necessary. */
					if (!worldmap) {

						int p, mainwidth;

						get_main_screen_size(&mainwidth, 0);
						for (p = NUMPOWERS - 1; p > 0; p--) {
							if (area.width * hws[p] <= mainwidth / 4) { 
								break;
							}
						}
						create_map(p, 0);
						/* Break to avoid a crash if create_map failed! */
						if (worldmap == NULL)
						     break;
					}
					SelectTheWindow(worldmapwin);
					update_window(worldmapwin);
					break;
				case miWindowsNewList:
					create_list();
					break;
				case miWindowsNewMap:
					create_map(default_power, mapnum++);
					break;
				default:
					win = winmenuwins[menuitem - miWindowsFirst];
					if (win != nil) {
						SelectTheWindow(win);
						update_window(win);
					}
					break;
			}
			break;
		case mViewMap:
			if (map == NULL) break;
			switch (menuitem)  {
				case miViewCloser:
					magnify_map(map, 1);
					break;
				case miViewFarther:
					magnify_map(map, -1);
					break;
				case miViewPeople:
					toggle_map_people(map);
					break;
				case miViewControl:
					toggle_map_control(map);
					break;
				case miViewElevations:
					toggle_map_elevations(map);
					break;
				case miViewDaylight:
					toggle_map_lighting(map);
					break;
				case miViewCoverage:
					toggle_map_coverage(map);
					break;
				case miViewOffscreen:
					set_offscreen_buffers(map);
					break;
				case miViewMeridians:
					set_meridians(map);
					break;
				case miViewWorldMap:
					worldmap_dialog();
					break;
			}
			break;


		case mViewWeather:
			if (map == NULL) break;
			switch (menuitem)  {
				case miWeatherTemperature:
					toggle_map_temperature(map);
					break;
				case miWeatherWinds:
					toggle_map_winds(map);
					break;
				case miWeatherClouds:
					toggle_map_clouds(map);
					break;
			}
			break;
		case mViewAngles:
			if (map == NULL) break;
			switch (menuitem)  {
				case miAngle15:
					set_map_angle(map, 15);
					break;
				case miAngle30:
					set_map_angle(map, 30);
					break;
				case miAngle90:
					set_map_angle(map, 90);
					break;
			}
			break;
		case mViewText:
			if (map == NULL) break;
			switch (menuitem)  {
				case miTextUnitNames:
					toggle_map_names(map);
					break;
				case miTextFeatureNames:
					toggle_featurenames(map);
					break;
				case miTextOptimizeFonts:
					toggle_optimize_fonts(map);
					break;
				case miTextEraseNames:
					toggle_erase_names(map);
					break;
				case miTextDrawEmblems:
					toggle_map_draw_emblems(map);
					break;
			}
			break;

		case mViewGrids:
			if (map == NULL) break;
			switch (menuitem)  {
				case miViewGrid:
					toggle_map_grid(map);
					break;
				case miViewTopline:
					toggle_map_topline(map);
					break;
				case miViewTopunit:
					toggle_map_topunit(map);
					break;
				case miViewScrollBars:
					toggle_map_scrollbars(map);
					break;
				case miViewControlPanel:
					toggle_map_cpanel(map);
					break;
				case miViewOtherMaps:
					toggle_map_other_maps(map);
					break;
			}
			break;

		case mViewColors:
			if (map == NULL) break;
			switch (menuitem)  {
				case miSideColors:
					toggle_map_sidecolors(map);
					break;
				case miIconMasks:
					toggle_iconmasks(map);
					break;
				case miBoxMasks:
					toggle_boxmasks(map);
					break;
				case miTextMasks:
					toggle_textmasks(map);
					break;
				case miSolidColorTerrain:
					toggle_solid_color_terrain(map);
					break;
			}
			break;

		case mViewBorders:
			if (map == NULL) break;
			switch (menuitem)  {
				case miFeatureBorders:
					toggle_featureborders(map);
					break;
				case miShoreLines:
					toggle_shorelines(map);
					break;
				case miSimpleBorders:
					toggle_simple_borders(map);
					break;
			}
			break;
		case mViewList:
			switch (menuitem)  {
				case miViewByType:
					set_list_sorting(list_from_window(topWindow), bytype, menuitem);
					break;
				case miViewByName:
					set_list_sorting(list_from_window(topWindow), byname, menuitem);
					break;
				case miViewBySide:
					set_list_sorting(list_from_window(topWindow), byside, menuitem);
					break;
				case miViewByActOrder:
					set_list_sorting(list_from_window(topWindow), byactorder, menuitem);
					break;
				case miViewByLocation:
					set_list_sorting(list_from_window(topWindow), bylocation, menuitem);
					break;
				case miViewCompleted:
					toggle_list_completed(list_from_window(topWindow));
					break;
				case miViewIncomplete:
					toggle_list_incomplete(list_from_window(topWindow));
					break;
				case miViewIconSize:
					toggle_list_large_icons(list_from_window(topWindow));
					break;
				case miListSideColors:
					toggle_list_sidecolors(list_from_window(topWindow));
					break;
				case miListDrawEmblems:
					toggle_list_draw_emblems(list_from_window(topWindow));
					break;
			}
			break;
		case mAITypes:
			switch (menuitem) {
				case 1:
					net_set_side_ai(dside, NULL);
					break;
				default:
					net_set_side_ai(dside, all_ai_ops[menuitem - 1]->name);
					break;
			}
			break;
		case mMagnifications:
			if (map == NULL) break;
			set_map_mag(map, menuitem - 1);
			break;
		case mMaterialTypes:
			if (map == NULL) break;
			toggle_map_materials(map, menuitem - 1);
			break;
		case mOptTerrainTypes:
			if (map == NULL) break;
			toggle_map_aux_terrain(map, map->vp->aux_terrain_types[menuitem]);
			break;
		case mPlanTypes:
			tmp_plan_type = PLAN_NONE;
			switch (menuitem)  {
				case miPlanTypeNone:
					tmp_plan_type = PLAN_NONE;
					break;
				case miPlanTypePassive:
					tmp_plan_type = PLAN_PASSIVE;
					break;
				case miPlanTypeDefensive:
					tmp_plan_type = PLAN_DEFENSIVE;
					break;
				case miPlanTypeExploratory:
					tmp_plan_type = PLAN_EXPLORATORY;
					break;
				case miPlanTypeOffensive:
					tmp_plan_type = PLAN_OFFENSIVE;
					break;
				case miPlanTypeColonizing:
					tmp_plan_type = PLAN_COLONIZING;
					break;
				case miPlanTypeImproving:
					tmp_plan_type = PLAN_IMPROVING;
					break;
				case miPlanTypeRandom:
					tmp_plan_type = PLAN_RANDOM;
					break;
			}
			do_plan_type_mi();
			break;
	}
	HiliteMenu(0);
}

/* Display the "About..." box. */

void
do_about_box()
{
	short ditem;
	Str255 tmpstr;
	WindowPtr win;
	PicHandle pic;
	short itemtype;  Handle itemhandle;  Rect itemrect;

	win = GetNewDialog(dAbout, NULL, (DialogPtr) -1L);
	/* Fill in the kernel's version and copyright. */
	GetDItem(win, diAboutVersion, &itemtype, &itemhandle, &itemrect);
	c2p(version_string(), tmpstr);
	SetIText(itemhandle, tmpstr);
	GetDItem(win, diAboutCopyright, &itemtype, &itemhandle, &itemrect);
	c2p(copyright_string(), tmpstr);
	SetIText(itemhandle, tmpstr);
	/* Substitute a color picture if we've got a color/gray screen. */
	if (hasColorQD) {
		GetDItem(win, diAboutPicture, &itemtype, &itemhandle, &itemrect);
		if ((pic = (PicHandle) GetResource('PICT', pSplashColor)) != nil) {
			SetDItem(win, diAboutPicture, itemtype, (Handle) pic, &itemrect);
		}
	}
	ShowWindow(win);
	SelectWindow(win);
	draw_default_button(win, diAboutOK);
	SetCursor(&QD(arrow));
	ModalDialog(NULL, &ditem);
	/* Just return, no matter what input. */
	HideWindow(win);
	DisposeDialog(win);
	update_all_map_windows();
}

/* This routine does both "save" and "save as". */

void
save_the_game(int askname, int quitting)
{
	Point pnt;
	char namebuf[256];
	Str255 tmpstr;
    SFReply reply;

#ifdef DESIGNERS
	/* Do the selective save only if we're not shutting down Xconq. */
	if (is_designer(dside) && !quitting) {
		designer_save_dialog();
		return;
	}
#endif
	if (askname || cursavename == NULL) {
		if (cursavename == NULL)
		  cursavename = saved_game_filename();
		/* Collect the file and path to save to. */
		SetPt(&pnt, 100, 100);
		c2p(cursavename, tmpstr);
		SFPutFile(pnt, "\pSave game as:", tmpstr, /*(DlgHookProcPtr)*/ nil, &reply);
		if (!reply.good)
		  return;
		/* Make the location of the file be the current volume. */
		SetVol(reply.fName, reply.vRefNum);
		p2c(((char *) reply.fName), namebuf);
		cursavename = copy_string(namebuf);
	}
	SetCursor(*watchcursor);
	write_entire_game_state(cursavename);
	set_game_file_type(cursavename);
	SetCursor(&QD(arrow));
}

/*THPrint printrecordhandle = nil;*/

void
maybe_init_print()
{
/*	if (printrecordhandle == nil) {
		printrecordhandle = (THPrint) NewHandle(sizeof(TPrint));
		PrOpen();
		PrintDefault(printrecordhandle);
	} */
}

void
do_page_setup_mi()
{
	maybe_init_print();
/*	PrStlDialog(printrecordhandle); */
}

/* Handle printing.  What gets printed depends on which window is in front. */

static void
do_print_mi()
{
	Map *map;
	List *list;

	maybe_init_print();
/*	if (!PrJobDialog(printrecordhandle)) return; */
	if ((map = map_from_window(topWindow)) != NULL) {
		print_map(map);
	} else if ((list = list_from_window(topWindow)) != NULL) {
		print_list(list);
	} else {
		/* (should at least be able to print help) */
	}
}

static void
resign_the_game(int forced)
{
	Str255 tmpstr;

	sprintf(tmpbuf, "Other players");
	c2p(tmpbuf, tmpstr);
	ParamText(tmpstr, "\p", "\p", "\p");
	switch (CautionAlert(aResignGame, nil)) {
		case aiResignGameOK:
			forcedtoresign = forced;
			net_resign_game(dside, NULL);
			break;
		case aiResignGameWillingToDraw:
			net_set_willing_to_draw(dside, TRUE);
			break;
		case aiResignGameCancel:
			break;
	}
}

/* Attempt to quit. */

void
quit_the_game()
{
	int confirmresign = FALSE;

#ifdef DESIGNERS
	/* If we're designing, need only confirm the save before quitting;
	   no resignation requirement. */
	if (is_designer(dside)) {
		switch (CautionAlert(aDesignerQuitGame, nil)) {
			case aiDesignerQuitGameOK:
				SetCursor(*watchcursor);
				save_the_game(FALSE, TRUE);
				SetCursor(&QD(arrow));
				/* Fall through to exit. */
			case aiDesignerQuitGameDontSave:
				exit_macconq();
				break;
			case aiDesignerQuitGameCancel:
				break;
		}
		return;
	}
#endif /* DESIGNERS */
	if (endofgame) {
		/* Game is already over, nothing to save, just leave. */
		exit_macconq();
	} else if (!gamestatesafe || !interfacestatesafe) {
		switch (CautionAlert(aQuitGame, nil)) {
			case aiQuitGameOK:
				if (all_others_willing_to_save(dside)) {
					SetCursor(*watchcursor);
					save_the_game(FALSE, TRUE);
					SetCursor(&QD(arrow));
					exit_macconq();
				} else {
					net_set_willing_to_save(dside, TRUE);
					/* (should warn that not all were willing to save) */
				}
				break;
			case aiQuitGameDontSave:
				if (all_others_willing_to_quit(dside)) {
					net_set_willing_to_draw(dside, TRUE);
				} else {
					/* Can only get out by resigning. */
					confirmresign = TRUE;
				}
				break;
			case aiQuitGameCancel:
				break;
		}
	} else {
		/* (should still confirm that we're not avoiding our fate?) */
		exit_macconq();
	}
	if (confirmresign) {
		resign_the_game(TRUE);
	}
}

static void
te_cut(TEHandle hdl)
{
	if (ZeroScrap() == noErr) {
		TECut(hdl);
		if (TEToScrap() != noErr)
		  ZeroScrap();
	}
}

static void
te_copy(TEHandle hdl)
{
	if (ZeroScrap() == noErr) {
		TECopy(hdl);
		if (TEToScrap() != noErr)
		  ZeroScrap();
	}
}

static void
te_paste(TEHandle hdl)
{
	if (TEFromScrap() == noErr) {
		TEPaste(hdl);
	}
}

static void
do_select_all_mi()
{
	Unit *unit;

	if (topWindow == commandwin) {
		/* (should add this) */
	} else if (topWindow == constructionwin) {
		/* (should add this) */
	} else if (frontmap) {
		for_all_units(unit) {
			if (side_may_select(unit)) {
				select_unit_on_map(frontmap, unit);
			}
		}
		/* Do all the drawing at once. */
		draw_selections(frontmap);
	} else if (0 /* is list */) {
	}
}

static void
do_find_previous_mi()
{
	if (frontmap) {
		select_previous_unit(frontmap);
	}
}

static void
do_find_next_mi()
{
	if (frontmap) {
		select_next_mover(frontmap);
	}
}

static void
do_find_location_mi()
{
	int x, y, oldsx, oldsy;

	if (find_location_dialog(&x, &y)) {
		if (in_area(x, y)) {
			if (frontmap) {
				set_view_focus(frontmap->vp, x, y);
				/* (should make a common routine for this?) */
				if (!in_middle(frontmap, x, y)) {
					oldsx = frontmap->vp->sx;  
					oldsy = frontmap->vp->sy;
					set_view_focus(frontmap->vp, x, y);
					m_center_on_focus(frontmap);

					/* Scroll offscreen instead of forcing update */
					scroll_map_window(frontmap, 
								       frontmap->vp->sx - oldsx, 
								       frontmap->vp->sy - oldsy);
				}
			}
		} else {
			beep();
		}
	}
}

static void
do_find_unit_by_name_mi()
{
	int x, y;
	Unit *unit;
	
	if (find_unit_dialog(&unit)) {
		if (unit != NULL) {
			scroll_best_map_to_unit(unit, TRUE);
		} else {
			beep();
		}
	}
}

static int
find_location_dialog(int *xp, int *yp)
{
	short done = FALSE, ditem, rslt;
	DialogPtr win;
	short itemtype;  Handle itemhandle;  Rect itemrect;

	rslt = FALSE;
	*xp = *yp = -1;
	win = GetNewDialog(dFindLocation, NULL, (DialogPtr) -1L);
	ShowWindow(win);
	while (!done) {
		draw_default_button(win, diFindLocationOK);
		SetCursor(&QD(arrow));
		ModalDialog(NULL, &ditem);
		switch (ditem) {
			case diFindLocationOK:
				GetDItem(win, diFindLocationText, &itemtype, &itemhandle, &itemrect);
				rslt = find_something(dside, get_string_from_item(itemhandle), 0, xp, yp, NULL);
				if (rslt)
				  done = TRUE;
				else
				  beep();
				break;
			case diFindLocationCancel:
				done = TRUE;
				break;
		}
	}
	DisposeDialog(win);
	update_all_map_windows();
	return rslt;
}

static int
worldmap_dialog(void)
{
	short done = FALSE, ditem;
	GrafPtr oldport;
	DialogPtr win;

	win = GetNewDialog(dWorldMap, NULL, (DialogPtr) -1L);
	GetPort(&oldport);	
	SetPort(win);
	ShowWindow(win);
	while (!done) {
		draw_default_button(win, diWorldMapOK);
		SetCursor(&QD(arrow));
		ModalDialog(NULL, &ditem);
		switch (ditem) {
			case diFindUnitOK:
				done = TRUE;
				break;
		}
	}
	DisposeDialog(win);
	SetPort(oldport);
	update_all_map_windows();
}

static int
find_unit_dialog(Unit **unitp)
{
	short done = FALSE, ditem, rslt;
	DialogPtr win;
	short itemtype;  Handle itemhandle;  Rect itemrect;

	rslt = FALSE;
	*unitp = NULL;
	win = GetNewDialog(dFindUnit, NULL, (DialogPtr) -1L);
	ShowWindow(win);
	while (!done) {
		draw_default_button(win, diFindUnitOK);
		SetCursor(&QD(arrow));
		ModalDialog(NULL, &ditem);
		switch (ditem) {
			case diFindUnitOK:
				GetDItem(win, diFindUnitText, &itemtype, &itemhandle, &itemrect);
				rslt = find_something(dside, get_string_from_item(itemhandle), 1, NULL, NULL, unitp);
				if (rslt)
				  done = TRUE;
				else
				  beep();
				break;
			case diFindUnitCancel:
				done = TRUE;
				break;
		}
	}
	DisposeDialog(win);
	update_all_map_windows();
	return rslt;
}

/* (should make generic) */
static int
find_something(Side *side, char *str, int findunit, int *xp, int *yp, Unit **unitp)
{
	Unit *unit;
	Feature *feature;

	if (empty_string(str))
	  return FALSE;
	if (findunit) {
		/* Thumb through the side's own units first. */
		for_all_side_units(side, unit) {
			if (in_play(unit)
				&& !empty_string(unit->name)
				&& strcmp(str, unit->name) == 0) {
				*unitp = unit;
				return TRUE;
			}
		}
		/* Look for other units that this side might know about. */
		for_all_units(unit) {
			if (in_play(unit)
				&& !empty_string(unit->name)
				&& strcmp(str, unit->name) == 0
				&& side_sees_image(side, unit)) {
				*unitp = unit;
				return TRUE;
			}
		}
	} else {
		if (isdigit(*str)) {
			if (sscanf(str, "%d,%d", xp, yp) == 2
				&& in_area(*xp, *yp))
			  return TRUE;
		} else {
			/* Look for a geographical feature. */
			/* Exact matches first, then approximate. */
    		for_all_features(feature) {
				if (feature->name && strcmp(feature->name, str) == 0) {
					*xp = feature->x;  *yp = feature->y;
					return TRUE;
				}
    		}
    		for_all_features(feature) {
				if (feature->name && strstr(feature->name, str) == 0) {
					*xp = feature->x;  *yp = feature->y;
					return TRUE;
				}
    		}
		}
	}
	return FALSE;
}

static void
do_find_selected_mi()
{
	List *list;
	UnitCloseup *closeup;
	
	if ((list = list_from_window(topWindow)) != NULL) {
		scroll_to_selected_unit_in_list(list);
	} else if (frontmap) {
		int i;
		Unit *unit;

		/* Scroll to the first valid selected unit we find. */
		for (i = 0; i < frontmap->numselections; ++i) {
			unit = frontmap->selections[i];
			if (in_play(unit)) {
				scroll_to_unit(frontmap, unit);
				return;
			}
		}
		beep();
	} else if ((closeup = unit_closeup_from_window(topFloat)) != NULL) {
		if (closeup->unit != NULL)
		  scroll_best_map_to_unit(closeup->unit, TRUE);
	} else if (constructionwin == topWindow) {
		scroll_to_selected_construction_unit();
	} else {
		/* nothing to do */
	}
}

/* Menu items/commands for unit play action. */

void
apply_to_all_selected(int (*fn)(Unit *unit), int beepfailure)
{
	int i, rslt, numcould = 0, numnot = 0;
	Map *map;
	List *list;  
	UnitCloseup *closeup;
	Unit *unit;

	if (fn == NULL)
	  return;
	if (frontmap) {
		for (i = 0; i < frontmap->numselections; ++i) {
			unit = frontmap->selections[i];
			/* Don't apply to selected units that we don't control. */
			if (in_play(unit) && side_controls_unit(dside, unit)) {
				rslt = (*fn)(unit);
				if (rslt)
				  ++numcould;
				else
				  ++numnot;
			}
		}
	} else if ((list = list_from_window(topWindow)) != NULL) {
		if ((unit = (Unit *) selected_unit_in_list(list)) != NULL) {
			rslt = (*fn)(unit);
			if (rslt)
			  ++numcould;
			else
			  ++numnot;
		}
	} else if ((closeup = unit_closeup_from_window(topFloat)) != NULL) {
		/* Don't apply to units that we don't control. */
		if (side_controls_unit(dside, closeup->unit)) {
			rslt = (*fn)(unit);
			if (rslt)
			  ++numcould;
			else
			  ++numnot;
		}
	} else if (maplist != NULL) {
		map = maplist;
		for (i = 0; i < map->numselections; ++i) {
			unit = map->selections[i];
			/* Don't apply to selected units that we don't control. */
			if (in_play(unit) && side_controls_unit(dside, unit)) {
				rslt = (*fn)(unit);
				if (rslt)
				  ++numcould;
				else
				  ++numnot;
			}
		}
	}
	/* If everybody that was asked to do this couldn't, beep once. */
	if (beepfailure && numcould == 0 && numnot > 0)
	  beep();
}

static void
do_city_dialog_mi()
{
	int i;
	Unit *unit;

	if (frontmap) {
		for (i = 0; i < frontmap->numselections; ++i) {
			if ((unit = frontmap->selections[i]) != NULL 
			       && u_advanced(unit->type)) {
				city_dialog(frontmap, unit);				
			}
		}
	}
}

void		/* Now declared extern. */
do_closeup_mi()
{
	int i;
	List *list;  UnitCloseup *unitcloseup;
	Unit *unit;
	
	if (frontmap) {
		for (i = 0; i < frontmap->numselections; ++i) {
			if ((unit = frontmap->selections[i]) != NULL) {
				if ((unitcloseup = find_unit_closeup(unit)) != NULL) {
					SelectTheWindow(unitcloseup->window);
				} else {
					create_unit_closeup(unit);
				}
			}
		}
	} else if ((list = list_from_window(topWindow)) != NULL) {
		if ((unit = (Unit *) selected_unit_in_list(list)) != NULL) {
			if ((unitcloseup = find_unit_closeup(unit)) != NULL) {
				SelectTheWindow(unitcloseup->window);
			} else {
				create_unit_closeup(unit);
			}
		}
	} else if ((unitcloseup = unit_closeup_from_window(topFloat)) != NULL) {

		if ((unit = unitcloseup->unit) != NULL) {
			force_update(unitcloseup->window);
		}
	}
}

int
do_down_command()
{
	int i, numcould = 0, numnot = 0, rawamt = 0;
	int amt, newalt;
	Point target;
	Unit *unit;

	rawamt = 0;	
	if (frontmap) {
		for (i = 0; i < frontmap->numselections; ++i) {
			if ((unit = frontmap->selections[i]) != NULL 
			       && valid_selection(unit)) {
				amt = rawamt;
				if (amt == 0 && unit_alt(unit) > 0)
				  amt = unit_alt(unit) / 2;
				newalt = (unit_alt(unit) - amt) << 1;
				if (valid(check_move_action(unit, unit, unit->x, unit->y, newalt))) {
					net_prep_move_action(unit, unit, unit->x, unit->y, newalt);
					++numcould;
				} else {
					++numnot;
				}
			}
		}
	}
	/* If nobody could do the action, beep once. */
	if (numcould == 0 && numnot > 0) {
		beep();
		return FALSE;
	} else {
		return TRUE;
	}
}

static void
do_overrun_mi()
{
	/* (should loop until mouse clicked in map) */
	beep();
}

static void
do_detonate_mi()
{
	apply_to_all_selected(do_one_detonate, TRUE);
}

static void
do_give_unit_mi(int mi)
{
	Side *side = side_n(mi);
	/* note that side_n returns NULL for mi == numsides */

    tmpcmdside = side;	
	apply_to_all_selected(do_one_give_unit, TRUE);
}

static void
moveonclick_mi()
{
	if (frontmap) {
		frontmap->moveonclick = !frontmap->moveonclick;
		/* (should force updates of map windows to reflect?) */
		/* Necessary or the control panel will get out of sync! */
		draw_control_panel(frontmap);
	} else {
		defaultmoveonclick = !defaultmoveonclick;
	}
}

void
do_plan_type_mi()
{
	apply_to_all_selected(do_one_plan_type, TRUE);	
}

static int
do_one_plan_type(Unit *unit)
{
    int newval;

	if (unit->plan) {
		newval = tmp_plan_type;
		net_set_unit_plan_type(dside, unit, newval);
	}
	return TRUE;
}

static void
do_take_mi()
{
	apply_to_all_selected(do_one_take, TRUE);
}

int
do_up_command()
{
	int i, numcould = 0, numnot = 0, rawamt = 1;
	int amt, newalt;
	Point target;
	Unit *unit;

	if (frontmap) {
		for (i = 0; i < frontmap->numselections; ++i) {
			if ((unit = frontmap->selections[i]) != NULL 
			       && valid_selection(unit)) {
				amt = rawamt;
				newalt = (unit_alt(unit) + amt) << 1;
				if (valid(check_move_action(unit, unit, unit->x, unit->y, newalt))) {
					net_prep_move_action(unit, unit, unit->x, unit->y, newalt);
					++numcould;
				} else {
					++numnot;
				}
			}
		}
	}
	/* If nobody could do the action, beep once. */
	if (numcould == 0 && numnot > 0) {
		beep();
		return FALSE;
	} else {
		return TRUE;
	}
}

static void
autoselect_mi()
{
	if (frontmap)
		frontmap->autoselect = !frontmap->autoselect;
	else 	defaultautoselect = !defaultautoselect;
}

static void
adjust_menu_item(MenuHandle menu, int item, int value)
{
	if (value)
	  EnableItem(menu, item);
	else
	  DisableItem(menu, item);
}

/* The state of menu items changes to reflect selected units, etc. */

/* Note: it is now the sole responsibility of adjust_menus to decide what commands
should be accesible and when. All enabled map commands will be executed using the 
frontmap, even if it is not in the topWIndow. */

void
adjust_menus()
{
	int i, m, t, numwins, menus_useful, numitems, text_win, has_text, offset;
	MenuHandle menu, menu2;
	unsigned char keyMap[16];
	int optionKey;
	Map *map;
	List *list;
	UnitCloseup *closeup;
	Unit *unit;
	WindowPtr win;

	/* Access world map if option key is down. */	
	GetKeys((unsigned long *) keyMap);
	optionKey = keyMap[0x3A >> 3] >> (0x3A & 7) & 1;
	if (optionKey && worldmap) {
		win = worldmapwin;
	} else	win = topWindow;

	map = map_from_window(win);
	list = list_from_window(win);
	
	/* This is kind of problematic since commands referring either to the
	topWindow or the topFloat now may appear in the same menu. Hopefully,
	it will not cause any problems, but if it does one would have to consider
	removing all menu commads belonging to closeups. */
	closeup = unit_closeup_from_window(topFloat);

	menus_useful =
		(gamedefined
		 && ((!beforestart && !endofgame)
		 	 || (gameinited && is_designer(dside))));
	/* Certain menus need to be built after the game is running. */
	if (menus_useful) {
		build_material_type_menu();
		build_side_menu();
		build_ai_type_menu();
	}
#if 0
	if (is_da_window(topWindow)) {
		if ((menu = GetMHandle(mEdit)) != nil) {
		}
		return;
	}
#endif
	menu = GetMHandle(mApple);
	if (menu != nil) {
		adjust_menu_item(menu, miAppleInstructions, gamedefined);
	}
	menu = GetMHandle(mFile);
	if (menu != nil) {
		/* Availability of file menu items depends on whether we're in a game. */
		adjust_menu_item(menu, miFileNew, !gamedefined);
		adjust_menu_item(menu, miFileOpen, !gamedefined);
		adjust_menu_item(menu, miFileConnect, !gamedefined);
		adjust_menu_item(menu, miFileClose, (win != NULL));
		adjust_menu_item(menu, miFileSave, menus_useful);
		adjust_menu_item(menu, miFileSaveAs, menus_useful);
		adjust_menu_item(menu, miFilePrintWindow, (map != NULL || list != NULL));
		adjust_menu_item(menu, miFileResign, menus_useful && dside->ingame);
	}
	menu = GetMHandle(mEdit);
	if (menu != nil) {
		/* Edit menu is always available, but individual items may be disabled. */
		adjust_menu_item(menu, miEditUndo, FALSE);
		text_win = has_text = FALSE;
		if (win && win == commandwin) {
			text_win = TRUE;
			has_text = ((*command_text)->selStart < (*command_text)->selEnd);
		} else if (win && win == constructionwin) {
			text_win = TRUE;
			has_text = ((*run_length_text)->selStart < (*run_length_text)->selEnd);
		}
		adjust_menu_item(menu, miEditCut, has_text);
		adjust_menu_item(menu, miEditCopy, has_text);
		adjust_menu_item(menu, miEditPaste, (text_win && (GetScrap(nil, 'TEXT', (long *) &offset) > 0)));
		adjust_menu_item(menu, miEditClear, has_text);
		adjust_menu_item(menu, miEditSelectAll, (map != NULL || list != NULL || has_text));
		if (menus_useful) {
#ifdef DESIGNERS
			CheckItem(menu, miEditDesign, is_designer(dside));
#else
			DisableItem(menu, miEditDesign);
#endif /* DESIGNERS */
		}
	}
	menu = GetMHandle(mFind);
	if (menu != nil) {
		if (gameinited) {
			EnableItem(menu, 0);
			adjust_menu_item(menu, miFindPrevious, menus_useful);
			adjust_menu_item(menu, miFindNext, menus_useful);
			DisableItem(menu, miFindNextOccupant);
			adjust_menu_item(menu, miFindLocation, menus_useful);
			adjust_menu_item(menu, miFindUnitByName, menus_useful);
			adjust_menu_item(menu, miFindDistance, menus_useful);
			adjust_menu_item(menu, miFindSelected, (map != NULL || list != NULL || closeup != NULL || constructionwin == win));
		} else {
			/* We're not even in a game yet, turn entire menu off. */
			DisableItem(menu, 0);
		}
	}
	menu = GetMHandle(mPlay);
	menu2 = GetMHandle(mMore);
	if (menu != nil && menu2 != nil) {
		if (gameinited) {
			EnableItem(menu, 0);
			/* Disable everything first, then selectively re-enable. */
			DisableItem(menu, miPlayCloseup);
			DisableItem(menu, miPlayCityDialog);
			DisableItem(menu, miPlayMove);
			DisableItem(menu, miPlaySetFormation);
			DisableItem(menu, miPlayReturn);
			DisableItem(menu, miPlayWake);
			DisableItem(menu, miPlaySleep);
			DisableItem(menu, miPlayReserve);
			DisableItem(menu, miPlayDelay);
			DisableItem(menu, miPlayBuild);
			DisableItem(menu, miPlayRepair);
			DisableItem(menu, miPlayAttack);
			DisableItem(menu, miPlayOverrun);
			DisableItem(menu, miPlayFire);
			DisableItem(menu, miPlayFireInto);
			DisableItem(menu, miPlayDetonate);
			EnableItem(menu2, 0);
			DisableItem(menu2, miMoreGive);
			DisableItem(menu2, miMoreTake);
			DisableItem(menu2, miMoreEmbark);
			DisableItem(menu2, miMoreDisembark);
			DisableItem(menu2, miMoreDrop);
			DisableItem(menu2, miMoreGiveUnit);
			DisableItem(menu2, miMoreDetach);
			DisableItem(menu2, miMoreDisband);
			DisableItem(menu2, miMoreAddTerrain);
			DisableItem(menu2, miMoreRemoveTerrain);
			DisableItem(menu2, miMorePlanTypes);
			DisableItem(menu2, miMoreAIControl);
			DisableItem(menu2, miMoreRename);
			/* Note that command enabling is accumulative for all units; if at least
			   one of the selected units can do something, the menu item turns on. */
			if (map != NULL) {
				for (i = 0; i < map->numselections; ++i) {
					if ((unit = map->selections[i]) != NULL) {
						enable_commands_for_unit(menu, menu2, unit);
					}
				}
			} else if (list != NULL) {
				if ((unit = (Unit *) selected_unit_in_list(list)) != NULL) {
					enable_commands_for_unit(menu, menu2, unit);
				}
			} else if (closeup != NULL) {
				/* Don't enable commands for enemy closeups. */
				if ((unit = closeup->unit) != NULL
				    && side_controls_unit(dside, unit)) {
					enable_commands_for_unit(menu, menu2, unit);
				}
			}
		} else {
			/* We're not even in a valid game state yet, turn entire menus off. */
			DisableItem(menu, 0);
			DisableItem(menu2, 0);
		}
	}
	menu = GetMHandle(mSide);
	if (menu != nil) {
		if (menus_useful) {
			EnableItem(menu, 0);
			CheckItem(menu, miSideMoveOnClick,
					  (map ? map->moveonclick : defaultmoveonclick));
			CheckItem(menu, miSideAutoSelect,
					  (map ? map->autoselect : defaultautoselect));
			CheckItem(menu, miSideAutoFinish, dside->autofinish);
			CheckItem(menu, miSideSound, playsounds);
			if (dside->nameslocked) {
				DisableItem(menu, miSideRename);
			} else {
				EnableItem(menu, miSideRename);
			}
		} else {
			/* We're not even in a game yet, turn entire menu off. */
			DisableItem(menu, 0);
		}
	}
	menu = GetMHandle(mWindows);
	if (menu != nil) {
		if (gameinited) {
			EnableItem(menu, 0);
			/* Most window types are always enabled. */
			CheckItem(menu, miWindowsGame,
				(gamewin && ((WindowPeek) gamewin)->visible));
			CheckItem(menu, miWindowsNotices,
				(noticewin && ((WindowPeek) noticewin)->visible));
			CheckItem(menu, miWindowsHistory,
				(historywin && ((WindowPeek) historywin)->visible));
			CheckItem(menu, miWindowsCommand,
				(commandwin && ((WindowPeek) commandwin)->visible));
			if (any_construction_possible()) {
				EnableItem(menu, miWindowsConstruction);
				CheckItem(menu, miWindowsConstruction,
					(constructionwin && ((WindowPeek) constructionwin)->visible));
			} else {
				DisableItem(menu, miWindowsConstruction);
			}
			DisableItem(menu, miWindowsResearch);
			for_all_side_units(dside, unit) {
				if (u_advanced(unit->type)) {
					EnableItem(menu, miWindowsResearch);
					break;
				}
			}
			CheckItem(menu, miWindowsScores,
				(scoreswin && ((WindowPeek) scoreswin)->visible));
#ifdef DESIGNERS
			if (is_designer(dside)) {
				EnableItem(menu, miWindowsDesign);
				CheckItem(menu, miWindowsDesign,
					(designwin && ((WindowPeek) designwin)->visible));
			} else	{
				DisableItem(menu, miWindowsDesign);
				CheckItem(menu, miWindowsDesign, false);
			}
#else
			DisableItem(menu, miWindowsDesign);
			CheckItem(menu, miWindowsDesign, false);
#endif /* DESIGNERS */
			CheckItem(menu, miWindowsWorldMap, worldmapwin && worldmapwin == win);
			/* Go through all the user-added windows. */
			numwins = CountMItems(menu) - miWindowsFirst + 1;		
			/* (miWindowsFirst equals the number of windows + 1) */
			for (i = 0; i < numwins; ++i) {
				CheckItem(menu, i + miWindowsFirst, (winmenuwins[i] == win));
			}
		} else {
			/* We're not even in a game yet, turn entire menu off. */
			DisableItem(menu, 0);
		}
	}
	menu = GetMHandle(mColors);
	if (menu != nil) {
		EnableItem(menu, 0);

	}
	/* If a map window is frontmost, install and adjust the map view menu. */
	if (map != NULL) {
		/* Delete the list view menu if that's what's installed currently. */
		menu = GetMHandle(mViewList);
		if (menu != nil)
		  DeleteMenu(mViewList);
		/* Make sure the map view menu is installed (is always at the end). */
		InsertMenu(mapviewmenu, 0);
		menu = GetMHandle(mViewMap);
		if (menu != nil) {
			EnableItem(menu, 0);
			if (map->vp->power == 0) {
				DisableItem(menu, miViewFarther);
			} else {
				EnableItem(menu, miViewFarther);
			}
			if (map->vp->power == NUMPOWERS-1) {
				DisableItem(menu, miViewCloser);
			} else {
				EnableItem(menu, miViewCloser);
			}
			EnableItem(menu, miViewOffscreen);
			if (worldmap) {
				EnableItem(menu, miViewWorldMap);
			} else {
				DisableItem(menu, miViewWorldMap);
			}
			if (people_sides_defined()) {
				EnableItem(menu, miViewPeople);
				CheckItem(menu, miViewPeople, map->vp->draw_people);
			} else {
				DisableItem(menu, miViewPeople);
			}
			if (control_sides_defined()) {
				EnableItem(menu, miViewControl);
				CheckItem(menu, miViewControl, map->vp->draw_control);
			} else {
				DisableItem(menu, miViewControl);
			}
			if (elevations_defined()) {
				EnableItem(menu, miViewElevations);
				CheckItem(menu, miViewElevations, map->vp->draw_elevations);
			} else {
				DisableItem(menu, miViewElevations);
			}
			if (temperatures_defined() || winds_defined() || clouds_defined()) {
				EnableItem(menu, miViewWeather);
			} else {
				DisableItem(menu, miViewWeather);
			}
			if (nummtypes > 0) {
				EnableItem(menu, miViewMaterials);
				/* (should do checkmark if anything in submenu is on) */
			} else {
				DisableItem(menu, miViewMaterials);
			}
			if (numbordtypes + numconntypes + numcoattypes > 0) {
				EnableItem(menu, miViewTerrain);
			} else {
				DisableItem(menu, miViewTerrain);
			}
			if (world.daylength != 1) {
				EnableItem(menu, miViewDaylight);
				CheckItem(menu, miViewDaylight, map->vp->draw_lighting);
			} else {
				DisableItem(menu, miViewDaylight);
			}
			if (dside->coverage) {
				EnableItem(menu, miViewCoverage);
				CheckItem(menu, miViewCoverage, map->vp->draw_cover);
			} else {
				DisableItem(menu, miViewCoverage);
			}
			menu = GetMHandle(mViewWeather);
			if (menu != nil) {
				EnableItem(menu, 0);
				if (temperatures_defined()) {
					EnableItem(menu, miWeatherTemperature);
					CheckItem(menu, miWeatherTemperature, map->vp->draw_temperature);
				} else {
					DisableItem(menu, miWeatherTemperature);
				}
				if (winds_defined()) {
					EnableItem(menu, miWeatherWinds);
					CheckItem(menu, miWeatherWinds, map->vp->draw_winds);
				} else {
					DisableItem(menu, miWeatherWinds);
				}
				if (clouds_defined()) {
					EnableItem(menu, miWeatherClouds);
					CheckItem(menu, miWeatherClouds, map->vp->draw_clouds);
				} else {
					DisableItem(menu, miWeatherClouds);
				}
			}
		}
	} else if (list != NULL) {
		/* Do the list view menu similarly. */
		menu = GetMHandle(mViewMap);
		if (menu != nil)
		  DeleteMenu(mViewMap);
		/* Make sure the menu is actually installed (is always at the end). */
		InsertMenu(listviewmenu, 0);
		menu = GetMHandle(mViewList);
		if (menu != nil) {
			EnableItem(menu, 0);
			if (1 /* at least one unit in list */) {
				EnableItem(menu, miViewByType);
				CheckItem(menu, miViewByType, (list->mainsortmi == miViewByType));
				EnableItem(menu, miViewByName);
				CheckItem(menu, miViewByName, (list->mainsortmi == miViewByName));
				EnableItem(menu, miViewBySide);
				CheckItem(menu, miViewBySide, (list->mainsortmi == miViewBySide));
				EnableItem(menu, miViewByActOrder);
				CheckItem(menu, miViewByActOrder, (list->mainsortmi == miViewByActOrder));
				EnableItem(menu, miViewByLocation);
				CheckItem(menu, miViewByLocation, (list->mainsortmi == miViewByLocation));
				/* should mark the secondary sort? */
				EnableItem(menu, miViewCompleted);
				CheckItem(menu, miViewCompleted, list->completed_units);
				EnableItem(menu, miViewIncomplete);
				CheckItem(menu, miViewIncomplete, list->incomplete_units);
				EnableItem(menu, miViewWithTransport);
				DisableItem(menu, miViewWithCommander);
				EnableItem(menu, miViewIconSize);
				CheckItem(menu, miViewIconSize, list->largeicons);
				EnableItem(menu, miListSideColors);
				CheckItem(menu, miListSideColors, list->sidecolors);
				EnableItem(menu, miListDrawEmblems);
				CheckItem(menu, miListDrawEmblems, list->draw_emblems);
			} else {
				DisableItem(menu, miViewByType);
				DisableItem(menu, miViewByName);
				DisableItem(menu, miViewBySide);
				DisableItem(menu, miViewByActOrder);
				DisableItem(menu, miViewByLocation);
				DisableItem(menu, miViewWithTransport);
				DisableItem(menu, miViewWithCommander);
				DisableItem(menu, miViewIconSize);
				DisableItem(menu, miListSideColors);
				DisableItem(menu, miListDrawEmblems);
			}
		}
	} else {
		/* For any other window, disable any or all of the view menus, as needed. */
		menu = GetMHandle(mViewList);
		if (menu != nil)
		  DisableItem(menu, 0);
		menu = GetMHandle(mViewMap);
		if (menu != nil)
		  DisableItem(menu, 0);
	}
	menu = GetMHandle(mMagnifications);
	if (menu != nil) {
		/* Always on. */
		EnableItem(menu, 0);
		if (map != NULL) {
			for (i = 0; i < NUMPOWERS; ++i) {
				CheckItem(menu, i + 1, (i == map->vp->power));
			}
		}
	}
	menu = GetMHandle(mMaterialTypes);
	if (menu != nil) {
		/* Always on, if any material types defined. */
		if (nummtypes > 0) {
			EnableItem(menu, 0);
			if (map != NULL) {
				for_all_material_types(m) {
					if (any_cell_materials_defined() && cell_material_defined(m)) {
						EnableItem(menu, m + 1);
						CheckItem(menu, m + 1, map->vp->draw_materials[m]);
					} else {
					    CheckItem(menu, i, FALSE);
						DisableItem(menu, m + 1);
					}
				}
			}
		} else {
			DisableItem(menu, 0);
		}
	}
	menu = GetMHandle(mOptTerrainTypes);
	if (menu != nil) {
		if (any_aux_terrain_defined()) {
			EnableItem(menu, 0);
			if (map != NULL) {
				numitems = CountMItems(menu);
				for (i = 1; i <= numitems; ++i) {
					t = map->vp->aux_terrain_types[i];
					if (any_aux_terrain_defined() && aux_terrain_defined(t)) {
						EnableItem(menu, i);
					    CheckItem(menu, i, map->vp->draw_aux_terrain[t]);
					} else {
					    CheckItem(menu, i, FALSE);
						DisableItem(menu, i);
					}
				}
			}
		} else {
			DisableItem(menu, 0);
		}
	}
	menu = GetMHandle(mAITypes);
	if (menu != nil) {
		/* Always on. */
		EnableItem(menu, 0);
		CheckItem(menu, 1, (!side_has_ai(dside)));
		for (i = 1; i < numaitypes; i++)
			CheckItem(menu, i + 1, side_has_ai(dside) && dside->aitype == i);
	}
	menu = GetMHandle(mViewText);
	if (menu != nil && map != NULL) {
		/* Always on. */
		EnableItem(menu, 0);
		EnableItem(menu, miTextUnitNames);
		CheckItem(menu, miTextUnitNames, ( map->vp->draw_names));
		EnableItem(menu, miTextFeatureNames);
		CheckItem(menu, miTextFeatureNames, (map->featurenames));
		EnableItem(menu, miTextOptimizeFonts);
		CheckItem(menu, miTextOptimizeFonts, (map->optimize_fonts));
		EnableItem(menu, miTextEraseNames);
		CheckItem(menu, miTextEraseNames, (map->erase_names));
		EnableItem(menu, miTextDrawEmblems);
		CheckItem(menu, miTextDrawEmblems, (map->draw_emblems));
	}

	menu = GetMHandle(mViewGrids);
	if (menu != nil && map != NULL) {
		/* Always on. */
		EnableItem(menu, 0);
		EnableItem(menu, miViewGrid);
		CheckItem(menu, miViewGrid, map->vp->draw_grid);
		EnableItem(menu, miViewTopline);
		CheckItem(menu, miViewTopline, (map->toplineh > 0));
		EnableItem(menu, miViewTopunit);
		CheckItem(menu, miViewTopunit, (map->topunith > 0));
		EnableItem(menu, miViewScrollBars);
		CheckItem(menu, miViewScrollBars, (map->sbarwid > 0));
		EnableItem(menu, miViewControlPanel);
		CheckItem(menu, miViewControlPanel, (map->conw > 0));
		if (nummaps > 1) {
			EnableItem(menu, miViewOtherMaps);
			CheckItem(menu, miViewOtherMaps, map->vp->draw_other_maps);
		} else {
			DisableItem(menu, miViewOtherMaps);
		}

	}

	menu = GetMHandle(mViewColors);
	if (menu != nil && map != NULL) {
		/* Always on. */
		EnableItem(menu, 0);
		EnableItem(menu, miSideColors);
		CheckItem(menu, miSideColors, map->sidecolors);
		EnableItem(menu, miIconMasks);
		CheckItem(menu, miIconMasks, map->iconmasks);
		EnableItem(menu, miBoxMasks);
		CheckItem(menu, miBoxMasks, map->boxmasks);
		EnableItem(menu, miTextMasks);
		CheckItem(menu, miTextMasks, map->textmasks);
		EnableItem(menu, miSolidColorTerrain);
		CheckItem(menu, miSolidColorTerrain, map->solid_color_terrain);
	}

	menu = GetMHandle(mViewBorders);
	if (menu != nil && map != NULL) {
		/* Always on. */
		EnableItem(menu, 0);
		EnableItem(menu, miFeatureBorders);
		CheckItem(menu, miFeatureBorders, map->featureborders);
		EnableItem(menu, miShoreLines);
		CheckItem(menu, miShoreLines, map->shorelines);
		EnableItem(menu, miSimpleBorders);
		CheckItem(menu, miSimpleBorders, map->simple_borders);
	}
	/* Everything has been tweaked, redraw the menu bar. */
	DrawMenuBar();
}

/* Tweak the command menu according to what the unit can do. */
/* (some of these should have the menu text tweaked also, terms weird sometimes) */

int any_transport_here PARAMS ((Side *side, Unit *unit, int x, int y));

int
any_transport_here(side, unit, x, y)
Side *side;
Unit *unit;
int x, y;
{
	Unit *unit2;

	for_all_stack(x, y, unit2) {
		if (unit2 != unit
			&& unit2 != unit->transport
			&& trusted_side(side, unit2->side)
			&& can_occupy(unit, unit2)
			) {
			return TRUE;
		}
	}
	return FALSE;
}

static void
enable_commands_for_unit(MenuHandle menu, MenuHandle menu2, Unit *unit)
{
	int u = unit->type, sn;
	Side *side2;
	MenuHandle menu3;

	/* Might get dead units in here, filter them out. */
	if (!in_play(unit))
	  return;
	/* If we can select the unit at all, we can always get a closeup of it. */
	EnableItem(menu, miPlayCloseup);
	/* (how to do checkmarks if multiple units selected? use '-' as per HIG) */
	CheckItem(menu, miPlayCloseup, (find_unit_closeup(unit) != NULL));
	/* If we don't actually have any control over the unit, or the game is over,
	   nothing more to do. */

	/* Enable city dialog for advanced unit. */
	if (u_advanced(unit->type))
		EnableItem(menu, miPlayCityDialog);

	if (!side_controls_unit(dside, unit) || endofgame)
	  return;
	if (can_move_at_all(unit)) {
		EnableItem(menu, miPlayMove);
		if (nummtypes > 0) {
			/* also check that unit carries any material and for places to return to */
			EnableItem(menu, miPlayReturn);
		}
	}
	if (unit->plan) {
		EnableItem(menu, miPlaySetFormation);
		EnableItem(menu, miPlayWake);
		CheckItem(menu, miPlayWake, !unit->plan->asleep);
		EnableItem(menu, miPlaySleep);
		CheckItem(menu, miPlaySleep, unit->plan->asleep);
		EnableItem(menu, miPlayReserve);
		CheckItem(menu, miPlayReserve, unit->plan->reserve);
		EnableItem(menu, miPlayDelay);
		CheckItem(menu, miPlayDelay, unit->plan->delayed);
		EnableItem(menu2, miMorePlanTypes);
		EnableItem(menu2, miMoreAIControl);
		CheckItem(menu2, miMoreAIControl, unit->plan->aicontrol);
		menu3 = GetMHandle(mPlanTypes);
		if (menu3 != nil) {
			EnableItem(menu3, 0);
			CheckItem(menu3, miPlanTypeNone, (unit->plan->type == PLAN_NONE));
			CheckItem(menu3, miPlanTypePassive, (unit->plan->type == PLAN_PASSIVE));
			CheckItem(menu3, miPlanTypeDefensive, (unit->plan->type == PLAN_DEFENSIVE));
			CheckItem(menu3, miPlanTypeExploratory, (unit->plan->type == PLAN_EXPLORATORY));
			CheckItem(menu3, miPlanTypeOffensive, (unit->plan->type == PLAN_OFFENSIVE));
			CheckItem(menu3, miPlanTypeRandom, (unit->plan->type == PLAN_RANDOM));
			CheckItem(menu3, miPlanTypeColonizing, (unit->plan->type == PLAN_COLONIZING));
			CheckItem(menu3, miPlanTypeImproving, (unit->plan->type == PLAN_IMPROVING));
		}
	}
	if ((can_create(unit) || can_complete(unit))
		&& (unit->transport == NULL
			|| !completed(unit->transport)
			|| uu_occ_can_build(unit->transport->type, u))
		|| can_develop(unit)) {
		EnableItem(menu, miPlayBuild);
	}
	if (can_repair(unit)) {
		EnableItem(menu, miPlayRepair);
	}
	if (can_attack(unit)) {
		EnableItem(menu, miPlayAttack);
		EnableItem(menu, miPlayOverrun);
	}
	if (can_fire(unit)) {
		EnableItem(menu, miPlayFire);
		EnableItem(menu, miPlayFireInto);
	}
	if (can_detonate(unit)) {
		EnableItem(menu, miPlayDetonate);
	}
	if (nummtypes > 0 /* (should also test unit capacity) */) {
		EnableItem(menu2, miMoreGive);
		EnableItem(menu2, miMoreTake);
	}
	if (any_transport_here(dside, unit, unit->x, unit->y)) {
		EnableItem(menu2, miMoreEmbark);
	}
	if (unit->transport != NULL) {
		EnableItem(menu2, miMoreDisembark);
	}
	/* (should decide what to do about Drop) */
	if (num_sides_allowed(u) > 1 || is_designer(dside)) {
		EnableItem(menu2, miMoreGiveUnit);
	}
	if (side_can_disband(dside, unit)) {
		EnableItem(menu2, miMoreDisband);
	}
	if (u_parts(u) > 1 && unit->hp > 1) {
		EnableItem(menu2, miMoreDetach);
	}
	if (can_add_terrain(unit)) {
		EnableItem(menu2, miMoreAddTerrain);
	}
	if (can_remove_terrain(unit)) {
		EnableItem(menu2, miMoreRemoveTerrain);
	}
	if (1 /* !unitnameslocked */) {
		EnableItem(menu2, miMoreRename);
	}
	/* Adjust the Find menu. */
	menu3 = GetMHandle(mFind);
	if (menu3 != nil) {
		if (gameinited) {
			adjust_menu_item(menu3, miFindNextOccupant, (unit->occupant || unit->nexthere || unit->transport));
		}
	}
	/* Adjust the give unit menu. */
	menu3 = GetMHandle(mSides);
	if (menu3 != nil) {
		if (num_sides_allowed(u) > 1 || is_designer(dside)) {
			EnableItem(menu3, 0);
			for_all_sides_plus_indep(side2) {
				sn = (side2 == indepside ? numsides + 1 : side2->id);
				if (unit_allowed_on_side(unit, side2)
					&& !(unit->side == side2 || (unit->side == NULL && side2 == indepside))) {
					EnableItem(menu3, sn);
				} else {
					DisableItem(menu3, sn);
				}
			}
		} else {
			DisableItem(menu3, 0);
		}
	}
}

