#!/usr/bin/wish4.0
# Copyright (C) 1995 John Williams
# Distributed with ABSOLUTELY NO WARRANTY (GNU General Public Licence)

# If you like it, send the author email and tell him so.
# Suggestions for improving the interface are especially welcome.
# John Williams <williams@cs.weber.edu>

# *** IMPORTANT *** IMPORTANT *** IMPORTANT ***
# change the following line to the directory where tkAtaxx is installed

set ATAXXDIR "."
#set ATAXXDIR "/usr/local/lib/tkataxx"

#TODO
# dialog to display winner
# option for larger icons

###################################
# ataxx_load_bitmaps
#	ARG size: appended to bitmap name to allow for different sizes
proc ataxx_load_bitmaps {size} {
	global ATAXXDIR
	image create bitmap IBLUE -file $ATAXXDIR/circle$size.xbm
	IBLUE configure -foreground blue

	image create bitmap IRED -file $ATAXXDIR/circle$size.xbm
	IRED configure -foreground red

	image create bitmap IBLANK -file $ATAXXDIR/blank$size.xbm

	image create bitmap IBLOCK -file $ATAXXDIR/block$size.xbm
}


###################################
# ataxx_setup
#	create main board and side-frames
proc ataxx_setup {} {
	global who

	wm title . "tkATAXX v1.0"

# setup board
	ataxx_load_bitmaps 16

	frame .b
	for {set x 0} {$x < 7} {incr x} {
		frame .b.x$x
		for {set y 0} {$y < 7} {incr y} {
			label .b.x$x.y$y -relief sunken -image IBLANK
			bindtags .b.x$x.y$y [concat [bindtags .b.x$x.y$y] .b]
		}
	}
	pack .b -side left
	pack .b.x0 .b.x1 .b.x2 .b.x3 .b.x4 .b.x5 .b.x6 -side left
	for {set x 0} {$x < 7} {incr x} {
		pack .b.x$x.y0 .b.x$x.y1 .b.x$x.y2 .b.x$x.y3 .b.x$x.y4 .b.x$x.y5 .b.x$x.y6 \
			-side top
	}

	frame .blue
	frame .blue.stat -borderwidth 2 -relief sunken
	label .blue.stat.i -image IBLUE
	label .blue.stat.c -textvariable n1 -width 3
	frame .red
	frame .red.stat -borderwidth 2 -relief sunken
	label .red.stat.i -image IRED
	label .red.stat.c -textvariable n2 -width 3
	pack .blue -before .b -side left -fill y
	pack .red -after .b -side right -fill y
	pack .blue.stat -side left -padx 5
	pack .red.stat -side right -padx 5
	pack .blue.stat.i .blue.stat.c -side top
	pack .red.stat.i .red.stat.c -side top

	wm resizable . 0 0

# bind events
	bind .b <Button-1> {ataxx_click %W}
	trace variable who w ataxx_indicatewho
}


###################################
# ataxx_indicatewho
#	changes the color of the side-frames to indicate whose turn it is
#	called when the variable who changes
proc ataxx_indicatewho {var1 var2 op} {
	global who state
	set color [$who cget -foreground]
	if {$state == "over" || $state == "layout"} {set color [.b cget -background]}
	.blue configure -background $color
	.red configure -background $color
}	


###################################
# random
#	a random number generator from the tcl faq
proc random {args} {
	global RNG_seed
	set max 259200
	set argcnt [llength $args]
	if {$argcnt < 1 || $argcnt > 2} {
		error "wrong # args: random limit | seed ?seedval?"
	}
	if {![string compare [lindex $args 0] seed]} {
		if {$argcnt == 2} {
			set RNG_seed [lindex $args 1]
		} else {
			set RNG_seed [expr ([pid] + [file atime /dev/kmem]) % $max]
		}
		return
	}
	if {![info exists RNG_seed]} {
		set RNG_seed [expr ([pid] + [file atime /dev/kmem]) % $max]
	}
	set RNG_seed [expr ($RNG_seed * 7141 + 54773) % $max]
	return [expr int([lindex $args 0] * ($RNG_seed / double($max)))]
}


###################################
# ataxx_save_blocks
#	save the current positions of any blocks
#	RETURN:  a list of windows
proc ataxx_save_blocks {} {
	set blocklist {BLOCK}
	for {set x 0} {$x < 7} {incr x} {
		for {set y 0} {$y < 7} {incr y} {
			if {[.b.x$x.y$y cget -image] == "IBLOCK"} {
				lappend blocklist .b.x$x.y$y
			}
		}
	}
	if {$blocklist == {BLOCK}} {set blocklist {}}
	return $blocklist
}


