1# The tcl/tk interface to Xconq.
2# Copyright (C) 1998-2000 Stanley T. Shebs.
3# Copyright (C) 2004, 2005 Eric A. McDonald.
4
5# Xconq is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2, or (at your option)
8# any later version.  See the file COPYING.
9
10# Lose the original main window, we don't have a use for it.
11
12wm title . "Xconq Main Window"
13wm withdraw .
14
15set pathlist [ split [ xconq_library_paths ] ";" ]
16
17lappend auto_path [file join [file dirname [info script]] BWidget]
18package require BWidget
19
20# The regular background color.
21#set bgcolor LemonChiffon
22set bgcolor LightGray
23# The "highlight" background color.
24# Fringe color around buttons and canvases on the mac.
25#set hbcolor LemonChiffon
26set hbcolor DarkGray
27# The "active" backgound color. Unused on the mac.
28#set abcolor LemonChiffon
29set abcolor LightGray
30# The troghcolor for scrollbars.
31#set tcolor LemonChiffon2
32set tcolor Gray
33# The map background color.
34#set mbcolor SandyBrown
35set mbcolor DarkGray
36# The listbox and scrollable canvas color.
37#set lcolor azure
38set lcolor AntiqueWhite
39# The select color is on all the time on Windows ...
40if { "$tcl_platform(platform)" == "windows" } {
41	set scolor white
42} else {
43	set scolor MediumBlue
44}
45# ... but not for menu item checkmarks.
46set micolor MediumBlue
47# The foreground color.
48set fgcolor black
49# The "active" foreground color.
50set afcolor SandyBrown
51# The color of the notices panel.
52set ncolor LightSkyBlue1
53
54set lineheight 5
55
56set utype_icon_size 32
57set mtype_icon_size 16
58
59# This flag is 1 if map displays are to use double-buffering for drawing.
60
61set dblbuffer 1
62
63# This flag 1 if the user is doing game design.
64
65set designer 0
66
67set any_elev_variation 0
68set any_temp_variation 0
69set any_wind_variation 0
70set any_clouds 0
71
72# Name of human or AI playing indepside, if any.
73set indepside_player ""
74
75set indepside_build 0
76set indepside_research 0
77set indepside_economy 0
78set indepside_treasury 0
79
80set indepside_entry 0
81set firstside_entry 0
82
83set num_avail_side_names 0
84
85# This global is the id/number of the side using the display.
86
87set dside 0
88
89# Name of dside's ai
90
91set dside_ai "none"
92
93# This global is the remote program id used when networking.
94
95set my_rid 0
96
97# This is the rid of the master.
98
99set master_rid 0
100
101set see_all 0
102
103set may_set_show_all 0
104
105set curunit 0
106
107set endofgame 0
108
109# Set this to 1 to get some handy bits for debugging the tcl/tk code.
110
111set debug 0
112
113set vary_world_size 0
114
115set new_width 0
116set new_height 0
117set new_circumference 0
118set new_latitude 0
119set new_longitude 0
120
121set vary_real_time 0
122
123set new_time_for_game 0
124set new_time_per_side 0
125set new_time_per_turn 0
126
127if { $debug } {
128    puts stdout "Font families are [ font families ]"
129    puts stdout "Paths are $pathlist"
130    # Double buffering makes it hard to see what is going on.
131    set dblbuffer 0
132}
133
134set last_world_width 0
135set last_world_power -1
136
137set ai_may_resign 0
138
139# This is the list of all the map view options that are available.
140
141set view_option_list { \
142	power \
143	grid \
144	coverage \
145	elevations \
146	lighting \
147	people \
148	control \
149	temperature \
150	winds \
151	clouds \
152	unit_names \
153	feature_names \
154	feature_boundaries \
155	meridians \
156	meridian_interval \
157	ai \
158    }
159
160foreach opt $view_option_list {
161    set prefs($opt) 0
162}
163
164# The array of displayable names for view options.
165
166set view_option_names(power) "Power"
167set view_option_names(grid) "Grid"
168set view_option_names(coverage) "Coverage"
169set view_option_names(elevations) "Elevations"
170set view_option_names(lighting) "Day/Night"
171set view_option_names(people) "People"
172set view_option_names(control) "Control"
173set view_option_names(temperature) "Temperature"
174set view_option_names(winds) "Winds"
175set view_option_names(clouds) "Clouds"
176set view_option_names(unit_names) "Unit Names"
177set view_option_names(feature_names) "Feature Names"
178set view_option_names(feature_boundaries) "Feature Boundaries"
179set view_option_names(meridians) "Meridians"
180set view_option_names(meridian_interval) "Meridian Interval"
181set view_option_names(ai) "AI Info"
182
183# The array of map command options corresponding to view options.
184
185set view_option_flags(power) -power
186set view_option_flags(grid) -grid
187set view_option_flags(coverage) -coverage
188set view_option_flags(elevations) -elevations
189set view_option_flags(lighting) -lighting
190set view_option_flags(people) -people
191set view_option_flags(control) -control
192set view_option_flags(temperature) -temperature
193set view_option_flags(winds) -winds
194set view_option_flags(clouds) -clouds
195set view_option_flags(unit_names) -unitnames
196set view_option_flags(feature_names) -featurenames
197set view_option_flags(feature_boundaries) -featureboundaries
198set view_option_flags(meridians) -meridians
199set view_option_flags(meridian_interval) -meridianinterval
200set view_option_flags(ai) -ai
201
202set imagery_option_list { \
203	terrain_images \
204	terrain_patterns \
205	transitions \
206    }
207
208foreach opt $imagery_option_list {
209    set prefs($opt) 0
210}
211
212set imagery_option_names(terrain_images) "Terrain Images"
213set imagery_option_names(terrain_patterns) "Terrain Patterns"
214set imagery_option_names(transitions) "Terrain Transitions"
215
216# Set some defaults that should be nonzero if no preferences found.
217
218set prefs(power) 5
219set prefs(meridian_interval) 600
220
221# (should handle case of non-availability)
222
223# Set platform-specific fonts for use in the startup dialogs. Also set
224# platform-specific default fonts in case no prefs file is loaded later.
225# Finally set the default joinhost to either 127.0.0.1 or localhost.
226
227if { "$tcl_platform(platform)" == "unix" } {
228	set stdfont {-size 12 -weight normal -family helvetica }
229	set boldfont {-size 12 -weight bold -family helvetica }
230	set bigfont {-size 14 -weight normal -family helvetica }
231	set titlefont {-size 14 -weight bold -family helvetica }
232	set hugefont {-size 36 -weight bold -family helvetica }
233	set mapfont {-size 12 -weight bold -family helvetica }
234	set prefs(font_family) helvetica
235	set prefs(font_size) 12
236	set prefs(joinhost) localhost
237	set scrollb 2
238	set listb 2
239	set textb 2
240}
241
242if { "$tcl_platform(platform)" == "macintosh" } {
243	set stdfont {-size 12 -weight normal -family helvetica }
244	set boldfont {-size 12 -weight bold -family helvetica }
245	set bigfont {-size 14 -weight normal -family helvetica }
246	set titlefont {-size 14 -weight bold -family helvetica }
247	set hugefont {-size 36 -weight bold -family helvetica }
248	set mapfont {-size 12 -weight normal -family gadget }
249	set prefs(font_family) helvetica
250	set prefs(font_size) 12
251	# MacTCL doesn't understand what "localhost" is.
252	set prefs(joinhost) 127.0.0.1
253	set scrollb 0
254	set listb 2
255	set textb 2
256}
257
258if { "$tcl_platform(platform)" == "windows" } {
259	set stdfont {-size 9 -weight normal -family arial }
260	set boldfont {-size 9 -weight bold -family arial }
261	set bigfont {-size 11 -weight normal -family arial }
262	set titlefont {-size 11 -weight bold -family arial }
263	set hugefont {-size 27 -weight bold -family arial }
264	set mapfont {-size 9 -weight bold -family arial }
265	set prefs(font_family) arial
266	set prefs(font_size) 9
267	# WinTCL doesn't understand what "127.0.0.1" is.
268	set prefs(joinhost) localhost
269	set scrollb 0
270	set listb 2
271	set textb 2
272}
273
274set prefs(joinport) 3075
275set prefs(myname) "John Doe"
276
277set prefs(want_checkpoints) 0
278set prefs(checkpoint_interval) 0
279set prefs(listallgames) 0
280
281set prefs(terrain_images) 1
282set prefs(transitions) 1
283
284set prefs(unit_names) 1
285set prefs(feature_names) 1
286
287set prefs(temperature) 1
288set prefs(clouds) 1
289set prefs(winds) 1
290
291# The preceding code is all executed during initial_ui_init(), and
292# thus goes before any customization done by the game design or user
293# preferences.
294
295# The initial splash screen.  This proc also sets up the framing and
296# buttons that later screens will use.
297
298proc popup_splash_screen {} {
299    if { "[ winfo exists .newgame ]" } {
300	return
301    }
302    create_newgame_window
303    add_splash_screen_dialog_items
304}
305
306proc create_newgame_window {} {
307    global debug bigfont boldfont stdfont titlefont hugefont prefs
308    global bgcolor hbcolor abcolor fgcolor afcolor
309    global my_rid master_rid
310
311    toplevel .newgame
312    wm title .newgame "Xconq Welcome"
313    wm withdraw .newgame
314
315    # Load the fonts from the preferences if present.
316    set stdfont [ list "-family" $prefs(font_family) "-size" $prefs(font_size) ]
317    set boldfont [ list "-family" $prefs(font_family) "-size" $prefs(font_size) "-weight" "bold" ]
318    if { $prefs(font_size) < 10 } {
319	    set bigfont [ list "-family" $prefs(font_family) "-size" [ expr $prefs(font_size) + 1 ] ]
320	    set titlefont [ list "-family" $prefs(font_family) "-size" [ expr $prefs(font_size) + 1 ] "-weight" "bold" ]
321    } else {
322	    set bigfont [ list "-family" $prefs(font_family) "-size" [ expr $prefs(font_size) + 2 ] ]
323	    set titlefont [ list "-family" $prefs(font_family) "-size" [ expr $prefs(font_size) + 2 ] "-weight" "bold" ]
324    }
325    set hugefont [ list "-family" $prefs(font_family) "-size" [ expr $prefs(font_size) * 3 ] "-weight" "bold" ]
326
327    # Picking a fixed size is bad in the sense that we don't also
328    # force the font to a known size (or provide scrollbars or
329    # anything, not that scrollbars are a nice solution).  This shows
330    # up in the variants dialog if the user has an 18 point font in
331    # .Xdefaults, for example.
332    frame .newgame.top -width 500 -height 370
333    if { $debug } {
334	.newgame.top config -bg green
335    } else {
336	.newgame.top config -bg $bgcolor
337    }
338
339    pack .newgame.top -side top -fill both -expand true
340    # We're planning to reuse this frame, don't let its size bounce around.
341    pack propagate .newgame.top false
342
343    frame .newgame.bottom -bg $bgcolor
344    pack .newgame.bottom -side bottom -fill both
345    frame .newgame.bottom.dummy -bg $bgcolor
346    pack .newgame.bottom.dummy -side left -padx 1
347    frame .newgame.bottom.dummy2 -bg $bgcolor
348    pack .newgame.bottom.dummy2 -side right -padx 1
349
350   button .newgame.bottom.b1 -width 10 -height 2 -text "New Game" -font $boldfont \
351	    -command { popup_game_dialog } -default active \
352	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
353	    -fg $fgcolor -activeforeground $afcolor
354    button .newgame.bottom.b2 -width 10 -height 2 -text "Open File" -font $boldfont \
355	    -command { popup_open_dialog } \
356	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
357	    -fg $fgcolor -activeforeground $afcolor
358    button .newgame.bottom.connect -width 10 -height 2 -text "Connect" -font $boldfont \
359	    -command { popup_connect } \
360	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
361	    -fg $fgcolor -activeforeground $afcolor
362    button .newgame.bottom.quit -width 10 -height 2 -text "Quit" -font $boldfont \
363	    -command { exit_xconq } \
364	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
365	    -fg $fgcolor -activeforeground $afcolor
366    pack .newgame.bottom.b1 .newgame.bottom.b2 .newgame.bottom.connect \
367	    .newgame.bottom.quit -side left -padx 4 -pady 6
368
369    bind .newgame <Key> {
370    	if {"%K" == "Escape"} {
371		.newgame.bottom.quit flash
372		exit_xconq
373	} elseif  {"%K" == "Return"} {
374		.newgame.bottom.b1 flash
375		popup_game_dialog
376	}
377    }
378    bind .newgame <n> { .newgame.bottom.b1 flash; popup_game_dialog }
379    bind .newgame <N> { .newgame.bottom.b1 flash; popup_game_dialog }
380    bind .newgame <o> { .newgame.bottom.b2 flash; popup_open_dialog }
381    bind .newgame <O> { .newgame.bottom.b2 flash; popup_open_dialog }
382    bind .newgame <c> { .newgame.bottom.connect flash; popup_connect }
383    bind .newgame <C> { .newgame.bottom.connect flash; popup_connect }
384    bind .newgame <q> { .newgame.bottom.quit flash; exit_xconq }
385    bind .newgame <Q> { .newgame.bottom.quit flash; exit_xconq }
386
387     center_on_screen .newgame
388}
389
390proc add_splash_screen_dialog_items {} {
391    global stdfont
392    global bgcolor hbcolor fgcolor
393
394    frame .newgame.top.frame -bg $bgcolor
395    pack .newgame.top.frame -side top -fill both
396    canvas .newgame.top.frame.splash -width 500 -height 304 \
397    	-bg $bgcolor -highlightbackground $hbcolor -borderwidth 1 -relief solid
398    pack .newgame.top.frame.splash -side top -anchor nw -padx 4 -pady 4
399    set splashname [ find_image_filename "splash.gif" ]
400    # Only try to create the image if we found the file.
401    if { "$splashname" != "" } {
402    	image create photo splash -file $splashname -width 500 -height 320
403	.newgame.top.frame.splash create image 0 5 -image splash -anchor nw
404    }
405
406    label .newgame.top.version -text "Version [ version_string ]" -font $stdfont -bg $bgcolor -fg $fgcolor
407    pack .newgame.top.version -side top -padx 4 -anchor nw
408    label .newgame.top.copyright -text [ copyright_string ] -font $stdfont -bg $bgcolor -fg $fgcolor
409    pack .newgame.top.copyright -side top -padx 4 -anchor nw
410}
411
412proc remove_splash_screen_dialog_items {} {
413    pack forget .newgame.top.frame
414    pack forget .newgame.top.version
415    pack forget .newgame.top.copyright
416}
417
418# The new game dialog.
419
420set list_all_games 0
421
422proc popup_game_dialog {} {
423    wm title .newgame "Xconq New Game Setup"
424
425    remove_splash_screen_dialog_items
426
427    # For now...
428    global my_rid master_rid
429
430    # Only solo players or masters may start the game load stage.
431    if { $my_rid == 0 || ($my_rid > 0 && $my_rid == $master_rid) } {
432	start_game_load_stage
433    }
434    if { $my_rid > 0 && $my_rid != $master_rid } {
435	.newgame.bottom.b1 config -state disabled
436	.newgame.bottom.b2 config -state disabled
437	return
438    }
439
440    add_new_game_dialog_items
441    .newgame.bottom.b1 config -text "New Game" -command { new_game }
442    .newgame.bottom.b2 config -command { popup_open_dialog }
443
444    bind .newgame <Key> {
445    	if {"%K" == "Escape"} {
446		.newgame.bottom.quit flash
447		exit_xconq
448	} elseif  {"%K" == "Return" && ($my_rid == 0 || $my_rid == $master_rid) } {
449		.newgame.bottom.b1 flash
450		new_game
451	}
452    }
453    bind .newgame <n> { .newgame.bottom.b1 flash; new_game }
454    bind .newgame <N> { .newgame.bottom.b1 flash; new_game }
455    bind .newgame <o> { .newgame.bottom.b2 flash; popup_open_dialog }
456    bind .newgame <O> { .newgame.bottom.b2 flash; popup_open_dialog }
457
458    update idletasks
459}
460
461proc add_new_game_dialog_items {} {
462    global bigfont boldfont titlefont stdfont
463    global scrollb listb textb
464    global bgcolor hbcolor abcolor tcolor lcolor scolor fgcolor afcolor
465    global prefs list_all_games
466
467    # The right side displays info about the selected game.
468
469    frame .newgame.top.right -bg $bgcolor -width 260
470    pack .newgame.top.right -side right -fill y
471    pack propagate .newgame.top.right false
472
473    # (should have a cool gif here instead)
474    # label .newgame.top.right.banner -text Xconq -font $titlefont -bg $bgcolor -fg $fgcolor
475    # pack .newgame.top.right.banner -side top -fill x -padx 12 -pady 4
476
477    canvas .newgame.top.right.preview -width 240 -height 160 \
478	-borderwidth 2 -relief sunken -bg $bgcolor -highlightbackground $hbcolor
479    .newgame.top.right.preview create text 120 85 -tag label -anchor c -fill $fgcolor
480    pack .newgame.top.right.preview -side top -padx 6 -pady 6 -expand false
481    pack propagate .newgame.top.right.preview false
482
483    label .newgame.top.right.version -text "??version??" -font $boldfont -bg $bgcolor -fg $fgcolor
484    pack .newgame.top.right.version -side top -fill x -padx 6 -pady 0
485
486    frame .newgame.top.right.blurb -relief sunken -borderwidth $textb -bg $bgcolor
487    pack .newgame.top.right.blurb -side top -fill x -padx 10 -pady 0
488
489    text .newgame.top.right.blurb.t -width 40 -height 10 -wrap word -font $stdfont \
490    	-bg $lcolor -highlightbackground $lcolor -fg $fgcolor -relief flat
491    pack .newgame.top.right.blurb.t -side left
492
493    frame .newgame.top.left -bg $bgcolor
494    pack .newgame.top.left -side left -fill y
495
496    set list_all_games [ listallgames ]
497    checkbutton .newgame.top.left.listall -text " Also list unfinished games" -font $boldfont -anchor w \
498	    -variable list_all_games -command { fill_new_game_list } \
499	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
500	    -selectcolor $scolor -fg $fgcolor -activeforeground $afcolor
501    pack .newgame.top.left.listall -side bottom -anchor w -pady 3 -padx 12
502
503    frame .newgame.top.left.f -bg $bgcolor
504    pack .newgame.top.left.f -side top -expand true -fill both -padx 8 -pady 8
505
506    listbox .newgame.top.left.f.games -selectmode browse -width 30 -font $bigfont \
507	    -yscrollcommand ".newgame.top.left.f.yscroll set" \
508	    -relief sunken -borderwidth $listb -bg $lcolor -fg $fgcolor
509    scrollbar .newgame.top.left.f.yscroll -orient vert \
510	    -command ".newgame.top.left.f.games yview" -width 16 -borderwidth $scrollb \
511	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
512    pack .newgame.top.left.f.yscroll -side right -fill y
513    pack .newgame.top.left.f.games -side left -expand true -fill y
514
515    fill_new_game_list
516
517    set numgames [ numgames ]
518
519    if { $numgames == 0 } {
520	.newgame.bottom.b1 config -state disabled
521    }
522
523    # A single click selects a game.
524    bind .newgame.top.left.f.games <ButtonRelease-1> { select_game }
525    # A double click opens the selected game.
526    bind .newgame.top.left.f.games <Double-Button-1> { select_game; new_game}
527
528
529    # Auto-pre-select the first game in the list.
530    .newgame.top.left.f.games selection set 0
531    select_game
532}
533
534proc fill_new_game_list {} {
535    global list_all_games
536    global game_title game_version game_base_name
537    global game_index
538
539    .newgame.top.left.f.games delete 0 end
540
541    set numgames [ numgames ]
542
543    set j 0
544    for { set i 0 } { $i < $numgames } { incr i } {
545	game_info $i
546	if { !$list_all_games } {
547	    if { ![ string match {[1-9]*} $game_version($i) ] } {
548		continue
549	    }
550	}
551	set entry "$game_base_name($i)$game_title($i)"
552	.newgame.top.left.f.games insert end " $entry"
553	set game_index($j) $i
554	incr j
555    }
556}
557
558proc remove_new_game_dialog_items {} {
559    pack forget .newgame.top.left
560    pack forget .newgame.top.right
561}
562
563# Adjust the right-side elements to reflect the currently-selected
564# game.
565
566# This global is used to title later startup dialogs.
567
568set selected_game_title "?unknown?"
569
570proc select_game {} {
571    global selected_game_title
572    global game_title game_version game_blurb game_name
573    global game_index game_picturename
574    global game_basemodule game_basemodule_picturename
575
576    set j [ .newgame.top.left.f.games curselection ]
577    if { $j == "" } {
578    	return
579    }
580    set i $game_index($j)
581    # First look for a picture with a defined name in the main module.
582    set entry "$game_picturename($i)"
583    set picname [ find_image_filename "$entry.gif" ]
584    # Then look for a picture named like the main module.
585    if { "$picname" == "" } {
586	    set entry "$game_name($i)"
587	    set picname [ find_image_filename "$entry.gif" ]
588    }
589    # The look for a picture with a defined name in the base module.
590    if { "$picname" == "" } {
591	    set entry "$game_basemodule_picturename($i)"
592	    set picname [ find_image_filename "$entry.gif" ]
593    }
594    # Then look for a picture named like the base module.
595    if { "$picname" == "" } {
596	    set entry "$game_basemodule($i)"
597	    set picname [ find_image_filename "$entry.gif" ]
598    }
599    # Finally look for the default picture.
600    if { "$picname" == "" } {
601	    set entry "default"
602	    set picname [ find_image_filename "$entry.gif" ]
603    }
604    # Only try to create the image if we found the file.
605    # Attempt to prevent image jumps - does not work.
606    set names [ image names ]
607    if { "$picname" != "" } {
608    	if { [ lsearch $names "preview" ] != -1 } {
609    		image delete preview
610    		.newgame.top.right.preview config -width 0 -height 0
611    	}
612    	image create photo preview -file $picname
613    	set w [ image width preview ]
614    	if { $w > 240 } { set w 240 }
615    	set h [ image height preview ]
616    	if { $h > 160 } { set h 160 }
617    	.newgame.top.right.preview config -width $w -height $h
618	.newgame.top.right.preview create image 5 5 -image preview -anchor nw
619    	.newgame.top.right.preview itemconfig label -text ""
620    } elseif { [ lsearch $names "preview" ] != -1 } {
621    	image delete preview
622    	.newgame.top.right.preview config -width 240 -height 160
623    	.newgame.top.right.preview itemconfig label -text "No picture available"
624    }
625    set version "$game_title($i) $game_version($i)"
626
627    .newgame.top.right.version config -text $version
628    .newgame.top.right.blurb.t configure -state normal
629    .newgame.top.right.blurb.t delete 1.0 end
630    .newgame.top.right.blurb.t insert end $game_blurb($i)
631    .newgame.top.right.blurb.t configure -state disabled
632    set selected_game_title $game_title($i)
633}
634
635proc new_game {} {
636    global game_index
637
638    set j [ .newgame.top.left.f.games curselection ]
639    if { $j == "" } {
640    	return
641    }
642    set i $game_index($j)
643    start_new_game $i
644    popup_variants_dialog
645}
646
647proc popup_open_dialog { } {
648    set dname [ game_homedir ]
649    set rslt [ tk_getOpenFile -initialdir $dname ]
650    # Empty result cancels.
651    if { "$rslt" == "" } {
652	return
653    }
654    # Set the working directory manually to the game file location (needed
655    # in both MacOS and Windows).
656    set home [ pwd ]
657    set dname [ file dirname $rslt ]
658    cd $dname
659    start_saved_game "$rslt"
660    cd $home
661    popup_variants_dialog
662}
663
664proc popup_variants_dialog {} {
665    global my_rid master_rid
666
667    # We need to call both of these since Open Game may bypass the
668    # New Game Dialog.
669    remove_splash_screen_dialog_items
670    remove_new_game_dialog_items
671
672    interpret_variants
673    set variants [ any_variants ]
674    # Proceed to player setup if there are no variants.
675    if { $variants == 0 } {
676    	if { $my_rid == 0 || ( $my_rid > 0 && $my_rid == $master_rid ) } {
677		.newgame.bottom.b1 config -text "OK" -command { set_players }
678		.newgame.bottom.b2 config -text "" -state disabled
679		set_variants
680	}
681		return
682    }
683
684    # In case we double-clicked a saved game.
685    if { !"[ winfo exists .newgame ]" } {
686	create_newgame_window
687    }
688    wm title .newgame "Xconq Variants Setup"
689
690    #Make more room already here which is needed in the player list.
691    # (this is for players thast bypassed the New Game dialog).
692    .newgame.top config -width 500 -height 500
693
694    add_variants_dialog_items
695    .newgame.bottom.b1 config -text "OK" -command { set_variants }
696    .newgame.bottom.b2 config -text "" -state disabled
697
698    bind .newgame <Key> {
699    	if {"%K" == "Escape"} {
700		.newgame.bottom.quit flash
701		exit_xconq
702	} elseif  {"%K" == "Return" && ($my_rid == 0 || $my_rid == $master_rid) } {
703		.newgame.bottom.b1 flash
704		set_variants
705	}
706    }
707    # Disable New Game and Open File bindings to prevent error messages when
708    # pressing the n and o keys by mistake.
709    bind .newgame <n> { }
710    bind .newgame <N> { }
711    bind .newgame <o> { }
712    bind .newgame <O> { }
713
714    # For now, always go along with host's changes.
715    if { $my_rid > 0 && $my_rid != $master_rid } {
716	.newgame.bottom.b1 config -state disabled
717	.newgame.top.buttons.worldsize config -state disabled
718	.newgame.top.buttons.realtime config -state disabled
719    }
720    update idletasks
721}
722
723proc add_variants_dialog_items {} {
724    global selected_game_title
725    global varianttext variantstate
726    global vary_world_size vary_real_time
727    global boldfont titlefont stdfont
728    global textb
729    global bgcolor hbcolor abcolor lcolor scolor fgcolor afcolor
730
731    if { !"[ winfo exists .newgame.top.header ]" } {
732	label .newgame.top.header \
733	    -text "Setup Variants for $selected_game_title" \
734	    -font $titlefont -bg $bgcolor -fg $fgcolor
735    }
736    pack .newgame.top.header -side top -pady 6
737
738    if { !"[ winfo exists .newgame.top.vhelp ]" } {
739	frame .newgame.top.vhelp -height 50 -relief sunken -borderwidth $textb \
740	-bg $bgcolor
741	pack propagate .newgame.top.vhelp false
742	text .newgame.top.vhelp.text -wrap word -font $stdfont -state disabled \
743	-bg $lcolor -highlightbackground $lcolor -fg $fgcolor -relief flat
744	pack .newgame.top.vhelp.text -side top -fill both
745    }
746    pack .newgame.top.vhelp -side bottom -fill x -padx 10 -pady 10
747
748    if { !"[ winfo exists .newgame.top.checks ]" } {
749	frame .newgame.top.checks -bg $bgcolor
750	set numactive 0
751	for { set v 0 } { $v < 30 } {incr v } {
752	    if { "$variantstate($v)" == "active" } {
753	    	incr numactive
754	    	if { $numactive > 14 } {
755	    		set row [ expr $numactive - 15 ]
756	    		set col 1
757	    	} else {
758			set row [ expr $numactive - 1 ]
759	    		set col 0
760	    	}
761		checkbutton .newgame.top.checks.v$v -text " $varianttext($v)" \
762		    -state normal -variable variantvalue($v) -font $boldfont \
763		    -command [ list set_variant_value_cmd $v ] \
764		    -bg $bgcolor -highlightbackground $bgcolor \
765		    -activebackground $abcolor -selectcolor $scolor \
766		    -fg $fgcolor -activeforeground $afcolor
767		grid .newgame.top.checks.v$v -sticky w -padx 10 -pady 2 \
768		    -column $col -row $row
769		bind .newgame.top.checks.v$v <Enter> \
770			[ list show_variant_help $v ]
771		bind .newgame.top.checks.v$v <Leave> \
772			[ list clear_variant_help $v ]
773	    }
774	}
775    }
776    pack .newgame.top.checks -side left -fill y
777
778    if { !"[ winfo exists .newgame.top.buttons ]" } {
779	frame .newgame.top.buttons -bg $bgcolor
780
781	button .newgame.top.buttons.worldsize -width 11 -text "World Size..." \
782		 -command { popup_world_size_dialog } -font $boldfont \
783		 -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
784		 -fg $fgcolor -activeforeground $afcolor
785	pack .newgame.top.buttons.worldsize -side top -anchor c -padx 20 -pady 10
786	button .newgame.top.buttons.realtime -width 11 -text "Real Time..." \
787		-command { popup_real_time_dialog } -font $boldfont \
788	    	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
789	    	-fg $fgcolor -activeforeground $afcolor
790	pack .newgame.top.buttons.realtime -side top -anchor c -padx 20 -pady 10
791	if { !$vary_world_size } {
792	    .newgame.top.buttons.worldsize config -state disabled
793	}
794	if { !$vary_real_time } {
795	    .newgame.top.buttons.realtime config -state disabled
796	}
797    }
798    pack .newgame.top.buttons -side right -fill y
799}
800
801proc show_variant_help { var } {
802    global varianthelp
803
804    set msg $varianthelp($var)
805    .newgame.top.vhelp.text configure -state normal
806    .newgame.top.vhelp.text delete 1.0 end
807    .newgame.top.vhelp.text insert end $msg
808    .newgame.top.vhelp.text configure -state disabled
809}
810
811proc clear_variant_help { var } {
812    .newgame.top.vhelp.text configure -state normal
813    .newgame.top.vhelp.text delete 1.0 end
814    .newgame.top.vhelp.text configure -state disabled
815}
816
817proc set_variant_value_cmd { n } {
818    global new_width new_height new_circumference
819    global new_time_for_game new_time_per_side new_time_per_turn
820    global variantstate variantvalue
821
822    if { $n == -1 } {
823	set_variant_value $n $new_width $new_height $new_circumference
824    } elseif { $n == -2 } {
825	set_variant_value $n $new_time_for_game $new_time_per_side \
826		$new_time_per_turn
827    } else {
828	set_variant_value $n $variantvalue($n) 0 0
829    }
830}
831
832proc remove_variants_dialog_items {} {
833    pack forget .newgame.top.header
834    pack forget .newgame.top.vhelp
835    pack forget .newgame.top.checks
836    pack forget .newgame.top.buttons
837}
838
839proc set_variants {} {
840    global my_rid master_rid
841
842    remove_variants_dialog_items
843    if { $my_rid == 0 || ( $my_rid > 0 && $my_rid == $master_rid ) } {
844	start_player_pre_setup_stage
845	start_player_setup_stage
846    }
847    popup_player_dialog
848}
849
850proc popup_world_size_dialog {} {
851    global my_rid master_rid
852
853    remove_variants_dialog_items
854    add_world_size_dialog_items
855    .newgame.bottom.b1 config -text "OK" \
856	    -command { world_size_ok_cmd }
857    .newgame.bottom.b2 config -text "Cancel" -state normal -borderwidth 2 \
858	    -command { world_size_cancel_cmd }
859
860    bind .newgame <Key> {
861    	if {"%K" == "Escape"} {
862		.newgame.bottom.b2 flash
863		world_size_cancel_cmd
864	} elseif  {"%K" == "Return" && ($my_rid == 0 || $my_rid == $master_rid) } {
865		.newgame.bottom.b1 flash
866		world_size_ok_cmd
867	}
868    }
869}
870
871proc add_world_size_dialog_items {} {
872    global new_width new_height new_circumference new_latitude new_longitude
873    global bgcolor hbcolor fgcolor afcolor stdfont boldfont
874
875    if { !"[ winfo exists .newgame.top.world ]" } {
876	canvas .newgame.top.world -width 380 -height 240 -bg gray \
877	-bg $bgcolor -highlightbackground $hbcolor
878	set wtop [ expr 120 - 60 ]
879	set wbot [ expr 120 + 60 ]
880	set wleft [ expr 190 - $new_circumference / 2 ]
881	set wright [ expr 190 + $new_circumference / 2 ]
882	.newgame.top.world create rect $wleft $wtop $wright $wbot -fill white \
883	    -outline $fgcolor
884	.newgame.top.world create line $wleft 120 $wright 120 -fill $fgcolor
885	set atop [ expr 120 - $new_height / 2 ]
886	set abot [ expr 120 + $new_height / 2 ]
887	set aleft [ expr 190 - $new_width / 2 ]
888	set aright [ expr 190 + $new_width / 2 ]
889	if { 1 } {
890	    .newgame.top.world create rect $aleft $atop $aright $abot -fill blue -outline $fgcolor
891	} else {
892	    # (should draw hexagon)
893	}
894    }
895    pack .newgame.top.world -side top -padx 10 -pady 10
896
897    if { !"[ winfo exists .newgame.top.sizes ]" } {
898	frame .newgame.top.sizes
899	set base .newgame.top.sizes
900	label $base.lwidth -text "Area Width:" -bg $bgcolor -fg $fgcolor -font $boldfont
901	entry $base.fwidth -width 4 -fg $fgcolor -font $stdfont
902	$base.fwidth insert end $new_width
903	label $base.lheight -text "x Height:" -bg $bgcolor -fg $fgcolor -font $boldfont
904	entry $base.fheight -width 4 -fg $fgcolor -font $stdfont
905	$base.fheight insert end $new_height
906	label $base.lcircumf -text "Circumference:" -bg $bgcolor -fg $fgcolor -font $boldfont
907	entry $base.fcircumf -width 6 -fg $fgcolor -font $stdfont
908	$base.fcircumf insert end $new_circumference
909	grid $base.lwidth $base.fwidth $base.lheight $base.fheight \
910		$base.lcircumf $base.fcircumf -sticky news
911# these not supported currently
912#	label $base.llon -text "Longitude:" -bg $bgcolor
913#	entry $base.flon -width 6 -fg $fgcolor
914#	$base.flon insert end $new_longitude
915#	label $base.llat -text "Latitude:" -bg $bgcolor
916#	entry $base.flat -width 6 -fg $fgcolor
917#	$base.flat insert end $new_latitude
918#	grid $base.llon $base.flon $base.llat $base.flat -sticky news
919    }
920    pack .newgame.top.sizes -side bottom
921}
922
923proc remove_world_size_dialog_items {} {
924    pack forget .newgame.top.world
925    pack forget .newgame.top.sizes
926}
927
928proc world_size_ok_cmd {} {
929    global new_width new_height new_circumference new_latitude new_longitude
930
931    set base .newgame.top.sizes
932    set new_width [ $base.fwidth get ]
933    set new_height [ $base.fheight get ]
934    set new_circumference [ $base.fcircumf get ]
935#    set new_latitude [ $base.flat get ]
936#    set new_longitude [ $base.flon get ]
937    set_variant_value_cmd -1
938    # Use the cancellation steps to finish here.
939    world_size_cancel_cmd
940}
941
942proc world_size_cancel_cmd {} {
943    remove_world_size_dialog_items
944    popup_variants_dialog
945}
946
947proc popup_real_time_dialog {} {
948    global my_rid master_rid
949
950    remove_variants_dialog_items
951    add_real_time_dialog_items
952    .newgame.bottom.b1 config -text "OK" \
953	    -command { real_time_ok_cmd }
954    .newgame.bottom.b2 config -text "Cancel" -state normal -borderwidth 2 \
955	    -command { real_time_cancel_cmd }
956
957    bind .newgame <Key> {
958    	if {"%K" == "Escape"} {
959		.newgame.bottom.b2 flash
960		real_time_cancel_cmd
961	} elseif  {"%K" == "Return" && ($my_rid == 0 || $my_rid == $master_rid) } {
962		.newgame.bottom.b1 flash
963		real_time_ok_cmd
964	}
965    }
966}
967
968proc add_real_time_dialog_items {} {
969    global new_time_for_game new_time_per_side new_time_per_turn
970    global bgcolor fgcolor afcolor stdfont boldfont
971
972    if { !"[ winfo exists .newgame.top.times ]" } {
973	frame .newgame.top.times -bg $bgcolor
974	set base .newgame.top.times
975	label $base.lforgame -text "Total Time (mins:secs) " -bg $bgcolor -fg $fgcolor -font $boldfont
976	entry $base.fforgame_m -width 4 -fg $fgcolor -font $stdfont
977	label $base.lforgame2 -text " : " -bg $bgcolor -fg $fgcolor -font $boldfont
978	entry $base.fforgame_s -width 4 -fg $fgcolor -font $stdfont
979	$base.fforgame_m insert end [ expr $new_time_for_game / 60 ]
980	$base.fforgame_s insert end [ expr $new_time_for_game % 60 ]
981	label $base.lperside -text "Per Side (mins:secs) " -bg $bgcolor -fg $fgcolor -font $boldfont
982	entry $base.fperside_m -width 4 -fg $fgcolor -font $stdfont
983	label $base.lperside2 -text " : " -bg $bgcolor -fg $fgcolor -font $boldfont
984	entry $base.fperside_s -width 4 -fg $fgcolor -font $stdfont
985	$base.fperside_m insert end [ expr $new_time_per_side / 60 ]
986	$base.fperside_s insert end [ expr $new_time_per_side % 60 ]
987	label $base.lperturn -text "Per Turn (mins:secs) " -bg $bgcolor -fg $fgcolor -font $boldfont
988	entry $base.fperturn_m -width 4 -fg $fgcolor -font $stdfont
989	label $base.lperturn2 -text " : " -bg $bgcolor -fg $fgcolor -font $boldfont
990	entry $base.fperturn_s -width 4 -fg $fgcolor -font $stdfont
991	$base.fperturn_m insert end [ expr $new_time_per_turn / 60 ]
992	$base.fperturn_s insert end [ expr $new_time_per_turn % 60 ]
993	grid $base.lforgame $base.fforgame_m $base.lforgame2 $base.fforgame_s \
994		-sticky news -pady 10
995	grid $base.lperside $base.fperside_m $base.lperside2 $base.fperside_s \
996		-sticky news -pady 10
997	grid $base.lperturn $base.fperturn_m $base.lperturn2 $base.fperturn_s \
998		-sticky news -pady 10
999    }
1000    pack .newgame.top.times -side top -fill both -expand true
1001}
1002
1003proc remove_real_time_dialog_items {} {
1004    pack forget .newgame.top.times
1005}
1006
1007proc real_time_ok_cmd {} {
1008    global new_time_for_game new_time_per_side new_time_per_turn
1009
1010    set base .newgame.top.times
1011    set new_time_for_game \
1012	    [ expr [ $base.fforgame_m get ] * 60 + [ $base.fforgame_s get ] ]
1013    set new_time_per_side \
1014	    [ expr [ $base.fperside_m get ] * 60 + [ $base.fperside_s get ] ]
1015    set new_time_per_turn \
1016	    [ expr [ $base.fperturn_m get ] * 60 + [ $base.fperturn_s get ] ]
1017    set_variant_value_cmd -2
1018    real_time_cancel_cmd
1019}
1020
1021proc real_time_cancel_cmd {} {
1022    remove_real_time_dialog_items
1023    popup_variants_dialog
1024}
1025
1026proc popup_player_dialog {} {
1027    global my_rid master_rid
1028
1029    # In case we double-clicked a saved game.
1030    if { !"[ winfo exists .newgame ]" } {
1031	create_newgame_window
1032    }
1033    wm title .newgame "Xconq Player Setup"
1034    add_player_dialog_items
1035    .newgame.bottom.b1 config -text "OK" -command { set_players }
1036    .newgame.bottom.b2 config -text "" -state disabled
1037
1038    bind .newgame <Key> {
1039    	if {"%K" == "Escape"} {
1040		.newgame.bottom.quit flash
1041		exit_xconq
1042	} elseif  {"%K" == "Return" && ($my_rid == 0 || $my_rid == $master_rid) } {
1043		.newgame.bottom.b1 flash
1044		set_players
1045	}
1046    }
1047
1048    # For now...
1049    if { $my_rid > 0 && $my_rid != $master_rid } {
1050	.newgame.bottom.b1 config -state disabled
1051    }
1052    update idletasks
1053}
1054
1055set selected_player -1
1056
1057set indepside_up 0
1058
1059proc add_player_dialog_items {} {
1060    global num_avail_side_names
1061    global selected_player
1062    global indepside_entry firstside_entry
1063    global boldfont bigfont titlefont stdfont scrollb
1064    global bgcolor hbcolor abcolor tcolor lcolor fgcolor afcolor
1065    global indepside_up
1066
1067    set nums [ numsides ]
1068    set maxs [ maxsides ]
1069
1070    # Add one row for indepside if in game and not hidden.
1071    if { $indepside_up } {
1072	set maxs [ expr $maxs + 1 ]
1073    }
1074    frame .newgame.top.plbuttons -bg $bgcolor
1075    pack .newgame.top.plbuttons -side right -padx 4 -pady 3 -fill y -expand true
1076
1077    frame .newgame.top.dummy -bg $bgcolor
1078    pack .newgame.top.dummy -side top -anchor nw -padx 10 -pady 3
1079    frame .newgame.top.listheadings -bg $bgcolor
1080    pack .newgame.top.listheadings -side top -anchor nw -padx 10 -pady 2
1081
1082    label .newgame.top.listheadings.dummy -bg $bgcolor -fg $fgcolor
1083    label .newgame.top.listheadings.side -text "Side" -font $titlefont -bg $bgcolor -fg $fgcolor
1084    label .newgame.top.listheadings.player -text "Player" -font $titlefont -bg $bgcolor -fg $fgcolor
1085    label .newgame.top.listheadings.aitype -text "AI" -font $titlefont -bg $bgcolor -fg $fgcolor
1086    label .newgame.top.listheadings.adv -text "Adv" -font $titlefont -bg $bgcolor -fg $fgcolor
1087
1088    grid  .newgame.top.listheadings.dummy \
1089    	   .newgame.top.listheadings.side \
1090    	   .newgame.top.listheadings.player  \
1091   	   .newgame.top.listheadings.aitype \
1092   	   .newgame.top.listheadings.adv -sticky w
1093
1094    # Enforce the same pixel positions as for the text in sp_entry below.
1095    grid columnconfig .newgame.top.listheadings 0 -minsize 38 -weight 0
1096    grid columnconfig .newgame.top.listheadings 1 -minsize 126 -weight 0
1097    grid columnconfig .newgame.top.listheadings 2 -minsize 84 -weight 0
1098    grid columnconfig .newgame.top.listheadings 3 -minsize 68 -weight 0
1099    grid columnconfig .newgame.top.listheadings 4 -minsize 6 -weight 0
1100
1101    set maxheight [ expr $maxs * (24 + 4 + 2) + 2 ]
1102
1103    frame .newgame.top.f1 -bg $bgcolor
1104    pack .newgame.top.f1 -side left -fill both -anchor nw -padx 8
1105
1106    scrollbar .newgame.top.f1.yscroll -orient vert \
1107	    -command { .newgame.top.f1.f11.c yview } -width 16 -borderwidth $scrollb \
1108   	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
1109    pack .newgame.top.f1.yscroll -side right -fill y
1110
1111    frame .newgame.top.f1.f11 -borderwidth 2 -relief sunken -bg $lcolor
1112    pack .newgame.top.f1.f11 -side left -fill both -expand false
1113
1114    canvas .newgame.top.f1.f11.c -width 360 -height $maxheight \
1115	    -scrollregion [ list 0 0 360 $maxheight ] \
1116	    -yscrollcommand { .newgame.top.f1.yscroll set } \
1117	    -bg $lcolor -highlightbackground $lcolor
1118    pack .newgame.top.f1.f11.c -side left -fill both
1119
1120   # Make sure the scrollbar is positioned at the top (this is needed under
1121   # MacOS but not under Windows or Unix.
1122   .newgame.top.f1.f11.c yview moveto 0.0
1123
1124    frame .newgame.top.f1.f11.c.f2  -bg $lcolor
1125    .newgame.top.f1.f11.c create window 0 0 -anchor nw \
1126	    -window .newgame.top.f1.f11.c.f2
1127
1128    # We make entries for all sides including the indepside, but we
1129    # choose whether to pack the indepside based on whether it is
1130    # active in the game or not.
1131    canvas .newgame.top.f1.f11.c.f2.dummy -width 360 -height -3 -borderwidth 0 \
1132	     -bg $lcolor -highlightbackground $lcolor
1133    pack .newgame.top.f1.f11.c.f2.dummy -side top -fill x
1134    for { set i 0 } { $i <= $maxs } { incr i } {
1135	set sp_entry .newgame.top.f1.f11.c.f2.s$i
1136	canvas $sp_entry -width 360 -height 24 -borderwidth 0 \
1137		 -bg $lcolor -highlightbackground $lcolor
1138	# Although indicating the current side/player by raising and
1139	# sinking relief seems good, it's visually confusing in practice;
1140	# so use a surrounding rect and make it thicker for selected side.
1141	$sp_entry create rect 32 3 350 23 -tag outline -outline gray
1142	$sp_entry create text 40 6 -tag side -anchor nw -text "" -font $bigfont -fill $fgcolor
1143	$sp_entry create text 166 6 -tag player -anchor nw -text "" -font $bigfont -fill $fgcolor
1144	$sp_entry create text 250 6 -tag aitype -anchor nw -text "" -font $bigfont -fill $fgcolor
1145	$sp_entry create text 326 6 -tag advantage -anchor nw -text "" -font $bigfont -fill $fgcolor
1146	imfsample $sp_entry.emblem -width 16 -height 16 -iwidth 16 -iheight 16 -bg $lcolor
1147	$sp_entry create window 6 6 -window $sp_entry.emblem -anchor nw
1148	if { $i <= $nums } {
1149	    $sp_entry itemconfig outline -width 1 -outline $fgcolor
1150	    update_player_entry $i
1151	}
1152	if { $i > 0 } {
1153	    pack $sp_entry -side top -fill x
1154	}
1155	if { $i == 0 } {
1156	    set indepside_entry $sp_entry
1157	}
1158	if { $i == 1 } {
1159	    set firstside_entry $sp_entry
1160	}
1161	bind $sp_entry <Button-1> "select_player $i"
1162    }
1163
1164    label .newgame.top.plbuttons.advlabel -text "Advantage" -bg $bgcolor -fg $fgcolor -font $boldfont
1165    grid .newgame.top.plbuttons.advlabel -columnspan 2 -sticky ew -padx 4
1166    button .newgame.top.plbuttons.aplus -text "+" -state disabled \
1167	    -command { adjust_advantage_cmd 1 } -width 2 \
1168	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1169	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1170    button .newgame.top.plbuttons.aminus -text "-" -state disabled \
1171	    -command { adjust_advantage_cmd -1 } -width 2 \
1172	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1173	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1174    grid .newgame.top.plbuttons.aplus .newgame.top.plbuttons.aminus -sticky ew -padx 4 -pady 2
1175
1176    label .newgame.top.plbuttons.sideslabel -text "Sides" -bg $bgcolor -fg $fgcolor -font $boldfont
1177    grid .newgame.top.plbuttons.sideslabel -columnspan 2 -sticky ew -padx 4
1178    button .newgame.top.plbuttons.add -text "Add Side" \
1179	    -command { add_player_cmd } -width 8 \
1180 	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1181 	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1182    grid .newgame.top.plbuttons.add -columnspan 2 -sticky ew -padx 4 -pady 2
1183    button .newgame.top.plbuttons.remove -text "Remove" \
1184	    -command { remove_side_and_player_cmd } -width 8 \
1185	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1186	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1187    grid .newgame.top.plbuttons.remove -columnspan 2 -sticky ew -padx 4 -pady 2
1188    menubutton .newgame.top.plbuttons.sidelib -text "Rename" \
1189	    -menu .newgame.top.plbuttons.sidelib.menu \
1190	    -borderwidth 2 -relief raised -width 8 \
1191	    -bg $bgcolor -highlightbackground $hbcolor \
1192	    -activebackground $abcolor \
1193	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1194    menu .newgame.top.plbuttons.sidelib.menu -tearoff 0 \
1195 	    -bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor -font $boldfont
1196    grid .newgame.top.plbuttons.sidelib -columnspan 2 -sticky ew -padx 4 -pady 2
1197    button .newgame.top.plbuttons.rename -text "Random" \
1198	    -command { rename_side_for_player_cmd -1 } -width 8 \
1199	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1200	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1201    grid .newgame.top.plbuttons.rename -columnspan 2 -sticky ew -padx 4 -pady 2
1202
1203    label .newgame.top.plbuttons.playerslabel -text "Players" -bg $bgcolor -fg $fgcolor -font $boldfont
1204    grid .newgame.top.plbuttons.playerslabel -columnspan 2 -sticky ew -padx 4
1205    button .newgame.top.plbuttons.computer -text "Switch AI" \
1206	    -command { cycle_ai_cmd } -width 8 -state normal \
1207	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1208	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1209    grid .newgame.top.plbuttons.computer -columnspan 2 -sticky ew -padx 4 -pady 2
1210    button .newgame.top.plbuttons.exchange -text "Exchange" \
1211	    -command { exchange_players_cmd } -width 8 -state normal \
1212	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1213	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1214    grid .newgame.top.plbuttons.exchange -columnspan 2 -sticky ew -padx 4 -pady 2
1215
1216    label .newgame.top.plbuttons.indeplabel -text "Indep Side" -bg $bgcolor -fg $fgcolor -font $boldfont
1217    grid .newgame.top.plbuttons.indeplabel -columnspan 2 -sticky ew -padx 4
1218    button .newgame.top.plbuttons.indepside -text "Reveal" \
1219	    -command { set_indepside toggle } -width 8 \
1220	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1221	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1222    grid .newgame.top.plbuttons.indepside -columnspan 2 -padx 4 -pady 2 -sticky ew
1223    button .newgame.top.plbuttons.indepconfig -text "Configure" \
1224	    -command { popup_indepside_config } -width 8 \
1225	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1226	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1227    grid .newgame.top.plbuttons.indepconfig -columnspan 2 -padx 4 -pady 2 -sticky ew
1228
1229    # Add names to the side library menu, disabling already-used names.
1230    set numsidelib [ side_lib_size ]
1231    for { set i 0 } { $i < $numsidelib } { incr i } {
1232	set colbreak 0
1233	if { $i % 25 == 0 } {
1234	    set colbreak 1
1235	}
1236	set sstate normal
1237	if { ![ side_lib_entry_available $i ] } {
1238	    set sstate disabled
1239	} else {
1240	    incr num_avail_side_names
1241	}
1242	.newgame.top.plbuttons.sidelib.menu add command \
1243		-label "[ side_lib_entry $i ]" -state $sstate \
1244		-command [ list rename_side_for_player_cmd $i ] \
1245		-columnbreak $colbreak
1246    }
1247    if { $num_avail_side_names == 0 } {
1248	.newgame.top.plbuttons.sidelib config -state disabled
1249    } else {
1250	.newgame.top.plbuttons.sidelib config -state normal
1251    }
1252    if { !"[ side_ingame 0 ]" } {
1253	.newgame.top.plbuttons.indepside config -state disabled
1254	.newgame.top.plbuttons.indepconfig config -state disabled
1255    }
1256    set_indepside initial
1257
1258    select_player 1
1259    update_allplayer_buttons
1260}
1261
1262proc adjust_advantage_cmd { amt } {
1263    global selected_player
1264
1265    adjust_advantage $selected_player $amt
1266    # Re-select so buttons get updated.
1267    select_player $selected_player
1268    update_player_entry $selected_player
1269}
1270
1271proc add_player_cmd {} {
1272    set newsel [ add_side_and_player ]
1273    if { $newsel < 0 } {
1274	return
1275    }
1276    update_player_entry $newsel
1277    select_player $newsel
1278    update_allplayer_buttons
1279}
1280
1281 proc remove_side_and_player_cmd {} {
1282    global selected_player
1283
1284    remove_side_and_player $selected_player
1285    set nums [ numsides ]
1286    set maxs [ maxsides ]
1287    set newsel $selected_player
1288    if { $newsel > $nums } {
1289	set newsel $nums
1290    }
1291    for { set i $selected_player } { $i <= $nums } { incr i } {
1292    	update_player_entry $i
1293    }
1294    select_player $newsel
1295    update_allplayer_buttons
1296
1297    # Finally erase the former last entry.
1298    set oldlast [ expr $nums + 1 ]
1299    if { $oldlast > $maxs } {
1300        return
1301    }
1302    set sp_entry .newgame.top.f1.f11.c.f2.s$oldlast
1303    $sp_entry.emblem replace imf "null"
1304    $sp_entry itemconfig outline -outline gray
1305    $sp_entry itemconfig side -text ""
1306    $sp_entry itemconfig player -text ""
1307    $sp_entry itemconfig aitype -text ""
1308    $sp_entry itemconfig advantage -text ""
1309}
1310
1311proc rename_side_for_player_cmd { n } {
1312    global selected_player
1313
1314    rename_side_for_player $selected_player $n
1315    update_player_entry $selected_player
1316}
1317
1318proc cycle_ai_cmd {} {
1319    global selected_player
1320
1321    set_ai_for_player $selected_player -cycle
1322    update_player_entry $selected_player
1323}
1324
1325proc exchange_players_cmd {} {
1326    global selected_player
1327
1328    set newsel [ exchange_players $selected_player -1 ]
1329    if { $newsel >= 0 } {
1330	update_player_entry $selected_player
1331	update_player_entry $newsel
1332	select_player $newsel
1333    }
1334}
1335
1336proc select_player { newsel } {
1337    global num_avail_side_names
1338    global selected_player
1339    global fgcolor
1340
1341    set nums [ numsides ]
1342    set mins [ minsides ]
1343
1344    # De-highlight any previous selection.
1345    if { $selected_player != -1 } {
1346	set sp_entry .newgame.top.f1.f11.c.f2.s$selected_player
1347	$sp_entry itemconfig outline -width 1 -outline $fgcolor
1348    }
1349    if { $newsel <= $nums } {
1350	set emptysel 0
1351	set selected_player $newsel
1352	set sp_entry .newgame.top.f1.f11.c.f2.s$selected_player
1353	$sp_entry itemconfig outline -width 2 -outline $fgcolor
1354	set side [ assigned_side $selected_player ]
1355	set player [ assigned_player $selected_player ]
1356    } else {
1357	set emptysel 1
1358    }
1359
1360    # Enable/disable advantage adjustment.
1361    if { !$emptysel && "[ player_advantage $player ]" < "[ max_advantage $side ]"} {
1362	set state normal
1363    } else {
1364	set state disabled
1365    }
1366    .newgame.top.plbuttons.aplus config -state $state
1367    if { !$emptysel && "[ player_advantage $player ]" > "[ min_advantage $side ]"} {
1368	set state normal
1369    } else {
1370	set state disabled
1371    }
1372    .newgame.top.plbuttons.aminus config -state $state
1373
1374    # Disable the Remove button for indepside and human players,
1375    # if minimum number of sides or if no player is selected.
1376    if { $emptysel } {
1377	set state disabled
1378    } else {
1379	set displayname [ player_displayname $player ]
1380	if { $side != 0 && $displayname == "" && $nums > $mins } {
1381	        set state normal
1382	} else {
1383	        set state disabled
1384	}
1385    }
1386    .newgame.top.plbuttons.remove config -state $state
1387
1388    if { !$emptysel && "[ can_rename $side ]" } {
1389	set state normal
1390    } else {
1391	set state disabled
1392    }
1393    .newgame.top.plbuttons.sidelib config -state $state
1394    .newgame.top.plbuttons.rename config -state $state
1395    # Turn off the popup menu if it is empty.
1396    if { $num_avail_side_names <= 0 } {
1397    	.newgame.top.plbuttons.sidelib config -state disabled
1398    }
1399
1400    # The other buttons are always active unless nothing selected.
1401    if { !$emptysel } {
1402	set state normal
1403    } else {
1404	set state disabled
1405    }
1406    .newgame.top.plbuttons.computer config -state $state
1407    .newgame.top.plbuttons.exchange config -state $state
1408}
1409
1410# Given the index of an assignment, update the side and player info at
1411# that index.
1412
1413proc update_player_entry { i } {
1414    global selected_player
1415    global fgcolor
1416
1417    # Make sure we have a valid selected player
1418    set nums [ numsides ]
1419    if { $selected_player > $nums } {
1420    	select_player $nums
1421    }
1422    # Nothing to do if command-line setup.
1423    if { !"[ winfo exists .newgame ]" } {
1424	return
1425    }
1426    set sp_entry .newgame.top.f1.f11.c.f2.s$i
1427    set side [ assigned_side $i ]
1428    if { $side == "?s?" } {
1429   	$sp_entry.emblem replace imf "null"
1430    	$sp_entry itemconfig outline -outline gray
1431    	$sp_entry itemconfig side -text ""
1432    	$sp_entry itemconfig player -text ""
1433    	$sp_entry itemconfig aitype -text ""
1434    	$sp_entry itemconfig advantage -text ""
1435    	return
1436    }
1437    # Ersatz images don't exist yet, so skip if none found.
1438    set ename [ side_emblem $side ]
1439    if { "$ename" != "null" } {
1440	$sp_entry.emblem replace imf $ename
1441    }
1442    set ingame [ side_ingame $side ]
1443    if { $ingame } {
1444	set color $fgcolor
1445	$sp_entry itemconfig outline -outline $fgcolor
1446    } else {
1447	set color gray
1448	$sp_entry itemconfig outline -outline gray
1449    }
1450    $sp_entry itemconfig side -text [ short_side_title $side ] -fill $color
1451    set player [ assigned_player $i ]
1452    $sp_entry itemconfig player -text [ simple_player_name $player ] -fill $color
1453    $sp_entry itemconfig aitype -text [ player_aitypename $player ] -fill $color
1454    set advantage [ player_advantage $player ]
1455    if { $advantage > 0 } {
1456	$sp_entry itemconfig advantage -text $advantage
1457    }
1458    if { "[ winfo exists .newgame.top.plbuttons.sidelib.menu ]" } {
1459	set numsidelib [ side_lib_size ]
1460	for { set i 0 } { $i < $numsidelib } { incr i } {
1461	    set sstate normal
1462	    if { ![ side_lib_entry_available $i ] } {
1463		set sstate disabled
1464	    }
1465	    .newgame.top.plbuttons.sidelib.menu entryconfig $i -state $sstate
1466	}
1467    }
1468}
1469
1470# Set the state of buttons that affect the whole list of side/players.
1471
1472proc update_allplayer_buttons {} {
1473    global selected_player
1474
1475    # Nothing to do if command-line setup.
1476    if { !"[ winfo exists .newgame ]" } {
1477	return
1478    }
1479    set nums [ numsides ]
1480    set maxs [ maxsides ]
1481    set mins [ minsides ]
1482
1483    if { $nums < $maxs } {
1484	set state normal
1485    } else {
1486	set state disabled
1487    }
1488    .newgame.top.plbuttons.add config -state $state
1489
1490    set side [ assigned_side $selected_player ]
1491    set player [ assigned_player $selected_player ]
1492    set displayname [ player_displayname $player ]
1493    if { $side != 0 && $displayname == "" && $nums > $mins } {
1494	set state normal
1495    } else {
1496	set state disabled
1497    }
1498    .newgame.top.plbuttons.remove config -state $state
1499
1500    if { $nums > 1 } {
1501	set state normal
1502    } else {
1503	set state disabled
1504    }
1505    .newgame.top.plbuttons.exchange config -state $state
1506}
1507
1508# No removal needed for player dialog items, this is the last dialog
1509# in the sequence.
1510
1511proc set_players {} {
1512    # Might have called during a command-line startup sequence...
1513    if { !"[ winfo exists .newgame ]" } {
1514	return
1515    }
1516    launch_game
1517}
1518
1519proc set_indepside { mode } {
1520    global indepside_entry firstside_entry
1521    global indepside_up indepside_player
1522
1523    set maxs [ maxsides ]
1524
1525    if { [ side_ingame 0 ] } {
1526	set indepplayer [ assigned_player indepside ]
1527	# First test if indepside has a human player.
1528	set indepside_player [ player_displayname $indepplayer ]
1529	# If not, test if it has an AI player.
1530	if { "$indepside_player" == "" } {
1531		set indepside_player [ player_aitypename $indepplayer ]
1532	}
1533    } else {
1534	set indepside_player ""
1535    }
1536    # Decide whether indepside player entry should be "up" or "down".
1537    if { $mode == "initial" } {
1538	if { "$indepside_player" != "" } {
1539	    set indepside_up 1
1540	}
1541    } else {
1542	if { !$indepside_up } {
1543	    set indepside_up 1
1544	} else {
1545	    set indepside_up 0
1546	}
1547    }
1548    if { $indepside_up } {
1549	# Add indepside to player list if not hidden.
1550	set maxs [ expr $maxs + 1 ]
1551	# Add the indepside entry
1552	update_player_entry 0
1553	pack $indepside_entry -before $firstside_entry -side top -fill x
1554	.newgame.top.plbuttons.indepside config -text "Hide"
1555    } else {
1556	# Make the indepside entry disappear
1557	update_player_entry 0
1558	pack forget $indepside_entry
1559	.newgame.top.plbuttons.indepside config -text "Reveal"
1560    }
1561    # Recompute the length of the player list.
1562    set maxheight [ expr $maxs * (24 + 4 + 2) + 2 ]
1563    .newgame.top.f1.f11.c config -width 360 -height $maxheight \
1564	    -scrollregion [ list 0 0 360 $maxheight ]
1565}
1566
1567proc popup_indepside_config {} {
1568    global indepside_build indepside_research indepside_economy indepside_treasury boldfont
1569    global new_indepside_build new_indepside_research new_indepside_economy new_indepside_treasury
1570    global bgcolor hbcolor abcolor scolor fgcolor afcolor
1571
1572    set new_indepside_build $indepside_build
1573    set new_indepside_research $indepside_research
1574    set new_indepside_economy $indepside_economy
1575    set new_indepside_treasury $indepside_treasury
1576
1577    if { "[ winfo exists .indepside ]" } {
1578    	# Kick the window manager awake.
1579    	wm withdraw .indepside
1580	wm deiconify .indepside
1581	focus -force .indepside
1582	return
1583    }
1584
1585    toplevel .indepside -bg $bgcolor -width 300 -height 200
1586    pack propagate .indepside true
1587    wm title .indepside "Independent Units Setup"
1588    wm withdraw .indepside
1589
1590    label .indepside.lab1 -text "Choose what independent units may do:" \
1591    -bg $bgcolor -fg $fgcolor -font $boldfont
1592    pack .indepside.lab1 -side top -pady 8 -padx 6
1593    checkbutton .indepside.build -text " Build new units if possible" \
1594	    -variable new_indepside_build -offvalue 0 -onvalue 1 \
1595	    -bg $bgcolor -highlightbackground $bgcolor \
1596	    -activebackground $abcolor \
1597	    -selectcolor $scolor -fg $fgcolor -activeforeground $afcolor \
1598	    -font $boldfont
1599    pack .indepside.build -side top -anchor nw -padx 30 -pady 4
1600    checkbutton .indepside.research -text " Research new advances" \
1601	    -variable new_indepside_research -offvalue 0 -onvalue 1 \
1602	    -bg $bgcolor -highlightbackground $bgcolor \
1603	    -activebackground $abcolor \
1604	    -selectcolor $scolor -fg $fgcolor -activeforeground $afcolor \
1605	    -font $boldfont
1606    pack .indepside.research -side top -anchor nw -padx 30 -pady 4
1607    checkbutton .indepside.economy -text " Produce and consume materials" \
1608	    -variable new_indepside_economy -offvalue 0 -onvalue 1 \
1609	    -bg $bgcolor -highlightbackground $bgcolor \
1610	    -activebackground $abcolor \
1611	    -selectcolor $scolor -fg $fgcolor -activeforeground $afcolor \
1612	    -font $boldfont
1613    pack .indepside.economy -side top -anchor nw -padx 30 -pady 4
1614    checkbutton .indepside.treasury -text " Use treasuries if available" \
1615	    -variable new_indepside_treasury -offvalue 0 -onvalue 1 \
1616	    -bg $bgcolor -highlightbackground $bgcolor \
1617	    -activebackground $abcolor \
1618	    -selectcolor $scolor -fg $fgcolor -activeforeground $afcolor \
1619	    -font $boldfont
1620    pack .indepside.treasury -side top -anchor nw -padx 30 -pady 4
1621
1622    frame .indepside.bottom -bg $bgcolor
1623    pack .indepside.bottom -side bottom -anchor e -padx 20 -pady 4
1624    button .indepside.bottom.ok -text "OK" -width 8 \
1625	    -command { ok_indepside } -default active \
1626	    -bg $bgcolor -highlightbackground $hbcolor \
1627	    -activebackground $abcolor \
1628	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1629    button .indepside.bottom.cancel -text "Cancel" -width 8 \
1630	    -command { cancel_indepside } \
1631	    -bg $bgcolor -highlightbackground $hbcolor \
1632	    -activebackground $abcolor \
1633	    -fg $fgcolor -activeforeground $afcolor -font $boldfont
1634    grid .indepside.bottom.cancel .indepside.bottom.ok -sticky ew \
1635	    -padx 6 -pady 4
1636
1637    if { [ numatypes ] == 0 } {
1638    	.indepside.research config -state disabled
1639    }
1640    if { [ nummtypes ] == 0 } {
1641    	.indepside.treasury config -state disabled
1642    }
1643    if { [ numtreasury ] == 0 } {
1644    	.indepside.treasury config -state disabled
1645    }
1646    bind .indepside <Key> {
1647    	if {"%K" == "Escape"} {
1648		.indepside.bottom.cancel flash
1649		cancel_indepside
1650	} elseif  {"%K" == "Return"} {
1651		.indepside.bottom.ok flash
1652		ok_indepside
1653	}
1654    }
1655    center_on_screen .indepside
1656}
1657
1658proc ok_indepside {} {
1659    global indepside_build indepside_research indepside_economy indepside_treasury
1660    global new_indepside_build new_indepside_research new_indepside_economy new_indepside_treasury
1661
1662    set indepside_build $new_indepside_build
1663    set indepside_research $new_indepside_research
1664    set indepside_economy $new_indepside_economy
1665    set indepside_treasury $new_indepside_treasury
1666
1667    set_indepside_options $indepside_build $indepside_research \
1668	    $indepside_economy $indepside_treasury
1669    wm withdraw .indepside
1670}
1671
1672proc cancel_indepside {} {
1673    wm withdraw .indepside
1674}
1675
1676# Launch the periodically-executing procedures that will run during
1677# the game.
1678
1679proc do_initial_setup {} {
1680    after 25 run_game_cmd
1681    after 50 animate_selection_cmd
1682    after 100 run_game_idle_cmd
1683}
1684
1685proc popup_connect {} {
1686    popup_chat
1687}
1688
1689proc join_game {} {
1690    global prefs
1691
1692    make_default_player_spec $prefs(myname)
1693    set rslt [ try_join_game "$prefs(joinhost):$prefs(joinport)" ]
1694    if { $rslt == -2 } {
1695	bell
1696	insert_chat_string 0 0 "Cannot join ongoing game at $prefs(joinhost):$prefs(joinport)\n"
1697    } elseif { $rslt == 0 } {
1698	bell
1699	insert_chat_string 0 0 "No response from host at $prefs(joinhost):$prefs(joinport)\n"
1700    # Turn off the New Game and Open Game buttons and their key bindings
1701    # if we became a network client.
1702    } elseif { $rslt == 1 } {
1703	.newgame.bottom.b1 config -state disabled
1704	.newgame.bottom.b2 config -state disabled
1705	bind .newgame <Key> {
1706		if {"%K" == "Escape"} {
1707			.newgame.bottom.quit flash
1708			exit_xconq
1709		} elseif  {"%K" == "Return"} {
1710		}
1711	}
1712	bind .newgame <n> { }
1713	bind .newgame <N> { }
1714	bind .newgame <o> { }
1715	bind .newgame <O> { }
1716    }
1717}
1718
1719proc host_game {} {
1720    global prefs
1721
1722    make_default_player_spec $prefs(myname)
1723    try_host_game "$prefs(joinhost):$prefs(joinport)"
1724}
1725
1726# The pregame chat window may actually last throughout a game - it
1727# provides an "out-of-band" communications channel for human players.
1728
1729proc popup_chat {} {
1730    global persons
1731    global env
1732    global debug
1733    global prefs
1734    global boldfont
1735    global stdfont
1736    global scrollb
1737    global listb
1738    global textb
1739    global bgcolor hbcolor abcolor tcolor lcolor fgcolor afcolor
1740    global my_rid master_rid
1741
1742    if { "[ winfo exists .chat ]" } {
1743        	# Kick the window manager awake.
1744	wm withdraw .chat
1745	wm deiconify .chat
1746	focus -force .chat
1747	return
1748    }
1749
1750    toplevel .chat
1751    wm title .chat "Xconq Chat"
1752    wm withdraw .chat
1753
1754    frame .chat.top -bg $bgcolor
1755    pack .chat.top -side top -fill x
1756
1757    frame .chat.top.parms -bg $bgcolor
1758    pack .chat.top.parms -side left -pady 4 -padx 4
1759
1760    label .chat.top.parms.namelabel -text "Your Name :" -font $boldfont -bg $bgcolor -fg $fgcolor
1761    label .chat.top.parms.hostlabel -text "Game Host :" -font $boldfont -bg $bgcolor -fg $fgcolor
1762    label .chat.top.parms.portlabel -text "Port :" -font $boldfont -bg $bgcolor -fg $fgcolor
1763
1764    grid .chat.top.parms.namelabel -sticky e -column 0
1765    grid .chat.top.parms.hostlabel -sticky e -column 0
1766    grid .chat.top.parms.portlabel -sticky e -column 0
1767
1768    entry .chat.top.parms.nameentry -textvariable prefs(myname) \
1769	-relief sunken -width 15 -fg $fgcolor -font $stdfont
1770    entry .chat.top.parms.hostentry -textvariable prefs(joinhost) \
1771	-relief sunken -width 15 -fg $fgcolor -font $stdfont
1772    entry .chat.top.parms.portentry -textvariable prefs(joinport) \
1773	-relief sunken -width 4 -fg $fgcolor -font $stdfont
1774
1775    grid .chat.top.parms.nameentry -sticky w -column 1 -row 0
1776    grid .chat.top.parms.hostentry -sticky w -column 1 -row 1
1777    grid .chat.top.parms.portentry -sticky w -column 1 -row 2
1778
1779    frame .chat.top.buttons -bg $bgcolor
1780    pack .chat.top.buttons -side bottom -padx 12 -pady 6 -anchor w
1781
1782    button .chat.top.buttons.host -text "Host Game" -bg $bgcolor \
1783    	-command { host_game } -font $boldfont -pady 8 -width 10 \
1784    	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1785    	-fg $fgcolor -activeforeground $afcolor
1786    pack .chat.top.buttons.host -side left -padx 3
1787    button .chat.top.buttons.join -text "Join Game" -bg $bgcolor \
1788    	 -command { join_game } -font $boldfont -pady 8 -width 10 \
1789    	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1790    	-fg $fgcolor -activeforeground $afcolor
1791    pack .chat.top.buttons.join -side left -padx 3
1792    button .chat.top.buttons.close -text "Close" -bg $bgcolor \
1793    	-command { withdraw_window ".chat" } -font $boldfont -pady 8 -width 10 \
1794    	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
1795    	-fg $fgcolor -activeforeground $afcolor
1796    pack .chat.top.buttons.close -side left -padx 3
1797
1798    label .chat.top.status -text "Status : Not Connected" -bg $bgcolor -font $boldfont -fg $fgcolor
1799    pack .chat.top.status -side left -padx 12 -pady 3
1800
1801    frame .chat.bottom -bg $bgcolor
1802    pack .chat.bottom -side bottom -fill x
1803
1804    label .chat.bottom.label -text "Message :" -bg $bgcolor -width 14 -anchor e -font $boldfont -fg $fgcolor
1805    pack .chat.bottom.label -side left -padx 0 -pady 4
1806    entry .chat.bottom.input -width 50 -state disabled -fg $fgcolor -font $stdfont
1807    pack .chat.bottom.input -side left -padx 22 -pady 4 -fill x -expand true
1808
1809    frame .chat.mid -width 500 -height 330 -bg $bgcolor
1810    if { $debug } {
1811	.chat.mid config -bg green
1812    }
1813    pack .chat.mid -side top -fill both -expand true
1814    pack propagate .chat.mid false
1815
1816    frame .chat.mid.left -borderwidth 2 -relief sunken -bg $bgcolor
1817    pack .chat.mid.left -side left -fill y
1818
1819    label .chat.mid.left.label -text "Players" -bg $bgcolor -anchor w -font $boldfont -fg $fgcolor
1820    pack .chat.mid.left.label -side top
1821    listbox .chat.mid.left.persons -width 15 -relief sunken -borderwidth $listb \
1822    -bg $lcolor -fg $fgcolor -font $stdfont
1823    pack .chat.mid.left.persons -side left -fill y -expand true
1824
1825    scrollbar .chat.mid.yscroll -orient vert \
1826	    -command ".chat.mid.right.t yview" -width 16 -borderwidth $scrollb \
1827    	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
1828   pack .chat.mid.yscroll -side right -fill y
1829
1830    frame .chat.mid.right -borderwidth $textb -relief sunken -bg $lcolor
1831    pack .chat.mid.right -side right -fill both -expand true
1832
1833    text .chat.mid.right.t -width 500 -height 500 -wrap word -font $stdfont -relief flat \
1834	    -yscrollcommand ".chat.mid.yscroll set"  -bg $lcolor -highlightbackground $lcolor -fg $fgcolor
1835    pack .chat.mid.right.t -side left -fill both -expand true
1836    # Don't let the user type into this window.
1837    .chat.mid.right.t config -state disabled
1838    # Bind Escape to the Close button.
1839    bind .chat <Key> {
1840	if {"%K" == "Escape"} {
1841		.chat.top.buttons.close flash
1842		wm withdraw .chat
1843	}
1844    }
1845    # Finally check if we were already connected and set items as required.
1846    if { $my_rid > 0 } {
1847	enable_chat
1848	.chat.top.buttons.host config -state disabled
1849	.chat.top.buttons.join config -state disabled
1850	.chat.top.parms.nameentry config -state disabled
1851	.chat.top.parms.hostentry config -state disabled
1852	.chat.top.parms.portentry config -state disabled
1853	if { $my_rid == $master_rid } {
1854		.chat.top.status config -text "Status : Accepting Connections"
1855	} else {
1856		.chat.top.status config -text "Status : Connected"
1857	}
1858    }
1859    center_on_screen .chat
1860}
1861
1862proc add_program { myrid rid str } {
1863    global persons
1864    global prefs
1865    global my_rid master_rid
1866
1867    set my_rid $myrid
1868
1869    set persons($rid,name) $str
1870
1871    # -host/-join arg setup does not create chat window.
1872    if { !"[ winfo exists .chat ]" } {
1873	return
1874    }
1875
1876    # Once the program is accepting connections, or connected, the
1877    # Host/Join buttons are no longer needed for anything.
1878    .chat.top.buttons.host config -state disabled
1879    .chat.top.buttons.join config -state disabled
1880    # Ditto for the name, host and port.
1881    .chat.top.parms.nameentry config -state disabled
1882    .chat.top.parms.hostentry config -state disabled
1883    .chat.top.parms.portentry config -state disabled
1884    if { $my_rid > 0 && $my_rid == $master_rid } {
1885	.chat.top.status config -text "Status : Accepting Connections"
1886    	# Always reenable the New Game button if .newgame exists.
1887	.newgame.bottom.b1 config -state normal
1888	# Only reenable the Open button if we have not yet selected a game.
1889	if { "[ numutypes ]" == 0 } {
1890		.newgame.bottom.b2 config -state normal
1891	}
1892    } else {
1893	.chat.top.status config -text "Status : Connected"
1894    }
1895    .chat.mid.left.persons insert end "$rid: $persons($rid,name)"
1896    enable_chat
1897    if { $rid == 1 } {
1898	set joinstr "is hosting a game at $prefs(joinhost)."
1899    } else {
1900	set joinstr "has joined the game."
1901    }
1902    insert_chat_string $myrid 0 "$persons($rid,name) $joinstr\n"
1903    # Connect button becomes a Chat button.
1904    if { "[ winfo exists .newgame.bottom.connect ]" } {
1905	.newgame.bottom.connect config -text "Chat"
1906    }
1907}
1908
1909# This proc should be called when chatting becomes possible.
1910
1911proc enable_chat {} {
1912    set cbuf .chat.bottom.input
1913
1914    $cbuf config -state normal
1915
1916    bind $cbuf <Key> { if {"%K" == "Return"} { send_chat_bdg ; break } }
1917
1918    # This is now the main widget of interest in the window.
1919    focus $cbuf
1920}
1921
1922proc send_chat_bdg {} {
1923    set cbuf .chat.bottom.input
1924
1925    send_chat "[ $cbuf get ]\n"
1926    $cbuf delete 0 end
1927}
1928
1929proc insert_chat_string { myrid rid str } {
1930    global persons
1931    global my_rid
1932
1933    set cbuf .chat.mid.right.t
1934
1935    if { !"[ winfo exists $cbuf ]" } {
1936	return
1937    }
1938
1939    $cbuf config -state normal
1940    if { $rid != 0 } {
1941	$cbuf insert end "$persons($rid,name): "
1942    }
1943    $cbuf insert end "$str"
1944    # (should only do if already scrolled to end)
1945    $cbuf yview moveto 1.0
1946    # Don't let the user type into this window.
1947    $cbuf config -state disabled
1948}
1949
1950proc popup_map { map } {
1951
1952    if { "[ winfo exists $map ]" } {
1953	# Kick the window manager awake.
1954	wm withdraw $map
1955	wm deiconify $map
1956	focus -force $map
1957    }
1958}
1959
1960proc close_map { map } {
1961    global nummaps
1962
1963    # Count the number of open maps.
1964    set openmaps 0
1965    for { set i 1 } { $i <= $nummaps } {incr i } {
1966    	set map2 .m$i
1967    	if { "[ winfo ismapped $map2 ]" } {
1968    		incr openmaps
1969    	}
1970    }
1971    # Never close the last open map.
1972    if { $openmaps > 1 } {
1973    	wm withdraw $map
1974    }
1975}
1976
1977# Create a map window, which is the main player interface to Xconq.
1978# The map window includes a map/view, a world map, plus info about
1979# individual units, lists of sides, unit types, etc.
1980
1981set nummaps 0
1982
1983proc create_map_window { mapn } {
1984    global bigfont boldfont stdfont titlefont hugefont mapfont
1985    global lineheight
1986    global utype_icon_size mtype_icon_size
1987    global nummaps map_widget map_number
1988    global dblbuffer
1989    global dside
1990    global prefs
1991    global debug
1992    global tcl_platform
1993    global scrollb
1994    global bgcolor hbcolor abcolor tcolor lcolor mbcolor fgcolor ncolor
1995    global indepside_player
1996
1997    # For the benefit of users that bypassed the splash screen, we do this once again.
1998    set stdfont [ list "-family" $prefs(font_family) "-size" $prefs(font_size) ]
1999    set boldfont [ list "-family" $prefs(font_family) "-size" $prefs(font_size) "-weight" "bold" ]
2000    if { $prefs(font_size) < 10 } {
2001	    set bigfont [ list "-family" $prefs(font_family) "-size" [ expr $prefs(font_size) + 1 ] ]
2002	    set titlefont [ list "-family" $prefs(font_family) "-size" [ expr $prefs(font_size) + 1 ] "-weight" "bold" ]
2003    } else {
2004	    set bigfont [ list "-family" $prefs(font_family) "-size" [ expr $prefs(font_size) + 2 ] ]
2005	    set titlefont [ list "-family" $prefs(font_family) "-size" [ expr $prefs(font_size) + 2 ] "-weight" "bold" ]
2006    }
2007    set hugefont [ list "-family" $prefs(font_family) "-size" [ expr $prefs(font_size) * 3 ] "-weight" "bold" ]
2008
2009    set asc [ font metrics $stdfont -ascent ]
2010    set dsc [ font metrics $stdfont -descent ]
2011    set lineheight [ expr $asc + $dsc + 1 ]
2012
2013    set nums [ numsides ]
2014    set numscores [ numscorekeepers ]
2015
2016    incr nummaps
2017
2018    set map .m$mapn
2019    toplevel $map
2020    # Necessary to force focus here since xconq will have lost its focus to
2021    # Windows if the chat dialog was not up and could receive focus when
2022    # the player setup dialog was dismissed.
2023    focus -force $map
2024
2025    set map_widget($mapn) $map
2026    set map_number($map) $mapn
2027
2028    wm title $map "Xconq Map $mapn"
2029
2030   # Make sure the map is just withdrawn if the close box is used.
2031    wm protocol $map WM_DELETE_WINDOW "close_map $map"
2032
2033    set_options_from_prefs $map
2034
2035    # Set the main window to take up most of the screen.
2036
2037    set mainwid [ winfo screenwidth . ]
2038    set mainhgt [ winfo screenheight . ]
2039
2040    set mainwid [ expr int(0.95 * $mainwid) ]
2041    set mainhgt [ expr int(0.90 * $mainhgt) ]
2042
2043    set geomspec ""
2044    set geomspec [ append geomspec $mainwid "x" $mainhgt ]
2045
2046    # Under MacOS and Windows we also need to set the correct offset.
2047    if { "$tcl_platform(platform)" == "macintosh" } {
2048    	set geomspec [ append geomspec "+0+20" ]
2049    }
2050    if { "$tcl_platform(platform)" == "windows" } {
2051    	set geomspec [ append geomspec "+0+0" ]
2052    }
2053
2054    wm geometry $map $geomspec
2055
2056    create_map_menus $map
2057
2058    for { set i 1 } { $i <= $nummaps } { incr i } {
2059    	set map2 .m$i
2060    	$map.menubar.windows add command -label "Map $i" \
2061    		-command "popup_map $map2"
2062    }
2063
2064    create_left_right_panes $map 0.80
2065
2066    # Set up the left side's subpanes.
2067
2068    create_top_bottom_panes $map.leftside 0.10
2069
2070    # Notices window.  We don't want tcl to allow user input into this
2071    # window (thing get confused that way).  Thus, we keep it in
2072    # -state disabled except when adding text to it.
2073    frame $map.leftside.topside.notices -borderwidth 1 -bg $bgcolor
2074    pack $map.leftside.topside.notices -side top -expand true -fill both
2075
2076    text $map.leftside.topside.notices.t -borderwidth 1 -height 1000 \
2077	    -font $stdfont \
2078	    -yscrollcommand "$map.leftside.topside.notices.yscroll set" \
2079	    -bg $ncolor -highlightbackground $ncolor -fg $fgcolor
2080    whelp $map.leftside.topside.notices.t "Notices of events and other info"
2081    scrollbar $map.leftside.topside.notices.yscroll -orient vert \
2082	    -command "$map.leftside.topside.notices.t yview" -width 16 \
2083	    -borderwidth $scrollb \
2084	    -bg $bgcolor -highlightbackground $hbcolor \
2085	    -activebackground $abcolor -troughcolor $tcolor
2086
2087    whelp $map.leftside.topside.notices.yscroll \
2088	    "Notices of events and other info"
2089    pack $map.leftside.topside.notices.yscroll -side right -fill y
2090    pack $map.leftside.topside.notices.t -side left -fill both -expand true
2091
2092    frame $map.leftside.botside.buttons -borderwidth 0 -bg $bgcolor
2093    pack $map.leftside.botside.buttons -side left -fill y
2094
2095    fill_in_button_box $mapn $map.leftside.botside.buttons
2096
2097    text $map.leftside.botside.mouseover -borderwidth 1 -height 1 \
2098	    -font $stdfont -bg $bgcolor -highlightbackground $hbcolor \
2099		-fg $fgcolor
2100    whelp $map.leftside.botside.mouseover \
2101	    "Description of what the mouse is over"
2102    pack $map.leftside.botside.mouseover -side top -fill x
2103
2104    frame $map.leftside.botside.uf -borderwidth 0 -bg $bgcolor
2105    pack $map.leftside.botside.uf -side top -fill x
2106
2107    canvas $map.leftside.botside.uf.unitinfo \
2108	    -height [ expr 5 * $lineheight + $lineheight / 2 ] -width 2000 \
2109	    -borderwidth 1 -relief sunken \
2110	    -bg $bgcolor -highlightbackground $hbcolor
2111    whelp $map.leftside.botside.uf.unitinfo "Details about the current unit"
2112    pack $map.leftside.botside.uf.unitinfo -side left -fill y -expand true
2113
2114    frame $map.leftside.botside.mapf -bg $bgcolor
2115    pack $map.leftside.botside.mapf -side bottom -fill both
2116
2117    # Ask for a frame larger than the window, so that it's guaranteed to
2118    # fill up its grid position.
2119    frame $map.leftside.botside.mapf.mapf2 -width 4000 -height 4000 -bg $mbcolor
2120    if { $debug } {
2121	$map.leftside.botside.mapf.mapf2 config -bg green
2122    }
2123    pack propagate $map.leftside.botside.mapf.mapf2 false
2124#    scrollbar $map.leftside.botside.mapf.xscroll -orient horiz \
2125#	    -command "$map.leftside.botside.mapf.mapf2.map xview" -width 16 -borderwidth $scrollb \
2126#	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
2127#    scrollbar $map.leftside.botside.mapf.yscroll -orient vert \
2128#	    -command "$map.leftside.botside.mapf.mapf2.map yview" -width 16 -borderwidth $scrollb \
2129#	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
2130#    grid $map.leftside.botside.mapf.mapf2 $map.leftside.botside.mapf.yscroll -sticky news
2131#    grid $map.leftside.botside.mapf.xscroll -sticky ew
2132    grid $map.leftside.botside.mapf.mapf2 -sticky news -padx 1 -pady 1
2133    grid rowconfigure $map.leftside.botside.mapf 0 -weight 1
2134    grid columnconfigure $map.leftside.botside.mapf 0 -weight 1
2135
2136    map $map.leftside.botside.mapf.mapf2.map \
2137    	    -power $prefs(power) \
2138    	    -bg $mbcolor \
2139	    -grid $prefs(grid) \
2140	    -coverage $prefs(coverage) \
2141	    -elevations $prefs(elevations) \
2142	    -lighting $prefs(lighting) \
2143	    -people $prefs(people) \
2144	    -control $prefs(control) \
2145	    -temperature $prefs(temperature) \
2146	    -winds $prefs(winds) \
2147	    -clouds $prefs(clouds) \
2148	    -unitnames $prefs(unit_names) \
2149	    -featurenames $prefs(feature_names) \
2150	    -featureboundaries $prefs(feature_boundaries) \
2151	    -meridians $prefs(meridians) \
2152	    -meridianinterval $prefs(meridian_interval) \
2153	    -ai $prefs(ai) \
2154	    -terrainimages $prefs(terrain_images) \
2155	    -terrainpatterns $prefs(terrain_patterns) \
2156	    -transitions $prefs(transitions) \
2157	    -mainfont $mapfont \
2158	    -featurefont $mapfont \
2159	    -dbl $dblbuffer
2160    pack $map.leftside.botside.mapf.mapf2.map -expand true
2161
2162    adjust_map_font_sizes $map
2163
2164    # Set up the right side's subpanes.
2165
2166    set rightwid [ expr (1.0 - 0.75) * $mainwid ]
2167
2168    # Create the turn/date pane.
2169
2170    frame $map.rightside.turnf -borderwidth 1 -relief sunken -bg $bgcolor
2171    pack $map.rightside.turnf -side top -fill x -expand true
2172
2173    canvas $map.rightside.turnf.turn -height [ expr $lineheight + 4 ] \
2174    	-bg $bgcolor -highlightbackground $hbcolor
2175    whelp $map.rightside.turnf.turn "Current turn info"
2176    pack $map.rightside.turnf.turn -side top -fill x -expand true
2177
2178    # Create the side list pane.
2179
2180    frame $map.rightside.gamef -borderwidth 1 -relief sunken -bg $bgcolor
2181    pack $map.rightside.gamef -side top -fill x -expand true
2182
2183    # (should be sized later, when actual side elements filled in)
2184
2185    # We compute this again since things may have changed during the
2186    # player setup.
2187    if { [ side_ingame 0 ] } {
2188	set indepplayer [ assigned_player indepside ]
2189	# First test if indepside has a human player.
2190	set indepside_player [ player_displayname $indepplayer ]
2191	# If not, test if it has an AI player.
2192	if { "$indepside_player" == "" } {
2193		set indepside_player [ player_aitypename $indepplayer ]
2194	}
2195    } else {
2196	set indepside_player ""
2197    }
2198    set game_entry_height [ expr ( 2 + $numscores ) * $lineheight + 20 ]
2199    set game_win_height [ expr $nums * $game_entry_height ]
2200    # Add the indepside if necessary.
2201    if { "$indepside_player" != "" } {
2202	set game_win_height [ expr { $game_win_height + $game_entry_height } ]
2203    }
2204    set numtreas [ numtreasury ]
2205    incr game_win_height [ expr (($numtreas + 1) / 2) * $lineheight ]
2206    set actualheight $game_win_height
2207    # Limit side list space to 40% of main window height.
2208    set limitheight [ expr ( $mainhgt * 40 ) / 100 ]
2209    if { $actualheight > $limitheight } {
2210	set actualheight $limitheight
2211    }
2212    canvas $map.rightside.gamef.game -height $actualheight \
2213	-scrollregion [ list 0 0 $rightwid $game_win_height ] \
2214	-yscrollcommand "$map.rightside.gamef.yscroll set" \
2215    	-bg $bgcolor -highlightbackground $hbcolor
2216    whelp $map.rightside.gamef.game "List of sides in game"
2217    scrollbar $map.rightside.gamef.yscroll -orient vert \
2218	-command "$map.rightside.gamef.game yview" -width 16 -borderwidth $scrollb \
2219        -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
2220    whelp $map.rightside.gamef.yscroll "List of sides in game"
2221    pack $map.rightside.gamef.yscroll -side right -fill y
2222    pack $map.rightside.gamef.game -side left -fill both -expand true
2223
2224    # Make sure the scrollbar is positioned at the top (this is needed under
2225    # MacOS but not under Windows or Unix).
2226    $map.rightside.gamef.game yview moveto 0.0
2227
2228#    $map.rightside.gamef.game create line 1 1 10 100 -stipple ants
2229
2230    # Create the world map pane.
2231
2232    # A border of 1 is more consistent, but not a good idea until the
2233    # grip has been changed from a box to a stripe between panes.
2234    frame $map.rightside.worldf -borderwidth 2 -relief sunken -bg $bgcolor
2235    pack $map.rightside.worldf -side bottom -fill both -expand true
2236    frame $map.rightside.worldf.2 -bg $mbcolor
2237    pack $map.rightside.worldf.2 -side bottom -fill both -expand true
2238
2239    set pow [ fit_map $rightwid ]
2240    # Limit world map space to 40% of main window height.
2241    set limitheight [ expr ( $mainhgt * 40 ) / 100 ]
2242    map $map.rightside.worldf.2.world -world 1 -power $pow -bg $mbcolor \
2243	    -maxheight $limitheight -dbl $dblbuffer
2244    whelp $map.rightside.worldf.2.world "Map of the whole world"
2245    # The pad here looks a little strange, but it serves two purposes:
2246    # first, to keep the grip from "leaking" into the world map when
2247    # scrolling, and second, to distinguish white terrain (such as ice)
2248    # from the sunken border of the frame.
2249    pack $map.rightside.worldf.2.world -padx 1 -pady 1
2250
2251    global last_world_width last_world_power
2252    set last_world_width $rightwid
2253    set last_world_power $pow
2254
2255    # Create the unit type list pane.  This comes last packingwise,
2256    # since it will usually need to scroll, so it's not so important
2257    # to give it all the space it would like.
2258
2259    frame $map.rightside.listf -borderwidth 1 -relief sunken -bg $bgcolor
2260    pack $map.rightside.listf -side top -expand true -fill x
2261
2262    set numu [ numutypes_available $dside ]
2263    set numm [ nummtypes ]
2264    set utype_entry_height [ expr $utype_icon_size + 4 ]
2265    set mtype_entry_height [ expr $mtype_icon_size + 4 ]
2266    set listwinheight [ expr $numu * $utype_entry_height ]
2267    if { $numm > 0 } {
2268    	incr listwinheight $utype_entry_height
2269    	incr listwinheight [ expr $numm * $mtype_entry_height ]
2270    }
2271    canvas $map.rightside.listf.unitlist -height $listwinheight \
2272	    -scrollregion [ list 0 0 $rightwid $listwinheight ] \
2273	    -yscrollcommand "$map.rightside.listf.yscroll set" \
2274	    -bg $bgcolor -highlightbackground $hbcolor
2275    whelp $map.rightside.listf.unitlist "List of unit types"
2276    scrollbar $map.rightside.listf.yscroll -orient vert \
2277	    -command "$map.rightside.listf.unitlist yview" -width 16 -borderwidth $scrollb \
2278	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
2279    whelp $map.rightside.listf.yscroll "List of unit types"
2280    pack $map.rightside.listf.yscroll -side right -fill y
2281    pack $map.rightside.listf.unitlist -side left -fill both -expand true
2282
2283    # Make sure the scrollbar is positioned at the top (this is needed under
2284    # MacOS but not under Windows or Unix.
2285    $map.rightside.listf.unitlist yview moveto 0.0
2286
2287    # Preload widget with tagged text and other items.
2288
2289    # Pre-tag groups of blank chars for the ranges that we will use for
2290    # notification and interaction.
2291    $map.leftside.topside.notices.t insert end " " notices
2292    $map.leftside.topside.notices.t insert end " " prefix
2293    $map.leftside.topside.notices.t insert end " " prompt
2294    $map.leftside.topside.notices.t insert end "  " answer
2295    # Make the user interaction things stand out more.
2296    $map.leftside.topside.notices.t tag config prefix -font $boldfont
2297    $map.leftside.topside.notices.t tag config prompt -font $boldfont
2298    $map.leftside.topside.notices.t tag config answer -font $boldfont
2299
2300    set unitinfo $map.leftside.botside.uf.unitinfo
2301#    imfsample $unitinfo.pic -width 44 -height 48 -iwidth 44 -iheight 48 \
2302#	-bg $bgcolor
2303    imfsample $unitinfo.pic -width 32 -height 32 -iwidth 32 -iheight 32 \
2304	-bg $bgcolor
2305    $unitinfo create window 4 6 -window $unitinfo.pic -anchor nw
2306    set col1 [ expr 6 + 44 ]
2307    set col2 250
2308    set ypos [ expr $lineheight + $lineheight / 2 ]
2309    $unitinfo create text $col1 $ypos -tag { handle textual } -fill $fgcolor
2310    $unitinfo create text $col2 $ypos -tag { hp textual col2 } -fill $fgcolor
2311    incr ypos $lineheight
2312    $unitinfo create text $col1 $ypos -tag { loc textual } -fill $fgcolor
2313    $unitinfo create text $col2 $ypos -tag { stack textual col2 } -fill $fgcolor
2314    incr ypos $lineheight
2315    $unitinfo create text $col1 $ypos -tag { occ textual } -fill $fgcolor
2316    $unitinfo create text $col2 $ypos -tag { s0 textual col2 } -fill $fgcolor
2317    incr ypos $lineheight
2318    $unitinfo create text $col1 $ypos -tag { plan textual } -fill $fgcolor
2319    $unitinfo create text $col2 $ypos -tag { s1 textual col2 } -fill $fgcolor
2320    incr ypos $lineheight
2321    $unitinfo create text $col1 $ypos -tag { t0 textual } -fill $fgcolor
2322    $unitinfo create text $col2 $ypos -tag { aux0 textual col2 } -fill $fgcolor
2323    incr ypos $lineheight
2324
2325#    $unitinfo create text $col1 $ypos -tag { t1 textual }
2326#    $unitinfo create text $col2 $ypos -tag { aux0 textual col2 }
2327
2328    # Make all the textual unit info items look the same.
2329    $unitinfo itemconfig textual -anchor sw -font $stdfont
2330
2331    set turnpane $map.rightside.turnf.turn
2332    $turnpane create text 4 4 -tag the_date -anchor nw -font $boldfont -fill $fgcolor
2333
2334    fill_in_side_list $map
2335
2336    fill_in_unit_type_list $map
2337
2338    make_normal_bindings $map
2339}
2340
2341proc fill_in_button_box { mapn buttonbox } {
2342    global bgcolor hbcolor abcolor fgcolor afcolor
2343
2344    button $buttonbox.move -bitmap shoot_cursor \
2345	    -width 24 -height 24 \
2346	    -command [ list execute_long_command $mapn "survey" ] \
2347	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2348	    -fg $fgcolor -activeforeground $afcolor
2349    whelp $buttonbox.move "Switch between move and survey modes"
2350    pack $buttonbox.move -side top
2351    frame $buttonbox.divider1 -width 24 -height 8 -bg $bgcolor
2352    pack $buttonbox.divider1 -side top
2353    button $buttonbox.build -bitmap build \
2354	    -width 24 -height 24 \
2355	    -command [ list execute_long_command $mapn "produce-unit" ] \
2356	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2357	    -fg $fgcolor -activeforeground $afcolor
2358    whelp $buttonbox.build "Build a type of unit"
2359    pack $buttonbox.build -side top
2360    button $buttonbox.return -bitmap return \
2361	    -width 24 -height 24 \
2362	    -command [ list execute_long_command $mapn "return" ] \
2363	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2364	    -fg $fgcolor -activeforeground $afcolor
2365    whelp $buttonbox.return "Return for more supplies"
2366    pack $buttonbox.return -side top
2367    button $buttonbox.sleep -bitmap sleep \
2368	    -width 24 -height 24 \
2369	    -command [ list execute_long_command $mapn "sleep" ] \
2370	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2371	    -fg $fgcolor -activeforeground $afcolor
2372    whelp $buttonbox.sleep "Sleep indefinitely"
2373    pack $buttonbox.sleep -side top
2374    button $buttonbox.reserve -bitmap reserve \
2375	    -width 24 -height 24 \
2376	    -command [ list execute_long_command $mapn "reserve" ] \
2377	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2378	    -fg $fgcolor -activeforeground $afcolor
2379    whelp $buttonbox.reserve "Reserve unit for next turn"
2380    pack $buttonbox.reserve -side top
2381    button $buttonbox.delay -bitmap delay \
2382	    -width 24 -height 24 \
2383	    -command [ list execute_long_command $mapn "delay" ] \
2384	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2385	    -fg $fgcolor -activeforeground $afcolor
2386    whelp $buttonbox.delay "Delay moving unit until others moved this turn"
2387    pack $buttonbox.delay -side top
2388    frame $buttonbox.divider2 -width 24 -height 8 -bg $bgcolor
2389    pack $buttonbox.divider2 -side top
2390    button $buttonbox.zoomin -bitmap closer \
2391	    -width 24 -height 24 \
2392	    -command [ list execute_long_command $mapn "zoom-in" ] \
2393	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2394	    -fg $fgcolor -activeforeground $afcolor
2395    whelp $buttonbox.zoomin "Zoom in"
2396    pack $buttonbox.zoomin -side top
2397    button $buttonbox.zoomout -bitmap farther \
2398	    -width 24 -height 24 \
2399	    -command [ list execute_long_command $mapn "zoom-out" ] \
2400	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2401	    -fg $fgcolor -activeforeground $afcolor
2402    whelp $buttonbox.zoomout "Zoom out"
2403    pack $buttonbox.zoomout -side top
2404    button $buttonbox.iso -bitmap iso \
2405	    -width 24 -height 24 \
2406	    -command [ list execute_long_command $mapn "map iso" ] \
2407	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2408	    -fg $fgcolor -activeforeground $afcolor
2409    whelp $buttonbox.iso "Switch between isometric and overhead"
2410    pack $buttonbox.iso -side top
2411    button $buttonbox.rotl -bitmap rotl -state disabled \
2412	    -width 24 -height 24 \
2413	    -command [ list execute_long_command $mapn "map rotl" ] \
2414	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2415	    -fg $fgcolor -activeforeground $afcolor
2416    whelp $buttonbox.rotl "Rotate view left"
2417    pack $buttonbox.rotl -side top
2418    button $buttonbox.rotr -bitmap rotr -state disabled \
2419	    -width 24 -height 24 \
2420	    -command [ list execute_long_command $mapn "map rotr" ] \
2421	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
2422	    -fg $fgcolor -activeforeground $afcolor
2423    whelp $buttonbox.rotr "Rotate view right"
2424    pack $buttonbox.rotr -side top
2425}
2426
2427# This proc adds all the informational elements about each side in the
2428# side list.
2429
2430proc fill_in_side_list { map } {
2431    global stdfont boldfont
2432    global lineheight
2433    global dside
2434    global bgcolor fgcolor
2435    global indepside_player
2436
2437    set nums [ numsides ]
2438    set dside [ dside ]
2439    set numtreas [ numtreasury ]
2440    set numscores [ numscorekeepers ]
2441
2442    # Turn on listing of indepside if either is true.
2443    if { "$indepside_player" == "" } {
2444	set firstside 1
2445    } else {
2446	set firstside 0
2447    }
2448    set sidelist $map.rightside.gamef.game
2449    set game_entry_height [ expr (2 + $numscores ) * $lineheight + 20 ]
2450
2451    set sy 0
2452    for { set i $firstside } { $i <= $nums } { incr i } {
2453	set tsy [ expr $sy + $lineheight ]
2454	set tpy [ expr $sy + (2 * $lineheight) ]
2455	set msy [ expr $sy + floor($lineheight * .60) ]
2456	set rtop [ expr $sy + (2 * $lineheight) + 4 ]
2457	set rbot [ expr $sy + (2 * $lineheight) + 12 ]
2458	if { $i > $firstside } {
2459	    $sidelist create line 0 [ expr $sy - 4 ] 2000 [ expr $sy - 4 ] -fill gray
2460	}
2461	imfsample $sidelist.e$i -width 16 -height 16 -bg $bgcolor
2462	$sidelist.e$i add imf [ side_emblem $i ]
2463	$sidelist create window 4 [ expr $sy + 0 ] -window $sidelist.e$i \
2464		-anchor nw
2465	$sidelist create text 24 $tsy -tag s$i -anchor sw -font $stdfont -fill $fgcolor
2466	$sidelist create text 24 $tpy -tag player$i -anchor sw -font $stdfont -fill $fgcolor
2467	# (should make conditional on liveness of side)
2468	$sidelist create rect 23 [ expr $rtop + 1 ] 23 $rbot -tag left$i \
2469		-fill LawnGreen -outline ""
2470	$sidelist create rect 23 [ expr $rtop + 1 ] 23 $rbot -tag resv$i \
2471		-fill magenta -outline ""
2472	$sidelist create rect 23 $rtop 125 $rbot -tag frame$i -outline $fgcolor
2473	for { set j 1 } { $j <= $numscores } { incr j } {
2474		set scy [ expr $sy + (2 + $j ) * $lineheight + 15 ]
2475		$sidelist create text 24 $scy -tag score$j$i -text "" -anchor sw -font $stdfont -fill $fgcolor
2476	}
2477	# Start the loss line and victory laurels offscreen.
2478	$sidelist create line 4000 $msy 5000 $msy -tag lost$i -fill $fgcolor
2479	$sidelist create bitmap 4000 [ expr $sy + 22 ] -bitmap laurels -tag won$i -anchor nw
2480	incr sy $game_entry_height
2481	# Possibly add treasury materials.
2482	if { $numtreas > 0 && $i == $dside } {
2483	    # Make two columns.
2484	    set rows [ expr ($numtreas + 1) / 2 ]
2485	    set j 0
2486	    for { set row 0 } { $row < $rows } { incr row } {
2487		$sidelist create text 40 [ expr $sy - 4 ] -text m$i,$j -tag m$i,$j -anchor ne -font $stdfont -fill $fgcolor
2488		$sidelist create text 45 [ expr $sy - 4 ] -text [ mtype_name [ mtype_actual $j ] ] -tag mt$i,$j \
2489			-anchor nw -font $stdfont -fill $fgcolor
2490		incr j
2491		# Only do second column if sufficient treasury materials.
2492		if { $j < $numtreas } {
2493		    $sidelist create text 120 [ expr $sy - 4 ] -text m$i,$j -tag m$i,$j -anchor ne -font $stdfont -fill $fgcolor
2494		    $sidelist create text 125 [ expr $sy - 4 ] -text [ mtype_name [ mtype_actual $j ] ] -tag mt$i,$j \
2495		    	-anchor nw -font $stdfont -fill $fgcolor
2496		    incr j
2497		}
2498		incr sy $lineheight
2499	    }
2500	}
2501    }
2502
2503    $sidelist itemconfig s$dside -font $boldfont
2504}
2505
2506# This proc adds all the informational elements about each unit type.
2507
2508proc fill_in_unit_type_list { map } {
2509    global stdfont boldfont bigfont
2510    global lineheight
2511    global utype_icon_size mtype_icon_size
2512    global dside
2513    global bgcolor fgcolor
2514
2515    set unitlist $map.rightside.listf.unitlist
2516
2517    set sy 1
2518    set utype_entry_height [ expr $utype_icon_size + 4 ]
2519    set numu [ numutypes_available $dside ]
2520    for { set i 0 } { $i < $numu } { incr i } {
2521	# Compute the y position of text items.
2522	set tsy [ expr $sy + $utype_icon_size / 2 ]
2523	imfsample $unitlist.u$i -width 32 -iwidth 32 -height 32 -iheight 32 \
2524		-bg $bgcolor
2525#	whelp $unitlist.u$i "name$i"
2526	$unitlist.u$i add imf [ u_image_name [ utype_actual $i ] ]
2527	# Add the side emblem as a second image, but don't display it
2528	# as an image; instead declare as the "emblem".
2529	$unitlist.u$i add imf [ side_emblem $dside ]
2530	$unitlist.u$i emblem 1
2531	$unitlist create window 4 $sy -window $unitlist.u$i -anchor nw
2532	$unitlist create text [ expr $utype_icon_size + 12 ] $tsy -tag u$i \
2533		-anchor s -font $stdfont -fill $fgcolor
2534	$unitlist create text [ expr $utype_icon_size + 24 ] $tsy -tag name$i \
2535		-anchor sw -font $stdfont -fill $fgcolor
2536	set tsy [ expr $sy + $utype_icon_size / 2 + $lineheight ]
2537	$unitlist create text [ expr $utype_icon_size + 42 ] $tsy -tag n$i \
2538		-anchor se -font $stdfont -fill $fgcolor
2539	$unitlist create text [ expr $utype_icon_size + 44 ] $tsy -tag i$i \
2540		-anchor sw -font $stdfont -fill $fgcolor
2541	set rtop [ expr $sy - 1 ]
2542	set rbot [ expr $sy + $utype_icon_size + 1 ]
2543	$unitlist create rect 3 $rtop [ expr $utype_icon_size + 5 ] $rbot \
2544		-tag rect$i -outline $bgcolor
2545	incr sy $utype_entry_height
2546    }
2547    set mtype_entry_height [ expr $mtype_icon_size + 4 ]
2548    set numm [nummtypes ]
2549    if { $numm > 0 } {
2550	set tsy [ expr $sy + $utype_icon_size / 2 + 6 ]
2551	$unitlist create text 10 $tsy -tag material -anchor sw -font $boldfont -fill $fgcolor -text "Material:"
2552	$unitlist create text 110 $tsy -tag supply -anchor se -font $stdfont -fill $fgcolor -text "supply"
2553	$unitlist create text 145 $tsy -tag production -anchor se -font $stdfont -fill $fgcolor -text "prod"
2554	$unitlist create text 185 $tsy -tag capacity -anchor se -font $stdfont -fill $fgcolor -text "capac"
2555	incr sy $utype_entry_height
2556	for { set i 0 } { $i < $numm } { incr i } {
2557		set tsy [ expr $sy + $mtype_icon_size / 2  ]
2558		imfsample $unitlist.m$i -width 16 -iwidth 16 \
2559		    -height 16 -iheight 16 -bg $bgcolor
2560		$unitlist.m$i add imf [ m_image_name $i ]
2561		$unitlist create window 10 [ expr $sy - 8 ] \
2562		    -window $unitlist.m$i -anchor nw
2563		$unitlist create text 30 $tsy -tag material$i \
2564			-anchor sw -font $stdfont -fill $fgcolor
2565		$unitlist create text 110 $tsy -tag supply$i \
2566			-anchor se -font $stdfont -fill $fgcolor
2567		$unitlist create text 145 $tsy -tag production$i \
2568			-anchor se -font $stdfont -fill $fgcolor
2569		$unitlist create text 185 $tsy -tag capacity$i \
2570			-anchor se -font $stdfont -fill $fgcolor
2571		incr sy $mtype_entry_height
2572	}
2573    }
2574}
2575
2576# The following collection of flags govern what is enabled and disabled
2577# in the menus and other controls.  They have to be set/reset each time
2578# a different unit becomes the current one.
2579
2580set can_act 0
2581set can_plan 0
2582set can_move 0
2583set can_return 0
2584set can_build 0
2585set can_repair 0
2586set can_change_type 0
2587set can_attack 0
2588set can_fire 0
2589set can_detonate 0
2590set can_give_take 0
2591set can_embark 0
2592set can_disembark 0
2593set can_detach 0
2594set can_disband 0
2595set can_add_terrain 0
2596set can_remove_terrain 0
2597
2598set can_see_people 0
2599set can_see_control 0
2600set can_see_elev 0
2601set can_see_lighting 0
2602set can_see_temp 0
2603set can_see_winds 0
2604set can_see_clouds 0
2605
2606set map_survey 0
2607
2608proc set_options_from_prefs { map } {
2609    global view_option_list
2610    global prefs
2611    global map_options
2612
2613    foreach opt $view_option_list {
2614	set map_options($map,$opt) $prefs($opt)
2615    }
2616}
2617
2618# Create the complete menu bar for a given map window.
2619
2620proc create_map_menus { map } {
2621    global view_option_names
2622    global map_options
2623    global map_number
2624    global tcl_platform
2625    global bgcolor abcolor scolor fgcolor afcolor micolor
2626    global dside_ai designer
2627
2628    set mapn $map_number($map)
2629
2630    set nums [ numsides ]
2631
2632    menu $map.menubar -bg $bgcolor -activebackground $abcolor -fg $fgcolor \
2633  	    -activeforeground $afcolor
2634    $map config -menu $map.menubar
2635
2636    # Add apple menu and about box support on the mac.
2637    if { "$tcl_platform(platform)" == "macintosh" } {
2638	    $map.menubar add cascade -menu $map.menubar.apple
2639	    menu $map.menubar.apple -bg $bgcolor -activebackground $abcolor \
2640		-fg $fgcolor -activeforeground $afcolor -tearoff 0
2641	    $map.menubar.apple add command -label "About Xconq..." -state normal
2642    }
2643    $map.menubar add cascade -label "File" -menu $map.menubar.file
2644    menu $map.menubar.file -postcommand [ list adjust_file_menu $map ] -tearoff 0 \
2645	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
2646    $map.menubar.file add command -label "New Game..." -state disabled
2647    $map.menubar.file add command -label "Open Game..." -state disabled
2648    $map.menubar.file add command -label "Chat" -state disabled \
2649	    -command { popup_chat }
2650    $map.menubar.file add separator
2651    $map.menubar.file add command -label "Close" -state disabled
2652    $map.menubar.file add command -label "Save Game" -accelerator "S" \
2653	    -command [ list execute_long_command $mapn "save 0" ]
2654    $map.menubar.file add command -label "Save Game As" \
2655	    -command [ list execute_long_command $mapn "save 1" ]
2656    $map.menubar.file add separator
2657    $map.menubar.file add command -label "Preferences..." \
2658	    -command { popup_preferences_dialog }
2659    $map.menubar.file add separator
2660    $map.menubar.file add command -label "Print..." -state disabled
2661    $map.menubar.file add separator
2662    $map.menubar.file add command -label Resign \
2663	    -command [ list execute_long_command $mapn "resign" ]
2664    $map.menubar.file add command -label Quit -accelerator "Q" \
2665	    -command [ list execute_long_command $mapn "quit" ]
2666
2667    $map.menubar add cascade -label "Edit" -menu $map.menubar.edit
2668    menu $map.menubar.edit -postcommand [ list adjust_edit_menu $map ] \
2669	-tearoff 0 -bg $bgcolor -activebackground $abcolor -fg $fgcolor \
2670	-activeforeground $afcolor
2671    $map.menubar.edit add command -label "Can't Undo" -state disabled
2672    $map.menubar.edit add separator
2673    $map.menubar.edit add command -label "Cut" -state disabled
2674    $map.menubar.edit add command -label "Copy" -state disabled
2675    $map.menubar.edit add command -label "Paste" -state disabled
2676    $map.menubar.edit add command -label "Clear" -state disabled
2677    $map.menubar.edit add separator
2678    $map.menubar.edit add command -label "Select All" -state disabled
2679    $map.menubar.edit add separator
2680    $map.menubar.edit add check -label "Design" \
2681	    -command [ list execute_long_command $mapn "design" ] \
2682	    -variable designer -offvalue 0 -onvalue 1 -selectcolor $micolor
2683
2684    $map.menubar add cascade -label "Find" -menu $map.menubar.find
2685    menu $map.menubar.find -postcommand [ list adjust_find_menu $map ] -tearoff 0 \
2686 	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
2687    $map.menubar.find add command -label "Previous" -state disabled
2688    $map.menubar.find add command -label "Next" -state disabled
2689    $map.menubar.find add command -label "Next Occupant" -accelerator "i" \
2690	    -command [ list execute_long_command $mapn "in" ]
2691    $map.menubar.find add separator
2692    $map.menubar.find add command -label "Location..." -state disabled
2693    $map.menubar.find add command -label "Unit by Name..." \
2694	    -command [ list popup_find_dialog $mapn ]
2695    $map.menubar.find add command -label "Distance" -accelerator "\#" \
2696	    -command [ list execute_long_command $mapn "distance" ]
2697    $map.menubar.find add separator
2698    $map.menubar.find add command -label "Current Unit" -accelerator "." \
2699	    -command [ list execute_long_command $mapn "recenter" ]
2700
2701    $map.menubar add cascade -label "Orders" -menu $map.menubar.play
2702    menu $map.menubar.play -postcommand [ list adjust_play_menu $map ] -tearoff 0 \
2703 	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
2704    $map.menubar.play add command -label "Closeup" -state disabled
2705    $map.menubar.play add command -label "City Dialog" -state disabled
2706    $map.menubar.play add command -label "Move To" -accelerator "m" \
2707	    -command [ list execute_long_command $mapn "move-to" ]
2708    $map.menubar.play add command -label "Return" -accelerator "r" \
2709	    -command [ list execute_long_command $mapn "return" ]
2710    $map.menubar.play add command -label "Set Formation" -accelerator "F" \
2711	    -command [ list execute_long_command $mapn "formation" ]
2712    $map.menubar.play add separator
2713    $map.menubar.play add command -label "Wake" -accelerator "w" \
2714	    -command [ list execute_long_command $mapn "wake" ]
2715    $map.menubar.play add command -label "Wake All" -accelerator "W" \
2716	    -command [ list execute_long_command $mapn "wakeall" ]
2717    $map.menubar.play add command -label "Sleep" -accelerator "s" \
2718	    -command [ list execute_long_command $mapn "sleep" ]
2719    $map.menubar.play add command -label "Reserve" \
2720	    -command [ list execute_long_command $mapn "reserve" ]
2721    $map.menubar.play add command -label "Idle" -accelerator "I" \
2722	    -command [ list execute_long_command $mapn "idle" ]
2723    $map.menubar.play add command -label "Delay" -accelerator "d" \
2724	    -command [ list execute_long_command $mapn "delay" ]
2725    $map.menubar.play add separator
2726    $map.menubar.play add command -label "Build" -accelerator "P" \
2727	    -command [ list execute_long_command $mapn "produce-unit" ]
2728    $map.menubar.play add command -label "Repair" \
2729	    -command [ list execute_long_command $mapn "repair" ]
2730    $map.menubar.play add command -label "Change Type" -accelerator "c" \
2731	    -command [ list execute_long_command $mapn "change-type" ]
2732    $map.menubar.play add separator
2733    $map.menubar.play add command -label "Attack" -accelerator "a" \
2734	    -command [ list execute_long_command $mapn "attack" ]
2735    $map.menubar.play add command -label "Overrun" \
2736	    -command [ list execute_long_command $mapn "attack" ]
2737    $map.menubar.play add command -label "Fire" -accelerator "f" \
2738	    -command [ list execute_long_command $mapn "fire" ]
2739    $map.menubar.play add command -label "Fire Into" -accelerator "^f" \
2740	    -command [ list execute_long_command $mapn "fire-into" ]
2741    $map.menubar.play add command -label "Detonate" -accelerator "\!" \
2742	    -command [ list execute_long_command $mapn "detonate" ]
2743
2744    $map.menubar add cascade -label "More Orders" -menu $map.menubar.more
2745    menu $map.menubar.more -postcommand [ list adjust_more_menu $map ] -tearoff 0 \
2746 	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
2747    $map.menubar.more add command -label "Give" -accelerator "g" \
2748	    -command [ list execute_long_command $mapn "give" ]
2749    $map.menubar.more add command -label "Take" -accelerator "t" \
2750	    -command [ list execute_long_command $mapn "take" ]
2751    $map.menubar.more add command -label "Collect" \
2752	    -command [ list execute_long_command $mapn "collect" ]
2753    $map.menubar.more add separator
2754    $map.menubar.more add command -label "Embark" -accelerator "e" \
2755	    -command [ list execute_long_command $mapn "embark" ]
2756    $map.menubar.more add command -label "Disembark" -accelerator "^e" \
2757	    -command [ list execute_long_command $mapn "disembark" ]
2758    $map.menubar.more add separator
2759    $map.menubar.more add command -label "Detach" \
2760	    -command [ list execute_long_command $mapn "detach" ]
2761    $map.menubar.more add command -label "Disband" -accelerator "D" \
2762	    -command [ list execute_long_command $mapn "disband" ]
2763    $map.menubar.more add separator
2764    $map.menubar.more add command -label "Add Terrain" -accelerator "A" \
2765	    -command [ list execute_long_command $mapn "add-terrain" ]
2766    $map.menubar.more add command -label "Remove Terrain" -accelerator "R" \
2767	    -command [ list execute_long_command $mapn "remove-terrain" ]
2768    $map.menubar.more add separator
2769    $map.menubar.more add cascade -label "Plan Type" \
2770	    -menu $map.menubar.more.plantype -state disabled
2771    menu $map.menubar.more.plantype -bg $bgcolor -activebackground $abcolor \
2772	    -fg $fgcolor -activeforeground $afcolor -tearoff 0
2773    $map.menubar.more.plantype add command -label "None" \
2774	    -command [ list execute_long_command $mapn "map plan-none" ]
2775    $map.menubar.more.plantype add command -label "Passive" \
2776	    -command [ list execute_long_command $mapn "map plan-passive" ]
2777    $map.menubar.more.plantype add command -label "Defensive" \
2778	    -command [ list execute_long_command $mapn "map plan-defensive" ]
2779    $map.menubar.more.plantype add command -label "Exploratory" \
2780	    -command [ list execute_long_command $mapn "map plan-exploratory" ]
2781    $map.menubar.more.plantype add command -label "Offensive" \
2782	    -command [ list execute_long_command $mapn "map plan-offensive" ]
2783    $map.menubar.more.plantype add command -label "Random" \
2784	    -command [ list execute_long_command $mapn "map plan-random" ]
2785    $map.menubar.more add command -label "AI Control" \
2786	    -command [ list execute_long_command $mapn "auto" ]
2787    $map.menubar.more add separator
2788    $map.menubar.more add command -label "Rename..." \
2789	    -command [ list execute_long_command $mapn "name" ]
2790    $map.menubar.more add cascade -label "Give Unit" \
2791	    -menu $map.menubar.more.giveunit
2792    menu $map.menubar.more.giveunit -bg $bgcolor -activebackground $abcolor \
2793	    -fg $fgcolor -activeforeground $afcolor -tearoff 0
2794    for { set i 0 } { $i <= $nums } { incr i } {
2795	$map.menubar.more.giveunit add command -label [ side_adjective $i ] \
2796		-command [ list execute_long_command 0 "$i give-unit" ]
2797    }
2798
2799    $map.menubar add cascade -label "Side" -menu $map.menubar.side
2800    menu $map.menubar.side -postcommand [ list adjust_side_menu $map ] -tearoff 0 \
2801 	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
2802    $map.menubar.side add command -label "Closeup" -state disabled
2803    $map.menubar.side add command -label "End This Turn" \
2804	    -command [ list execute_long_command $mapn "end-turn" ]
2805    $map.menubar.side add separator
2806    $map.menubar.side add radio -label "Move Mode" -accelerator "z" \
2807	    -command [ list execute_long_command $mapn "survey" ] \
2808	    -variable map_survey -value 0 -selectcolor $micolor
2809    $map.menubar.side add radio -label "Survey Mode" -accelerator "z" \
2810	    -command [ list execute_long_command $mapn "survey" ] \
2811	    -variable map_survey -value 1 -selectcolor $micolor
2812    $map.menubar.side add separator
2813    $map.menubar.side add cascade -label "AI" \
2814	    -menu $map.menubar.side.ai
2815    menu $map.menubar.side.ai -bg $bgcolor -activebackground $abcolor \
2816	    -fg $fgcolor -activeforeground $afcolor -tearoff 0
2817    $map.menubar.side.ai add radio -label "None" \
2818	    -command [ list execute_long_command $mapn "ai none" ] \
2819	    -variable dside_ai -value "none" -selectcolor $micolor
2820    $map.menubar.side.ai add radio -label "Mplayer" \
2821	    -command [ list execute_long_command $mapn "ai mplayer" ] \
2822	    -variable dside_ai -value "mplayer" -selectcolor $micolor
2823    $map.menubar.side.ai add radio -label "Iplayer" \
2824	    -command [ list execute_long_command $mapn "ai iplayer" ] \
2825	    -variable dside_ai -value "iplayer" -selectcolor $micolor
2826    $map.menubar.side add check -label "AI May Resign" \
2827	    -state active \
2828	    -command { toggle_ai_may_resign } \
2829	    -variable ai_may_resign -offvalue 0 -onvalue 1 -selectcolor $micolor
2830    $map.menubar.side add separator
2831    $map.menubar.side add command -label "Doctrines" -state disabled
2832    $map.menubar.side add separator
2833    $map.menubar.side add command -label "Message" -accelerator "M" \
2834	    -command [ list execute_long_command $mapn "message" ]
2835# $map.menubar.side add command -label "Agreements" \
2836#	    -command { create_agreements_window }
2837
2838    $map.menubar add cascade -label "Windows" -menu $map.menubar.windows
2839    menu $map.menubar.windows -postcommand [ list adjust_windows_menu $map ] \
2840 	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor \
2841	-tearoff 0
2842    $map.menubar.windows add command -label "Scores" \
2843	    -command { popup_scores }
2844    $map.menubar.windows add command -label "Research" \
2845	    -command { popup_research_dialog }
2846    $map.menubar.windows add separator
2847    $map.menubar.windows add command -label "New Map" \
2848	    -command [ list execute_long_command $mapn "new-map" ]
2849    $map.menubar.windows add separator
2850
2851    $map.menubar add cascade -label "View" -menu $map.menubar.view
2852    menu $map.menubar.view -bg $bgcolor -activebackground $abcolor \
2853	    -fg $fgcolor -activeforeground $afcolor -tearoff 0
2854    $map.menubar.view add command -label "Recenter" -accelerator "." \
2855	    -command [ list execute_long_command $mapn "recenter" ]
2856    $map.menubar.view add command -label "Closer" -accelerator "\}" \
2857	    -command [ list execute_long_command $mapn "zoom-in" ]
2858    $map.menubar.view add command -label "Farther" -accelerator "\{" \
2859	    -command [ list execute_long_command $mapn "zoom-out" ]
2860    $map.menubar.view add separator
2861    $map.menubar.view add check -label $view_option_names(grid) \
2862	    -command [ list set_map_view_option $map grid ] \
2863	    -variable map_options($map,grid) -offvalue 0 -onvalue 1 -selectcolor $micolor
2864    $map.menubar.view add check -label $view_option_names(coverage) \
2865	    -command [ list set_map_view_option $map coverage ] \
2866	    -variable map_options($map,coverage) -offvalue 0 -onvalue 1 -selectcolor $micolor
2867    $map.menubar.view add check -label $view_option_names(elevations) \
2868	    -command [ list set_map_view_option $map elevations ] \
2869	    -variable map_options($map,elevations) -offvalue 0 -onvalue 1 -selectcolor $micolor
2870    $map.menubar.view add command -label "Contour Interval" \
2871	    -command [ list popup_contour_interval_dialog $map ]
2872    $map.menubar.view add check -label $view_option_names(lighting) \
2873	    -command [ list set_map_view_option $map lighting ] \
2874	    -variable map_options($map,lighting) -offvalue 0 -onvalue 1 -selectcolor $micolor
2875    $map.menubar.view add check -label $view_option_names(people) \
2876	    -command [ list set_map_view_option $map people ] \
2877	    -variable map_options($map,people) -offvalue 0 -onvalue 1 -selectcolor $micolor
2878    $map.menubar.view add check -label $view_option_names(control) \
2879	    -command [ list set_map_view_option $map control ] \
2880	    -variable map_options($map,control) -offvalue 0 -onvalue 1 -selectcolor $micolor
2881    $map.menubar.view add cascade -label "Weather" \
2882	    -menu $map.menubar.view.weather
2883    menu $map.menubar.view.weather -bg $bgcolor -activebackground $abcolor \
2884	    -fg $fgcolor -activeforeground $afcolor -tearoff 0
2885    $map.menubar.view.weather add check -label $view_option_names(temperature) \
2886	    -command [ list set_map_view_option $map temperature ] \
2887	    -variable map_options($map,temperature) -offvalue 0 -onvalue 1 -selectcolor $micolor
2888    $map.menubar.view.weather add check -label $view_option_names(winds) \
2889	    -command [ list set_map_view_option $map winds ] \
2890	    -variable map_options($map,winds) -offvalue 0 -onvalue 1 -selectcolor $micolor
2891    $map.menubar.view.weather add check -label $view_option_names(clouds) \
2892	    -command [ list set_map_view_option $map clouds ] \
2893	    -variable map_options($map,clouds) -offvalue 0 -onvalue 1 -selectcolor $micolor
2894    $map.menubar.view add check -label $view_option_names(unit_names) \
2895	    -command [ list set_map_view_option $map unit_names ] \
2896	    -variable map_options($map,unit_names) -offvalue 0 -onvalue 1 -selectcolor $micolor
2897    $map.menubar.view add check -label $view_option_names(feature_names) \
2898	    -command [ list set_map_view_option $map feature_names ] \
2899	    -variable map_options($map,feature_names) -offvalue 0 -onvalue 1 -selectcolor $micolor
2900    $map.menubar.view add check -label $view_option_names(feature_boundaries) \
2901	    -command [ list set_map_view_option $map feature_boundaries ] \
2902	    -variable map_options($map,feature_boundaries) \
2903	    -offvalue 0 -onvalue 1 -selectcolor $micolor
2904    $map.menubar.view add check -label $view_option_names(meridians) \
2905	    -command [ list set_map_view_option $map meridians ] \
2906	    -variable map_options($map,meridians) -offvalue 0 -onvalue 1 -selectcolor $micolor
2907    $map.menubar.view add cascade -label $view_option_names(meridian_interval) \
2908	    -menu $map.menubar.view.mi
2909    menu $map.menubar.view.mi -bg $bgcolor -activebackground $abcolor \
2910	    -fg $fgcolor -activeforeground $afcolor -tearoff 0
2911    $map.menubar.view.mi add radio -label "15 min" \
2912	    -command [ list set_map_view_option $map meridian_interval ] \
2913	    -variable map_options($map,meridian_interval) -value 15 -selectcolor $micolor
2914    $map.menubar.view.mi add radio -label "30 min" \
2915	    -command [ list set_map_view_option $map meridian_interval ] \
2916	    -variable map_options($map,meridian_interval) -value 30 -selectcolor $micolor
2917    $map.menubar.view.mi add radio -label "1 deg" \
2918	    -command [ list set_map_view_option $map meridian_interval ] \
2919	    -variable map_options($map,meridian_interval) -value 60 -selectcolor $micolor
2920    $map.menubar.view.mi add radio -label "2 deg" \
2921	    -command [ list set_map_view_option $map meridian_interval ] \
2922	    -variable map_options($map,meridian_interval) -value 120 -selectcolor $micolor
2923    $map.menubar.view.mi add radio -label "5 deg" \
2924	    -command [ list set_map_view_option $map meridian_interval ] \
2925	    -variable map_options($map,meridian_interval) -value 300 -selectcolor $micolor
2926    $map.menubar.view.mi add radio -label "10 deg" \
2927	    -command [ list set_map_view_option $map meridian_interval ] \
2928	    -variable map_options($map,meridian_interval) -value 600 -selectcolor $micolor
2929    $map.menubar.view.mi add radio -label "Other..." \
2930	    -command [ list popup_meridian_interval_dialog $mapn ] \
2931	    -variable map_options($map,meridian_interval) -value 1
2932    $map.menubar.view add check -label $view_option_names(ai) \
2933	    -command [ list set_map_view_option $map ai ] \
2934	    -variable map_options($map,ai) -offvalue 0 -onvalue 1 -selectcolor $micolor
2935
2936    # Disable the help system on MacOS < 8.6 since it crashes there.
2937    if { "$tcl_platform(platform)" != "macintosh" || $tcl_platform(osVersion) >= 8.6 } {
2938	$map.menubar add cascade -label "Help" -menu $map.menubar.help
2939	menu $map.menubar.help -bg $bgcolor -activebackground $abcolor \
2940		    -fg $fgcolor -activeforeground $afcolor -tearoff 0
2941	$map.menubar.help add command -label "Xconq Help" -accelerator "?" \
2942	   		-command { popup_help_dialog }
2943
2944   	init_help_menu $mapn
2945    }
2946
2947    # Chop up the help menu if necessary (workaround for clunky
2948    # menu support on Unix systems).
2949    if { "$tcl_platform(platform)" == "unix" } {
2950	set menu $map.menubar.help
2951	# Get the number of menu items.
2952	set numitems [ $menu index end ]
2953	# Get the max menu height in pixels (with some margin).
2954	set ymax [ expr [ lindex [ wm maxsize $menu ] 1 ] - 100 ]
2955	# Get the height of one item in pixels (Tcl should provide this).
2956	set spacing [ expr [ $menu yposition 2 ] - [ $menu yposition 1 ] ]
2957	# Get the number of columns (rounded down).
2958	set columns [ expr $numitems * $spacing / $ymax ]
2959	# Compute the protruding rest, if any.
2960	set rest [ expr $numitems * $spacing % $ymax ]
2961	# We have a rest.
2962	if { $rest > 0 } {
2963		# We need one more column.
2964		set columns [ expr $columns + 1 ]
2965		# Recompute ymax so that the columns are filled up.
2966		set ymax [ expr $numitems * $spacing / $columns ]
2967	}
2968	# Finally chop up the menu.
2969	for { set i 1 } { $i < $numitems } { incr i } {
2970		set ypos [ $menu yposition $i ]
2971		if { $ypos > $ymax } {
2972			$menu entryconfig $i -columnbreak 1
2973		}
2974	}
2975    }
2976
2977    # Add command key shortcuts on the Mac.
2978    if { "$tcl_platform(platform)" == "macintosh" } {
2979
2980	$map.menubar.file entryconfig "New Game..." -accel Command-N
2981	$map.menubar.file entryconfig "Open Game..." -accel Command-O
2982	$map.menubar.file entryconfig Close -accel Command-W
2983	$map.menubar.file entryconfig "Save Game" -accel Command-S
2984	$map.menubar.file entryconfig Quit -accel Command-Q
2985
2986	$map.menubar.edit entryconfig "Select All" -accel Command-A
2987
2988	$map.menubar.find entryconfig "Current Unit" -accel Command-F
2989
2990	$map.menubar.play entryconfig Closeup -accel Command-C
2991	$map.menubar.play entryconfig Return -accel Command-R
2992	$map.menubar.play entryconfig Build -accel Command-P
2993	$map.menubar.play entryconfig Attack -accel Command--
2994	$map.menubar.play entryconfig Detonate -accel Command-=
2995
2996	$map.menubar.more entryconfig Disband -accel Command-K
2997
2998	$map.menubar.side entryconfig "End This Turn" -accel Command-E
2999
3000	$map.menubar.windows entryconfig Scores -accel Command-1
3001	$map.menubar.windows entryconfig Research -accel Command-2
3002	$map.menubar.windows entryconfig "New Map" -accel Command-M
3003
3004    }
3005
3006    global may_set_show_all
3007    global show_all_was_enabled
3008
3009    set show_all_was_enabled($map) 0
3010
3011    if { $may_set_show_all } {
3012	add_show_all_item $map
3013    }
3014
3015    adjust_view_menu $map
3016}
3017
3018# Given a help topic key, add it to the menu.  This is called
3019# from C code.
3020
3021proc add_help_topic_menu { num key } {
3022    global tcl_platform
3023
3024    set map .m$num
3025    $map.menubar.help add command -label "$key" \
3026	-command [ list get_help_on_topic "$key" ]
3027}
3028
3029proc get_help_on_topic { key } {
3030    popup_help_dialog
3031    help_goto "$key"
3032}
3033
3034proc add_show_all_item { map } {
3035    global show_all_was_enabled
3036    global map_number
3037    global micolor
3038
3039    $map.menubar.view add check -label "Show All" \
3040	    -command [ list execute_long_command $map_number($map) "map show-all" ] \
3041	    -variable map_options($map,show_all) -offvalue 0 -onvalue 1 -selectcolor $micolor
3042    set show_all_was_enabled($map) 1
3043}
3044
3045proc set_map_view_option { map opt } {
3046    global view_option_flags
3047    global map_options
3048
3049    $map.leftside.botside.mapf.mapf2.map config $view_option_flags($opt) $map_options($map,$opt)
3050}
3051
3052proc adjust_file_menu { map } {
3053    global my_rid
3054    global endofgame
3055    global designer
3056
3057    adjust_menu_entry $map file "Chat" [ expr ($my_rid > 0) && !$endofgame ]
3058    adjust_menu_entry $map file "Save Game" [ expr !$endofgame ]
3059    adjust_menu_entry $map file "Save Game As" [ expr !$endofgame ]
3060    adjust_menu_entry $map file "Resign" [ expr !$endofgame && !$designer ]
3061}
3062
3063proc adjust_edit_menu { map } {
3064    global endofgame
3065
3066    adjust_menu_entry $map edit "Design" [ expr !$endofgame ]
3067}
3068
3069# Enable/disable things on the find menu.
3070
3071proc adjust_find_menu { map } {
3072    global curunit
3073    global can_act can_plan can_move can_return can_embark can_disembark
3074    global can_build can_repair can_change_type can_disband
3075    global can_add_terrain can_remove_terrain
3076    global can_give_take can_detach
3077    global can_attack can_fire can_detonate
3078
3079    # (should disable if no next occ)
3080    adjust_menu_entry $map find "Next Occupant" [ expr $curunit ]
3081    adjust_menu_entry $map find "Distance" [ expr $curunit ]
3082    adjust_menu_entry $map find "Current Unit" [ expr $curunit ]
3083}
3084
3085# Enable/disable things on the play menu.
3086
3087proc adjust_play_menu { map } {
3088    global curunit
3089    global can_act can_plan can_move can_return can_embark can_disembark
3090    global can_build can_repair can_change_type can_disband
3091    global can_add_terrain can_remove_terrain
3092    global can_give_take can_detach
3093    global can_attack can_fire can_detonate
3094
3095    adjust_menu_entry $map play "Move To" [ expr $curunit && $can_move ]
3096    adjust_menu_entry $map play "Return" [ expr $curunit && $can_return ]
3097    adjust_menu_entry $map play "Set Formation" [ expr $curunit && $can_move ]
3098    adjust_menu_entry $map play "Wake" [ expr $curunit && $can_plan ]
3099    adjust_menu_entry $map play "Wake All" [ expr $curunit && $can_plan ]
3100    adjust_menu_entry $map play "Sleep" [ expr $curunit && $can_plan ]
3101    adjust_menu_entry $map play "Reserve" [ expr $curunit && $can_plan ]
3102    adjust_menu_entry $map play "Idle" [ expr $curunit && $can_plan ]
3103    adjust_menu_entry $map play "Delay" [ expr $curunit && $can_plan ]
3104    adjust_menu_entry $map play "Build" [ expr $curunit && $can_build ]
3105    adjust_menu_entry $map play "Repair" [ expr $curunit && $can_repair ]
3106    adjust_menu_entry $map play "Change Type" [ expr $curunit && $can_change_type ]
3107    adjust_menu_entry $map play "Attack" [ expr $curunit && $can_attack ]
3108    adjust_menu_entry $map play "Overrun" [ expr $curunit && $can_move && $can_attack ]
3109    adjust_menu_entry $map play "Fire" [ expr $curunit && $can_fire ]
3110    adjust_menu_entry $map play "Fire Into" [ expr $curunit && $can_fire ]
3111    adjust_menu_entry $map play "Detonate" [ expr $curunit && $can_detonate ]
3112}
3113
3114# Enable/disable things on the more menu.
3115
3116proc adjust_more_menu { map } {
3117    global curunit
3118    global can_act can_plan can_move can_return can_embark can_disembark
3119    global can_build can_repair can_change_type can_disband
3120    global can_add_terrain can_remove_terrain
3121    global can_give_take can_detach
3122    global can_attack can_fire can_detonate
3123    global endofgame
3124
3125    adjust_menu_entry $map more "Give" [ expr $curunit && $can_give_take ]
3126    adjust_menu_entry $map more "Take" [ expr $curunit && $can_give_take ]
3127    adjust_menu_entry $map more "Collect" [ expr $curunit && $can_move && $can_give_take ]
3128    adjust_menu_entry $map more "Embark" [ expr $curunit && $can_embark ]
3129    adjust_menu_entry $map more "Disembark" [ expr $curunit && $can_disembark ]
3130    adjust_menu_entry $map more "Detach" [ expr $curunit && $can_detach ]
3131    adjust_menu_entry $map more "Disband" [ expr $curunit && $can_disband ]
3132    adjust_menu_entry $map more "Add Terrain" [ expr $curunit && $can_add_terrain ]
3133    adjust_menu_entry $map more "Remove Terrain" [ expr $curunit && $can_remove_terrain ]
3134#	This kills the submenu.
3135#   adjust_menu_entry $map more "Plan Type" [ expr $curunit && $can_plan ]
3136    adjust_menu_entry $map more "AI Control" [ expr $curunit && $can_plan ]
3137    adjust_menu_entry $map more "Rename..." [ expr !$endofgame ]
3138#	This kills the submenu.
3139#    adjust_menu_entry $map more "Give Unit" [ expr !$endofgame ]
3140}
3141
3142# Enable/disable things on the side menu.
3143
3144proc adjust_side_menu { map } {
3145    global endofgame
3146
3147    adjust_menu_entry $map side "End This Turn" [ expr !$endofgame ]
3148    adjust_menu_entry $map side "Move Mode" [ expr !$endofgame ]
3149    adjust_menu_entry $map side "Survey Mode" [ expr !$endofgame ]
3150#	This kills the submenu.
3151#    adjust_menu_entry $map side "AI" [ expr !$endofgame ]
3152}
3153
3154# Enable/disable things on the windows menu.
3155
3156proc adjust_windows_menu { map } {
3157    global endofgame nummaps
3158
3159    set numa [ numatypes ]
3160    adjust_menu_entry $map windows "Research" [ expr !$endofgame && $numa ]
3161    # Alternatively, we could force newly-created maps to come up
3162    # in survey mode, but it seems unlikely that players would
3163    # ever have much use for creating new maps after the game is over.
3164    adjust_menu_entry $map windows "New Map" [ expr !$endofgame ]
3165    # Update the number of maps. First get the number of menu items (minus 1).
3166    set numitems [ $map.menubar.windows index end ]
3167    # Substract 4 to get the number of listed maps.
3168    set mapitems [ expr ( $numitems - 4 ) ]
3169    # Add popup entries for all unlisted maps.
3170    for { set i [ expr ( $mapitems + 1 ) ]  } { $i <= $nummaps } { incr i } {
3171    	set map2 .m$i
3172    	$map.menubar.windows add command -label "Map $i" \
3173    		-command "popup_map $map2"
3174    }
3175
3176}
3177
3178# Enable/disable things on the view menu.
3179
3180proc adjust_view_menu { map } {
3181    global see_all
3182    global can_see_people can_see_control can_see_elev can_see_lighting
3183    global can_see_temp can_see_winds can_see_clouds
3184    global view_option_names
3185    global designer
3186
3187    adjust_menu_entry $map view $view_option_names(coverage) [ expr !$see_all ]
3188    adjust_menu_entry $map view $view_option_names(people) $can_see_people
3189    adjust_menu_entry $map view $view_option_names(control) $can_see_control
3190    adjust_menu_entry $map view $view_option_names(elevations) $can_see_elev
3191    adjust_menu_entry $map view "Contour Interval" $can_see_elev
3192    adjust_menu_entry $map view $view_option_names(lighting) $can_see_lighting
3193    set weather [ expr $can_see_temp | $can_see_winds | $can_see_clouds ]
3194    adjust_menu_entry $map view "Weather" $weather
3195    if { $weather } {
3196	adjust_menu_entry $map view.weather $view_option_names(temperature) \
3197		$can_see_temp
3198	adjust_menu_entry $map view.weather $view_option_names(winds) \
3199		$can_see_winds
3200	adjust_menu_entry $map view.weather $view_option_names(clouds) \
3201		$can_see_clouds
3202    }
3203    set feats [ expr ([ numfeatures ] > 0) || $designer ]
3204    if { $feats == 0 } {
3205	$map.menubar.view entryconfig $view_option_names(feature_names) -variable 0
3206	$map.menubar.view entryconfig $view_option_names(feature_boundaries) -variable 0
3207    }
3208    adjust_menu_entry $map view $view_option_names(feature_names) $feats
3209    adjust_menu_entry $map view $view_option_names(feature_boundaries) $feats
3210}
3211
3212# Enable/disable a single specified menu entry.
3213
3214proc adjust_menu_entry { map menu entryname val } {
3215    set state disabled
3216    if { $val } {
3217	set state active
3218    }
3219    $map.menubar.$menu entryconfig $entryname -state $state
3220}
3221
3222proc toggle_ai_may_resign {} {
3223    global ai_may_resign
3224
3225    if { $ai_may_resign } {
3226	execute_long_command 0 "ai +"
3227    } else {
3228	execute_long_command 0 "ai -"
3229    }
3230}
3231
3232# A popup to set the elevation contour interval directly.
3233
3234set contour_interval 0
3235set contour_interval_map foo
3236
3237proc popup_contour_interval_dialog { map } {
3238    global contour_interval_map stdfont boldfont
3239    global bgcolor hbcolor abcolor fgcolor afcolor
3240
3241    set contour_interval_map $map
3242
3243    if { "[ winfo exists .contour ]" } {
3244	# Kick the window manager awake.
3245	wm withdraw .contour
3246	wm deiconify .contour
3247	focus -force .contour
3248	return
3249    }
3250
3251    # Create and then immediately withdraw the window
3252    # so that it does not bounce around later.
3253    toplevel .contour -bg $bgcolor -width 240 -height 160
3254    pack propagate .contour true
3255    wm withdraw .contour
3256    wm title .contour "Xconq Contour Interval"
3257
3258    frame .contour.dummy
3259    pack .contour.dummy -pady 6
3260    label .contour.label -text "Spacing in meters:" -bg $bgcolor -fg $fgcolor -font $boldfont
3261    pack .contour.label -side top -pady 6
3262    entry .contour.interval -textvariable contour_interval -fg $fgcolor \
3263    	-relief sunken -width 15 -font $stdfont
3264    pack .contour.interval -side top -pady 6
3265
3266    frame .contour.bottom -bg $bgcolor
3267    pack .contour.bottom -side bottom -anchor center -padx 20 -pady 4
3268    button .contour.bottom.ok -text "OK" \
3269	    -command { ok_contour_interval } -default active \
3270	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
3271	    -fg $fgcolor -activeforeground $afcolor -width 8 -font $boldfont
3272    button .contour.bottom.cancel -text "Cancel" \
3273	    -command { withdraw_window ".contour" } \
3274	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
3275	    -fg $fgcolor -activeforeground $afcolor -width 8 -font $boldfont
3276    grid .contour.bottom.cancel .contour.bottom.ok -sticky ew -padx 8 -pady 4
3277
3278    bind .contour <Key> {
3279    	if {"%K" == "Escape"} {
3280		.contour.bottom.cancel flash
3281		withdraw_window ".contour"
3282	} elseif  {"%K" == "Return"} {
3283		.contour.bottom.ok flash
3284		ok_contour_interval
3285	}
3286    }
3287    center_above_curmap .contour
3288}
3289
3290proc ok_contour_interval {} {
3291    global contour_interval
3292    global contour_interval_map map_number
3293
3294    execute_long_command $map_number($contour_interval_map) \
3295	    "map contour-interval=$contour_interval"
3296
3297    withdraw_window ".contour"
3298}
3299
3300set new_meridian_interval 0
3301
3302set meridian_map_number 0
3303
3304proc popup_meridian_interval_dialog { mapn } {
3305    global new_meridian_interval
3306    global meridian_map_number
3307    global map_options
3308    global prefs
3309    global bgcolor hbcolor abcolor fgcolor afcolor boldfont stdfont
3310
3311    # We need to set a global since the key binding doesn't know the
3312    # value of $mapn any longer when OK is pressed.
3313    set meridian_map_number $mapn
3314
3315    set new_meridian_interval $prefs(meridian_interval)
3316
3317    # Create and then immediately withdraw the window
3318    # so that it does not bounce around later.
3319    toplevel .meridian -bg $bgcolor -width 240 -height 160
3320    pack propagate .meridian true
3321    wm withdraw .meridian
3322    wm title .meridian "Xconq Meridian Interval"
3323
3324    frame .meridian.dummy
3325    pack .meridian.dummy -pady 6
3326    label .meridian.label -text "Spacing in arc minutes:" -bg $bgcolor -fg $fgcolor -font $boldfont
3327    pack .meridian.label -side top -pady 6
3328    entry .meridian.interval -textvariable new_meridian_interval \
3329	    -fg $fgcolor -relief sunken -width 15 -font $stdfont
3330    pack .meridian.interval -side top -pady 6
3331
3332    frame .meridian.bottom -bg $bgcolor
3333    pack .meridian.bottom -side bottom -anchor center -padx 20 -pady 4
3334    button .meridian.bottom.ok -text "OK" \
3335	    -command [ list ok_meridian_interval $meridian_map_number ] -default active \
3336	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
3337	    -fg $fgcolor -activeforeground $afcolor -width 8 -font $boldfont
3338    button .meridian.bottom.cancel -text "Cancel" \
3339	    -command { .meridian.bottom.cancel flash;  destroy .meridian } \
3340	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
3341	    -fg $fgcolor -activeforeground $afcolor -width 8 -font $boldfont
3342     grid .meridian.bottom.cancel .meridian.bottom.ok -sticky ew -padx 8 -pady 4
3343
3344    bind .meridian <Key> {
3345    	if {"%K" == "Escape"} {
3346		.meridian.bottom.cancel flash
3347		wm withdraw .meridian
3348		destroy .meridian
3349	} elseif  {"%K" == "Return"} {
3350		.meridian.bottom.ok flash
3351		ok_meridian_interval $meridian_map_number
3352	}
3353    }
3354    center_above_curmap .meridian
3355}
3356
3357proc ok_meridian_interval { mapn } {
3358    global new_meridian_interval
3359    global map_options
3360    global map_widget
3361    global newprefs
3362
3363    if { $mapn > 0 } {
3364	set map $map_widget($mapn)
3365	set map_options($map,meridian_interval) $new_meridian_interval
3366	set_map_view_option $map meridian_interval
3367    } else {
3368	# If 0 is passed as $mapn it means that we are setting the prefs.
3369	set newprefs(meridian_interval) $new_meridian_interval
3370    }
3371    wm withdraw .meridian
3372    destroy .meridian
3373}
3374
3375# Given a map window, set up all of its standard event bindings.
3376
3377proc make_normal_bindings { map } {
3378    global dside
3379
3380    bind $map <Key> {
3381    	    if {"%K" == "Return" \
3382	    	|| "%K" == "Delete" \
3383	    	|| "%K" == "Escape" \
3384	    	|| "%K" == "BackSpace" \
3385	    	|| "%K" == "Right" \
3386	    	|| "%K" == "Left" \
3387	    	|| "%K" == "Up" \
3388	    	|| "%K" == "Down" \
3389	    	|| "%K" == "Home" \
3390	    	|| "%K" == "Prior" \
3391	    	|| "%K" == "Next" \
3392	    	|| "%K" == "End" \
3393	    	|| "%K" == "KP_1" \
3394	    	|| [string length "%A"] <= 1} {
3395	    		handle_key_binding "%A" "%K" %W %X %Y
3396	    }
3397    }
3398
3399    set mapview $map.leftside.botside.mapf.mapf2.map
3400
3401    bind $mapview <ButtonPress> { mouse_down_cmd %W %x %y %b }
3402    bind $mapview <ButtonRelease> { mouse_up_cmd %W %x %y %b }
3403    bind $mapview <Motion> { mouse_over_cmd %W %x %y }
3404    bind $mapview <Leave> { mouse_over_cmd %W -1 -1 }
3405
3406    bind $map <Enter> { update_widget_help "%W" }
3407
3408    set numu [ numutypes_available $dside ]
3409    set unitlist $map.rightside.listf.unitlist
3410    for { set i 0 } { $i < $numu } { incr i } {
3411	bind $unitlist.u$i <ButtonPress> [ list select_unit_type $map $i ]
3412    }
3413
3414    set worldview $map.rightside.worldf.2.world
3415
3416    bind $worldview <ButtonPress> { world_mouse_down_cmd %W %x %y %b }
3417    bind $worldview <ButtonRelease> { world_mouse_up_cmd %W %x %y %b }
3418    bind $worldview <Motion> { world_mouse_over_cmd %W %x %y }
3419    bind $worldview <Leave> { world_mouse_over_cmd %W -1 -1 }
3420
3421    bind $map.rightside.worldf <Configure> { resize_world_map %W %v %w %h }
3422
3423    bind $map.leftside.botside.uf.unitinfo <Configure> \
3424	    { resize_unit_info %W %v %w %h }
3425}
3426
3427# Handle a keystroke by passing it into C code along the current mouse
3428# position, and update the numeric prefix argument if the key was a
3429# digit adding to the prefix.
3430
3431# The map_number($win) existence test is to handle the unusual but
3432# reproducible case of a non-toplevel window getting passed in here
3433# (according to the supposed event binding stack rules).  Rather than
3434# trying to figure out what's going on, just dig out the toplevel and
3435# go with it, since that's all we really care about.
3436
3437proc handle_key_binding { stra strk win x y } {
3438    global map_number
3439
3440    if { [ info exists map_number($win) ] } {
3441	set mwin $win
3442    } else {
3443	set mwin [ winfo toplevel $win ]
3444	if { ! [ info exists map_number($mwin) ] } {
3445	    low_notify "key binding screwup in $win, ignoring key"
3446	    return
3447	}
3448    }
3449    set prefix [ interp_key $map_number($mwin) "$stra" "$strk" $x $y ]
3450    $mwin.leftside.topside.notices.t configure -state normal
3451    $mwin.leftside.topside.notices.t delete prefix.first "prefix.last -1 chars"
3452    if { "$prefix" >= 0 } {
3453	$mwin.leftside.topside.notices.t insert prefix.first ":" prefix
3454	$mwin.leftside.topside.notices.t insert prefix.first $prefix prefix
3455    }
3456    $mwin.leftside.topside.notices.t configure -state disabled
3457}
3458
3459proc run_game_cmd {} {
3460    set interval [ run_game 1 ]
3461    after $interval run_game_cmd
3462#    after 1 run_game_cmd
3463}
3464
3465proc animate_selection_cmd {} {
3466    animate_selection
3467    after 100 animate_selection_cmd
3468}
3469
3470proc run_game_idle_cmd {} {
3471    run_game_idle
3472#    after 100 run_game_idle_cmd
3473    after 50 run_game_idle_cmd
3474}
3475
3476# Map zoom command.
3477
3478proc zoom_in_out { mapn incr } {
3479    global map_widget
3480
3481    set map $map_widget($mapn)
3482    set maxpower 6
3483
3484    set power [ $map.leftside.botside.mapf.mapf2.map cget -power ]
3485    set newpower [ expr $power + $incr ]
3486    if { $newpower < 0 } {
3487	set newpower 0
3488    }
3489    if { $newpower > $maxpower } {
3490	set newpower $maxpower
3491    }
3492    if { $newpower != $power } {
3493	$map.leftside.botside.mapf.mapf2.map config -power $newpower
3494	# Update the states of various controls.
3495	if { $newpower < $maxpower } {
3496	    set newstate normal
3497	} else {
3498	    set newstate disabled
3499	}
3500	$map.menubar.view entryconfigure "Closer" -state $newstate
3501	$map.leftside.botside.buttons.zoomin config -state $newstate
3502	if { $newpower > 0 } {
3503	    set newstate normal
3504	} else {
3505	    set newstate disabled
3506	}
3507	$map.menubar.view entryconfigure "Farther" -state $newstate
3508	$map.leftside.botside.buttons.zoomout config -state $newstate
3509
3510	adjust_map_font_sizes $map
3511    }
3512}
3513
3514proc adjust_map_font_sizes { map } {
3515    global boldfont mapfont
3516    global tcl_platform
3517
3518    set power [ $map.leftside.botside.mapf.mapf2.map cget -power ]
3519
3520    # Pick sizes that look good on each platform
3521    if { "$tcl_platform(platform)" == "unix" } {
3522	if { $power < 4 } {
3523		set mainsize 10
3524		set featuresize 12
3525	} elseif { $power == 4 } {
3526		set mainsize 12
3527		set featuresize 16
3528	} elseif { $power == 5 } {
3529		set mainsize 14
3530		set featuresize 20
3531	} elseif { $power == 6 } {
3532		set mainsize 18
3533		set featuresize 32
3534	}
3535    }
3536    if { "$tcl_platform(platform)" == "macintosh" } {
3537	if { $power < 4 } {
3538		set mainsize 9
3539		set featuresize 12
3540	} elseif { $power == 4 } {
3541		set mainsize 10
3542		set featuresize 14
3543	} elseif { $power == 5 } {
3544		set mainsize 12
3545		set featuresize 20
3546	} elseif { $power == 6 } {
3547		set mainsize 18
3548		set featuresize 36
3549	}
3550    }
3551    if { "$tcl_platform(platform)" == "windows" } {
3552	if { $power < 4 } {
3553		set mainsize 7
3554		set featuresize 8
3555	} elseif { $power == 4 } {
3556		set mainsize 8
3557		set featuresize 11
3558	} elseif { $power == 5 } {
3559		set mainsize 10
3560		set featuresize 16
3561	} elseif { $power == 6 } {
3562		set mainsize 16
3563		set featuresize 24
3564	}
3565    }
3566    set tmpfont $mapfont
3567    append tmpfont [ list "-size" $mainsize ]
3568    $map.leftside.botside.mapf.mapf2.map config -mainfont $tmpfont
3569    set tmpfont $mapfont
3570    append tmpfont [ list "-size" $featuresize ]
3571    $map.leftside.botside.mapf.mapf2.map config -featurefont $tmpfont
3572}
3573
3574# Turn isometric display on and off.
3575
3576proc set_isometric { mapn flag scale } {
3577    global map_widget
3578
3579    set map $map_widget($mapn)
3580    $map.leftside.botside.mapf.mapf2.map config -isometric $flag \
3581	    -verticalscale $scale
3582    if { $flag } {
3583	set newstate normal
3584    } else {
3585	set newstate disabled
3586    }
3587    $map.leftside.botside.buttons.rotl config -state $newstate
3588    $map.leftside.botside.buttons.rotr config -state $newstate
3589}
3590
3591# Set the direction of viewing for an isometric display.
3592
3593proc set_iso_dir { mapn dir } {
3594    global map_widget
3595
3596    set map $map_widget($mapn)
3597    $map.leftside.botside.mapf.mapf2.map config -direction $dir
3598}
3599
3600# Update routines called from C code.
3601
3602proc update_game_state { str } {
3603    global debug
3604    global nummaps map_widget
3605
3606    if { $debug } {
3607	set str "$str (Debug)"
3608    }
3609    for { set i 1 } { $i <= $nummaps } { incr i } {
3610	$map_widget($i).rightside.turnf.turn itemconfig the_date -text $str
3611    }
3612}
3613
3614# (should optimize by remembering states and changing canvas items
3615# only once)
3616
3617proc update_game_side_info { s str str2 everingame beforestart ingame status } {
3618    global nummaps
3619    global map_widget
3620    global bgcolor fgcolor
3621    global dside dside_ai
3622
3623    # Update the selected AI in the AI menu.
3624    set dplayer [ assigned_player $dside ]
3625    set dside_ai [ player_aitypename $dplayer ]
3626    # The menu code cannot handle empty strings.
3627    if { $dside_ai == "" } {
3628    	set dside_ai "none"
3629    }
3630    # puts stdout "ugsi $s $str $everingame $ingame $status"
3631    for { set i 1 } { $i <= $nummaps } { incr i } {
3632	set sidelist $map_widget($i).rightside.gamef.game
3633	$sidelist itemconfig s$s -text $str
3634	$sidelist itemconfig player$s -text $str2
3635	if { !$everingame && !$beforestart } {
3636	    $sidelist itemconfig s$s -fill gray
3637	    $sidelist itemconfig left$s -fill $bgcolor
3638	    $sidelist itemconfig resv$s -fill $bgcolor
3639	    $sidelist itemconfig frame$s -outline $bgcolor
3640	} elseif { !$ingame } {
3641	    $sidelist itemconfig frame$s -outline gray
3642	    $sidelist itemconfig left$s -fill $bgcolor
3643	    $sidelist itemconfig resv$s -fill $bgcolor
3644	} else {
3645	    $sidelist itemconfig s$s -fill $fgcolor
3646	}
3647	if { $status > 0 } {
3648	    # Find the the victory laurels and move into visibility.
3649	    set lis [ $sidelist coords won$s ]
3650	    set xval [ lindex $lis 0 ]
3651	    if { $xval > 4 } {
3652		$sidelist move won$s [expr 4 - $xval ] 0
3653		$sidelist raise won$s
3654	    }
3655	}
3656	if { $status < 0 } {
3657	    # Find the the loss line and move into visibility.
3658	    set lis [ $sidelist coords lost$s ]
3659	    set xval [ lindex $lis 0 ]
3660	    if { $xval > 0 } {
3661		$sidelist move lost$s [expr 0 - $xval ] 0
3662		$sidelist raise lost$s
3663	    }
3664	}
3665    }
3666}
3667
3668proc update_game_side_score { which str } {
3669    global nummaps map_widget
3670
3671    for { set i 1 } { $i <= $nummaps } { incr i } {
3672	set game $map_widget($i).rightside.gamef.game
3673	$game itemconfig $which -text $str
3674    }
3675}
3676
3677# (should optimize by remembering states and changing canvas items
3678# only once)
3679
3680proc update_side_progress { s acting left resv finished } {
3681    global lineheight
3682    global nummaps map_widget
3683    global fgcolor
3684
3685    # puts stdout "progress $s $acting $left $resv $finished"
3686    for { set i 1 } { $i <= $nummaps } { incr i } {
3687	set game $map_widget($i).rightside.gamef.game
3688	set old [ $game coords left$s ]
3689	set rtop [ lindex $old 1 ]
3690	set rbot [ lindex $old 3 ]
3691	if { $acting } {
3692	    $game itemconfig frame$s -outline $fgcolor
3693	    $game coords left$s 23 $rtop [ expr 23 + $left  + 1 ] $rbot
3694	    $game coords resv$s 23 $rtop [ expr 23 + $resv ] $rbot
3695	    if { !$finished } {
3696		$game itemconfig left$s -fill LawnGreen
3697		$game itemconfig resv$s -fill magenta
3698
3699	    } else {
3700		$game itemconfig left$s -fill violet
3701		$game itemconfig resv$s -fill violet
3702	    }
3703	} else {
3704	    $game itemconfig frame$s -outline gray
3705	    $game coords left$s 23 $rtop 23 $rbot
3706	    $game coords resv$s 23 $rtop 23 $rbot
3707	}
3708    }
3709}
3710
3711proc update_side_treasury { s j amt } {
3712    global nummaps map_widget
3713
3714    for { set i 1 } { $i <= $nummaps } { incr i } {
3715	set game $map_widget($i).rightside.gamef.game
3716	$game itemconfig m$s,$j -text $amt
3717    }
3718}
3719
3720proc update_unitlist_char { n str } {
3721    global nummaps map_widget
3722
3723    for { set i 1 } { $i <= $nummaps } { incr i } {
3724	set unitlist $map_widget($i).rightside.listf.unitlist
3725	$unitlist itemconfig u$n -text $str
3726    }
3727}
3728
3729proc update_unitlist_count { n str } {
3730    global nummaps map_widget
3731
3732    for { set i 1 } { $i <= $nummaps } { incr i } {
3733	set unitlist $map_widget($i).rightside.listf.unitlist
3734	$unitlist itemconfig n$n -text $str
3735    }
3736}
3737
3738proc update_unitlist_incomplete { n str } {
3739    global nummaps map_widget
3740
3741    for { set i 1 } { $i <= $nummaps } { incr i } {
3742	set unitlist $map_widget($i).rightside.listf.unitlist
3743	$unitlist itemconfig i$n -text $str
3744    }
3745}
3746
3747proc update_unitlist_name { n str } {
3748    global nummaps map_widget
3749
3750    for { set i 1 } { $i <= $nummaps } { incr i } {
3751	set unitlist $map_widget($i).rightside.listf.unitlist
3752	$unitlist itemconfig name$n -text $str
3753    }
3754}
3755
3756proc update_unitlist_material { n str } {
3757    global nummaps map_widget
3758
3759    for { set i 1 } { $i <= $nummaps } { incr i } {
3760	set unitlist $map_widget($i).rightside.listf.unitlist
3761	$unitlist itemconfig material$n -text $str
3762    }
3763}
3764
3765proc update_unitlist_supply { n str } {
3766    global nummaps map_widget
3767
3768    for { set i 1 } { $i <= $nummaps } { incr i } {
3769	set unitlist $map_widget($i).rightside.listf.unitlist
3770	$unitlist itemconfig supply$n -text $str
3771    }
3772}
3773
3774proc update_unitlist_production { n str } {
3775    global nummaps map_widget
3776
3777    for { set i 1 } { $i <= $nummaps } { incr i } {
3778	set unitlist $map_widget($i).rightside.listf.unitlist
3779	$unitlist itemconfig production$n -text $str
3780    }
3781}
3782
3783proc update_unitlist_capacity { n str } {
3784    global nummaps map_widget
3785
3786    for { set i 1 } { $i <= $nummaps } { incr i } {
3787	set unitlist $map_widget($i).rightside.listf.unitlist
3788	$unitlist itemconfig capacity$n -text $str
3789     }
3790 }
3791
3792proc update_unit_info { mapn tag str } {
3793    global curunit
3794    global map_widget
3795
3796    if { "$tag" == "curunit" } {
3797	set curunit $str
3798    } else {
3799	$map_widget($mapn).leftside.botside.uf.unitinfo itemconfig $tag -text $str
3800    }
3801}
3802
3803# Make sure the unit picture in the unit info window is showing the
3804# given image and emblem, switching if necessary.
3805
3806set last_image "(no)"
3807set last_emblem "(no)"
3808
3809proc update_unit_picture { mapn image emblem } {
3810    global map_widget
3811    global last_image last_emblem
3812
3813    if { "$image" != "$last_image" } {
3814	set imsamp $map_widget($mapn).leftside.botside.uf.unitinfo.pic
3815	if { "$image" != "(no)" } {
3816	    $imsamp replace imf $image
3817	    if { "$emblem" != "$last_emblem" } {
3818		if { "$emblem" != "(no)" } {
3819		    $imsamp replace emblem $emblem
3820		    $imsamp emblem 1
3821		} else {
3822		    $imsamp remove emblem $last_emblem
3823		    $imsamp emblem -1
3824		}
3825	    }
3826	    set last_emblem $emblem
3827	} else {
3828	    $imsamp remove all
3829	    set last_emblem "(no)"
3830	}
3831	set last_image $image
3832    } elseif { "$emblem" != "$last_emblem" } {
3833	set imsamp $map_widget($mapn).leftside.botside.uf.unitinfo.pic
3834	if { "$emblem" != "(no)" } {
3835	    $imsamp replace emblem $emblem
3836	    $imsamp emblem 1
3837	} else {
3838	    $imsamp remove emblem $last_emblem
3839	    $imsamp emblem -1
3840	}
3841	set last_emblem $emblem
3842    }
3843}
3844
3845# Update the appearance of any mode controls/displays.
3846
3847proc update_mode { mapn mode } {
3848    global map_survey
3849    global map_widget
3850
3851    if { "$mode" == "survey" } {
3852	set map_survey 1
3853	set relief raised
3854    } elseif { "$mode" == "move" } {
3855	set map_survey 0
3856	set relief sunken
3857    } else {
3858	# This will induce a distinctive tcl error shortly.
3859	set relief badmode
3860    }
3861    $map_widget($mapn).leftside.botside.buttons.move config -relief $relief
3862    update idletasks
3863}
3864
3865proc whelp { widg str } {
3866    global widget_help_strings
3867
3868    set widget_help_strings($widg) $str
3869}
3870
3871# Given a widget, put any helpful info about it in the mouseover display.
3872
3873proc update_widget_help { widg } {
3874    global widget_help_strings
3875    global nummaps
3876
3877    if { [ info exists widget_help_strings($widg) ] } {
3878	set str $widget_help_strings($widg)
3879    } else {
3880	set str ""
3881    }
3882    # a hack, should extract map from widget
3883    if { $nummaps == 1 } {
3884	update_mouseover 1 $str
3885    }
3886}
3887
3888# Replace the current mouseover text with the given version.
3889# Time-critical, called from C and tcl code.
3890# (should try to replace text string in one op if possible)
3891
3892proc update_mouseover { mapn str } {
3893    global map_widget
3894
3895    $map_widget($mapn).leftside.botside.mouseover configure -state normal
3896    $map_widget($mapn).leftside.botside.mouseover delete 1.0 end
3897    $map_widget($mapn).leftside.botside.mouseover insert insert "$str"
3898    $map_widget($mapn).leftside.botside.mouseover configure -state disabled
3899}
3900
3901# Scroll the main or world map by the given amount.
3902
3903proc autoscroll { mapn which xdelta ydelta } {
3904    global map_widget
3905
3906    if { $which == 0 } {
3907	set widget $map_widget($mapn).leftside.botside.mapf.mapf2.map
3908    } else {
3909	set widget $map_widget($mapn).rightside.worldf.2.world
3910    }
3911    if { $xdelta != 0 } {
3912	$widget xview scroll $xdelta units
3913    }
3914    if { $ydelta != 0 } {
3915	$widget yview scroll $ydelta units
3916    }
3917    if { $xdelta != 0  || $ydelta != 0 } {
3918	update idletasks
3919    }
3920}
3921
3922proc update_action_controls_info { a1 a2 a3 a4 a5 flags } {
3923    global can_act can_plan can_move can_return can_embark can_disembark
3924    global can_build can_repair can_change_type can_disband
3925    global can_add_terrain can_remove_terrain
3926    global can_give_take can_detach
3927    global can_attack can_fire can_detonate
3928    global curunit
3929    global nummaps map_widget
3930
3931    set can_act $a1
3932    set can_plan $a2
3933    set can_move $a3
3934    set can_build $a4
3935    set can_attack $a5
3936    set can_return 0
3937    set can_repair 0
3938    set can_change_type 0
3939    set can_fire 0
3940    set can_detonate 0
3941    set can_embark 0
3942    set can_disembark 0
3943    set can_disband 0
3944    set can_detach 0
3945    set can_add_terrain 0
3946    set can_remove_terrain 0
3947    set can_give_take 0
3948
3949    foreach flag $flags {
3950	set $flag 1
3951    }
3952    for { set i 1 } { $i <= $nummaps } { incr i } {
3953	set buttons $map_widget($i).leftside.botside.buttons
3954	set state normal
3955	if { !$curunit || !$can_build } {
3956	    set state disabled
3957	}
3958	$buttons.build config -state $state
3959	set state normal
3960	if { !$curunit || !$can_return } {
3961	    set state disabled
3962	}
3963	$buttons.return config -state $state
3964	set state normal
3965	if { !$curunit || !$can_plan } {
3966	    set state disabled
3967	}
3968	$buttons.sleep config -state $state
3969	$buttons.reserve config -state $state
3970	$buttons.delay config -state $state
3971    }
3972}
3973
3974proc update_view_controls_info { a1 a3 a4 a5 a6 a7 a8 a9 } {
3975    global see_all
3976    global can_see_people can_see_control can_see_elev can_see_lighting
3977    global can_see_temp can_see_winds can_see_clouds
3978    global nummaps map_widget
3979
3980    set see_all $a1
3981    set can_see_people $a3
3982    set can_see_control $a4
3983    set can_see_elev $a5
3984    set can_see_lighting $a6
3985    set can_see_temp $a7
3986    set can_see_winds $a8
3987    set can_see_clouds $a9
3988    for { set i 1 } { $i <= $nummaps } { incr i } {
3989	set map $map_widget($i)
3990	adjust_view_menu $map
3991    }
3992}
3993
3994proc update_show_all_info { a1 } {
3995    global see_all
3996    global may_set_show_all
3997    global show_all_was_enabled
3998    global nummaps map_widget
3999
4000    if { $see_all } {
4001	return
4002    }
4003    set may_set_show_all $a1
4004    # Make "Show All" menu item appear and disappear.
4005    if { $may_set_show_all } {
4006	for { set i 1 } { $i <= $nummaps } { incr i } {
4007	    set map $map_widget($i)
4008	    if { !$show_all_was_enabled($map) } {
4009		add_show_all_item $map
4010	    }
4011	}
4012    } else {
4013	for { set i 1 } { $i <= $nummaps } { incr i } {
4014	    set map $map_widget($i)
4015	    if { $show_all_was_enabled($map) } {
4016		$map.menubar.view delete "Show All"
4017		set show_all_was_enabled($map) 0
4018	    }
4019	}
4020    }
4021}
4022
4023proc update_show_all { mapn value } {
4024    global see_all
4025    global map_widget
4026    global map_options
4027
4028    if { $see_all } {
4029	return
4030    }
4031    set map $map_widget($mapn)
4032    set map_options($map,show_all) $value
4033}
4034
4035proc low_notify { str } {
4036    global nummaps map_widget
4037
4038    for { set i 1 } { $i <= $nummaps } { incr i } {
4039	set notices $map_widget($i).leftside.topside.notices.t
4040	$notices configure -state normal
4041	$notices insert notices.last $str notices
4042	$notices configure -state disabled
4043	# (should only do if already scrolled to end of notices)
4044	$notices yview moveto 1.0
4045    }
4046}
4047
4048proc ask_bool_mode { mapn str dflt } {
4049    global bgcolor fgcolor afcolor
4050    global map_widget
4051    global mapnum
4052    global titlefont
4053
4054    set map $map_widget($mapn)
4055    # A new global is needed since bind will not pass on $mapn directly.
4056    set mapnum $mapn
4057    set color Gold
4058
4059    # Create and then immediately withdraw the window
4060    # so that it does not bounce around later.
4061    toplevel .bool -bg $color -width 340 -height 160
4062    wm withdraw .bool
4063    wm title .bool "Xconq Query"
4064    pack propagate .bool false
4065
4066    message .bool.msg -text "$str" -bg $color -fg $fgcolor -font $titlefont \
4067	-aspect 500
4068    frame .bool.buttons -bg $color
4069    pack .bool.buttons -side bottom -padx 0 -pady 8
4070    pack .bool.msg -side top -padx 4 -expand true
4071
4072    button .bool.buttons.no -text No -command [ list bool_no $mapn ] \
4073	-bg $color -highlightbackground $color -activebackground $color \
4074	-fg $fgcolor -activeforeground $afcolor -width 6 -font $titlefont
4075    button .bool.buttons.yes -text Yes -command [ list bool_yes $mapn ] \
4076	-bg $color -highlightbackground $color -activebackground $color \
4077	-fg $fgcolor -activeforeground $afcolor -width 6 -default active -font $titlefont
4078    grid .bool.buttons.no .bool.buttons.yes -sticky e -padx 12 -pady 4
4079
4080    bind .bool <Key> {
4081    		if {"%K" == "Return"} {
4082    			.bool.buttons.yes flash
4083    			bool_yes $mapnum
4084    		} elseif {"%K" == "Escape"} {
4085    			.bool.buttons.no flash
4086    			bool_no $mapnum
4087    		}
4088    }
4089    bind .bool <Y> { .bool.buttons.yes flash; bool_yes $mapnum }
4090    bind .bool <y> { .bool.buttons.yes flash; bool_yes $mapnum }
4091    bind .bool <N> { .bool.buttons.no flash; bool_no $mapnum }
4092    bind .bool <n> { .bool.buttons.no flash; bool_no $mapnum }
4093
4094    center_above_curmap .bool
4095}
4096
4097proc bool_yes { mapn } {
4098    interp_key $mapn "y" "y" 0 0
4099}
4100
4101proc bool_no { mapn } {
4102    interp_key $mapn "n" "n" 0 0
4103}
4104
4105proc ask_bool_done { mapn } {
4106    wm withdraw .bool
4107	destroy .bool
4108}
4109
4110proc ask_position_mode { mapn str } {
4111    global map_widget
4112
4113    $map_widget($mapn).leftside.topside.notices.t configure -state normal
4114    $map_widget($mapn).leftside.topside.notices.t insert prompt.first "$str" prompt
4115    $map_widget($mapn).leftside.botside.mapf.mapf2.map config -cursor crosshair
4116    $map_widget($mapn).leftside.topside.notices.t configure -state disabled
4117    # (should only do if already scrolled to end of notices)
4118    $map_widget($mapn).leftside.topside.notices.t yview moveto 1.0
4119}
4120
4121proc ask_position_done { mapn } {
4122    global map_widget
4123
4124    clear_command_line $mapn
4125    # (should be restoring prev cursor) */
4126    $map_widget($mapn).leftside.botside.mapf.mapf2.map config -cursor arrow
4127}
4128
4129proc ask_unit_type_mode { mapn str } {
4130    global map_widget
4131
4132    set notices $map_widget($mapn).leftside.topside.notices.t
4133    $notices configure -state normal
4134    $notices insert prompt.first "$str" prompt
4135    $notices configure -state disabled
4136    # (should only do if already scrolled to end of notices)
4137    $notices yview moveto 1.0
4138}
4139
4140proc enable_unitlist { mapn n flag } {
4141    global map_widget
4142    global bgcolor fgcolor
4143
4144    set map $map_widget($mapn)
4145    if { $flag == 1 } {
4146	set color $fgcolor
4147    } else {
4148	set color $bgcolor
4149    }
4150    $map.rightside.listf.unitlist itemconfig rect$n -outline $color
4151}
4152
4153proc select_unit_type { map n } {
4154    global map_number
4155    global fgcolor
4156
4157    set color [ $map.rightside.listf.unitlist itemcget rect$n -outline ]
4158    if { "$color" == $fgcolor } {
4159	set_unit_type $map_number($map) [ utype_actual $n ]
4160	# Arguments are dummies, this is effectively a pseudo-event
4161	# that gets the modalhandler function to run.
4162	interp_key $map_number($map) a a 0 0
4163    }
4164}
4165
4166proc ask_unit_type_done { mapn } {
4167    clear_command_line $mapn
4168}
4169
4170proc ask_terrain_type_mode { mapn str } {
4171    global map_widget
4172
4173    set notices $map_widget($mapn).leftside.topside.notices.t
4174    $notices configure -state normal
4175    $notices insert prompt.first "$str" prompt
4176    $notices configure -state disabled
4177    # (should only do if already scrolled to end of notices)
4178    $notices yview moveto 1.0
4179}
4180
4181proc ask_terrain_type_done { mapn } {
4182    clear_command_line $mapn
4183}
4184
4185# Put a given string and default into the map's prompt and answer tags
4186# in its notices window.
4187
4188proc ask_string_mode { mapn str dflt } {
4189    global map_widget
4190
4191    set notices $map_widget($mapn).leftside.topside.notices.t
4192    $notices configure -state normal
4193    $notices insert prompt.first "$str" prompt
4194    $notices insert "answer.first + 1 chars" "$dflt" answer
4195    $notices configure -state disabled
4196    # (should only do if already scrolled to end of notices)
4197    $notices yview moveto 1.0
4198}
4199
4200# Replace the answer tag with a new string.
4201
4202proc update_string_mode { mapn answer } {
4203    global map_widget
4204
4205    set notices $map_widget($mapn).leftside.topside.notices.t
4206    $notices configure -state normal
4207    $notices delete "answer.first + 1 chars" "answer.last - 1 chars"
4208    # FIXME: need some quoting in case the user types an open brace.
4209    $notices insert "answer.first + 1 chars" $answer answer
4210    $notices configure -state disabled
4211}
4212
4213proc ask_string_done { mapn } {
4214    clear_command_line $mapn
4215}
4216
4217# Side asking mode is similar to string asking mode.
4218
4219proc ask_side_mode { mapn str dflt } {
4220    global map_widget
4221
4222    set notices $map_widget($mapn).leftside.topside.notices.t
4223    $notices configure -state normal
4224    $notices insert prompt.first "$str" prompt
4225    $notices insert "answer.first + 1 chars" "$dflt" answer
4226    $notices configure -state disabled
4227    # (should only do if already scrolled to end of notices)
4228    $notices yview moveto 1.0
4229}
4230
4231proc update_side_mode { mapn answer } {
4232    global map_widget
4233
4234    set notices $map_widget($mapn).leftside.topside.notices.t
4235    $notices configure -state normal
4236    $notices delete "answer.first + 1 chars" "answer.last - 1 chars"
4237    $notices insert "answer.first + 1 chars" $answer answer
4238    $notices configure -state disabled
4239}
4240
4241proc ask_side_done { mapn } {
4242    clear_command_line $mapn
4243}
4244
4245proc clear_command_line { mapn } {
4246    global map_widget
4247
4248    set notices $map_widget($mapn).leftside.topside.notices.t
4249    $notices configure -state normal
4250    $notices delete prefix.first "prefix.last - 1 chars"
4251    $notices delete prompt.first "prompt.last - 1 chars"
4252    $notices delete "answer.first + 1 chars" "answer.last - 1 chars"
4253    $notices configure -state disabled
4254}
4255
4256set new_find_name ""
4257set mapn_find_name 0
4258
4259proc popup_find_dialog { mapn } {
4260    global mapn_find_name
4261    global bgcolor hbcolor abcolor fgcolor afcolor boldfont stdfont
4262
4263    set mapn_find_name $mapn
4264
4265    if { "[ winfo exists .find ]" } {
4266    	# Kick the window manager awake.
4267    	wm withdraw .find
4268	wm deiconify .find
4269	focus -force .find
4270	return
4271    }
4272
4273    # Create and then immediately withdraw the window
4274    # so that it does not bounce around later.
4275    toplevel .find -bg $bgcolor -width 240 -height 160
4276    pack propagate .find true
4277    wm withdraw .find
4278    wm title .find "Xconq Find"
4279
4280    frame .find.dummy
4281    pack .find.dummy -pady 6
4282    label .find.label -text "Name of unit to find:" -bg $bgcolor -fg $fgcolor -font $boldfont
4283    pack .find.label -side top -pady 6
4284    entry .find.name -textvariable new_find_name -fg $fgcolor -relief sunken -width 15 -font $stdfont
4285    pack .find.name -side top -pady 6
4286    label .find.matches -text "" -bg $bgcolor -fg $fgcolor -font $boldfont
4287    pack .find.matches -side top -pady 6
4288
4289    frame .find.bottom -bg $bgcolor
4290    pack .find.bottom -side bottom -anchor center -padx 20 -pady 4
4291    button .find.bottom.find -text "Find" -command ok_find -default active \
4292    	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4293    	-fg $fgcolor -activeforeground $afcolor -width 8 -font $boldfont
4294    button .find.bottom.cancel -text "Cancel" \
4295        -command { withdraw_window ".find" } \
4296    	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor	\
4297    	-fg $fgcolor -activeforeground $afcolor -width 8 -font $boldfont
4298    grid .find.bottom.cancel .find.bottom.find -sticky ew -padx 8 -pady 4
4299
4300    bind .find <Key> {
4301    	if {"%K" == "Escape"} {
4302		.find.bottom.cancel flash
4303		withdraw_window ".find"
4304	} elseif  {"%K" == "Return"} {
4305		.find.bottom.find flash
4306		ok_find
4307	}
4308    }
4309    center_above_curmap .find
4310}
4311
4312proc ok_find {} {
4313    global new_find_name
4314    global mapn_find_name
4315
4316    set rslt [ center_on_unit $mapn_find_name "$new_find_name" ]
4317    if { $rslt == 1 } {
4318	.find.matches config -text "$rslt match found"
4319    } else {
4320	.find.matches config -text "$rslt matches found"
4321    }
4322    if { $rslt == 0 } {
4323	bell
4324    } else {
4325        withdraw_window ".find"
4326    }
4327}
4328
4329# The research dialog lets the player select a new type of advance
4330# to research.
4331
4332proc popup_research_dialog {} {
4333    global stdfont boldfont
4334    global tcl_platform
4335    global scrollb
4336    global listb
4337    global bgcolor hbcolor abcolor tcolor lcolor fgcolor afcolor
4338
4339    # First of all set the research popup flag.
4340    set_research_popped_up 1
4341
4342    if { "[ winfo exists .research ]" } {
4343	# Kick the window manager awake.
4344	wm withdraw .research
4345	wm deiconify .research
4346	focus -force .research
4347	fill_research_dialog
4348	return
4349    }
4350
4351    # Create and then immediately withdraw the window
4352    # so that it does not bounce around later.
4353    toplevel .research -bg $bgcolor
4354    wm withdraw .research
4355    wm title .research "Xconq Research"
4356
4357   # Make sure close_research is called even if the close box is used.
4358    wm protocol .research WM_DELETE_WINDOW close_research
4359
4360    label .research.current -width 25 -height 2 -font $stdfont -bg $bgcolor -fg $fgcolor
4361    pack .research.current -side top
4362
4363    frame .research.bottom -bg $bgcolor
4364    pack .research.bottom -side bottom -fill x -padx 15
4365    button .research.bottom.ok -text "Research" -command ok_research \
4366        -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4367        -fg $fgcolor -activeforeground $afcolor -font $boldfont
4368    pack .research.bottom.ok -side left -padx 5 -pady 5
4369    button .research.bottom.rest -text "Rest" -command rest_research \
4370        -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4371        -fg $fgcolor -activeforeground $afcolor -font $boldfont
4372    pack .research.bottom.rest -side left -padx 5 -pady 5
4373    button .research.bottom.cancel -text "Close" \
4374        -command { close_research } \
4375        -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4376        -fg $fgcolor -activeforeground $afcolor -font $boldfont
4377    pack .research.bottom.cancel -side left -padx 5 -pady 5
4378
4379    listbox .research.topics -selectmode browse -width 25 \
4380	-yscrollcommand ".research.yscroll set" -relief sunken -borderwidth $listb \
4381	-bg $lcolor -fg $fgcolor -font $stdfont
4382    # Whether this scrollbar is actually needed depends on how many
4383    # choices the user has, and what the fonts are, but it doesn't
4384    # seem wise to make assumptions as the former is GDL and the latter
4385    # is a user preference.
4386    scrollbar .research.yscroll -orient vert \
4387	-command ".research.topics yview" -width 16 -borderwidth $scrollb \
4388	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4389	-troughcolor $tcolor
4390    pack .research.yscroll -side right -fill y
4391    pack .research.topics -side top -expand true -fill both
4392
4393    center_above_curmap .research
4394    fill_research_dialog
4395}
4396
4397proc fill_research_dialog {} {
4398    if { !"[ winfo exists .research ]" } {
4399	return
4400    }
4401    set numa [ numatypes ]
4402    set cura [ current_advance ]
4403    .research.current config -text "Researching $cura"
4404    .research.topics delete 0 end
4405    for { set i 0 } { $i < $numa } { incr i } {
4406	set aname [ available_advance $i ]
4407	if { "$aname" != "?" } {
4408	    .research.topics insert end " $aname"
4409	    if { "$aname" == "$cura" } {
4410    		.research.topics selection set $i
4411    		.research.topics see $i
4412    	    }
4413	} else {
4414	    break
4415	}
4416    }
4417    if { "$cura" == "Nothing" } {
4418	.research.topics selection set 0
4419    }
4420}
4421
4422proc ok_research {} {
4423    set i [ .research.topics curselection ]
4424    if { $i == "" } {
4425    	return
4426    }
4427    set_side_research $i
4428    close_research
4429}
4430
4431proc rest_research {} {
4432    set_side_research nothing
4433    close_research
4434}
4435
4436proc close_research {} {
4437   withdraw_window ".research"
4438    set_research_popped_up 0
4439}
4440
4441# Create and popup an agreement editing window.
4442
4443proc create_agreements_window {} {
4444    global textb
4445    global bgcolor hbcolor abcolor lcolor fgcolor afcolor
4446
4447    if { "[ winfo exists .agreements ]" } {
4448    	# Kick the window manager awake.
4449    	wm withdraw .agreements
4450	wm deiconify .agreements
4451	focus -force .agreements
4452	update_agreement_display
4453	return
4454    }
4455
4456    # Create and then immediately withdraw the window
4457    # so that it does not bounce around later.
4458    toplevel .agreements -bg $bgcolor
4459    wm withdraw .agreements
4460    wm title .agreements "Xconq Agreements"
4461
4462#    puts stdout "[agreements]"
4463
4464    frame .agreements.top -bg $bgcolor
4465    pack .agreements.top -side top -fill x
4466
4467    scrolled_listbox .agreements.top.toc -selectmode browse
4468    pack .agreements.top.toc -side left -fill both -expand true
4469
4470    bind .agreements.top.toc.list <ButtonRelease-1> { select_agreement }
4471
4472    frame .agreements.top.titlef -bg $bgcolor
4473    pack .agreements.top.titlef -side top -fill x
4474
4475    label .agreements.top.titlef.tlabel -text "Title:" -bg $bgcolor -fg $fgcolor
4476    pack .agreements.top.titlef.tlabel -side left -anchor nw
4477    entry .agreements.top.titlef.title -fg $fgcolor
4478    pack .agreements.top.titlef.title -side left -anchor nw
4479
4480    frame .agreements.top.statef -bg $bgcolor
4481    pack .agreements.top.statef -side top -fill x
4482
4483    label .agreements.top.statef.slabel -text "State:" -bg $bgcolor -fg $fgcolor
4484    pack .agreements.top.statef.slabel -side left -anchor nw
4485    label .agreements.top.statef.state -text "()" -bg $bgcolor -fg $fgcolor
4486    pack .agreements.top.statef.state -side left -anchor nw
4487
4488    label .agreements.top.termslabel -text "Terms:" -bg $bgcolor -fg $fgcolor
4489    pack .agreements.top.termslabel -side top -anchor nw
4490
4491    frame .agreements.top.termsf -relief sunken -borderwidth $textb -bg $bgcolor
4492    pack .agreements.top.termsf -side top
4493
4494    text .agreements.top.termsf.terms -width 40 -height 20 \
4495     -bg $lcolor -highlightbackground $lcolor -fg $fgcolor -relief flat
4496    pack .agreements.top.termsf.terms -side top
4497
4498    .agreements.top.termsf.terms delete 1.0 end
4499    .agreements.top.termsf.terms insert insert "(terms)"
4500
4501    label .agreements.top.sideslabel -text "Sides:" -bg $bgcolor -fg $fgcolor
4502    pack .agreements.top.sideslabel -side top -anchor nw
4503
4504    frame .agreements.top.sidesf -height 100 -bg $bgcolor
4505    pack .agreements.top.sidesf -side top -fill both
4506
4507    canvas .agreements.top.sidesf.sides -width 300 -height 100 \
4508	-borderwidth 2 -relief sunken \
4509	-bg $bgcolor -highlightbackground $hbcolor
4510    pack .agreements.top.sidesf.sides -side top -fill both
4511
4512    # Add listboxes for drafters, proposers, signers, announcees
4513    # Add text boxes for terms and comments
4514    # Add popup to choose specific types of terms
4515
4516    frame .agreements.bot     -bg $bgcolor
4517    pack .agreements.bot -side bottom -fill both -expand true
4518
4519    button .agreements.bot.new -text "New" \
4520	-command { new_agreement } \
4521	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4522	-fg $fgcolor -activeforeground $afcolor
4523    pack .agreements.bot.new -side left
4524    button .agreements.bot.addside -text "Add Side" -state disabled \
4525	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4526	-fg $fgcolor -activeforeground $afcolor
4527    pack .agreements.bot.addside -side left
4528    button .agreements.bot.circulate -text "Circulate" -state disabled \
4529	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4530	-fg $fgcolor -activeforeground $afcolor
4531    pack .agreements.bot.circulate -side left
4532    button .agreements.bot.propose -text "Propose" -state disabled \
4533	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4534	-fg $fgcolor -activeforeground $afcolor
4535    pack .agreements.bot.propose -side left
4536    button .agreements.bot.sign -text "Sign" -state disabled \
4537	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4538	-fg $fgcolor -activeforeground $afcolor
4539    pack .agreements.bot.sign -side left
4540    button .agreements.bot.withdraw -text "Withdraw" -state disabled \
4541	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4542	-fg $fgcolor -activeforeground $afcolor
4543    pack .agreements.bot.withdraw -side left
4544    button .agreements.bot.done -text "Done" \
4545	    -command { close_agreements_window } \
4546	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4547	-fg $fgcolor -activeforeground $afcolor
4548    pack .agreements.bot.done -side left
4549
4550    center_above_curmap .agreements
4551}
4552
4553proc new_agreement {} {
4554    execute_long_command 0 "agreement-draft"
4555    update_agreement_display
4556}
4557
4558proc close_agreements_window {} {
4559    withdraw_window ".agreements"
4560}
4561
4562proc update_agreement_display {} {
4563    .agreements.top.toc.list delete 0 end
4564    set aglist [ agreements ]
4565    foreach agid $aglist {
4566	.agreements.top.toc.list insert end $agid
4567    }
4568    # (should add info about selected agreement)
4569}
4570
4571proc select_agreement {} {
4572    set i [ .agreements.top.toc.list curselection ]
4573    if { $i == "" } {
4574    	return
4575    }
4576    set agid [ .agreements.top.toc.list get $i ]
4577}
4578
4579proc popup_scores {} {
4580    global stdfont boldfont
4581    global scrollb
4582    global textb
4583    global bgcolor hbcolor abcolor tcolor lcolor fgcolor afcolor
4584
4585    if { "[ winfo exists .scores ]" } {
4586    	# Kick awake the window manager.
4587    	wm withdraw .scores
4588	wm deiconify .scores
4589	focus -force .scores
4590	# Refresh the scores list each time.
4591	.scores.main.text delete 1.0 end
4592	.scores.main.text insert end [ get_scores ]
4593	return
4594    }
4595
4596    # Create and then immediately withdraw the window
4597    # so that it does not bounce around later.
4598    toplevel .scores -bg $bgcolor
4599    wm withdraw .scores
4600    wm title .scores "Xconq Scores"
4601
4602    frame .scores.bottom -bg $bgcolor
4603    pack .scores.bottom -side bottom -fill x
4604    button .scores.bottom.close -text "Close" -command { dismiss_scores } -default active \
4605	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4606	-fg $fgcolor -activeforeground $afcolor -width 8 -font $boldfont
4607    pack .scores.bottom.close -side right -pady 6 -padx 25
4608
4609    frame .scores.main -width 400 -height 300 -relief sunken -borderwidth $textb -bg $lcolor
4610    text .scores.main.text -yscrollcommand ".scores.yscroll set" -font $stdfont \
4611	-bg $lcolor -highlightbackground $lcolor -wrap word -fg $fgcolor -relief flat
4612    scrollbar .scores.yscroll -orient vert \
4613	-command ".scores.main.text yview" -width 16 -borderwidth $scrollb \
4614	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
4615    pack .scores.yscroll -side right -fill y
4616    pack .scores.main -side top -fill both -expand true
4617    pack propagate .scores.main false
4618    pack .scores.main.text -side top -fill both -expand true
4619
4620    .scores.main.text insert end [ get_scores ]
4621    .scores.main.text configure -state disabled
4622
4623    bind .scores <Key> {
4624    	if {"%K" == "Return" || "%K" == "Escape"} {
4625		.scores.bottom.close flash
4626		dismiss_scores
4627	}
4628    }
4629    center_above_curmap .scores
4630}
4631
4632proc dismiss_scores {} {
4633    withdraw_window ".scores"
4634}
4635
4636# Create and popup the preferences dialog.
4637
4638proc popup_preferences_dialog {} {
4639    global view_option_list
4640    global stdfont boldfont
4641    global last_prefs_topic
4642    global listb
4643    global bgcolor hbcolor abcolor lcolor fgcolor afcolor
4644
4645    if { "[ winfo exists .prefs ]" } {
4646	# Kick the window manager awake.
4647	wm withdraw .prefs
4648	wm deiconify .prefs
4649	focus -force .prefs
4650	init_newprefs
4651	return
4652    }
4653
4654    # Create and then immediately withdraw the window
4655    # so that it does not bounce around later.
4656    toplevel .prefs -bg $bgcolor
4657    wm withdraw .prefs
4658    wm title .prefs "Xconq Preferences"
4659
4660    frame .prefs.main -bg $bgcolor
4661    pack .prefs.main -side top -fill both -expand true
4662
4663    frame .prefs.main.topics -bg $bgcolor
4664    pack .prefs.main.topics -side left -padx 6 -pady 6 -anchor nw
4665    listbox .prefs.main.topics.list -selectmode browse -font $stdfont \
4666    	-height 5 -width 10 -relief sunken -borderwidth $listb -bg $lcolor -fg $fgcolor
4667    pack .prefs.main.topics.list -side left
4668    .prefs.main.topics.list insert end " Map View"
4669    .prefs.main.topics.list insert end " Fonts"
4670    .prefs.main.topics.list insert end " Files"
4671    .prefs.main.topics.list insert end " Imagery"
4672    .prefs.main.topics.list insert end " Network"
4673
4674    frame .prefs.main.v -width 300 -height 220 -bg $bgcolor
4675    pack .prefs.main.v -side left -padx 8 -pady 6
4676    pack propagate .prefs.main.v true
4677
4678    add_map_prefs_items
4679    set last_prefs_topic " Map View"
4680
4681    bind .prefs.main.topics.list <ButtonRelease-1> { select_prefs_topic }
4682
4683    frame .prefs.bot -bg $bgcolor
4684    pack .prefs.bot -side bottom -anchor e -padx 20 -pady 4
4685
4686    button .prefs.bot.ok -text OK -width 8 -font $boldfont \
4687	    -command { ok_preferences } -default active \
4688	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4689	    -fg $fgcolor -activeforeground $afcolor
4690    button .prefs.bot.cancel -text Cancel -width 8 -font $boldfont \
4691	    -command { dismiss_preferences_dialog } \
4692	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
4693	    -fg $fgcolor -activeforeground $afcolor
4694    grid .prefs.bot.cancel .prefs.bot.ok -sticky ew -padx 6 -pady 4
4695
4696    init_newprefs
4697    # Select "Map View" by default.
4698    .prefs.main.topics.list selection set 0
4699
4700    bind .prefs <Key> {
4701    	if {"%K" == "Escape"} {
4702		.prefs.bot.cancel flash
4703		withdraw_window ".prefs"
4704	} elseif  {"%K" == "Return"} {
4705		.prefs.bot.ok flash
4706		ok_preferences
4707	}
4708    }
4709    center_above_curmap .prefs
4710}
4711
4712proc init_newprefs {} {
4713    global view_option_list
4714    global imagery_option_list
4715    global prefs newprefs
4716
4717    foreach opt $view_option_list {
4718	set newprefs($opt) $prefs($opt)
4719    }
4720    set_power_pref $newprefs(power)
4721    set_font_family_newpref $prefs(font_family)
4722    set_font_size_newpref $prefs(font_size)
4723    foreach opt $imagery_option_list {
4724	set newprefs($opt) $prefs($opt)
4725    }
4726    set newprefs(want_checkpoints) $prefs(want_checkpoints)
4727    set newprefs(checkpoint_interval) $prefs(checkpoint_interval)
4728    set newprefs(listallgames) $prefs(listallgames)
4729    set newprefs(joinhost) $prefs(joinhost)
4730    set newprefs(joinport) $prefs(joinport)
4731    set newprefs(myname) $prefs(myname)
4732}
4733
4734proc add_map_prefs_items {} {
4735    global view_option_list view_option_names boldfont
4736    global bgcolor hbcolor abcolor scolor fgcolor afcolor
4737
4738    set mapvf .prefs.main.v.map
4739    if { !"[ winfo exists $mapvf ]" } {
4740	frame $mapvf -bg $bgcolor
4741
4742	menubutton $mapvf.power -text $view_option_names(power) \
4743		-borderwidth 2 -relief raised \
4744		-menu $mapvf.power.menu \
4745		-bg $bgcolor -highlightbackground $hbcolor \
4746		-activebackground $abcolor \
4747		-fg $fgcolor -activeforeground $afcolor -font $boldfont
4748	pack $mapvf.power -side top -anchor nw
4749	menu $mapvf.power.menu -tearoff 0 -font $boldfont \
4750		-bg $bgcolor -activebackground $abcolor -fg $fgcolor \
4751		-activeforeground $afcolor
4752	for { set i 0 } { $i <= 6 } { incr i } {
4753	    $mapvf.power.menu add command -label "$i" \
4754		    -command [ list set_power_pref $i ]
4755	}
4756	frame $mapvf.checks -bg $bgcolor
4757	pack $mapvf.checks -side top
4758	set cnt 0
4759	foreach opt $view_option_list {
4760	    if { "$opt" == "power" } continue
4761	    if { "$opt" == "meridian_interval" } continue
4762	    set opts($cnt) $opt
4763	    incr cnt
4764	}
4765	for { set i 0 } { $i < $cnt } { incr i 2 } {
4766	    set opt1 $opts($i)
4767	    set j [ expr $i + 1 ]
4768	    if { $j < $cnt } {
4769		set even 1
4770	    } else {
4771		set even 0
4772	    }
4773	    checkbutton $mapvf.checks.$opt1 \
4774		    -text " $view_option_names($opt1)" \
4775		    -variable newprefs($opt1) \
4776		    -bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
4777		    -activebackground $abcolor -selectcolor $scolor \
4778		    -fg $fgcolor -activeforeground $afcolor
4779	    if { $even } {
4780		set opt2 $opts($j)
4781		checkbutton $mapvf.checks.$opt2 \
4782			-text " $view_option_names($opt2)" \
4783			-variable newprefs($opt2) \
4784			-bg $bgcolor -highlightbackground $bgcolor \
4785			-font $boldfont \
4786			-activebackground $abcolor -selectcolor $scolor \
4787			-fg $fgcolor -activeforeground $afcolor
4788		grid $mapvf.checks.$opt1 $mapvf.checks.$opt2 -sticky w -pady 2
4789	    } else {
4790		grid $mapvf.checks.$opt1 -pady 2
4791	    }
4792	}
4793	button $mapvf.minterval -text $view_option_names(meridian_interval) \
4794	    -width 16 -font $boldfont \
4795	    -command [ list popup_meridian_interval_dialog 0 ] \
4796	    -bg $bgcolor -highlightbackground $hbcolor \
4797	    -activebackground $abcolor \
4798	    -fg $fgcolor -activeforeground $afcolor
4799	pack $mapvf.power -side top -anchor nw
4800	pack $mapvf.minterval -side bottom -anchor nw -pady 5
4801    }
4802    pack $mapvf -side left -anchor nw
4803}
4804
4805proc remove_map_prefs_items {} {
4806    pack forget .prefs.main.v.map
4807}
4808
4809proc add_fonts_prefs_items {} {
4810    global prefs boldfont
4811    global textb
4812    global bgcolor hbcolor abcolor lcolor fgcolor afcolor
4813
4814    if { !"[ winfo exists .prefs.main.v.fonts ]" } {
4815	frame .prefs.main.v.fonts -bg $bgcolor
4816
4817	frame .prefs.main.v.fonts.name -bg $bgcolor
4818	pack .prefs.main.v.fonts.name -side top -anchor w -pady 4
4819
4820	label .prefs.main.v.fonts.name.label -text "Font:" -bg $bgcolor \
4821	    -fg $fgcolor -font $boldfont
4822	grid .prefs.main.v.fonts.name.label -row 0 -column 0
4823
4824	menubutton .prefs.main.v.fonts.name.family -text "$prefs(font_family)" \
4825		-borderwidth 2 -relief raised \
4826		-menu .prefs.main.v.fonts.name.family.menu \
4827		-bg $bgcolor -highlightbackground $hbcolor \
4828		-activebackground $abcolor \
4829		-fg $fgcolor -activeforeground $afcolor -font $boldfont
4830	grid .prefs.main.v.fonts.name.family -row 0 -column 1
4831
4832	menu .prefs.main.v.fonts.name.family.menu -tearoff 0 -font $boldfont \
4833		-bg $bgcolor -activebackground $abcolor -fg $fgcolor \
4834		-activeforeground $afcolor
4835	foreach family [font families] {
4836	    .prefs.main.v.fonts.name.family.menu add command -label "$family" \
4837		    -command [ list set_font_family_newpref $family ]
4838	}
4839
4840	frame .prefs.main.v.fonts.size -bg $bgcolor
4841	pack .prefs.main.v.fonts.size -side top -anchor w -pady 4
4842
4843	label .prefs.main.v.fonts.size.label -text "Size:" -bg $bgcolor \
4844	    -fg $fgcolor -font $boldfont
4845	grid .prefs.main.v.fonts.size.label -row 0 -column 0
4846
4847	menubutton .prefs.main.v.fonts.size.size -text "$prefs(font_size)" \
4848		-borderwidth 2 -relief raised \
4849		-menu .prefs.main.v.fonts.size.size.menu \
4850		-bg $bgcolor -highlightbackground $hbcolor \
4851		-activebackground $abcolor \
4852		-fg $fgcolor -activeforeground $afcolor -font $boldfont
4853	grid .prefs.main.v.fonts.size.size -row 0 -column 1
4854
4855	menu .prefs.main.v.fonts.size.size.menu -tearoff 0 -font $boldfont \
4856		-bg $bgcolor -activebackground $abcolor -fg $fgcolor \
4857		-activeforeground $afcolor
4858	foreach size { 9 10 12 14 16 18 20 24 28 32 36 } {
4859	    .prefs.main.v.fonts.size.size.menu add command -label "$size" \
4860		    -command [ list set_font_size_newpref $size ]
4861	}
4862	# The size of the text widget will change as the font sizes;
4863	# so keep it inside a fixed-size box.
4864	frame .prefs.main.v.fonts.sampf -width 160 -height 80 \
4865			-relief sunken -borderwidth $textb -bg $bgcolor
4866	pack .prefs.main.v.fonts.sampf -side top -pady 4
4867	pack propagate .prefs.main.v.fonts.sampf false
4868
4869	set tmpfont [ list "-family" $prefs(font_family) "-size" $prefs(font_size) ]
4870	text .prefs.main.v.fonts.sampf.sample -font $tmpfont \
4871		-bg $lcolor -highlightbackground $lcolor -fg $fgcolor -relief flat
4872	pack .prefs.main.v.fonts.sampf.sample -side top
4873	.prefs.main.v.fonts.sampf.sample insert end "Your triumph is complete."
4874	.prefs.main.v.fonts.sampf.sample config -state disabled
4875    }
4876    pack .prefs.main.v.fonts -side left -anchor nw
4877}
4878
4879proc remove_fonts_prefs_items {} {
4880    pack forget .prefs.main.v.fonts
4881}
4882
4883proc add_files_prefs_items {} {
4884    global prefs boldfont stdfont
4885    global bgcolor hbcolor abcolor scolor fgcolor afcolor
4886
4887    set filesf .prefs.main.v.files
4888    if { !"[ winfo exists $filesf ]" } {
4889	frame $filesf -bg $bgcolor
4890
4891	checkbutton $filesf.listallgames -text " Also list unfinished games" \
4892		-variable newprefs(listallgames) \
4893		-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
4894		-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
4895		-activeforeground $afcolor
4896	pack $filesf.listallgames -side bottom -anchor w -pady 4
4897
4898	checkbutton $filesf.checkpoint -text " Save game" \
4899		-variable newprefs(want_checkpoints) \
4900		-command { toggle_checkpoints } \
4901		-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
4902		-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
4903		-activeforeground $afcolor
4904	pack $filesf.checkpoint -side left -anchor w
4905
4906	frame $filesf.cpf -bg $bgcolor
4907	pack $filesf.cpf -side left -anchor w
4908
4909	label $filesf.cpf.lab1 -text "every" -bg $bgcolor -fg $fgcolor \
4910	    -font $boldfont
4911	entry $filesf.cpf.interval -width 2 -relief sunken \
4912		-textvariable newprefs(checkpoint_interval) -fg $fgcolor \
4913		-font $stdfont
4914	label $filesf.cpf.lab2 -text "turns" -bg $bgcolor -fg $fgcolor \
4915		-font $boldfont
4916	pack $filesf.cpf.lab1 $filesf.cpf.interval $filesf.cpf.lab2 -side left
4917	if { $prefs(want_checkpoints) } {
4918		.prefs.main.v.files.cpf.interval config -state normal
4919	} else {
4920		.prefs.main.v.files.cpf.interval config -state disabled
4921	}
4922    }
4923    pack $filesf -side left -anchor nw -pady 14
4924}
4925
4926proc toggle_checkpoints {} {
4927    global newprefs
4928
4929    if { $newprefs(want_checkpoints) } {
4930	set state normal
4931    } else {
4932	set state disabled
4933    }
4934    .prefs.main.v.files.cpf.interval config -state $state
4935}
4936
4937proc remove_files_prefs_items {} {
4938    pack forget .prefs.main.v.files
4939}
4940
4941proc add_network_prefs_items {} {
4942    global prefs boldfont stdfont
4943    global bgcolor fgcolor afcolor
4944
4945    set netf .prefs.main.v.network
4946    if { !"[ winfo exists $netf ]" } {
4947	frame $netf -bg $bgcolor
4948	pack $netf -side top -anchor nw
4949
4950	label $netf.namelabel -text "Your Name :" -font $boldfont \
4951	    -bg $bgcolor -fg $fgcolor
4952	label $netf.hostlabel -text "Game Host :" -font $boldfont \
4953	    -bg $bgcolor -fg $fgcolor
4954	label $netf.portlabel -text "Port :" -font $boldfont -bg $bgcolor \
4955	    -fg $fgcolor
4956
4957	grid $netf.namelabel -sticky w -column 0 -pady 2
4958	grid $netf.hostlabel -sticky w -column 0 -pady 2
4959	grid $netf.portlabel -sticky w -column 0 -pady 2
4960
4961	entry $netf.nameentry -textvariable newprefs(myname) \
4962	    -relief sunken -width 15 -fg $fgcolor -font $stdfont
4963	entry $netf.hostentry -textvariable newprefs(joinhost) \
4964	    -relief sunken -width 15 -fg $fgcolor -font $stdfont
4965	entry $netf.portentry -textvariable newprefs(joinport) \
4966	    -relief sunken -width 4 -fg $fgcolor -font $stdfont
4967
4968	grid $netf.nameentry -sticky w -column 1 -row 0 -pady 2
4969	grid $netf.hostentry -sticky w -column 1 -row 1 -pady 2
4970	grid $netf.portentry -sticky w -column 1 -row 2 -pady 2
4971    }
4972    pack $netf -side left -anchor nw
4973}
4974
4975proc remove_network_prefs_items {} {
4976    pack forget .prefs.main.v.network
4977}
4978
4979proc add_imagery_prefs_items {} {
4980    global prefs boldfont
4981    global imagery_option_names
4982    global bgcolor hbcolor abcolor scolor fgcolor afcolor
4983
4984    set imageryf .prefs.main.v.imagery
4985    if { !"[ winfo exists $imageryf ]" } {
4986	frame $imageryf -bg $bgcolor
4987
4988	checkbutton $imageryf.terrain_images \
4989		-text " $imagery_option_names(terrain_images)" \
4990		-variable newprefs(terrain_images) \
4991		-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
4992		-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
4993		-activeforeground $afcolor
4994	pack $imageryf.terrain_images -side top -anchor w -pady 2
4995	checkbutton $imageryf.terrain_patterns \
4996		-text " $imagery_option_names(terrain_patterns)" \
4997		-variable newprefs(terrain_patterns) \
4998		-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
4999		-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
5000		-activeforeground $afcolor
5001	pack $imageryf.terrain_patterns -side top -anchor w -pady 2
5002	checkbutton $imageryf.transitions \
5003		-text " $imagery_option_names(transitions)" \
5004		-variable newprefs(transitions) \
5005		-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
5006		-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
5007		-activeforeground $afcolor
5008	pack $imageryf.transitions -side top -anchor w -pady 2
5009    }
5010    pack $imageryf -side left -anchor nw
5011}
5012
5013proc remove_imagery_prefs_items {} {
5014    pack forget .prefs.main.v.imagery
5015}
5016
5017proc set_power_pref { val } {
5018    global newprefs
5019
5020    set newprefs(power) $val
5021    .prefs.main.v.map.power config -text "Power $newprefs(power)"
5022}
5023
5024proc set_font_family_newpref { val } {
5025    global newprefs
5026
5027    set newprefs(font_family) $val
5028    if { "[ winfo exists .prefs.main.v.fonts ]" } {
5029	.prefs.main.v.fonts.name.family config -text "$newprefs(font_family)"
5030	set tmpfont [ list "-family" $newprefs(font_family) \
5031		"-size" $newprefs(font_size) ]
5032	.prefs.main.v.fonts.sampf.sample config -font $tmpfont
5033    }
5034}
5035
5036proc set_font_size_newpref { val } {
5037    global newprefs
5038
5039    set newprefs(font_size) $val
5040    if { "[ winfo exists .prefs.main.v.fonts ]" } {
5041	.prefs.main.v.fonts.size.size config -text "$newprefs(font_size)"
5042	set tmpfont [ list "-family" $newprefs(font_family) \
5043		"-size" $newprefs(font_size) ]
5044    	.prefs.main.v.fonts.sampf.sample config -state normal
5045	.prefs.main.v.fonts.sampf.sample config -font $tmpfont
5046    	.prefs.main.v.fonts.sampf.sample config -state disabled
5047    }
5048}
5049
5050proc set_pref_value { pref val } {
5051    global prefs
5052    global stdfont boldfont
5053
5054#    puts stdout "Setting prefs($pref) = $val"
5055    set prefs($pref) $val
5056}
5057
5058proc select_prefs_topic {} {
5059    global last_prefs_topic
5060
5061    set i [ .prefs.main.topics.list curselection ]
5062    if { $i == "" } {
5063    	return
5064    }
5065    set str [ .prefs.main.topics.list get $i ]
5066#    puts stdout "want $str prefs"
5067    if { $str == $last_prefs_topic } {
5068	return
5069    }
5070    if { $last_prefs_topic == " Map View" } {
5071	remove_map_prefs_items
5072    } elseif { $last_prefs_topic == " Fonts" } {
5073	remove_fonts_prefs_items
5074    } elseif { $last_prefs_topic == " Files" } {
5075	remove_files_prefs_items
5076    } elseif { $last_prefs_topic == " Imagery" } {
5077	remove_imagery_prefs_items
5078    } elseif { $last_prefs_topic == " Network" } {
5079	remove_network_prefs_items
5080    }
5081    if { $str == " Map View" } {
5082	add_map_prefs_items
5083    } elseif { $str == " Fonts" } {
5084	add_fonts_prefs_items
5085    } elseif { $str == " Files" } {
5086	add_files_prefs_items
5087    } elseif { $str == " Imagery" } {
5088	add_imagery_prefs_items
5089    } elseif { $str == " Network" } {
5090	add_network_prefs_items
5091    }
5092    set last_prefs_topic $str
5093}
5094
5095# Accept the new preference settings, copying them into the prefs array
5096# and saving into a file.
5097
5098proc ok_preferences {} {
5099    global view_option_list
5100    global view_option_flags
5101    global imagery_option_list
5102    global prefs newprefs
5103    global nummaps map_widget
5104    global stdfont bigfont boldfont titlefont hugefont
5105
5106    set nums [ numsides ]
5107    set dside [ dside ]
5108    set numtreas [ numtreasury ]
5109    set numscores [ numscorekeepers ]
5110
5111    # Set the view option preferences.
5112    foreach opt $view_option_list {
5113	set_pref_value $opt $newprefs($opt)
5114    }
5115    # Set the font preferences.
5116    set_pref_value font_family $newprefs(font_family)
5117    set_pref_value font_size $newprefs(font_size)
5118    set stdfont [ list "-family" $prefs(font_family) \
5119	    "-size" $prefs(font_size) ]
5120    set boldfont [ list "-family" $prefs(font_family) \
5121	    "-size" $prefs(font_size) "-weight" "bold" ]
5122    set hugefont [ list "-family" $prefs(font_family) \
5123	    "-size" [ expr $prefs(font_size) * 3 ] "-weight" "bold" ]
5124    if { $prefs(font_size) < 10 } {
5125	    set bigfont [ list "-family" $prefs(font_family) \
5126		    "-size" [ expr $prefs(font_size) + 1 ] ]
5127	    set titlefont [ list "-family" $prefs(font_family) \
5128		    "-size" [ expr $prefs(font_size) + 1 ] "-weight" "bold" ]
5129    } else {
5130	    set bigfont [ list "-family" $prefs(font_family) \
5131		    "-size" [ expr $prefs(font_size) + 2 ] ]
5132	    set titlefont [ list "-family" $prefs(font_family) \
5133		    "-size" [ expr $prefs(font_size) + 2 ] "-weight" "bold" ]
5134    }
5135    # Update existing map windows that use text.
5136    for { set i 1 } { $i <= $nummaps } { incr i } {
5137	set map $map_widget($i)
5138	$map.leftside.topside.notices.t config -font $stdfont
5139	$map.leftside.topside.notices.t tag config prefix -font $boldfont
5140	$map.leftside.topside.notices.t tag config prompt -font $boldfont
5141	$map.leftside.topside.notices.t tag config answer -font $boldfont
5142	$map.leftside.botside.mouseover config -font $stdfont
5143	$map.leftside.botside.uf.unitinfo itemconfig textual -font $stdfont
5144#	$map.leftside.botside.mapf.mapf2.map config -font $boldfont
5145	# Update the fonts used in the date pane.
5146	set turnpane $map.rightside.turnf.turn
5147	$turnpane itemconfig the_date -font $boldfont
5148	# Update the fonts used in the side list.
5149    	set sidelist $map.rightside.gamef.game
5150    	for { set j 1 } { $j <= $nums } { incr j } {
5151    		if { $j == $dside } {
5152	 		$sidelist itemconfig s$j -font $boldfont
5153	 	} else {
5154	 		$sidelist itemconfig s$j -font $stdfont
5155		}
5156		$sidelist itemconfig player$j -font $stdfont
5157		for { set k 1 } { $k <= $numscores } { incr k } {
5158			$sidelist itemconfig score$k$j -font $stdfont
5159		}
5160		if { $numtreas > 0 && $j == $dside } {
5161			set rows [ expr ($numtreas + 1) / 2 ]
5162			set k 0
5163	    		for { set row 0 } { $row < $rows } { incr row } {
5164				$sidelist itemconfig m$j,$k -font $stdfont
5165				$sidelist itemconfig mt$j,$k -font $stdfont
5166				incr k
5167				if { $k < $numtreas } {
5168				    $sidelist itemconfig m$j,$k -font $stdfont
5169				    $sidelist itemconfig mt$j,$k -font $stdfont
5170				    incr k
5171       				}
5172       			}
5173       		}
5174	}
5175	# Update the fonts used in the unit type list.
5176	set unitlist $map.rightside.listf.unitlist
5177	$unitlist itemconfig type -font $stdfont
5178	$unitlist itemconfig num -font $stdfont
5179	set numu [ numutypes_available $dside ]
5180	for { set j 0 } { $j < $numu } { incr j } {
5181		$unitlist itemconfig u$j -font $stdfont
5182		$unitlist itemconfig n$j -font $stdfont
5183		$unitlist itemconfig i$j -font $stdfont
5184		$unitlist itemconfig name$j -font $stdfont
5185	}
5186	$unitlist itemconfig material -font $boldfont
5187	$unitlist itemconfig supply -font $stdfont
5188	$unitlist itemconfig production -font $stdfont
5189	$unitlist itemconfig capacity -font $stdfont
5190	set numm [ nummtypes ]
5191	for { set j 0 } { $j < $numm } { incr j } {
5192		$unitlist itemconfig material$j -font $stdfont
5193		$unitlist itemconfig supply$j -font $stdfont
5194		$unitlist itemconfig production$j -font $stdfont
5195		$unitlist itemconfig capacity$j -font $stdfont
5196	}
5197    }
5198    # Update fonts in the help window.
5199    if { [ winfo exists .help ] } {
5200	.help.top.help config -font $boldfont
5201	.help.top.prev config -font $boldfont
5202	.help.top.next config -font $boldfont
5203	.help.top.back config -font $boldfont
5204	.help.top.close config -font $boldfont
5205	.help.bot.topics.list config -font $stdfont
5206	.help.bot.t.txt config -font $stdfont
5207	.help.bot.t.txt tag config heading -font $titlefont
5208    }
5209    # Update fonts in the scores window.
5210    if { [ winfo exists .scores ] } {
5211	.scores.bottom.close config -font $boldfont
5212	.scores.main.text config -font $stdfont
5213    }
5214    # Update fonts in the research window.
5215    if { [ winfo exists .research ] } {
5216	.research.current config -font $boldfont
5217	.research.bottom.ok config -font $boldfont
5218	.research.bottom.rest config -font $boldfont
5219	.research.bottom.cancel config -font $boldfont
5220	.research.topics config -font $stdfont
5221    }
5222    # Update fonts in the prefs window and its subframes.
5223    if { [ winfo exists .prefs ] } {
5224	.prefs.main.topics.list config -font $stdfont
5225	.prefs.bot.ok config -font $boldfont
5226	.prefs.bot.cancel config -font $boldfont
5227	if { [ winfo exists .prefs.main.v.map ] } {
5228		.prefs.main.v.map.power config -font $boldfont
5229		.prefs.main.v.map.power.menu config -font $boldfont
5230		foreach opt $view_option_list {
5231			if { [ winfo exists .prefs.main.v.map.checks.$opt ] } {
5232			    .prefs.main.v.map.checks.$opt config -font $boldfont
5233			}
5234		}
5235	}
5236	if { [ winfo exists .prefs.main.v.fonts ] } {
5237		.prefs.main.v.fonts.name.label config -font $boldfont
5238		.prefs.main.v.fonts.name.family config -font $boldfont
5239		.prefs.main.v.fonts.name.family.menu config -font $boldfont
5240		.prefs.main.v.fonts.size.label config -font $boldfont
5241		.prefs.main.v.fonts.size.size config -font $boldfont
5242		.prefs.main.v.fonts.size.size.menu config -font $boldfont
5243	}
5244	if { [ winfo exists .prefs.main.v.files ] } {
5245		.prefs.main.v.files.checkpoint config -font $boldfont
5246		.prefs.main.v.files.cpf.lab1 config -font $boldfont
5247		.prefs.main.v.files.cpf.interval config -font $stdfont
5248		.prefs.main.v.files.cpf.lab2 config -font $boldfont
5249	}
5250	if { [ winfo exists .prefs.main.v.network ] } {
5251		.prefs.main.v.network.namelabel config -font $boldfont
5252		.prefs.main.v.network.hostlabel config -font $boldfont
5253		.prefs.main.v.network.portlabel config -font $boldfont
5254		.prefs.main.v.network.nameentry config -font $stdfont
5255		.prefs.main.v.network.hostentry config -font $stdfont
5256		.prefs.main.v.network.portentry config -font $stdfont
5257	}
5258	if { [ winfo exists .prefs.main.v.imagery ] } {
5259		.prefs.main.v.imagery.terrain_images config -font $boldfont
5260		.prefs.main.v.imagery.terrain_patterns config -font $boldfont
5261		.prefs.main.v.imagery.transitions config -font $boldfont
5262	}
5263    }
5264    # Update fonts in the design window and its subframes.
5265    if { [ winfo exists .design ] } {
5266    	.design.dbuttons.brush config -font $boldfont
5267    	.design.dbuttons.brush.menu config -font $boldfont
5268    	.design.design.done config -font $boldfont
5269	if { [ winfo exists .design.design.fnormal ] } {
5270		.design.design.fnormal.label config -font $boldfont
5271	}
5272	if { [ winfo exists .design.design.fterrain ] } {
5273		.design.design.fterrain.label config -font $boldfont
5274		.design.design.fterrain.fg config -font $boldfont
5275		.design.design.fterrain.fg.menu config -font $boldfont
5276		.design.design.fterrain.bg config -font $boldfont
5277		.design.design.fterrain.bg.menu config -font $boldfont
5278	}
5279	if { [ winfo exists .design.design.funit ] } {
5280		.design.design.funit.label config -font $boldfont
5281		.design.design.funit.type config -font $boldfont
5282		.design.design.funit.type.menu config -font $boldfont
5283		.design.design.funit.side config -font $boldfont
5284		.design.design.funit.side.menu config -font $boldfont
5285	}
5286	if { [ winfo exists .design.design.fpeople ] } {
5287		.design.design.fpeople.label config -font $boldfont
5288		.design.design.fpeople.people config -font $boldfont
5289		.design.design.fpeople.people.menu config -font $boldfont
5290	}
5291	if { [ winfo exists .design.design.fcontrol ] } {
5292		.design.design.fcontrol.label config -font $boldfont
5293		.design.design.fcontrol.control config -font $boldfont
5294		.design.design.fcontrol.control.menu config -font $boldfont
5295	}
5296	if { [ winfo exists .design.design.ffeature ] } {
5297		.design.design.ffeature.label config -font $boldfont
5298		.design.design.ffeature.name config -font $boldfont
5299		.design.design.ffeature.name.menu config -font $boldfont
5300		.design.design.ffeature.buttons.new config -font $boldfont
5301		.design.design.ffeature.buttons.rename config -font $boldfont
5302		.design.design.ffeature.buttons.delete config -font $boldfont
5303		.design.design.ffeature.fields.namelabel config -font $boldfont
5304		.design.design.ffeature.fields.hostlabel config -font $boldfont
5305		.design.design.ffeature.fields.newname config -font $stdfont
5306		.design.design.ffeature.fields.typename config -font $stdfont
5307	}
5308	if { [ winfo exists .design.design.fmaterial ] } {
5309		.design.design.fmaterial.label config -font $boldfont
5310	}
5311	if { [ winfo exists .design.design.felevation ] } {
5312		.design.design.felevation.label config -font $boldfont
5313		.design.design.felevation.entries.lab1 config -font $boldfont
5314		.design.design.felevation.entries.lab2 config -font $boldfont
5315		.design.design.felevation.entries.entry config -font $stdfont
5316		.design.design.felevation.entries.ventry config -font $stdfont
5317		.design.design.felevation.entries.lab3 config -font $boldfont
5318		.design.design.felevation.buttons.set config -font $boldfont
5319		.design.design.felevation.buttons.raise config -font $boldfont
5320		.design.design.felevation.buttons.lower config -font $boldfont
5321		.design.design.felevation.buttons.fix config -font $boldfont
5322		.design.design.felevation.state1 config -font $boldfont
5323		.design.design.felevation.state2 config -font $boldfont
5324	}
5325	if { [ winfo exists .design.design.ftemperature ] } {
5326		.design.design.ftemperature.label1 config -font $boldfont
5327		.design.design.ftemperature.set config -font $boldfont
5328		.design.design.ftemperature.entry config -font $stdfont
5329		.design.design.ftemperature.label2 config -font $boldfont
5330	}
5331	if { [ winfo exists .design.design.fclouds ] } {
5332		.design.design.fclouds.label config -font $boldfont
5333		.design.design.fclouds.entries.dlab config -font $boldfont
5334		.design.design.fclouds.entries.blab config -font $boldfont
5335		.design.design.fclouds.entries.hlab config -font $boldfont
5336		.design.design.fclouds.entries.dentry config -font $boldfont
5337		.design.design.fclouds.entries.dentry.menu config -font $boldfont
5338		.design.design.fclouds.entries.bentry config -font $stdfont
5339		.design.design.fclouds.entries.hentry config -font $stdfont
5340		.design.design.fclouds.entries.set config -font $boldfont
5341	}
5342	if { [ winfo exists .design.design.fwinds ] } {
5343		.design.design.fwinds.label config -font $boldfont
5344		.design.design.fwinds.entries.dlab config -font $boldfont
5345		.design.design.fwinds.entries.flab config -font $boldfont
5346		.design.design.fwinds.entries.dir config -font $boldfont
5347		.design.design.fwinds.entries.dir.menu config -font $boldfont
5348		.design.design.fwinds.entries.force config -font $boldfont
5349		.design.design.fwinds.entries.force.menu config -font $boldfont
5350	}
5351	if { [ winfo exists .design.design.fview ] } {
5352		.design.design.fview.label config -font $boldfont
5353	}
5354    }
5355    # Update fonts in designer save window.
5356    if { [ winfo exists .dsave ] } {
5357    	.dsave.top.modulelabel config -font $boldfont
5358    	.dsave.top.modulename config -font $stdfont
5359    	.dsave.f1.all config -font $boldfont
5360    	.dsave.f1.types config -font $boldfont
5361    	.dsave.f1.tables config -font $boldfont
5362    	.dsave.f1.globals config -font $boldfont
5363    	.dsave.f1.scoring config -font $boldfont
5364    	.dsave.f1.world config -font $boldfont
5365    	.dsave.f1.area config -font $boldfont
5366    	.dsave.f1.terrain config -font $boldfont
5367    	.dsave.f1.areamisc config -font $boldfont
5368    	.dsave.f1.weather config -font $boldfont
5369    	.dsave.f1.material config -font $boldfont
5370    	.dsave.f1.sides config -font $boldfont
5371    	.dsave.f1.sideviews config -font $boldfont
5372    	.dsave.f1.sidedocts config -font $boldfont
5373    	.dsave.f1.players config -font $boldfont
5374    	.dsave.f1.units config -font $boldfont
5375    	.dsave.f1.unitids config -font $boldfont
5376    	.dsave.f1.unitprops config -font $boldfont
5377    	.dsave.f1.unitactions config -font $boldfont
5378    	.dsave.f1.unitplans config -font $boldfont
5379    	.dsave.f1.history config -font $boldfont
5380    	.dsave.f1.save config -font $boldfont
5381    	.dsave.f1.cancel config -font $boldfont
5382    }
5383    # Update fonts in contour window.
5384    if { [ winfo exists .contour ] } {
5385    	.contour.label config -font $boldfont
5386    	.contour.interval config -font $stdfont
5387    	.contour.bottom.ok config -font $boldfont
5388    	.contour.bottom.cancel config -font $boldfont
5389    }
5390    # Update fonts in meridian window.
5391    if { [ winfo exists .meridian ] } {
5392    	.meridian.label config -font $boldfont
5393    	.meridian.interval config -font $stdfont
5394    	.meridian.bottom.ok config -font $boldfont
5395    	.meridian.bottom.cancel config -font $boldfont
5396    }
5397    # Update fonts in find window.
5398    if { [ winfo exists .find ] } {
5399    	.find.label config -font $boldfont
5400    	.find.name config -font $stdfont
5401    	.find.matches config -font $boldfont
5402    	.find.bottom.find config -font $boldfont
5403    	.find.bottom.cancel config -font $boldfont
5404    }
5405    # Set the files preferences.
5406    set_pref_value listallgames $newprefs(listallgames)
5407    set_pref_value want_checkpoints $newprefs(want_checkpoints)
5408    set_pref_value checkpoint_interval $newprefs(checkpoint_interval)
5409    # Set the imagery preferences.
5410    foreach opt $imagery_option_list {
5411	set_pref_value $opt $newprefs($opt)
5412	for { set i 1 } { $i <= $nummaps } { incr i } {
5413	    set mapv $map_widget($i).leftside.botside.mapf.mapf2.map
5414	    $mapv config -terrainimages $prefs(terrain_images)
5415	    $mapv config -terrainpatterns $prefs(terrain_patterns)
5416	    $mapv config -transitions $prefs(transitions)
5417	}
5418    }
5419    # Set the network preferences.
5420    set_pref_value joinhost $newprefs(joinhost)
5421    set_pref_value joinport $newprefs(joinport)
5422    set_pref_value myname $newprefs(myname)
5423
5424    save_preferences
5425    dismiss_preferences_dialog
5426}
5427
5428# Make the dialog go away, without altering any preferences.
5429
5430proc dismiss_preferences_dialog {} {
5431    withdraw_window ".prefs"
5432}
5433
5434# Create and popup the help window.
5435
5436proc popup_help_dialog {} {
5437    global stdfont titlefont boldfont
5438    global scrollb
5439    global listb
5440    global textb
5441    global bgcolor hbcolor abcolor tcolor lcolor fgcolor afcolor
5442    global tcl_platform
5443
5444    # Disable the help system on MacOS < 8.6 since it crashes there.
5445    if { "$tcl_platform(platform)" == "macintosh" && $tcl_platform(osVersion) < 8.6 } {
5446	return
5447    }
5448
5449    if { [ winfo exists .help ] } {
5450	# Kick the window manager awake.
5451	wm withdraw .help
5452	wm deiconify .help
5453	focus -force .help
5454	return
5455    }
5456
5457    # Create and then immediately withdraw the window
5458    # so that it does not bounce around later.
5459    toplevel .help -bg $bgcolor
5460    wm withdraw .help
5461    wm title .help "Xconq Help"
5462
5463    frame .help.top -bg $bgcolor
5464    pack .help.top -side top -fill x -padx 2
5465
5466    button .help.top.help -text "Help" \
5467	-command { help_goto help } \
5468	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5469	-fg $fgcolor -activeforeground $afcolor -font $boldfont
5470    button .help.top.prev -text "Prev" \
5471	-command { help_goto prev } \
5472	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5473	-fg $fgcolor -activeforeground $afcolor -font $boldfont
5474    button .help.top.next -text "Next" \
5475	-command { help_goto next } \
5476	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5477	-fg $fgcolor -activeforeground $afcolor -font $boldfont
5478    button .help.top.back -text "Back" \
5479	-command { help_goto back } \
5480	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5481	-fg $fgcolor -activeforeground $afcolor -font $boldfont
5482    button .help.top.close -text "Close" \
5483	-command { dismiss_help_dialog } \
5484	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5485	-fg $fgcolor -activeforeground $afcolor -font $boldfont
5486    pack .help.top.help .help.top.prev .help.top.next -side left -padx 2 -pady 4
5487    pack .help.top.back .help.top.close -side left -padx 2 -pady 4
5488
5489    frame .help.bot -bg $bgcolor
5490    pack .help.bot -side bottom -fill both -expand true
5491
5492    frame .help.bot.topics -bg $lcolor
5493    pack .help.bot.topics -side left -fill both -expand true
5494    listbox .help.bot.topics.list -yscrollcommand [ list .help.bot.topics.yscroll set ]  \
5495    	-selectmode browse -font $stdfont -relief sunken -borderwidth $listb -bg $lcolor -fg $fgcolor
5496    scrollbar .help.bot.topics.yscroll -orient vert \
5497	-command [ list .help.bot.topics.list yview ] -width 16 -borderwidth $scrollb \
5498	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
5499    pack .help.bot.topics.yscroll -side right -fill y
5500    pack .help.bot.topics.list -side left -fill both -expand true
5501
5502    bind .help.bot.topics.list <ButtonRelease-1> { select_help_topic }
5503
5504    frame .help.bot.t -relief sunken -borderwidth $textb -bg $lcolor
5505    text .help.bot.t.txt -width 60 -height 30 -font $stdfont -wrap word -relief flat \
5506	-yscrollcommand { .help.bot.scroll set } \
5507	-bg $lcolor -highlightbackground $lcolor -fg $fgcolor -highlightthickness 0 -cursor arrow
5508    scrollbar .help.bot.scroll -command { .help.bot.t.txt yview } -width 16 -borderwidth $scrollb \
5509	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
5510    pack .help.bot.scroll -side right -fill y
5511    pack .help.bot.t -side right -fill both -expand true
5512    pack .help.bot.t.txt -side left -fill both -expand true -padx 10
5513
5514    Tree .help.bot.t.txt.tree -padx 4 -relief ridge -borderwidth 1 \
5515	-bg $bgcolor -deltax 30 -deltay 20 -highlightbackground $lcolor \
5516	-height 0 -width 0 -highlightcolor $lcolor
5517    canvas .help.bot.t.txt.img -width 44 -height 48 \
5518	-bg $lcolor -highlightbackground $lcolor
5519#    imfsample .help.bot.t.txt.img.samp -width 44 -height 48 \
5520#	-iwidth 44 -iheight 48 -bg $lcolor
5521    imfsample .help.bot.t.txt.img.samp -width 32 -height 32 \
5522	-iwidth 32 -iheight 32 -bg $lcolor
5523    .help.bot.t.txt.img create window 2 2 -anchor nw \
5524	    -window .help.bot.t.txt.img.samp
5525    .help.bot.t.txt window create end -window .help.bot.t.txt.img
5526    .help.bot.t.txt insert end "(heading)" heading
5527    .help.bot.t.txt tag config heading -font $titlefont
5528    .help.bot.t.txt insert end "\n"
5529    .help.bot.t.txt insert end "(text)" body
5530    .help.bot.t.txt config -state disabled
5531
5532    init_help_list
5533    # Select the "map" entry in the list.
5534    .help.bot.topics.list selection set 1
5535    help_goto "map"
5536    # But scroll to the head of the list.
5537    .help.bot.topics.list see 0
5538    center_above_curmap .help
5539}
5540
5541# Dig up the selected topic and go to that node.
5542
5543proc select_help_topic {} {
5544    set i [ .help.bot.topics.list curselection ]
5545    if { $i == "" } {
5546    	return
5547    }
5548    set str [ .help.bot.topics.list get $i ]
5549    # Remove the leading white space.
5550    set str2 [ string trimleft $str ]
5551    help_goto "$str2"
5552}
5553
5554# Given a help topic key, add it to the list of topics.  This is called
5555# from C code.
5556
5557proc add_help_topic_key { key } {
5558    .help.bot.topics.list insert end " $key"
5559}
5560
5561# This proc is called from C code to actually fill in the help window
5562# with help topic and text.
5563
5564proc update_help { key contents nclass arg } {
5565    global bgcolor
5566
5567    .help.bot.t.txt configure -state normal
5568    .help.bot.t.txt delete heading.first heading.last
5569    .help.bot.t.txt insert 1.1 "$key" heading
5570    if { $nclass == "u" } {
5571	.help.bot.t.txt.img.samp replace imf [ u_image_name $arg ]
5572    } elseif { $nclass == "t" } {
5573	.help.bot.t.txt.img.samp replace imf [ t_image_name $arg ]
5574    } else {
5575	.help.bot.t.txt.img.samp remove imf foo
5576    }
5577    .help.bot.t.txt delete body.first body.last
5578    .help.bot.t.txt insert end "$contents" body
5579    .help.bot.t.txt tag add all 1.0 end
5580    .help.bot.t.txt tag configure all -spacing1 1 -spacing2 2 -spacing3 1
5581
5582    if { $nclass == "u" } {
5583    	set rxp "Required advances to build: "
5584	set xy [.help.bot.t.txt search $rxp 0.0 end]
5585	if { $xy != "" } {
5586             set xy $xy+[string length $rxp]chars
5587             set le [.help.bot.t.txt search . $xy]
5588             set te ""
5589             set cnt 0
5590             while { $te != $le } {
5591                 set te [.help.bot.t.txt search , $xy $le]
5592                 if { $te == "" } { set te $le }
5593                 .help.bot.t.txt tag add tag$cnt $xy $te
5594                 .help.bot.t.txt tag configure tag$cnt -relief raised -borderwidth 1 \
5595                 		-background $bgcolor
5596                 set moji [.help.bot.t.txt get $xy $te]
5597                 .help.bot.t.txt tag bind tag$cnt <Button-1> "help_goto \"$moji\""
5598                 incr cnt
5599                 set xy $te+1chars
5600             }
5601	}
5602    }
5603    if { $nclass == "a" } {
5604	set cnt 0
5605	foreach rxp { "Prerequisites: " "Needed for: " "Enables: "} {
5606             set tmp [.help.bot.t.txt search $rxp 0.0 end]
5607             if { $tmp != "" } {
5608             	set tmp $tmp+[string length $rxp]chars
5609             	set xy $tmp
5610             	set le [.help.bot.t.txt search . $xy]
5611             	set te ""
5612             	while { $te != $le } {
5613                     set te [.help.bot.t.txt search , $xy $le]
5614                     if { $te == "" } { set te $le }
5615                     .help.bot.t.txt tag add tagg$cnt $xy $te
5616                     .help.bot.t.txt tag configure tagg$cnt -relief raised -borderwidth 1 \
5617                     	-background $bgcolor
5618                     set moji [.help.bot.t.txt get $xy $te]
5619                     .help.bot.t.txt tag bind tagg$cnt <Button-1> "help_goto \"$moji\""
5620                     incr cnt
5621                     set xy $te+2chars
5622                 }
5623             }
5624    	}
5625    }
5626
5627    .help.bot.t.txt yview moveto 0
5628    .help.bot.t.txt configure -state disabled
5629    .help.bot.t.txt window create end -window .help.bot.t.txt.tree -pady 10
5630    .help.bot.t.txt.tree configure -height 0 -width 0
5631    .help.bot.t.txt.tree delete [.help.bot.t.txt.tree nodes root]
5632    # This update is essential for correct redrawing of the tree in MacTCL.
5633    update idletasks
5634    if { $nclass == "a"} {
5635	.help.bot.t.txt.tree bindText <ButtonPress-1> tree_node_clicked
5636	.help.bot.t.txt.tree insert end root 1 -text $key -open 1
5637	add_tree_node 1 1
5638	.help.bot.t.txt.tree configure -height [llength [.help.bot.t.txt.tree visiblenodes]] -width 40
5639    }
5640    # Update the current selection in the help topics list.
5641    .help.bot.topics.list selection clear 0 end
5642    for { set i 0 } { $i < [.help.bot.topics.list size] } { incr i } {
5643	set str [ .help.bot.topics.list get $i ]
5644	# Remove the leading white space.
5645	set str2 [ string trimleft $str ]
5646    	if { $str2 == $key} {
5647		.help.bot.topics.list selection set $i
5648		.help.bot.topics.list see $i
5649		break
5650	}
5651    }
5652}
5653
5654proc tree_node_clicked { node } {
5655    help_goto "[.help.bot.t.txt.tree itemcget $node -text]"
5656}
5657
5658proc add_tree_node { key dep } {
5659    set temp_node_text [.help.bot.t.txt.tree itemcget $key -text]
5660    for { set i 0 } { $i < [numatypes]} { incr i } {
5661        if { [atype_name $i] == $temp_node_text } {
5662            set num $i
5663	    break
5664	}
5665    }
5666
5667    for { set i 0 } { $i < [numatypes] } { incr i } {
5668        if { [ advance_needed_to_research $num $i] == 1} {
5669            incr dep
5670            if { $dep > 6 } { break }
5671            set addn $key$dep
5672            .help.bot.t.txt.tree insert end $key $addn -text "[atype_name $i]" -open 1
5673            add_tree_node $addn $dep
5674        }
5675    }
5676}
5677
5678proc scrolled_listbox { f args } {
5679    global scrollb
5680    global listb
5681    global bgcolor hbcolor abcolor tcolor lcolor bgcolor
5682
5683    frame $f -bg $bgcolor
5684    listbox $f.list -yscrollcommand [ list $f.yscroll set ] \
5685    	-relief sunken -borderwidth $listb -bg $lcolor -fg $fgcolor
5686    eval { $f.list config } $args
5687    scrollbar $f.yscroll -orient vert \
5688	    -command [ list $f.list yview ] -width 16 -borderwidth $scrollb \
5689	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
5690    pack $f.yscroll -side right -fill y
5691    pack $f.list -side left -fill both -expand true
5692}
5693
5694proc scrolled_textbox { f args } {
5695    global scrollb
5696    global bgcolor hbcolor abcolor tcolor lcolor bgcolor
5697
5698    frame $f -bg $bgcolor
5699    text $f.text -yscrollcommand [ list $f.yscroll set ]
5700 	    -bg $lcolor -highlightbackground $lcolor -fg $fgcolor
5701    eval { $f.text config } $args
5702    scrollbar $f.yscroll -orient vert \
5703	    -command [ list $f.text yview ] -width 16 -borderwidth $scrollb \
5704 	    -bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor -troughcolor $tcolor
5705    pack $f.yscroll -side right -fill y
5706    pack $f.text -side top -fill both -expand true
5707}
5708
5709# Make the dialog go away.
5710
5711proc dismiss_help_dialog {} {
5712    withdraw_window ".help"
5713}
5714
5715# Game save dialog.
5716
5717set save_filename ""
5718
5719proc popup_game_save { name forcepopup } {
5720    global designer
5721    global save_filename
5722    global tcl_platform
5723
5724    if { $designer } {
5725	popup_designer_save
5726	return
5727    }
5728    set dname [ file dirname $name ]
5729    set fname [ file tail $name ]
5730    if { $forcepopup } {
5731        # -initialfile does not work correctly on the mac (the TCL 8.3 docs
5732        # claim that it is just ignored, but this is not true. Rather, the
5733        # name passed by -initialfile is used, but the save directory is not
5734        # set correctly). A fix for this is now implemented below.
5735	set filename [ tk_getSaveFile -initialfile $fname -initialdir $dname ]
5736    } else {
5737	set filename $fname
5738    }
5739    # Note that we can't just execute the long command "save",
5740    # because it calls this proc.
5741    if { "$filename" != "" } {
5742    	# We need to set the save directory manually in both MacOS and Windows.
5743	set home [ pwd ]
5744        	cd $dname
5745	game_save $filename
5746     	cd $home
5747    }
5748}
5749
5750# Game end dialogs.
5751
5752proc popup_game_over_dialog { fate } {
5753    global stdfont hugefont boldfont
5754    global tcl_platform
5755    global prefs
5756    global bgcolor fgcolor afcolor
5757
5758    # No more mode switching.
5759    disable_move_mode
5760    # (should change all action buttons)
5761    # (should) Let the display settle down a bit.
5762    # sleep 1
5763    # Update the scores list.
5764    if { "[ winfo exists .scores ]" } {
5765    	.scores.main.text configure -state normal
5766	.scores.main.text delete 1.0 end
5767	.scores.main.text insert end [ get_scores ]
5768    	.scores.main.text configure -state disabled
5769    }
5770    if { "$fate" == "won" } {
5771	set msg "You Won!"
5772	set color PaleGreen1
5773    } elseif { "$fate" == "lost" } {
5774	set msg "You Lost!"
5775	set color pink
5776    } else {
5777	set msg "Game Over!"
5778	set color $bgcolor
5779    }
5780
5781    # Create and then immediately withdraw the window
5782    # so that it does not bounce around later.
5783    toplevel .gameover -bg $color
5784    wm withdraw .gameover
5785    wm title .gameover "Xconq Game Over"
5786
5787    frame .gameover.top -width 280 -height 210 -bg $color
5788    pack .gameover.top -side top -fill x
5789
5790    label .gameover.top.fate -text $msg -font $hugefont -bg $color -fg $fgcolor
5791    pack .gameover.top.fate -padx 4 -pady 4
5792
5793    button .gameover.quitnow -text "Quit Now" \
5794	-command { .gameover.quitnow flash
5795			  dismiss_game_over_dialog
5796			  set_want_to_exit 1
5797	} \
5798	-padx 20 -pady 8 -default active \
5799	-bg $color -highlightbackground $color -activebackground $color \
5800	-fg $fgcolor -activeforeground $afcolor -font $boldfont
5801    pack .gameover.quitnow -side top -padx 4 -pady 4
5802
5803    bind .gameover <Key> {
5804    	if {"%K" == "Return"} {
5805    		.gameover.quitnow flash
5806    		dismiss_game_over_dialog
5807		set_want_to_exit 1
5808    	}
5809    }
5810
5811    label .gameover.hint -width 36 -font $stdfont -bg $color \
5812    	-text "If you continue, you can look around\n and see how the game ended." \
5813    	-fg $fgcolor
5814    pack .gameover.hint -side top -padx 4 -pady 4
5815
5816    button .gameover.continue -text "Continue" \
5817	-command { .gameover.continue flash
5818			  dismiss_game_over_dialog
5819	} -padx 20 -pady 8 \
5820	-bg $color -highlightbackground $color -activebackground $color \
5821	-fg $fgcolor -activeforeground $afcolor -font $boldfont
5822    pack .gameover.continue -side top -padx 4 -pady 16
5823
5824    center_above_curmap .gameover
5825}
5826
5827proc dismiss_game_over_dialog {} {
5828    withdraw_window ".gameover"
5829}
5830
5831proc disable_move_mode {} {
5832    global nummaps map_widget
5833
5834    for { set i 1 } { $i <= $nummaps } { incr i } {
5835	$map_widget($i).leftside.botside.buttons.move config -state disabled
5836    }
5837}
5838
5839# Error/warning dialogs.
5840
5841set suppress_warnings 0
5842
5843proc popup_init_error_dialog { str } {
5844    tk_messageBox -type ok -icon error \
5845	    -message "Fatal Setup Error: $str\n\n\
5846	    Something is seriously wrong, either with Xconq \
5847	    or with the game that you chose."
5848}
5849
5850proc popup_init_warning_dialog { str } {
5851    global suppress_warnings
5852
5853    if { $suppress_warnings } {
5854	return
5855    }
5856    set rslt [ tk_messageBox -type yesno -icon warning \
5857	    -message "Warning: $str\n\
5858	    Xconq may not be able to give you exactly the game \
5859	    that you asked for.  Do you want to continue \
5860	    setting up this game?" ]
5861    if { $rslt == "no" } {
5862	exit_xconq
5863    }
5864    # (should try to reuse dialog - may need custom)
5865    set rslt [ tk_messageBox -type yesno -icon question \
5866	    -message "Do you want to see any further warnings?" ]
5867    if { $rslt == "no" } {
5868	set suppress_warnings 1
5869    }
5870}
5871
5872proc popup_run_error_dialog { str } {
5873    set rslt [ tk_messageBox -type yesno -icon error \
5874	    -message "Fatal Error: $str\n\
5875	    Xconq cannot possibly continue on, \
5876	    but may able to save the game; \
5877	    would you like to try to save it?" ]
5878    if { $rslt == "yes" } {
5879	execute_long_command 0 "save"
5880    }
5881    # Exiting will be done by the program. (why?)
5882}
5883
5884proc popup_run_warning_dialog { str } {
5885    global suppress_warnings
5886    global endofgame
5887
5888    if { $suppress_warnings } {
5889	return
5890    }
5891    if { !$endofgame } {
5892	set rslt [ tk_messageBox -type yesno -icon warning \
5893		-message "Warning: $str\n\
5894		This is not fatal, \
5895		but may cause more serious problems later on.\
5896		Do you want to continue playing this game?\
5897		(if `no', you will get a chance to save it)" ]
5898	if { $rslt == "no" } {
5899	    # (should try to reuse dialog - may need custom)
5900	    set rslt [ tk_messageBox -type yesno -icon warning \
5901		    -message "Would you like to save the game?" ]
5902	    if { $rslt == "yes" } {
5903		execute_long_command 0 "save"
5904	    }
5905	    exit_xconq
5906	}
5907    } else {
5908	# The post-end-of-game version doesn't offer to save.
5909	set rslt [ tk_messageBox -type yesno -icon warning \
5910		-message "Warning: $str\n\
5911		Do you want to continue?" ]
5912	if { $rslt == "no" } {
5913	    exit_xconq
5914	}
5915    }
5916    # (should try to reuse dialog - may need custom)
5917    set rslt [ tk_messageBox -type yesno -icon question \
5918	    -message "Do you want to see any further warnings?" ]
5919    if { $rslt == "no" } {
5920	set suppress_warnings 1
5921    }
5922    reset_popup_flag
5923}
5924
5925# Designer support.
5926
5927set selected_design_tool normal
5928
5929set last_dbutton .design.dbuttons.normal
5930set last_frame .design.design.fnormal
5931
5932set curfid 0
5933
5934proc popup_design_palette {} {
5935    global bgcolor hbcolor abcolor fgcolor afcolor boldfont designer
5936
5937    set designer 1
5938    if { "[ winfo exists .design ]" } {
5939	# Make the palette appear again.
5940	wm withdraw .design
5941	wm deiconify .design
5942	focus -force .design
5943    } else {
5944	# Create the design palette from scratch.
5945	toplevel .design -bg $bgcolor
5946	wm withdraw .design
5947	wm title .design "Xconq Design"
5948
5949	# Make sure close_design_palette is called even if the close box is used.
5950	wm protocol .design WM_DELETE_WINDOW close_design_palette
5951
5952	# Create a new frame for the design buttons.
5953	frame .design.dbuttons -bg $bgcolor
5954
5955	# First column of buttons.
5956	button .design.dbuttons.normal -bitmap looking_glass \
5957		-width 24 -height 24 \
5958		-command { select_paint normal make_normal_frame } \
5959		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5960		-fg $fgcolor -activeforeground $afcolor -font $boldfont
5961	button .design.dbuttons.terrain -bitmap paint_cell \
5962		-width 24 -height 24 \
5963		-command { select_paint terrain make_terrain_paint_frame } \
5964		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5965		-fg $fgcolor -activeforeground $afcolor -font $boldfont
5966	button .design.dbuttons.unit -bitmap paint_unit \
5967		-width 24 -height 24 \
5968		-command { select_paint unit make_unit_paint_frame } \
5969		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5970		-fg $fgcolor -activeforeground $afcolor -font $boldfont
5971	button .design.dbuttons.people -bitmap paint_people \
5972		-width 24 -height 24 \
5973		-command { select_paint people make_people_paint_frame } \
5974		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5975		-fg $fgcolor -activeforeground $afcolor -font $boldfont
5976	button .design.dbuttons.control -bitmap paint_control \
5977		-width 24 -height 24 \
5978		-command { select_paint control make_control_paint_frame } \
5979		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5980		-fg $fgcolor -activeforeground $afcolor -font $boldfont
5981	button .design.dbuttons.feature -bitmap paint_feature \
5982		-width 24 -height 24 \
5983		-command { select_paint feature make_feature_paint_frame } \
5984		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5985		-fg $fgcolor -activeforeground $afcolor -font $boldfont
5986
5987	# Second column.
5988	button .design.dbuttons.material -bitmap paint_material \
5989		-width 24 -height 24 -state disabled \
5990		-command { select_paint material make_material_paint_frame } \
5991		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5992		-fg $fgcolor -activeforeground $afcolor -font $boldfont
5993	button .design.dbuttons.elevation -bitmap paint_elev \
5994		-width 24 -height 24 \
5995		-command { select_paint elevation make_elev_paint_frame } \
5996		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
5997		-fg $fgcolor -activeforeground $afcolor -font $boldfont
5998	button .design.dbuttons.temperature -bitmap paint_temp \
5999		-width 24 -height 24 \
6000		-command { select_paint temperature make_temp_paint_frame } \
6001		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6002		-fg $fgcolor -activeforeground $afcolor -font $boldfont
6003	button .design.dbuttons.clouds -bitmap paint_clouds \
6004		-width 24 -height 24 \
6005		-command { select_paint clouds make_clouds_paint_frame } \
6006		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6007		-fg $fgcolor -activeforeground $afcolor -font $boldfont
6008	button .design.dbuttons.winds -bitmap paint_winds \
6009		-width 24 -height 24 \
6010		-command { select_paint winds make_winds_paint_frame } \
6011		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6012		-fg $fgcolor -activeforeground $afcolor -font $boldfont
6013	button .design.dbuttons.view -bitmap paint_view \
6014		-width 24 -height 24 \
6015		-command { select_paint view make_view_paint_frame } \
6016		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6017		-fg $fgcolor -activeforeground $afcolor -font $boldfont
6018	menubutton .design.dbuttons.brush -text "0" -width 1 -height 1 \
6019		-background white -borderwidth 2 -relief raised \
6020		-menu .design.dbuttons.brush.menu \
6021		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6022		-fg $fgcolor -activeforeground $afcolor -font $boldfont
6023	menu .design.dbuttons.brush.menu -tearoff 0 -font $boldfont \
6024		-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6025	for { set i 0 } { $i < 10 } { incr i } {
6026	    .design.dbuttons.brush.menu add command -label "$i" \
6027		    -command [ list dbg_set_design_data curbrushradius $i 0 ]
6028	}
6029
6030	grid .design.dbuttons.normal .design.dbuttons.material
6031	grid .design.dbuttons.terrain .design.dbuttons.elevation
6032	grid .design.dbuttons.unit .design.dbuttons.temperature
6033	grid .design.dbuttons.people .design.dbuttons.clouds
6034	grid .design.dbuttons.control .design.dbuttons.winds
6035	grid .design.dbuttons.feature .design.dbuttons.view
6036	grid .design.dbuttons.brush -columnspan 2 -sticky news
6037
6038	# Create the frame that will enclose info about painting.
6039	frame .design.design -width 200 -height 150 \
6040		-borderwidth 2 -relief sunken -bg $bgcolor
6041	pack propagate .design.design true
6042
6043	button .design.design.done -text "Done" \
6044		-command { close_design_palette } \
6045		-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6046		-fg $fgcolor -activeforeground $afcolor -default active -font $boldfont
6047	pack .design.design.done -side bottom -pady 6 -padx 15
6048
6049	bind .design <Key> { if {"%K" == "Return"} {
6050				.design.design.done flash
6051				close_design_palette
6052			}
6053    	}
6054    	pack .design.dbuttons -side left -fill y
6055	pack .design.design -side left -fill y
6056    }
6057
6058    global any_elev_variation
6059    if { !$any_elev_variation } {
6060	.design.dbuttons.elevation config -state disabled
6061    }
6062    global any_temp_variation
6063    if { !$any_temp_variation } {
6064	.design.dbuttons.temperature config -state disabled
6065    }
6066    global any_wind_variation
6067    if { !$any_wind_variation } {
6068	.design.dbuttons.winds config -state disabled
6069    }
6070    global any_clouds
6071    if { !$any_clouds } {
6072	.design.dbuttons.clouds config -state disabled
6073    }
6074    global see_all
6075    if { $see_all } {
6076	.design.dbuttons.view config -state disabled
6077    }
6078
6079    center_above_curmap .design
6080    select_paint normal make_normal_frame
6081    update idletasks
6082}
6083
6084proc close_design_palette {} {
6085    global designer
6086
6087    execute_long_command 0 "design"
6088    withdraw_window ".design"
6089    set designer 0
6090}
6091
6092proc select_paint { type maker } {
6093    global last_dbutton
6094    global last_frame
6095    global bgcolor
6096
6097    $last_dbutton config -relief raised
6098    .design.dbuttons.$type config -relief sunken
6099    set last_dbutton .design.dbuttons.$type
6100    if { "[ winfo exists $last_frame ]" == 1 } {
6101	pack forget $last_frame
6102    }
6103    set fframe .design.design.f$type
6104    if { "[ winfo exists $fframe ]" == 0 } {
6105	frame $fframe -bg $bgcolor
6106	pack $fframe -side top -fill both
6107	$maker $fframe
6108    } else {
6109	pack $fframe -side top -fill both
6110    }
6111    set last_frame $fframe
6112    select_design_tool $type
6113    update idletasks
6114}
6115
6116proc make_normal_frame { fnormal } {
6117    global boldfont
6118    global bgcolor hbcolor fgcolor
6119
6120    label $fnormal.label -text "Normal" -bg $bgcolor -fg $fgcolor -font $boldfont
6121    pack $fnormal.label -side top -fill x -pady 4
6122}
6123
6124proc make_terrain_paint_frame { fterrain } {
6125    global boldfont
6126    global bgcolor hbcolor abcolor fgcolor afcolor
6127
6128    set numt [ numttypes ]
6129
6130    label $fterrain.label -text "Paint Terrain" -bg $bgcolor -fg $fgcolor -font $boldfont
6131    pack $fterrain.label -side top -fill x -pady 4
6132
6133    canvas $fterrain.canvas -width 100 -height 100 \
6134	-bg $bgcolor -highlightbackground $hbcolor
6135    pack $fterrain.canvas -side left -pady 4 -pady 4
6136
6137    # Place the foreground terrain second, so that it overlaps the
6138    # background terrain.
6139    imfsample $fterrain.canvas.bg -width 44 -height 48 -bg $bgcolor
6140    $fterrain.canvas.bg add imf [ t_image_name 0 ]
6141    $fterrain.canvas create window 30 50 -anchor nw -window $fterrain.canvas.bg
6142
6143    imfsample $fterrain.canvas.fg -width 44 -height 48 -bg $bgcolor
6144    $fterrain.canvas.fg add imf [ t_image_name 0 ]
6145    $fterrain.canvas create window 4 4 -anchor nw -window $fterrain.canvas.fg
6146
6147    menubutton $fterrain.fg -text [ ttype_name 0 ] \
6148	-borderwidth 2 -relief raised \
6149	-menu $fterrain.fg.menu \
6150	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6151	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6152    pack $fterrain.fg -expand true
6153    menu $fterrain.fg.menu -tearoff 0 -font $boldfont \
6154	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6155    for { set i 0 } { $i < $numt } { incr i } {
6156	$fterrain.fg.menu add command -label [ ttype_name $i ] \
6157		-command [ list dbg_set_design_data curttype $i 0 ]
6158    }
6159
6160    menubutton $fterrain.bg -text [ ttype_name 0 ] \
6161	-borderwidth 2 -relief raised \
6162	-menu $fterrain.bg.menu \
6163	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6164	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6165    pack $fterrain.bg -expand true
6166    menu $fterrain.bg.menu -tearoff 0 -font $boldfont \
6167	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6168    for { set i 0 } { $i < $numt } { incr i } {
6169	$fterrain.bg.menu add command -label [ ttype_name $i ] \
6170		-command [ list dbg_set_design_data curbgttype $i 0 ]
6171    }
6172
6173    bind $fterrain.canvas <ButtonPress> \
6174	    { cycle_design_data terrain incr }
6175    bind $fterrain.canvas <Control-ButtonPress> \
6176	    { cycle_design_data terrain decr }
6177    bind $fterrain.canvas.fg <ButtonPress> \
6178	    { cycle_design_data terrain incr }
6179    bind $fterrain.canvas.fg <Control-ButtonPress> \
6180	    { cycle_design_data terrain decr }
6181    bind $fterrain.canvas.bg <ButtonPress> \
6182	    { cycle_design_data terrain incr }
6183    bind $fterrain.canvas.bg <Control-ButtonPress> \
6184	    { cycle_design_data terrain decr }
6185}
6186
6187proc make_unit_paint_frame { funit } {
6188    global boldfont
6189    global bgcolor hbcolor abcolor fgcolor afcolor
6190
6191    set numu [ numutypes ]
6192    set nums [ numsides ]
6193
6194    label $funit.label -text "Place Unit" -bg $bgcolor -fg $fgcolor -font $boldfont
6195    pack $funit.label -side top -fill x -pady 4
6196
6197    canvas $funit.canvas -width 34 -height 34 \
6198	-bg $bgcolor -highlightbackground $hbcolor
6199    pack $funit.canvas -side left -padx 6 -pady 6
6200    imfsample $funit.canvas.samp -width 32 -height 32 -bg $bgcolor
6201    $funit.canvas.samp add imf [ u_image_name 0 ]
6202    $funit.canvas create window 1 1 -anchor nw -window $funit.canvas.samp
6203
6204    menubutton $funit.type -text [ utype_name 0 ] \
6205	-borderwidth 2 -relief raised \
6206	-menu $funit.type.menu \
6207	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6208	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6209    pack $funit.type -expand true -pady 4
6210    menu $funit.type.menu -tearoff 0 -font $boldfont \
6211	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6212    for { set i 0 } { $i < $numu } { incr i } {
6213	$funit.type.menu add command -label [ utype_name $i ] \
6214		-command [ list dbg_set_design_data curutype $i 0 ]
6215    }
6216
6217    menubutton $funit.side -text [ side_adjective 0 ] \
6218	-borderwidth 2 -relief raised \
6219	-menu $funit.side.menu \
6220	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6221	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6222    pack $funit.side -expand true -pady 4
6223    menu $funit.side.menu -tearoff 0 -font $boldfont \
6224	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6225    for { set i 0 } { $i <= $nums } { incr i } {
6226	$funit.side.menu add command -label [ side_adjective $i ] \
6227		-command [ list dbg_set_design_data curusidenumber $i 0 ]
6228	# Preload the unit sample with emblems for all sides, then
6229	# later we can just select at will.
6230	if { $i >= 1 } {
6231	    $funit.canvas.samp add imf [ side_emblem $i ]
6232	}
6233    }
6234
6235    bind $funit.canvas <ButtonPress> \
6236	    [ list cycle_design_data unit incr ]
6237    bind $funit.canvas <Control-ButtonPress> \
6238	    [ list cycle_design_data unit decr ]
6239    bind $funit.canvas.samp <ButtonPress> \
6240	    [ list cycle_design_data unit incr ]
6241    bind $funit.canvas.samp <Control-ButtonPress> \
6242	    [ list cycle_design_data unit decr ]
6243}
6244
6245proc make_people_paint_frame { fpeople } {
6246    global boldfont
6247    global bgcolor hbcolor abcolor fgcolor afcolor
6248
6249    set nums [ numsides ]
6250
6251    label $fpeople.label -text "Paint People" -bg $bgcolor -fg $fgcolor -font $boldfont
6252    pack $fpeople.label -side top -fill x -pady 4
6253
6254    canvas $fpeople.canvas -width 32 -height 32 \
6255	-bg $bgcolor -highlightbackground $hbcolor
6256    pack $fpeople.canvas -side left -pady 4 -pady 4
6257    imfsample $fpeople.canvas.people -width 16 -height 16 -bg $bgcolor
6258    $fpeople.canvas.people add imf [ side_emblem 0 ]
6259    $fpeople.canvas create window 16 16 -anchor c \
6260	    -window $fpeople.canvas.people
6261
6262    menubutton $fpeople.people -text [ side_name 0 ] \
6263	-borderwidth 2 -relief raised \
6264	-menu $fpeople.people.menu \
6265	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6266	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6267    pack $fpeople.people -expand true
6268    menu $fpeople.people.menu -tearoff 0 -font $boldfont \
6269	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6270    for { set i 0 } { $i <= $nums } { incr i } {
6271	$fpeople.people.menu add command -label [ side_name $i ] \
6272		-command [ list dbg_set_design_data curpeoplenumber $i 0 ]
6273    }
6274
6275    bind $fpeople.canvas <ButtonPress> \
6276	    [ list cycle_design_data people incr ]
6277    bind $fpeople.canvas <Control-ButtonPress> \
6278	    [ list cycle_design_data people decr ]
6279
6280    # Automatically turn on display of people layer.
6281    # (should indicate better what is happening)
6282    global nummaps map_widget
6283    global map_options
6284    for { set i 1 } { $i <= $nummaps } { incr i } {
6285	if { $map_options($map_widget($i),people) == 0 } {
6286	    set map_options($map_widget($i),people) 1
6287	    set_map_view_option $map_widget($i) people
6288	}
6289    }
6290}
6291
6292proc make_control_paint_frame { fcontrol } {
6293    global boldfont
6294    global bgcolor hbcolor abcolor fgcolor afcolor
6295
6296    set nums [ numsides ]
6297
6298    label $fcontrol.label -text "Paint Control" -bg $bgcolor -fg $fgcolor -font $boldfont
6299    pack $fcontrol.label -side top -fill x -pady 4
6300
6301    canvas $fcontrol.canvas -width 32 -height 32 \
6302	-bg $bgcolor -highlightbackground $hbcolor
6303    pack $fcontrol.canvas -side left -pady 4 -pady 4
6304    imfsample $fcontrol.canvas.control -width 16 -height 16 -bg $bgcolor -fg $fgcolor
6305    $fcontrol.canvas.control add imf [ side_emblem 0 ]
6306    $fcontrol.canvas create window 16 16 -anchor c \
6307	    -window $fcontrol.canvas.control
6308
6309    menubutton $fcontrol.control -text [ side_name 0 ] \
6310	-borderwidth 2 -relief raised \
6311	-menu $fcontrol.control.menu \
6312	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6313	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6314    pack $fcontrol.control -expand true
6315    menu $fcontrol.control.menu -tearoff 0 -font $boldfont \
6316	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6317    for { set i 0 } { $i <= $nums } { incr i } {
6318	$fcontrol.control.menu add command -label [ side_name $i ] \
6319		-command [ list dbg_set_design_data curcontrolnumber $i 0 ]
6320    }
6321
6322    bind $fcontrol.canvas <ButtonPress> \
6323	    [ list cycle_design_data control incr ]
6324    bind $fcontrol.canvas <Control-ButtonPress> \
6325	    [ list cycle_design_data control decr ]
6326
6327    # Automatically turn on display of control layer.
6328    # (should indicate better what is happening)
6329    global nummaps map_widget
6330    global map_options
6331    for { set i 1 } { $i <= $nummaps } { incr i } {
6332	if { $map_options($map_widget($i),control) == 0 } {
6333	    set map_options($map_widget($i),control) 1
6334	    set_map_view_option $map_widget($i) control
6335	}
6336    }
6337}
6338
6339set rename_name ""
6340set rename_type_name ""
6341
6342proc make_feature_paint_frame { ffeature } {
6343    global boldfont stdfont
6344    global curfid
6345    global bgcolor hbcolor abcolor fgcolor afcolor
6346
6347    set numf [ numfeatures ]
6348
6349    label $ffeature.label -text "Paint Feature" -bg $bgcolor -fg $fgcolor -font $boldfont
6350    pack $ffeature.label -side top -fill x -pady 4
6351
6352    menubutton $ffeature.name -text "[ feature_desc 0 ]" \
6353	-borderwidth 2 -relief raised \
6354	-menu $ffeature.name.menu \
6355	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6356	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6357    pack $ffeature.name -side top
6358    menu $ffeature.name.menu -tearoff 0 -font $boldfont \
6359	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6360    $ffeature.name.menu add command -label "[ feature_desc 0 ]" \
6361	    -command [ list dbg_set_design_data curfid 0 0 ]
6362    for { set i 1 } { $i <= $numf } { incr i } {
6363	set colbreak 0
6364	if { $i % 25 == 0 } {
6365	    set colbreak 1
6366	}
6367	$ffeature.name.menu add command -label "[ feature_desc $i ]" \
6368		-command [ list dbg_set_design_data curfid $i 0 ] \
6369		-columnbreak $colbreak
6370    }
6371
6372    frame $ffeature.buttons -bg $bgcolor
6373    pack $ffeature.buttons -side top -pady 4 -padx 4
6374
6375    button $ffeature.buttons.new -text New \
6376	-command { new_feature } \
6377	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6378	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6379    button $ffeature.buttons.rename -text Rename -state disabled \
6380	-command { rename_feature $curfid } \
6381	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6382	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6383    button $ffeature.buttons.delete -text Del -state disabled \
6384	-command { delete_feature $curfid } \
6385	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6386	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6387    pack $ffeature.buttons.new $ffeature.buttons.rename $ffeature.buttons.delete \
6388    	-side left -anchor nw -padx 4 -pady 4
6389
6390    frame $ffeature.fields -bg $bgcolor
6391    pack $ffeature.fields -side left -pady 4 -padx 4
6392
6393    label $ffeature.fields.namelabel -text "Name :" -bg $bgcolor -fg $fgcolor -font $boldfont
6394    label $ffeature.fields.hostlabel -text "Type :" -bg $bgcolor -fg $fgcolor -font $boldfont
6395
6396    grid $ffeature.fields.namelabel -sticky e -column 0
6397    grid $ffeature.fields.hostlabel -sticky e -column 0
6398
6399    entry $ffeature.fields.newname -textvariable rename_name \
6400    	-relief sunken -width 18 -fg $fgcolor -font $stdfont
6401    entry $ffeature.fields.typename -textvariable rename_type_name \
6402    	-relief sunken -width 18 -fg $fgcolor -font $stdfont
6403
6404    grid $ffeature.fields.newname -sticky w -column 1 -row 0
6405    grid $ffeature.fields.typename -sticky w -column 1 -row 1
6406
6407    update_feature_name_entry 0
6408}
6409
6410# For the given feature id, update the rename fields.
6411
6412proc update_feature_name_entry { fid } {
6413    global rename_name rename_type_name
6414
6415    set state normal
6416    if { $fid == 0 } {
6417	set state disabled
6418	set rename_name ""
6419	set rename_type_name ""
6420    } else {
6421	set rawinfo [ feature_info $fid ]
6422	set finfo "list $rawinfo"
6423	set finfo2 [ lindex $finfo 1 ]
6424	set rename_name [ lindex $finfo2 0 ]
6425	set rename_type_name [ lindex $finfo2 1 ]
6426    }
6427    .design.design.ffeature.buttons.rename config -state $state
6428    .design.design.ffeature.buttons.delete config -state $state
6429}
6430
6431# Make the proposed renaming real.
6432
6433proc rename_feature { fid } {
6434    global rename_name rename_type_name
6435
6436    set_feature_info $fid $rename_name $rename_type_name
6437    # Update the feature menu entry.
6438    .design.design.ffeature.name.menu entryconfigure $fid \
6439	    -label "[ feature_desc $fid ]"
6440    # Update the menu button as well, for immediate feedback.
6441    .design.design.ffeature.name config -text "[ feature_desc $fid ]"
6442}
6443
6444# Make the given feature disappear.
6445
6446proc delete_feature { fid } {
6447    global curfid
6448
6449    if { $fid < 1 } {
6450	# (should complain)
6451	return
6452    }
6453    set entryname [ feature_desc $fid ]
6454    destroy_feature $fid
6455    # Clear from the feature menu entry, but not by index.
6456    # (what if entryname were a number?)
6457    .design.design.ffeature.name.menu delete $entryname
6458    # If the deleted feature was the currently selected one (which is
6459    # usually the case), make the previous feature current.
6460    if { $curfid == $fid } {
6461	incr curfid -1
6462	dbg_set_design_data curfid $curfid 0
6463    }
6464}
6465
6466proc make_material_paint_frame { fmaterial } {
6467    global boldfont
6468    global bgcolor fgcolor
6469
6470    label $fmaterial.label -text "Paint Material" -bg $bgcolor -fg $fgcolor -font $boldfont
6471    pack $fmaterial.label -side top -fill x -pady 4
6472}
6473
6474set elev_var 0
6475set elev_vary_var 0
6476
6477proc make_elev_paint_frame { felev } {
6478    global boldfont stdfont
6479    global elev_var elev_vary_var
6480    global bgcolor hbcolor abcolor fgcolor afcolor
6481
6482    label $felev.label -text "Paint Elevation" -bg $bgcolor -fg $fgcolor -font $boldfont
6483    pack $felev.label -side top -fill x -pady 4
6484
6485    frame $felev.entries -bg $bgcolor
6486    pack $felev.entries -side top -anchor nw -padx 4
6487
6488    label $felev.entries.lab1 -text "Elevation :" -bg $bgcolor -fg $fgcolor -font $boldfont
6489    label $felev.entries.lab2 -text "+/- :" -bg $bgcolor -fg $fgcolor -font $boldfont
6490
6491    grid $felev.entries.lab1 -sticky e -column 0
6492    grid $felev.entries.lab2 -sticky e -column 0
6493
6494    entry $felev.entries.entry -textvariable elev_var \
6495    	-relief sunken -width 6 -fg $fgcolor -font $stdfont
6496    entry $felev.entries.ventry -textvariable elev_vary_var \
6497    	-relief sunken -width 6 -fg $fgcolor -font $stdfont
6498
6499    grid $felev.entries.entry -sticky w -column 1 -row 0
6500    grid $felev.entries.ventry -sticky w -column 1 -row 1
6501
6502    label $felev.entries.lab3 -text " (random)" -bg $bgcolor -fg $fgcolor -font $boldfont
6503
6504    grid $felev.entries.lab3 -sticky e -column 2 -row 1
6505
6506    frame $felev.buttons -bg $bgcolor
6507    pack $felev.buttons -side top
6508
6509    button $felev.buttons.set -text Set \
6510	-command { set_elevation } \
6511	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6512	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6513    button $felev.buttons.raise -text + \
6514	-command { raise_elevation } \
6515	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6516	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6517    button $felev.buttons.lower -text - \
6518	-command { lower_elevation } \
6519	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6520	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6521    button $felev.buttons.fix -text Fix \
6522	-command { designer_fix elevation } \
6523	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6524	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6525    pack $felev.buttons.set $felev.buttons.raise $felev.buttons.lower $felev.buttons.fix \
6526    	-side left -anchor nw -padx 4 -pady 8
6527
6528    label $felev.state1 -text "Set to elevation 0" -bg $bgcolor -fg $fgcolor -font $boldfont
6529    pack $felev.state1 -side top -anchor nw -padx 4
6530    label $felev.state2 -text "Randomly vary +/- 0" -bg $bgcolor -fg $fgcolor -font $boldfont
6531    pack $felev.state2 -side top -anchor nw -padx 4
6532
6533    # Automatically turn on display of elevations.
6534    # (should indicate better what is happening)
6535    global nummaps map_widget
6536    global map_options
6537    for { set i 1 } { $i <= $nummaps } { incr i } {
6538	if { $map_options($map_widget($i),elevations) == 0 } {
6539	    set map_options($map_widget($i),elevations) 1
6540	    set_map_view_option $map_widget($i) elevations
6541	}
6542    }
6543}
6544
6545proc set_elevation {} {
6546    global elev_var elev_vary_var
6547
6548    dbg_set_design_data curelevation $elev_var 0
6549    dbg_set_design_data curelevation_vary $elev_vary_var 0
6550}
6551
6552proc raise_elevation {} {
6553    global elev_var elev_vary_var
6554
6555    dbg_set_design_data curelevation incr $elev_var
6556    dbg_set_design_data curelevation_vary $elev_vary_var 0
6557}
6558
6559proc lower_elevation {} {
6560    global elev_var elev_vary_var
6561
6562    dbg_set_design_data curelevation decr $elev_var
6563    dbg_set_design_data curelevation_vary $elev_vary_var 0
6564}
6565
6566set tempvar 0
6567
6568proc make_temp_paint_frame { ftemp } {
6569    global boldfont stdfont
6570    global tempvar
6571    global bgcolor hbcolor abcolor fgcolor afcolor
6572
6573    label $ftemp.label1 -text "Paint Temperature" -bg $bgcolor -fg $fgcolor -font $boldfont
6574    pack $ftemp.label1 -side top -fill x -pady 4
6575
6576    button $ftemp.set -text Set \
6577	-command { set_temperature } \
6578	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6579	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6580    pack $ftemp.set -side left -anchor nw -padx 8 -pady 4
6581
6582    entry $ftemp.entry -textvariable tempvar \
6583    	-relief sunken -width 6 -fg $fgcolor -font $stdfont
6584    pack $ftemp.entry -side left -padx 4 -pady 4
6585
6586    label $ftemp.label2 -text "degrees" -bg $bgcolor -fg $fgcolor -font $boldfont
6587    pack $ftemp.label2 -side left -padx 4 -pady 4
6588}
6589
6590proc set_temperature {} {
6591    global tempvar
6592
6593    dbg_set_design_data curtemperature $tempvar 0
6594}
6595
6596set cloudtype 0
6597set cloudbottom 0
6598set cloudheight 0
6599
6600proc make_clouds_paint_frame { fclouds } {
6601    global cloudtype cloudbottom cloudheight
6602    global boldfont stdfont
6603    global bgcolor hbcolor abcolor fgcolor afcolor
6604
6605    label $fclouds.label -text "Paint Clouds" -bg $bgcolor -fg $fgcolor -font $boldfont
6606    pack $fclouds.label -side top -fill x -pady 4
6607
6608    frame $fclouds.entries -bg $bgcolor
6609    pack $fclouds.entries -side top -anchor nw -padx 4
6610
6611    label $fclouds.entries.dlab -text "Type :" -bg $bgcolor -fg $fgcolor -font $boldfont
6612    label $fclouds.entries.blab -text "Bottom :" -bg $bgcolor -fg $fgcolor -font $boldfont
6613    label $fclouds.entries.hlab -text "Height :" -bg $bgcolor -fg $fgcolor -font $boldfont
6614
6615    grid $fclouds.entries.dlab -sticky e -column 0
6616    grid $fclouds.entries.blab -sticky e -column 0
6617    grid $fclouds.entries.hlab -sticky e -column 0
6618
6619    menubutton $fclouds.entries.dentry -text "0" \
6620	-borderwidth 2 -relief raised \
6621	-menu $fclouds.entries.dentry.menu \
6622	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6623	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6624    menu $fclouds.entries.dentry.menu -tearoff 0 -font $boldfont \
6625	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6626    foreach cloudtype { 0 1 2 3 4 } {
6627	$fclouds.entries.dentry.menu add command -label "$cloudtype" \
6628		-command [ list dbg_set_design_data curcloudtype $cloudtype 0 ]
6629    }
6630
6631    entry $fclouds.entries.bentry -textvariable cloudbottom \
6632    	-relief sunken -width 6 -fg $fgcolor -font $stdfont
6633    entry $fclouds.entries.hentry -textvariable cloudheight \
6634    	-relief sunken -width 6 -fg $fgcolor -font $stdfont
6635
6636    grid $fclouds.entries.dentry -sticky w -column 1 -row 0
6637    grid $fclouds.entries.bentry -sticky w -column 1 -row 1
6638    grid $fclouds.entries.hentry -sticky w -column 1 -row 2
6639
6640    button $fclouds.entries.set -text Set \
6641	-command { set_clouds } \
6642	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6643	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6644
6645    grid $fclouds.entries.set -sticky e -padx 4 -column 2 -row 2
6646}
6647
6648proc set_clouds {} {
6649    global cloudbottom cloudheight
6650
6651    dbg_set_design_data curcloudbottom $cloudbottom 0
6652    dbg_set_design_data curcloudheight $cloudheight 0
6653}
6654
6655proc make_winds_paint_frame { fwinds } {
6656    global boldfont
6657    global bgcolor hbcolor abcolor fgcolor afcolor
6658
6659    label $fwinds.label -text "Paint Winds" -bg $bgcolor -fg $fgcolor -font $boldfont
6660    pack $fwinds.label -side top -fill x -pady 4
6661
6662    frame $fwinds.entries -bg $bgcolor
6663    pack $fwinds.entries -side top -anchor nw -padx 4
6664
6665    label $fwinds.entries.dlab -text "Direction :" -bg $bgcolor -fg $fgcolor -font $boldfont
6666    label $fwinds.entries.flab -text "Force :" -bg $bgcolor -fg $fgcolor -font $boldfont
6667
6668    grid $fwinds.entries.dlab -sticky e -column 0
6669    grid $fwinds.entries.flab -sticky e -column 0
6670
6671    menubutton $fwinds.entries.dir -text "0" \
6672	-borderwidth 2 -relief raised \
6673	-menu $fwinds.entries.dir.menu \
6674	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6675	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6676    menu $fwinds.entries.dir.menu -tearoff 0 -font $boldfont \
6677	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6678    foreach dir { 0 1 2 3 4 5 } {
6679	$fwinds.entries.dir.menu add command -label "$dir" \
6680		-command [ list dbg_set_design_data curwinddir $dir 0 ]
6681    }
6682    menubutton $fwinds.entries.force -text "0" \
6683	-borderwidth 2 -relief raised \
6684	-menu $fwinds.entries.force.menu \
6685	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
6686	-fg $fgcolor -activeforeground $afcolor -font $boldfont
6687    menu $fwinds.entries.force.menu -tearoff 0 -font $boldfont \
6688	-bg $bgcolor -activebackground $abcolor -fg $fgcolor -activeforeground $afcolor
6689    foreach force { 0 1 2 3 4 } {
6690	$fwinds.entries.force.menu add command -label "$force" \
6691		-command [ list dbg_set_design_data curwindforce $force 0 ]
6692    }
6693
6694    grid $fwinds.entries.dir -sticky w -column 1 -row 0
6695    grid $fwinds.entries.force -sticky w -column 1 -row 1
6696}
6697
6698proc make_view_paint_frame { fview } {
6699    global boldfont
6700    global bgcolor fgcolor
6701
6702    label $fview.label -text "Paint View" -bg $bgcolor -fg $fgcolor -font $boldfont
6703    pack $fview.label -side top -fill x -pady 4
6704
6705}
6706
6707# Make the palette go away, but don't destroy - might want to get it back
6708# in the near future.
6709
6710proc dismiss_design_palette {} {
6711    global designer
6712
6713    set designer 0
6714    if { "[ winfo exists .design ]" } {
6715        withdraw_window ".design"
6716    }
6717}
6718
6719# Given the name of a designer tool, make it the current one in use.
6720
6721proc select_design_tool { name } {
6722    global selected_design_tool
6723
6724    if { $name == $selected_design_tool } {
6725	return
6726    }
6727    set_design_tool $name
6728    set selected_design_tool $name
6729}
6730
6731# Given a type of design data/tool and a value for that type of data,
6732# set it to be the value to paint and update any feedback displays.
6733
6734proc dbg_set_design_data { type val val2 } {
6735    global curfid
6736
6737    set newval [ set_design_data $type $val $val2 ]
6738    set dframe .design.design
6739    if { $type == "curttype" } {
6740	$dframe.fterrain.canvas.fg replace imf [ t_image_name $newval ]
6741	$dframe.fterrain.fg config -text [ ttype_name $newval ]
6742    } elseif { $type == "curbgttype" } {
6743	$dframe.fterrain.canvas.bg replace imf [ t_image_name $newval ]
6744	$dframe.fterrain.bg config -text [ ttype_name $newval ]
6745    } elseif { $type == "curutype" } {
6746	$dframe.funit.canvas.samp replace imf [ u_image_name $newval ]
6747	$dframe.funit.type config -text [ utype_name $newval ]
6748    } elseif { $type == "curusidenumber" } {
6749	$dframe.funit.side config -text [ side_adjective $newval ]
6750	if { $newval > 0 } {
6751	    $dframe.funit.canvas.samp emblem $newval
6752	} else {
6753	    $dframe.funit.canvas.samp emblem -1
6754	}
6755    } elseif { $type == "curpeoplenumber" } {
6756	$dframe.fpeople.canvas.people replace imf [ side_emblem $newval ]
6757	$dframe.fpeople.people config -text [ side_name $newval ]
6758    } elseif { $type == "curcontrolnumber" } {
6759	$dframe.fcontrol.canvas.control replace imf [ side_emblem $newval ]
6760	$dframe.fcontrol.control config -text [ side_name $newval ]
6761    } elseif { $type == "curfid" } {
6762	$dframe.ffeature.name config -text [ feature_desc $newval ]
6763	update_feature_name_entry $newval
6764	# The current feature appears in a different color, so all
6765	# maps need to be updated.
6766	global nummaps
6767	for { set i 1 } { $i <= $nummaps } { incr i } {
6768	    execute_long_command $i "refresh"
6769	}
6770	set curfid $newval
6771    } elseif { $type == "curelevation" } {
6772	global elev_var elev_vary_var
6773	set lab $dframe.felevation.state1
6774	if { $val == "incr" } {
6775	    $lab config -text "Raise elevation by $elev_var"
6776	} elseif { $val == "decr" } {
6777	    $lab config -text "Lower elevation by $elev_var"
6778	} else {
6779	    $lab config -text "Set elevation to $elev_var"
6780	}
6781    } elseif { $type == "curelevation_vary" } {
6782	global elev_var elev_vary_var
6783	$dframe.felevation.state2 config -text "Randomly vary +/- $elev_vary_var"
6784    } elseif { $type == "curcloudtype" } {
6785	.design.design.fclouds.entries.dentry config -text "$newval"
6786    } elseif { $type == "curwinddir" } {
6787	.design.design.fwinds.entries.dir config -text "$newval"
6788    } elseif { $type == "curwindforce" } {
6789	.design.design.fwinds.entries.force config -text "$newval"
6790    } elseif { $type == "curbrushradius" } {
6791	.design.dbuttons.brush config -text "$newval"
6792    }
6793}
6794
6795proc cycle_design_data { type dir } {
6796    # The brush size setter is not a selectable tool.
6797    if { $type != "brush" } {
6798	select_design_tool $type
6799    }
6800    if { $type == "terrain" } {
6801	dbg_set_design_data curttype $dir 0
6802    } elseif { $type == "unit" } {
6803	dbg_set_design_data curutype $dir 0
6804    } elseif { $type == "people" } {
6805	dbg_set_design_data curpeoplenumber $dir 0
6806    } elseif { $type == "control" } {
6807	dbg_set_design_data curcontrolnumber $dir 0
6808    } elseif { $type == "feature" } {
6809	dbg_set_design_data curfid $dir 0
6810    } elseif { $type == "brush" } {
6811	dbg_set_design_data curbrushradius $dir o
6812    }
6813}
6814
6815proc new_feature {} {
6816    set fid [ create_new_feature ]
6817    .design.design.ffeature.name.menu add command \
6818	    -label "[ feature_desc $fid ]" \
6819	    -command [ list dbg_set_design_data curfid $fid 0 ]
6820    dbg_set_design_data curfid $fid 0
6821}
6822
6823set dsave_done 0
6824
6825set dsave(name) "game-data"
6826
6827set dsave(all) 1
6828set dsave(types) 0
6829set dsave(tables) 0
6830set dsave(globals) 0
6831set dsave(scoring) 0
6832set dsave(world) 0
6833set dsave(area) 0
6834set dsave(terrain) 0
6835set dsave(areamisc) 0
6836set dsave(weather) 0
6837set dsave(material) 0
6838set dsave(sides) 0
6839set dsave(views) 0
6840set dsave(docts) 0
6841set dsave(players) 0
6842# set dsave(agreements) 0
6843set dsave(units) 0
6844set dsave(unitids) 0
6845set dsave(unitprops) 0
6846set dsave(unitactions) 0
6847set dsave(unitplans) 0
6848set dsave(history) 0
6849
6850proc popup_designer_save {} {
6851    global dsave dsave_done stdfont boldfont
6852    global bgcolor hbcolor abcolor scolor fgcolor afcolor
6853
6854    if { [ winfo exists .dsave ] } {
6855	# Kick the window manager awake.
6856	wm withdraw .dsave
6857	wm deiconify .dsave
6858	focus -force .dsave
6859	return
6860    }
6861
6862    # Create and then immediately withdraw the window
6863    # so that it does not bounce around later.
6864    toplevel .dsave -bg $bgcolor
6865    wm withdraw .dsave
6866    wm title .dsave "Xconq Designer Save"
6867
6868    set dsave_done 0
6869
6870    frame .dsave.top -bg $bgcolor
6871    pack .dsave.top -side top -anchor w -padx 8 -pady 12
6872
6873    label .dsave.top.modulelabel -text "Module Name : " -bg $bgcolor -fg $fgcolor -font $boldfont
6874    entry .dsave.top.modulename -relief sunken -width 20 -fg $fgcolor -font $stdfont
6875    .dsave.top.modulename insert end $dsave(name)
6876    pack .dsave.top.modulelabel .dsave.top.modulename -side left
6877
6878    frame .dsave.f1 -bg $bgcolor
6879    pack .dsave.f1 -side top -padx 8
6880
6881    checkbutton .dsave.f1.all -text " Save All" -variable dsave(all) \
6882	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6883	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6884	-activeforeground $afcolor
6885    grid .dsave.f1.all -sticky w -pady 4
6886
6887    checkbutton .dsave.f1.types -text " Types" -variable dsave(types) \
6888	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6889	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6890	-activeforeground $afcolor
6891    checkbutton .dsave.f1.tables -text " Tables" -variable dsave(tables) \
6892	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6893	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6894	-activeforeground $afcolor
6895    grid .dsave.f1.types .dsave.f1.tables -sticky w -pady 4
6896
6897    checkbutton .dsave.f1.globals -text " Globals" -variable dsave(globals) \
6898	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6899	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6900	-activeforeground $afcolor
6901    grid .dsave.f1.globals -sticky w -pady 4
6902
6903    checkbutton .dsave.f1.scoring -text " Scoring" -variable dsave(scoring) \
6904	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6905	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6906	-activeforeground $afcolor
6907    grid .dsave.f1.scoring -sticky w -pady 4
6908
6909    checkbutton .dsave.f1.world -text " World" -variable dsave(world) \
6910	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6911	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6912	-activeforeground $afcolor
6913    grid .dsave.f1.world -sticky w -pady 4
6914
6915    checkbutton .dsave.f1.area -text " Area" -variable dsave(area) \
6916	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6917	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6918	-activeforeground $afcolor
6919    checkbutton .dsave.f1.terrain -text " Terrain" -variable dsave(terrain) \
6920	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6921	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6922	-activeforeground $afcolor
6923    checkbutton .dsave.f1.areamisc -text " Misc" -variable dsave(areamisc) \
6924	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6925	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6926	-activeforeground $afcolor
6927    checkbutton .dsave.f1.weather -text " Weather" -variable dsave(weather) \
6928	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6929	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6930	-activeforeground $afcolor
6931    checkbutton .dsave.f1.material -text " Materials" \
6932	-variable dsave(material) \
6933	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6934	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6935	-activeforeground $afcolor
6936    grid .dsave.f1.area .dsave.f1.areamisc .dsave.f1.terrain \
6937	    .dsave.f1.weather .dsave.f1.material -sticky w -pady 4
6938
6939    checkbutton .dsave.f1.sides -text " Sides" -variable dsave(sides) \
6940	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6941	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6942	-activeforeground $afcolor
6943    checkbutton .dsave.f1.sideviews -text " Views" -variable dsave(views) \
6944	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6945	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6946	-activeforeground $afcolor
6947    checkbutton .dsave.f1.sidedocts -text " Doctrines" \
6948	-variable dsave(docts) \
6949	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6950	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6951	-activeforeground $afcolor
6952    grid .dsave.f1.sides .dsave.f1.sideviews .dsave.f1.sidedocts -sticky w \
6953	-pady 4
6954
6955    checkbutton .dsave.f1.players -text " Players" -variable dsave(players) \
6956	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6957	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6958	-activeforeground $afcolor
6959    grid .dsave.f1.players -sticky w -pady 4
6960
6961#    checkbutton .dsave.f1.agreements -text " Agreements" \
6962#	-variable dsave(agreements) \
6963#	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6964#	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6965#	-activeforeground $afcolor
6966#    grid .dsave.f1.agreements -sticky w -pady 4
6967
6968    checkbutton .dsave.f1.units -text " Units" -variable dsave(units) \
6969	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6970	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6971	-activeforeground $afcolor
6972    checkbutton .dsave.f1.unitids -text " IDs" -variable dsave(unitids) \
6973	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6974	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6975	-activeforeground $afcolor
6976    checkbutton .dsave.f1.unitprops -text " Props" \
6977	-variable dsave(unitprops) \
6978	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6979	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6980	-activeforeground $afcolor
6981    checkbutton .dsave.f1.unitactions -text " Actions" \
6982	-variable dsave(unitactions) \
6983	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6984	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6985	-activeforeground $afcolor
6986    checkbutton .dsave.f1.unitplans -text " Plans" \
6987	-variable dsave(unitplans) \
6988	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6989	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6990	-activeforeground $afcolor
6991    grid .dsave.f1.units .dsave.f1.unitids .dsave.f1.unitprops \
6992	.dsave.f1.unitactions .dsave.f1.unitplans -sticky w -pady 4
6993
6994    checkbutton .dsave.f1.history -text " History" -variable dsave(history) \
6995	-bg $bgcolor -highlightbackground $bgcolor -font $boldfont \
6996	-activebackground $abcolor -selectcolor $scolor -fg $fgcolor \
6997	-activeforeground $afcolor
6998    grid .dsave.f1.history -sticky w -pady 4
6999
7000    frame .dsave.bottom -bg $bgcolor
7001    pack .dsave.bottom -side bottom -anchor e -padx 20 -pady 4
7002
7003    button .dsave.bottom.save -text "Save" -width 8 \
7004	    -command { save_design } -default active \
7005	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
7006	-fg $fgcolor -activeforeground $afcolor -font $boldfont
7007    button .dsave.bottom.cancel -text "Cancel" -width 8 \
7008	    -command { set dsave_done 1 } \
7009	-bg $bgcolor -highlightbackground $hbcolor -activebackground $abcolor \
7010	-fg $fgcolor -activeforeground $afcolor -font $boldfont
7011    grid .dsave.bottom.cancel .dsave.bottom.save -sticky ew -padx 6 -pady 4
7012
7013    center_above_curmap .dsave
7014    focus .dsave
7015    tkwait visibility .dsave
7016    grab .dsave
7017    tkwait variable dsave_done
7018    grab release .dsave
7019    destroy .dsave
7020}
7021
7022proc save_design {} {
7023    global dsave dsave_done
7024
7025    set args ""
7026    if { $dsave(all) } { set args " all $args" }
7027    if { $dsave(types) } { set args " types $args" }
7028    if { $dsave(tables) } { set args " tables $args" }
7029    if { $dsave(globals) } { set args " globals $args" }
7030    if { $dsave(scoring) } { set args " scoring $args" }
7031    if { $dsave(world) } { set args " world $args" }
7032    if { $dsave(area) } { set args " area $args" }
7033    if { $dsave(areamisc) } { set args " areamisc $args" }
7034    if { $dsave(terrain) } { set args " terrain $args" }
7035    if { $dsave(weather) } { set args " weather $args" }
7036    if { $dsave(material) } { set args " material $args" }
7037    if { $dsave(sides) } { set args " sides $args" }
7038    if { $dsave(views) } { set args " views $args" }
7039    if { $dsave(docts) } { set args " docts $args" }
7040    if { $dsave(players) } { set args " players $args" }
7041#    if { $dsave(agreements) } { set args " agreements $args" }
7042    if { $dsave(units) } { set args " units $args" }
7043    if { $dsave(unitids) } { set args " unitids $args" }
7044    if { $dsave(unitprops) } { set args " unitprops $args" }
7045    if { $dsave(unitactions) } { set args " unitactions $args" }
7046    if { $dsave(unitplans) } { set args " unitplans $args" }
7047    if { $dsave(history) } { set args " history $args" }
7048    set dsave(name) "[.dsave.top.modulename get ]"
7049    set dname [ game_homedir ]
7050    set filename [ tk_getSaveFile -initialfile $dsave(name).g -initialdir $dname ]
7051    if { "$filename" != "" } {
7052	designer_save $dsave(name) $filename $args
7053    }
7054    set dsave_done 1
7055}
7056
7057proc create_left_right_panes { win leftratio } {
7058    global bgcolor
7059
7060    frame $win.leftside -borderwidth 2 -relief sunken -bg $bgcolor
7061    place $win.leftside -in $win -relx 0 -rely 1.0 \
7062	    -relwidth $leftratio -relheight 1 -anchor sw
7063
7064    set rightratio [ expr 1.0 - $leftratio ]
7065
7066    frame $win.rightside -borderwidth 2 -relief sunken -bg $bgcolor
7067    place $win.rightside -in $win -relx 1.0 -rely 1.0 \
7068	    -relwidth $rightratio -relheight 1 -anchor se
7069
7070    frame $win.grip -width 9 -height 9 -borderwidth 2 -relief raised -bg $bgcolor
7071    place $win.grip -relx $leftratio -rely 0.95 -anchor c
7072
7073    bind $win.grip <ButtonPress-1>	"lr_panedwindow_grab $win"
7074    bind $win.grip <B1-Motion>		"lr_panedwindow_drag $win %X"
7075    bind $win.grip <ButtonRelease-1>	"lr_panedwindow_drop $win %X"
7076}
7077
7078proc lr_panedwindow_grab { win } {
7079    $win.grip config -relief sunken
7080}
7081
7082proc lr_panedwindow_drag { win x } {
7083    set realx [ expr $x - [ winfo rootx $win ] ]
7084    set xmax [ winfo width $win ]
7085    set frac [ expr double($realx) / $xmax ]
7086    if { $frac < 0.05 } {
7087	set frac 0.05
7088    }
7089    if { $frac > 0.95 } {
7090	set frac 0.95
7091    }
7092    place $win.grip -relx $frac
7093    return $frac
7094}
7095
7096proc lr_panedwindow_drop { win x } {
7097    set frac [ lr_panedwindow_drag $win $x ]
7098    place $win.leftside -relwidth $frac
7099    place $win.rightside -relwidth [ expr 1.0 - $frac ]
7100    place $win.grip -relx $frac
7101    $win.grip config -relief raised
7102}
7103
7104proc create_top_bottom_panes { win topratio } {
7105    global bgcolor
7106
7107    frame $win.topside -borderwidth 1 -relief sunken -bg $bgcolor
7108    place $win.topside -in $win -relx 0 -rely 0 \
7109	    -relwidth 1 -relheight $topratio -anchor nw
7110
7111    set bottomratio [ expr 1.0 - $topratio ]
7112
7113    frame $win.botside -borderwidth 1 -relief sunken -bg $bgcolor
7114    place $win.botside -in $win -relx 0 -rely 1.0 \
7115	    -relwidth 1 -relheight $bottomratio -anchor sw
7116
7117    frame $win.grip -width 9 -height 9 -borderwidth 2 -relief raised -bg $bgcolor
7118    place $win.grip -relx 0.95 -rely $topratio -anchor c
7119
7120    bind $win.grip <ButtonPress-1>	"tb_panedwindow_grab $win"
7121    bind $win.grip <B1-Motion>		"tb_panedwindow_drag $win %Y"
7122    bind $win.grip <ButtonRelease-1>	"tb_panedwindow_drop $win %Y"
7123}
7124
7125proc tb_panedwindow_grab { win } {
7126    $win.grip config -relief sunken
7127}
7128
7129proc tb_panedwindow_drag { win y } {
7130    set realy [ expr $y - [ winfo rooty $win ] ]
7131    set ymax [ winfo height $win ]
7132    set frac [ expr double($realy) / $ymax ]
7133    if { $frac < 0.05 } {
7134	set frac 0.05
7135    }
7136    if { $frac > 0.95 } {
7137	set frac 0.95
7138    }
7139    place $win.grip -rely $frac
7140    return $frac
7141}
7142
7143proc tb_panedwindow_drop { win y } {
7144    set frac [ tb_panedwindow_drag $win $y ]
7145    place $win.topside -relheight $frac
7146    place $win.botside -relheight [ expr 1.0 - $frac ]
7147    place $win.grip -rely $frac
7148    $win.grip config -relief raised
7149}
7150
7151proc fit_map { wid } {
7152    for { set i 6 } { $i >= 0 } { incr i -1 } {
7153	set siz [ map_size_at_power $i ]
7154	if { [ lindex $siz 0 ] <= $wid } {
7155	    return $i
7156	}
7157    }
7158    return 0
7159}
7160
7161proc resize_world_map { worldf val w h } {
7162    global last_world_width last_world_power
7163
7164    if { $val == 613 } {
7165	if { $last_world_width != $w } {
7166	    set newpow [ fit_map $w ]
7167	    if { $newpow != $last_world_power } {
7168		$worldf.world config -power $newpow
7169		set last_world_width $w
7170		set last_world_power $newpow
7171	    }
7172	}
7173    }
7174}
7175
7176# If the unit info box has changed size, adjust the position of the
7177# second column of info so that it is always in the middle.
7178
7179proc resize_unit_info { unitinfo val w h } {
7180    set oldcol2 [ lindex [ $unitinfo coords hp ] 0 ]
7181    set newcol2 [ expr $w / 2 ]
7182    $unitinfo move col2 [ expr $newcol2 - $oldcol2 ] 0
7183}
7184
7185proc find_image_filename { name } {
7186    global pathlist
7187
7188    foreach path $pathlist {
7189	set filename [ file join $path $name ]
7190	if { "[ file exists $filename ]" } {
7191	    return $filename
7192	}
7193    }
7194    # Fallback - look for sibling images dir next to each library path.
7195    foreach path $pathlist {
7196	set filename [ file join [ file dirname $path ] "images" $name ]
7197	if { "[ file exists $filename ]" } {
7198	    return $filename
7199	}
7200    }
7201    return ""
7202}
7203
7204# This procedure will center win above the current map 2/5 from the top.
7205# The window should be withdrawn before calling the procedure to prevent
7206# it from bouncing around when the geometry is updated.
7207
7208proc center_above_curmap { win } {
7209    global tcl_platform
7210
7211    # This code doesn't work under Windows. Should figure out why.
7212    if { "$tcl_platform(platform)" != "windows" } {
7213	set num [ curmap_number ]
7214    	set map .m$num
7215    } else {
7216	set map .m1
7217    }
7218    # Update window size before recentering while still invisible.
7219    update idletasks
7220    # Center win above the current map.
7221    set x [ expr { [ winfo x $map ] + [ winfo width $map ] / 2 - [ winfo reqwidth $win ] / 2 } ]
7222    set y [ expr { [ winfo y $map ] + [ winfo height $map ] * 2 / 5 - [ winfo reqheight $win ] * 2 / 5 } ]
7223    wm geometry $win "+$x+$y"
7224    # Finally make the window visible in its new position.
7225    wm deiconify $win
7226    focus -force $win
7227    update idletasks
7228}
7229
7230proc center_on_screen { win } {
7231
7232    # Update window size before recentering while still invisible.
7233    update idletasks
7234    # Center win on the main screen.
7235    set x [ expr { [ winfo screenwidth . ] / 2 - [ winfo reqwidth $win ] / 2 } ]
7236    set y [ expr { [ winfo screenheight . ] * 2 / 5 - [ winfo reqheight $win ] * 2 / 5 } ]
7237    wm geometry $win "+$x+$y"
7238    # Finally make the window visible in its new position.
7239    wm deiconify $win
7240    focus -force $win
7241    update idletasks
7242}
7243
7244proc bring_to_front { win } {
7245
7246    set frontwin [ focus ]
7247    # If there is no focus just focus $win.
7248    if { $frontwin == "" } {
7249	focus -force $win
7250         update idletasks
7251	return
7252    }
7253    # Kick the window manager awake and focus $win if another focus exists.
7254    if { $frontwin != $win } {
7255	wm withdraw $win
7256	wm deiconify $win
7257	focus -force $win
7258         update idletasks
7259    }
7260}
7261
7262