# init-startup.tcl --
#
#	This is the first file sourced during program initialization. It is 
#	sourced before init_angband() is called.
#

# Global program name
set Angband(name) ZAngbandTk

# Global version string
set Angband(vers) [angband game version]r1

# Angband's directory
set Angband(dir) [angband game directory ANGBAND_DIR_ROOT]

# The tk directory
set Angband(dirTK) [angband game directory ANGBAND_DIR_TK]

# Program initialized
set Angband(init) 0

# Packages
lappend auto_path [file join $Angband(dirTK) library]
package require Cxrlwin

# Development debug support
set path [file join $Angband(dirTK) errorInfo.tcl]
if {[file exists $path]} {

	set DEBUG 1

	debughook bindings no
	debughook commands no
	debughook widgets no

	package require dbwin 1.0

	source [file join $Angband(dirTK) errorInfo.tcl]
	tracesetup

	InitCommandWindow

	proc ASSERT {condition message} {
		if {![expr $condition]} {
			error $message
		}
	}
	
} else {

	set DEBUG 0
	proc dbwin string {}
	proc Debug string {}
	proc ASSERT {condition message} {}
}

# Global --
#
#	Query and modify info.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Global {info args} {

	global Global

	# Set info
	if {[llength $args]} {
		switch -- $info {
			default {
				set Global($info) [lindex $args 0]
			}
		}

	# Get info
	} else {
		switch -- $info {
			default {
				return $Global($info)
			}
		}
	}
}

# AboutApplication --
#
#	Display program information.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc AboutApplication {} {

	global Angband

	tk_messageBox -title About \
		-message "$Angband(name) $Angband(vers)\nby Tim Baker and\
			others\nContact: dbaker@direct.ca"
}

# OpenGame --
#
#	Choose a savefile and play a game.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc OpenGame {} {

	global Angband

if 1 {

	# Hack -- Update the button
	update

	uplevel #0 source [file join $Angband(dirTK) choose-game.tcl]
	NSChooseGame::InitModule
} else {
	set types {
		{{Save Files} "" SAVE}
	}
	set fileName [tk_getOpenFile -filetypes $types -parent . \
		-initialdir [file join $Angband(dir) lib save]]
	if {[string length $fileName]} {
		uplevel #0 angband game open \"$fileName\"
	}
}
}

# QuitNoSave --
#
#	Quit the game without saving. If the game is not asking for
#	a command, then call "game abort". Otherwise do a clean exit.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc QuitNoSave {} {

	global Angband

	# Check if game is waiting for a command
	if {[string compare [angband inkey_flags] INKEY_CMD]} {
		angband game abort
		return
	}

	# Ask the user to confirm quit with save
	set answer [tk_messageBox -icon question -type yesno \
		-title "Quit $Angband(name)" -message "Do you really want to\
		quit without saving?"]
	if {$answer == "no"} return

	# Quit without saving
	DoUnderlyingCommand ^E
}

# InitStartupScreen --
#
#	Initialize the startup window.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc InitStartupScreen {} {

	global Angband

	wm title . "$Angband(name) $Angband(vers)"
	wm resizable . no no

	# Quit application if the user closes the window
	wm protocol . WM_DELETE_WINDOW "exit"

	# Load the "Tcl Powered Logo"
	image create photo Image_PwrdLogo175 \
		-file [file join $Angband(dir) tk image pwrdLogo175.gif]

	# Program name
	label .title \
		-text "$Angband(name) $Angband(vers)" -font "Times 18 bold"

	# Program info
	set info "$Angband(name): Copyright (c) 1998 Tim Baker\n"
	append info "Based on ZAngband: Copyright (c) 1998 Topi Ylinen\n"
	append info "Send comments to dbaker@direct.ca"
	label .info \
		-text $info -justify left

	# Tcl Powered Logo
	label .logo \
		-image Image_PwrdLogo175

	# Startup progress
	listbox .prompt \
		-width 15 -height 10 -borderwidth 0 -highlightthickness 0
	.prompt insert end "Initializing arrays..."

	# Geometry
	pack .title \
		-side top -expand no -anchor w
	pack .info \
		-side top -expand no -anchor w
	pack .logo \
		-side left -expand no
	pack [frame .filler -borderwidth 0 -height 10] -side top -anchor w
	pack .prompt \
		-side top -expand no -pady 00 -padx 20 -anchor w

	# Position
	WindowPosition . 2 3

	update
}