###################################
# ataxx_set_blocks
#	place blocks on the board
#	ARG blocklist: a list of block positions used if $block_style==current
proc ataxx_set_blocks {blocklist} {
	global block_style
	if {$block_style == "none"} {return}
	if {$block_style == "current"} {
		foreach w $blocklist {
			if {$w != "BLOCK"} {
				$w configure -image IBLOCK -relief flat
			}
		}
	}
	if {$block_style == "random"} {
# need to figure out how to do a random function
		set n [expr [random 4] + 1]
		while {$n} {
			incr n -1
			set x [random 6]
			set y [random 6]
			.b.x$x.y$y configure -image IBLOCK -relief flat
			.b.x[expr 6 - $x].y$y configure -image IBLOCK -relief flat
			.b.x$x.y[expr 6 - $y] configure -image IBLOCK -relief flat
			.b.x[expr 6 - $x].y[expr 6 - $y] configure -image IBLOCK -relief flat
		}
	}
}


###################################
# ataxx_new
#	set the board up in the initial position
#	ARG confirm: whether to dialog the user before erasing a game in progress
proc ataxx_new { {confirm 1} } {
	global state who hist inhist
	if {$confirm && $state != "over" && $hist != ""} {
		set yn [tk_dialog .confirm NEW "There is a game in progress. \
     Are you sure?" "" 0 Yes No]
		if {$yn != 0} {return}
	}
	set blocklist [ataxx_save_blocks]
# initial configuration
	for {set x 0} {$x < 7} {incr x} {
		for {set y 0} {$y < 7} {incr y} {
			.b.x$x.y$y configure -image IBLANK -relief sunken
		}
	}
# if blocks are selected, set them up here
	ataxx_set_blocks $blocklist
	.b.x0.y0 configure -image IBLUE -relief sunken
	.b.x6.y6 configure -image IBLUE -relief sunken
	.b.x0.y6 configure -image IRED -relief sunken
	.b.x6.y0 configure -image IRED -relief sunken
	set state pick
	.b configure -cursor arrow
	set who IBLUE
	set hist {}
	set inhist end
	ataxx_image
	ataxx_menu_update
}


###################################
# ataxx_computer
#	start the computer player in the background
proc ataxx_computer {} {
	global who board player thinking state ATAXXDIR
	if {$player($who) != 0 && $state!="over"} {
		set state think
#		tk_dialog .showmove MOVE "ctaxx -d$player($who) $board" "" 0 OK
		set thinking [open "| $ATAXXDIR/ctaxx -d$player($who) $board"]
		after 1000 {fileevent $thinking readable {ataxx_comp_move $thinking}}
	}
}


###################################
# ataxx_comp_move
#	called by fileevent when the computer is done thinking
#	ARG fid: file id to read move from
proc ataxx_comp_move {fid} {
	global state move
	set fx 0
	set fy 0
	set tx 0
	set ty 0
	set dash "-"
	set move [read -nonewline $fid]
	close $fid
	set state pick
	if {$move=="pass" || $move==""} {
		ataxx_pass
		ataxx_menu_update
		return
	}
#	tk_dialog .showmove MOVE "$move" "" 0 OK
	scan $move "%c%c-%c%c" fx fy tx ty
	incr fx -97
	incr tx -97
	incr fy -49
	incr ty -49
#	tk_dialog .showmove MOVE [format "%s %d%d-%d%d" $move $fx $fy $tx $ty] "" 0 OK	
	if {[ataxx_move .b.x$fx.y$fy .b.x$tx.y$ty]==0} {
		ataxx_image
		ataxx_computer
		ataxx_menu_update
	}
}


###################################
# ataxx_move
#	verify legality of move and do it
#	ARGS from, to: widgets name of the from and to spaces
#	RETURN: 1 if the move in illegal
proc ataxx_move {from to} {
	global who hist inhist
# check for valid move
	if {[$from cget -image] != $who} {return -code return 1}
	if {[$to cget -image] != "IBLANK"} {return -code return 1}
	set x1 [string index $to 4]
	set y1 [string index $to 7]
	set x2 [string index $from 4]
	set y2 [string index $from 7]
	set dx [expr abs($x1 - $x2)]
	set dy [expr abs($y1 - $y2)]
	set dist $dx
	if {$dy > $dist} {set dist $dy}
	if {$dist > 2} {return -code return 1}
# configure spaces
	if {$who == "IBLUE"} { set notwho IRED } else { set notwho IBLUE }
	if {$dist == 2} {$from configure -image IBLANK}
	$to configure -image $who
	set bx $x1
	set ex $x1
	set by $y1
	set ey $y1
	if {$x1 > 0} {incr bx -1}
	if {$x1 < 6} {incr ex}
	if {$y1 > 0} {incr by -1}
	if {$y1 < 6} {incr ey}
	set changed ""
	for {set x $bx} {$x <= $ex} {incr x} {
		for {set y $by} {$y <= $ey} {incr y} {
			if {[.b.x$x.y$y cget -image] == $notwho} {
				.b.x$x.y$y configure -image $who 
				lappend changed .b.x$x.y$y
			}
		}
	}
# do history stuff
	if {$inhist != "end"} {
		set hist [lrange $hist 0 [expr $inhist - 1]]
		set inhist end
	}
	lappend hist "$from $to [list $changed]"
# change who
	set who $notwho
	return 0
}


###################################
# ataxx_pass
#	pass instead of moving a piece
proc ataxx_pass {} {
	global state who hist inhist
	set state pick
	.b configure -cursor arrow
# do history stuff
	if {$inhist != "end"} {
		set hist [lrange $hist 0 [expr $inhist - 1]]
		set inhist end
	}
	lappend hist "pass"
	if {$who == "IBLUE"} { set notwho IRED } else { set notwho IBLUE }
	set who $notwho
	ataxx_image
	ataxx_computer
}


###################################
# ataxx_pick
#	user clicked on source space
#	ARG w: widget name of the space clicked
proc ataxx_pick {w} {
	global who pick_space state bl i1 i2
	set color [$w cget -image]
	if {$color != $who} {return}
	# mark the space
	set pick_space $w
	set state place
	.b configure -cursor target
}


###################################
# ataxx_place
#	user clicked on destination space
#	ARG w: widget name of the space clicked
proc ataxx_place {w} {
	global who pick_space state bl i1 i2 hist inhist
	set state pick
	.b configure -cursor arrow
	# unmark pick_space
	if {[$w cget -image] != "IBLANK"} {return}
	set x1 [string index $w 4]
	set y1 [string index $w 7]
	set x2 [string index $pick_space 4]
	set y2 [string index $pick_space 7]
	set dx [expr abs($x1 - $x2)]
	set dy [expr abs($y1 - $y2)]
	set dist $dx
	if {$dy > $dist} {set dist $dy}
	if {$dist > 2} {return}
# valid move
	ataxx_move $pick_space $w
# check for end of game
	ataxx_image
	ataxx_computer
	ataxx_menu_update
}


###################################
# ataxx_click
#	handle mouse click event
#	ARG w: widget name of the space clicked
proc ataxx_click {w} {
	global who pick_space state bl i1 i2
	switch $state {
	pick {
		ataxx_pick $w
	     }
	place {
		ataxx_place $w
 	      }
	over {}
	layout {}
	}
}


###################################
# ataxx_image
#	take a snapshot of the board
#	update piece counts and check for game over
proc ataxx_image {} {
	global board n1 n2 nb state who
	set n1 0
	set n2 0
	set nb 0
	set board ""
	for {set y 0} {$y < 7} {incr y} {
		for {set x 0} {$x < 7} {incr x} {
			switch [.b.x$x.y$y cget -image] {
			IBLUE {set s "1" ; incr n1}
			IRED {set s "2" ; incr n2}
			IBLANK {set s "." ; incr nb}
			IBLOCK {set s "#"}
			default {puts  [.b.x$x.y$y cget -image]}
			}
			append board $s
		}
	}
	if {$who == "IBLUE"} {
		append board "1"
	} else {
		append board "2"
	}
	if {$nb == 0 || $n1 == 0 || $n2 == 0} {
		set state over
		ataxx_indicatewho 1 2 3	
	}
}