# angband_startup --
#
#	Called by Angband (and below) to display status messages
#	during program initialization.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc angband_startup what {

	switch -- $what {

		init_misc {
			set prompt "    misc"
		}
		init_script {
			set prompt "    script"
		}
		init_f_info {
			set prompt "    features"
		}
		init_k_info {
			set prompt "    objects"
		}
		init_a_info {
			set prompt "    artifacts"
		}
		init_e_info {
			set prompt "    ego-items"
		}
		init_r_info {
			set prompt "    monsters"
		}
		init_wilderness {
			set prompt "    wilderness"
		}
		init_towns {
			set prompt "    towns"
		}
		init_buildings {
			set prompt "    buildings"
		}
		init_quests {
			set prompt "    quests"
		}
		init_other {
			set prompt "    other"
		}
		init_alloc {
			set prompt "    alloc"
		}

		default {
			set prompt $what
		}
	}

	.prompt insert end $prompt
	.prompt see end

	update
}

# angband_initialized --
#
#	Called by Angband when program initialization is complete.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc angband_initialized {} {

	global Angband

	.prompt delete 0 end
	.prompt insert end "Sourcing scripts..."
	
	# Source library files
	angband_startup "    object.tcl"
	source [file join $Angband(dirTK) library object.tcl]
	angband_startup "    buttonlabel.tcl"
	source [file join $Angband(dirTK) library buttonlabel.tcl]
	angband_startup "    canvist.tcl"
	source [file join $Angband(dirTK) library canvist.tcl]
	angband_startup "    canvist2.tcl"
	source [file join $Angband(dirTK) library canvist2.tcl]
	angband_startup "    menu.tcl"
	source [file join $Angband(dirTK) library menu.tcl]
	angband_startup "    module.tcl"
	source [file join $Angband(dirTK) library module.tcl]
	angband_startup "    status-text.tcl"
	source [file join $Angband(dirTK) library status-text.tcl]
	angband_startup "    progress.tcl"
	source [file join $Angband(dirTK) library progress.tcl]
	source [file join $Angband(dirTK) library progress2.tcl]
	source [file join $Angband(dirTK) library progress-window.tcl]
	angband_startup "    tabs.tcl"
	source [file join $Angband(dirTK) library tabs.tcl]
	angband_startup "    texist.tcl"
	source [file join $Angband(dirTK) library texist.tcl]
	angband_startup "    toolbar.tcl"
	source [file join $Angband(dirTK) library toolbar.tcl]
	angband_startup "    toplevel.tcl"
	source [file join $Angband(dirTK) library toplevel.tcl]
	angband_startup "    utils.tcl"
	source [file join $Angband(dirTK) library utils.tcl]
	angband_startup "    window-manager.tcl"
	source [file join $Angband(dirTK) library window-manager.tcl]

	# Only load when needed
	NSModule::AddModule NSColorPicker [file join $Angband(dirTK) library color-picker.tcl]

	# Remove the prompt, and add some buttons
	destroy .filler
	destroy .prompt

	# Buttons
	button .newgame \
		-text "New" -command "angband game new" -width 11 -underline 0
	button .opengame \
		-text "Open" -command "OpenGame" -width 11 -underline 0
	button .config \
		-text "Setup" -command "NSConfig::ChooseConfig" -width 11 -underline 0
	button .quit \
		-text "Quit" -command "angband game quit" -width 11 -underline 0

	# Geometry
	pack [frame .filler1 -height 20 -borderwidth 0] \
		-side top
	pack .newgame \
		-side top -expand no -pady 0 -padx 20
	pack [frame .filler2 -height 10 -borderwidth 0] \
		-side top
	pack .opengame \
		-side top -expand no -pady 0 -padx 20
	pack [frame .filler3 -height 10 -borderwidth 0] \
		-side top
	pack .config \
		-side top -expand no -pady 0 -padx 20
	pack [frame .filler4 -height 10 -borderwidth 0] \
		-side top
	pack .quit \
		-side top -expand no -pady 0 -padx 20

	# KeyPress bindings
	bind . <KeyPress-n> \
		"tkButtonInvoke .newgame"
	bind . <KeyPress-o> \
		"tkButtonInvoke .opengame"
	bind . <KeyPress-s> \
		"tkButtonInvoke .config"
	bind . <KeyPress-q> \
		"tkButtonInvoke .quit"
	bind . <KeyPress-Escape> \
		"tkButtonInvoke .quit"

	# Focus on Open Button
	focus .opengame

	uplevel #0 source [file join $Angband(dirTK) config.tcl]
	NSConfig::InitModule
}