###################################
# ataxx_undo
#	undo a history move
proc ataxx_undo {} {
	global hist inhist who state
	if {$inhist == "end"} {
		set inhist [llength $hist]
	}
	incr inhist -1
	if {$inhist < 0} {return}
	if {$who == "IBLUE"} { set notwho IRED } else { set notwho IBLUE }
	set move [lindex $hist $inhist]
	if {$move != "pass"} {
		[lindex $move 0] configure -image $notwho
		[lindex $move 1] configure -image IBLANK
		set changed [lindex $move 2]
		foreach i $changed {
			$i configure -image $who
		}
	}
	set state pick
	set who $notwho
	.b configure -cursor arrow
	ataxx_image
	ataxx_menu_update
}


###################################
# ataxx_redo
#	redo a history move
proc ataxx_redo {} {
	global hist inhist who state
	if {$inhist == "end"} {return}
	if {$who == "IBLUE"} { set notwho IRED } else { set notwho IBLUE }
	set move [lindex $hist $inhist]
	incr inhist
	if {$inhist >= [llength $hist]} {
		set inhist end
	}
	if {$move != "pass"} {
		set x1 [string index [lindex $move 0] 4]
		set y1 [string index [lindex $move 0] 7]
		set x2 [string index [lindex $move 1] 4]
		set y2 [string index [lindex $move 1] 7]
		set dx [expr abs($x1 - $x2)]
		set dy [expr abs($y1 - $y2)]
		set dist $dx
		if {$dy > $dist} {set dist $dy}
		if {$dist == 2} {
			[lindex $move 0] configure -image IBLANK
		}
		[lindex $move 1] configure -image $who
		set changed [lindex $move 2]
		foreach i $changed {
			$i configure -image $who
		}
	}
	set state pick
	set who $notwho
	.b configure -cursor arrow
	ataxx_image
	ataxx_menu_update
}									 
				     

###################################
# ataxx_layout
#	called when clicking on board in layout mode
#	ARG w: widget name clicked
#	ARG b: button number
proc ataxx_layout {w b} {
# need a way to configure a BLOCK
#    control-click, or middle toggles between blank/block
	switch $b {
	1 {$w configure -image IBLUE}
	3 {$w configure -image IRED}
	2 {
		if {[$w cget -image] == "IBLANK"} {
			$w configure -image IBLOCK -relief flat
		} else {
			$w configure -image IBLANK -relief sunken
		}
	  }
	}    
	ataxx_image
}


###################################
# ataxx_layout_state
#	called from layout menu item
#	toggle between layout mode and playing mode
proc ataxx_layout_state {} {
	global state
	if {$state != "layout"} {  
		bind .b <ButtonPress> {ataxx_layout %W %b}
		bind .b <Button-1> {}
		set state layout	
		ataxx_indicatewho 1 2 3
		ataxx_menu_update 1 2 3
		.m.game.m entryconfigure 2 -label "Play Game"
	} else {		
		bind .b <Button-1> {ataxx_click %W} 
		bind .b <ButtonPress> {}
		set state pick
		ataxx_image
		ataxx_indicatewho 1 2 3
		ataxx_menu_update 1 2 3
		.m.game.m entryconfigure 2 -label "Layout"
	}		   
}



###################################
# ataxx_setup_menu
# 	setup the MENU BAR
# 	Game: new, quit, configure
# 	Edit: undo,redo, pass, edit board, history window
# 	player 1, player 2
# 	block: random, none, or current
# 	help
proc ataxx_setup_menu {} {
	global player block_style

	frame .m
	pack .m -side top -before [lindex [pack slaves .] 0] -fill x
	menubutton .m.game -text Game -menu .m.game.m
	menubutton .m.edit -text Edit -menu .m.edit.m
	menubutton .m.blue -image IBLUE -menu .m.blue.m
	menubutton .m.red -image IRED -menu .m.red.m
	menubutton .m.block -image IBLOCK -menu .m.block.m
	menubutton .m.help -text Help -menu .m.help.m
	pack .m.game .m.edit .m.blue .m.red .m.block -side left
	pack .m.help -side right

	menu .m.game.m -tearoff 0
	.m.game.m add command -label New -command {ataxx_new}
	.m.game.m add separator
	.m.game.m add command -label Layout -command {ataxx_layout_state}
	.m.game.m add command -label History -command {ataxx_history_window}
#	.m.game.m add command -label Size -state disabled
	.m.game.m add separator
	.m.game.m add command -label Quit -command {destroy .}

	menu .m.edit.m -tearoff 0
	.m.edit.m add command -label Undo -command {ataxx_undo}
	.m.edit.m add command -label Redo -command {ataxx_redo}
	.m.edit.m add separator
	.m.edit.m add command -label Pass -command {ataxx_pass}
	
	menu .m.blue.m -tearoff 0
	.m.blue.m add radiobutton -label Human -variable player(IBLUE) -value 0
	.m.blue.m add separator
	.m.blue.m add radiobutton -label 1 -variable player(IBLUE) -value 1
	.m.blue.m add radiobutton -label 2 -variable player(IBLUE) -value 2
	.m.blue.m add radiobutton -label 3 -variable player(IBLUE) -value 3
	.m.blue.m add radiobutton -label 4 -variable player(IBLUE) -value 4
	.m.blue.m add radiobutton -label 5 -variable player(IBLUE) -value 5
	set player(IBLUE) 0
	
	menu .m.red.m -tearoff 0
	.m.red.m add radiobutton -label Human -variable player(IRED) -value 0
	.m.red.m add separator
	.m.red.m add radiobutton -label 1 -variable player(IRED) -value 1
	.m.red.m add radiobutton -label 2 -variable player(IRED) -value 2
	.m.red.m add radiobutton -label 3 -variable player(IRED) -value 3
	.m.red.m add radiobutton -label 4 -variable player(IRED) -value 4
	.m.red.m add radiobutton -label 5 -variable player(IRED) -value 5
	set player(IRED) 0
	trace variable player w ataxx_menu_update

	menu .m.block.m -tearoff 0
	.m.block.m add radiobutton -label None -variable block_style -value none
	.m.block.m add radiobutton -label Same -variable block_style -value current
	.m.block.m add radiobutton -label Random -variable block_style -value random
	set block_style none

	menu .m.help.m -tearoff 0
	.m.help.m add command -label Rules -command {ataxx_help_window ataxx.txt}
	.m.help.m add command -label Usage -command {ataxx_help_window usage.txt}
}


###################################
# ataxx_help_window
#	called from help rules menu item
#	create help viewing window and load the rules file into it.
#	ARG file: help file to display
proc ataxx_help_window {file} {
	global ATAXXDIR
	if {! [winfo exists .help]} {
		toplevel .help
		wm title .help "tkATAXX Help"

		text .help.t -height 20 -width 40 -wrap word
		scrollbar .help.s -orient vertical
		.help.t configure -yscrollcommand ".help.s set"
		.help.s configure -command ".help.t yview"
	
		pack .help.t -side left -fill both -expand 1
		pack .help.s -side right -fill y -before .help.t
	}

#TODO make sure it is displayed, and bring to front
	.help.t configure -state normal
	set helpfile [open $ATAXXDIR/$file r]
	set helptext [read $helpfile]
	close $helpfile
	.help.t delete 1.0 end
	.help.t insert end $helptext
	.help.t configure -state disabled
}


###################################
# ataxx_menu_update
#	update the state of the menu options Undo, Redo, and Pass
#	called manually and when the player array changes
#	ARGS a1,a2,a3 are needed for the trace command
proc ataxx_menu_update { {a1 ""} {a2 ""} {a3 ""} } {
	global state who hist inhist thinking player
	# undo
	if {$inhist==0 || $hist=={} || $state=="layout"} {
		.m.edit.m entryconfigure 0 -state disabled
	} else {
		.m.edit.m entryconfigure 0 -state normal
	}
	# redo
	if {$inhist=="end" || $hist=={} || $state=="layout"} {
		.m.edit.m entryconfigure 1 -state disabled
	} else {
		.m.edit.m entryconfigure 1 -state normal
	}
	# pass
	if {$player($who)!=0 && $state!="think" && $state!="over"} {
		.m.edit.m entryconfigure 3 -label Go -state normal -command {ataxx_computer}
	} else {
		.m.edit.m entryconfigure 3 -label Pass -command {ataxx_pass}
		if {$player($who)==0 && $state!="over" && $state!="layout"} {
			.m.edit.m entryconfigure 3 -state normal
		} else {
			.m.edit.m entryconfigure 3 -state disabled
		}
	}
}


###################################
# History Window routines
###################################

# this is supposed to determine the width of a character
proc tkTextAveWidth {w} {
  set ndx [$w index "@0,0 linestart"]
  $w see $ndx
  $w insert $ndx n
  set width [lindex [$w bbox $ndx] 2]
  $w delete $ndx
  return $width
}