# Because init-other.tcl isn't called before Angband starts calling
# "angband_xxx", I must set a dummy proc's here.

proc angband_notice args {
}

proc angband_display args {
}

# angband_birth --
#
#	Called by Angband to kick off character creation.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc angband_birth action {

	global Angband
	global Windows

	if {[catch {

		switch -- $action {
	
			setup {
				uplevel source [file join $Angband(dirTK) birth.tcl]
				uplevel source [file join $Angband(dirTK) player.tcl]
				NSBirth::InitModule
			}
		}

	} result]} {

		set message "An error occured:\n    $result\nQuit now?"
		set answer [tk_messageBox -title "$Angband(name) Error" \
			-message $message -type yesno -icon question]
		if {$answer == "yes"} [angband game abort]
	}
}

proc InitLoadWindow {} {

	global AngbandPriv
	global NSProgress2

	# Hack -- NSBirth may call "angband_load init" to prevent there
	# being no front windows, so we allow this to get called twice.
	# If there are no front windows, the application is swapped
	# into the background.
	if {[winfo exists .load]} return

	set win .load
	toplevel $win -borderwidth 3 -relief raised
	wm overrideredirect $win yes
#	wm title $win "Starting AngbandTk"
#	wm resizable $win no no

	frame $win.progress \
		-borderwidth 0
	label $win.progress.prompt \
		-text "Starting game..." -borderwidth 0
	frame $win.progress.frame \
		-borderwidth 0 -relief sunken
	set progId [NSObject::New NSProgress2 $win.progress.frame 150 8 Red gray60]
	frame $win.divider1 \
		-borderwidth 1 -relief sunken -height 2
	listbox $win.list \
		-height 5 -width 40 -background White

	pack $win.progress \
		-side top -padx 5 -pady 5 -fill x
	pack $win.progress.prompt \
		-side top -pady 2 -padx 0 -anchor w
	pack $win.progress.frame \
		-side top -pady 0 -padx 0 -fill x
	pack $NSProgress2($progId,frame) \
		-fill x
	pack $win.divider1 \
		-side top -pady 2 -padx 5 -fill x
	pack $win.list \
		-side top -pady 5 -padx 5

	NSProgress2::SetDoneRatio $progId 0.0

	# Position the window
	WindowPosition $win 2 3

	# This inocuous call insures an *active* front window exists
	focus $win

	# Hide the startup screen
	wm withdraw .

	# Cleanup the startup screen
	foreach window [winfo children .] {
		if {[string compare [winfo class $window] Toplevel]} {
			destroy $window
		}
	}
	image delete Image_PwrdLogo175

	set AngbandPriv(load,win) $win
	set AngbandPriv(load,list) $win.list
	set AngbandPriv(load,prog) $progId
}	

# angband_load --
#
#	Called by Angband to display info during savefile loading.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc angband_load {action {message ""}} {

	global AngbandPriv

	switch -- $action {
		init {
			InitLoadWindow
		}
		kill {
			set win $AngbandPriv(load,win)
			destroy $win
		}
		note {
			$AngbandPriv(load,win).progress.prompt configure -text $message
			set list $AngbandPriv(load,list)
			$list insert end $message
			$list see end
		}
		progress {
			NSProgress2::SetDoneRatio $AngbandPriv(load,prog) $message
		}
		prompt {
			$AngbandPriv(load,win).progress.prompt configure -text $message
		}
	}

	update
}

# init_askfor_display --
#
#	Creates the window that is used to ask the user for information
#	when importing old savefiles.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc init_askfor_display {} {

	global AngbandPriv
	
	set win .askfor
	toplevel $win
	wm transient $win $AngbandPriv(load,win)

	set label $win.prompt
	label $label \
		-font "{MS Sans Serif} 10 bold underline"

	set label $win.info
	message $label \
		-width 350

	set frame $win.content
	frame $frame \
		-borderwidth 0

	set frame $win.divider1
	frame $frame \
		-borderwidth 1 -height 2 -relief sunken

	set frame $win.buttons
	frame $frame \
		-borderwidth 0
	button $frame.cancel \
		-command "angband game abort" -text "Quit" -underline 0 \
		-width 9
	button $frame.ok \
		-command "set AngbandPriv(askfor_quest,result) 1" -text "OK" \
		-underline 0 -width 9 -default active

	pack $frame.cancel \
		-side right -pady 5 -padx 5
	pack $frame.ok \
		-side right -pady 5 -padx 5

	grid rowconfigure $win 0 -weight 0
	grid rowconfigure $win 1 -weight 0
	grid rowconfigure $win 2 -weight 1
	grid rowconfigure $win 3 -weight 0
	grid rowconfigure $win 4 -weight 0
	grid columnconfigure $win 0 -weight 1

	grid $win.prompt \
		-row 0 -col 0 -rowspan 1 -columnspan 1 -sticky w -padx 5 -pady 5
	grid $win.info \
		-row 1 -col 0 -rowspan 1 -columnspan 1 -sticky w -padx 10 -pady 5
	grid $win.content \
		-row 2 -col 0 -rowspan 1 -columnspan 1 -sticky news -padx 10 -pady 5
	grid $win.divider1 \
		-row 3 -col 0 -rowspan 1 -columnspan 1 -sticky ew -padx 10
	grid $win.buttons \
		-row 4 -col 0 -rowspan 1 -columnspan 1 -sticky ew -padx 5 -pady 5

	bind $win <KeyPress-Return> \
		"tkButtonInvoke $win.buttons.ok"

	return $win
}

# angband_askfor_quest --
#
#	Returns the number of additional quests the user wants. Called when
#	reading a pre-2.2.0 savefile.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc angband_askfor_quest max_random {

	global AngbandPriv

	set win [init_askfor_display]
	wm title $win "Import Old Savefile"

	# Default value
	set AngbandPriv(askfor_quest,max_quest) 20

	$win.prompt configure -text "Enter number of quests"
	
	$win.info configure -text "Enter the number of quests you'd like your\
		character to complete in addition to the two required quests\
		(Oberon and the Serpent of Chaos). The actual number of quests\
		may be smaller if your character is deeper than the quest level.\n\nIf\
		you do not want any additional quests, enter 0."

	set frame $win.content.quest
	frame $frame \
		-borderwidth 0
	entry $frame.num \
		-width 4 -font {Courier 9} \
		-textvariable AngbandPriv(askfor_quest,max_quest)
	label $frame.max \
		-text "(Max of $max_random)" -font {Courier 9}

	pack $frame \
		-side top -anchor w -padx 50
	pack $frame.num \
		-side left -expand no
	pack $frame.max \
		-side left -expand no

	$frame.num selection range 0 end
	$frame.num icursor end

	WindowPosition $win 2 3
	
	# Set up a grab and claim focus too
	NSUtils::GrabSave $win
	focus $frame.num

	while {1} {
	
		# Wait
		set AngbandPriv(askfor_quest,result) 0
		tkwait variable AngbandPriv(askfor_quest,result)

		set number $AngbandPriv(askfor_quest,max_quest)
		if {[string length $number]} {
			if {![regsub -all \[^0-9\] $number "" number]} {
				if {$number >= 0 && $number <= $max_random} {
					break
				}
			}
		}

		# Invalid
		set entry $win.content.quest.num
		$entry delete 0 end
		$entry insert 0 20
		$entry selection range 0 end
		$entry icursor end
		focus $entry
		bell
	}
	
	# Release grab and reset focus
	NSUtils::GrabRelease $win

	destroy $win
	update
	
	return $number
}