###################################
# ataxx_history_window
#	create the history window, load/save buttons, and bindings
#	called from the History menu item
proc ataxx_history_window {} {
	global hist filename
	if {[winfo exists .h]} {return}
	toplevel .h
	wm title .h "tkATAXX Move History"
	text .h.t -height 20 -width 30 -tabs "50 150" \
		-wrap none -state disabled -setgrid 1
	scrollbar .h.s -orient vertical
	.h.t configure -yscrollcommand ".h.s set"
	.h.s configure -command ".h.t yview"
	pack .h.s -side right -fill y   
	pack .h.t -side right -fill both -expand 1		   

	frame .h.file
	button .h.file.load -text Load -command ataxx_history_load
	button .h.file.save -text Save -command ataxx_history_save
	entry .h.file.name -textvariable filename
	pack .h.file -side top -before .h.s
	pack .h.file.load .h.file.save .h.file.name -side left

# set tabs based on character width
# STILL NOT WORKING
#	wm deiconify .h
#	.h.t configure -state normal
#	set cw [tkTextAveWidth .h.t]
#	.h.t configure -tabs "[expr $cw * 5] [expr $cw * 20]"
#	.h.t configure -state disabled

	trace variable hist w ataxx_update_history_window
	ataxx_update_history_window
}	
	

###################################
# ataxx_history_save
#	save the game history to a file
# need to save blocks, if any
proc ataxx_history_save {} {
	global filename hist
	set filename [string trim $filename]
	if {$filename == "" || [string first " " $filename] >= 0} {
		set filename "? ? ?"
		return
	}
	if {[file exists $filename]} {
# verify overwrite
	}
	set blocks [ataxx_save_blocks]
	set fp 0
	set fp [open $filename w]
	if {$fp == "0"} {
		return
	}
	if {$blocks != {}} {puts $fp $blocks}
	puts $fp $hist
	close $fp
}


###################################
# ataxx_history_load
#	load the game history from a file
#	call ataxx_new & ataxx_redo to recreate the final position
# need to load blocks, if any
proc ataxx_history_load {} {
	global filename hist inhist
	set filename [string trim $filename]
	if {$filename == "" || [string first " " $filename] >= 0} {
		set filename "? ? ?"
		return
	}
	if {[file exists $filename] == 0} {
		return
	}
	ataxx_new
	set blocks [lindex $hist 0]
	if {[lindex $blocks 0] == "BLOCK"} {
		set hist [lrange $hist 1 end]
		ataxx_set_blocks $blocks
	}
	if {$hist != ""} {return}
	set fp 0
	set fp [open $filename r]
	if {$fp == "0"} {
		return
	}
	set hist [read $fp]
	close $fp
# do all the moves loaded	
	set inhist 0
	while {$inhist != "end"} {
		ataxx_redo
	}
}	


###################################
# ataxx_disp_move
#	ARG move: list of from and to widget spaces, usually from history
#	RETURNS:  human readable move
proc ataxx_disp_move {move} {
	set fr [lindex $move 0]
	if {$move == "pass"} { return $move }
	set to [lindex $move 1]
	scan $fr ".b.x%d.y%d" fx fy
	scan $to ".b.x%d.y%d" tx ty
	set dispfr "[format %c [expr $fx + 97]][expr $fy + 1]"
	set dispto "[format %c [expr $tx + 97]][expr $ty + 1]"
	set disp "$dispfr - $dispto"
	return $disp
}


###################################
# ataxx_update_history_window
#	update the history displayed in the history window
#	called when hist changes (but not when inhist changes)
proc ataxx_update_history_window { {a1 ""} {a2 ""} {a3 ""} } {
	global hist inhist	       
	if {[winfo exists .h] == 0} {
		trace vdelete hist w ataxx_update_history_window
		return
	}							      
	.h.t configure -state normal
	.h.t delete 1.0 end
	set lend [llength $hist]
#	if {$inhist != "end" && $inhist < $lend} {
#		set lend $inhist
#	}
	if {$lend == 0} {return}
	for {set ln 0} {$ln < $lend} {} {
		.h.t insert end "[expr $ln + 1].\t"
		set disp [ataxx_disp_move [lindex $hist $ln]]
		.h.t insert end "${disp}\t"
		incr ln
		if {$ln < $lend} {
			set disp [ataxx_disp_move [lindex $hist $ln]]
			.h.t insert end "${disp}\n"
		}
		incr ln
	}			    
	.h.t configure -state disabled
	.h.t yview end
}


###################################
# startup code
ataxx_setup
ataxx_setup_menu
ataxx_new 0