# angband_askfor_hard_quests --
#
#	Returns a boolean depending on whether the user wants to use the
#	"hard_quests" birth option. Called when reading a pre-2.2.1 savefile.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc angband_askfor_hard_quests {} {

	global AngbandPriv

	set win [init_askfor_display]
	wm title $win "Import Old Savefile"

	# Default value
	set AngbandPriv(askfor_quest,hard_quests) 0

	$win.prompt configure -text "Hard quests option"
	
	$win.info configure \
		-text "Using 'hard quests' mode makes the random quests harder,\
			because you have to kill all monsters at the same visit to the\
			quest level. If you leave the level while some quest monsters\
			are still alive, then all killed quest monsters are revived on\
			your next visit to this level."

	checkbutton $win.content.checkHard \
		-text "Use hard quests" \
		-variable AngbandPriv(askfor_quest,hard_quests) -borderwidth 0

	pack $win.content.checkHard \
		-side top -anchor w -padx 50

	WindowPosition $win 2 3
	
	# Set up a grab and claim focus too
	NSUtils::GrabSave $win
	focus $win.content.checkHard

	# Wait
	set AngbandPriv(askfor_quest,result) 0
	tkwait variable AngbandPriv(askfor_quest,result)

	# Release grab and reset focus
	NSUtils::GrabRelease $win

	destroy $win
	update
	
	return $AngbandPriv(askfor_quest,hard_quests)
}

# angband_askfor_wilderness --
#
#	Returns a boolean depending on whether the user wants to use the
#	"wilderness" birth option. Called when reading a pre-2.1.3 savefile.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc angband_askfor_wilderness {} {

	global AngbandPriv

	set win [init_askfor_display]
	wm title $win "Import Old Savefile"

	# Default value
	set AngbandPriv(askfor_quest,wilderness) 1

	$win.prompt configure -text "Wilderness option"
	
	$win.info configure \
		-text "'Wilderness' mode enables the extended wilderness of ZAngband\
		giving you a wilderness and several new towns to explore.\
		Switching off 'wilderness' mode is recommended for slower computers,\
		because the wilderness slows down the system a bit."

	checkbutton $win.content.wilderness \
		-text "Allow extended wilderness" \
		-variable AngbandPriv(askfor_quest,wilderness) -borderwidth 0

	pack $win.content.wilderness \
		-side top -anchor w -padx 50

	WindowPosition $win 2 3
	
	# Set up a grab and claim focus too
	NSUtils::GrabSave $win
	focus $win.content.wilderness

	# Wait
	set AngbandPriv(askfor_quest,result) 0
	tkwait variable AngbandPriv(askfor_quest,result)

	# Release grab and reset focus
	NSUtils::GrabRelease $win

	destroy $win
	update
	
	return $AngbandPriv(askfor_quest,wilderness)
}

# Hack -- Require WindowPosition() command
source [file join $Angband(dirTK) library utils.tcl]

# Poor-Man's Font Management
if {[winfo screenwidth .] > 800} {
	Global font,fixed,normal {Courier 10}
	Global font,fixed,small {Courier 9}
} else {
	Global font,fixed,normal {Courier 9}
	Global font,fixed,small {Courier 8}
}

# Begin
InitStartupScreen

if $DEBUG {
	raise .
	focus .
	wm iconify .errors
	wm iconify .command
}

set i 0
foreach device [angband sound device] {
	dbwin "WaveOut Device: $device\n"
	foreach flag [angband sound support $i] {
		dbwin "\t$flag\n"
	}
	foreach flag [angband sound caps $i] {
		dbwin "\t$flag\n"
	}
	incr i
}
