# value-manager.tcl --
#
#	A module to record various values, and inform client's when those
#	values are modified. Both the value and name of the value are
#	managed here.
#

namespace eval NSValueManager {

variable Command
variable Value
variable ValuePriv

# NSValueManager::InitModule --
#
#	Description
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc InitModule {} {

	global Angband
	variable Value
	variable ValuePriv

	# Each client gets a unique ID
	set ValuePriv(clientId) 0

	# These are the default values. The tk/config/value file is sourced
	# below to set user-defined values.
	Manage healthBarBD 220
	Manage healthBarBD2 145
	Manage healthBarBD22 165
	Manage healthBarBL 21
	Manage healthBarBL2 145
	Manage healthBarDone 35
	Manage healthBarDone2 127
	Manage healthBarToDo 251
	Manage healthBarToDo2 127
	Manage healthNameBD 252
	Manage healthNameBD2 127
	Manage healthNameBG 252
	Manage healthNameBG2 127
	Manage healthNameBL 252
	Manage healthNameBL2 127
	Manage healthNameText 0
	Manage healthNameText2 145

	Manage friendBarBD 229
	Manage friendBarBD2 145
	Manage friendBarBL 74
	Manage friendBarBL2 145
	Manage friendBarDone 225
	Manage friendBarDone2 145
	Manage friendBarToDo 129
	Manage friendBarToDo2 145

	Manage listBG 253
	Manage listHilite 17
	Manage listInactive 249

	Manage mapBRIGHT_FLOOR "252"
	Manage mapBRIGHT_WALL "252"
	Manage mapCHARACTER "5"
	Manage mapDOOR "137"
	Manage mapDOWNSTAIR "66"
	Manage mapFLOOR "249"
	Manage mapMIDDLE "250"
	Manage mapMONSTER "35"
	Manage mapOBJECT "191"
	Manage mapUNKNOWN "255"
	Manage mapUPSTAIR "186"
	Manage mapWALL "251"
	Manage mapYELLOW_FLOOR "248"
	Manage mapYELLOW_WALL "250"

	Manage statusBD 253
	Manage statusBD2 145
	Manage statusBG 129
	Manage statusBG2 145
	Manage statusBL 0
	Manage statusBL2 145
	Manage statusText 0
	Manage statusText2 180

	Manage TV_AMULET 17
	Manage TV_ARCANE_BOOK 247
	Manage TV_ARROW 52
	Manage TV_BOLT 52
	Manage TV_BOOTS 52
	Manage TV_BOTTLE 0
	Manage TV_BOW 101
	Manage TV_CHAOS_BOOK 35
	Manage TV_CHEST 250
	Manage TV_CLOAK 52
	Manage TV_CROWN 52
	Manage TV_DEATH_BOOK 129
	Manage TV_DIGGING 250
	Manage TV_DRAG_ARMOR 250
	Manage TV_FLASK 5
	Manage TV_FOOD 52
	Manage TV_GLOVES 52
	Manage TV_GOLD 17
	Manage TV_HAFTED 0
	Manage TV_HARD_ARMOR 250
	Manage TV_HELM 52
	Manage TV_JUNK 0
	Manage TV_LIFE_BOOK 0
	Manage TV_LITE 5
	Manage TV_NATURE_BOOK 185
	Manage TV_NONE 0
	Manage TV_POLEARM 0
	Manage TV_POTION 180
	Manage TV_RING 217
	Manage TV_ROD 30
	Manage TV_SCROLL 0
	Manage TV_SHIELD 52
	Manage TV_SHOT 52
	Manage TV_SKELETON 0
	Manage TV_SOFT_ARMOR 250
	Manage TV_SORCERY_BOOK 180
	Manage TV_SPIKE 250
	Manage TV_STAFF 52
	Manage TV_SWORD 0
	Manage TV_TRUMP_BOOK 17
	Manage TV_WAND 196

	Manage show_icons 1
	Manage use_sound 1
	Manage ambient_delay 50
	Manage monster_delay 100
	Manage scroll_follow 1

	Manage tip,current 1000
	Manage tip,show 1

	Manage progress,showBars 1
	Manage progress,showNumbers 0

	Manage bigmap,scale 4
	Manage micromap,scale 4

	Manage misc,mode,exp 1
	Manage misc,mode,armor_class 1

	Manage messages,combine 1
	Manage messages,max 2048

	Manage settings,showUnused 0

	set path [angband game directory ANGBAND_DIR_XTRA_SOUND]
	Manage sound,directory [file split $path]
	
	if {$::DEBUG} {

		# Verify we have all the tval's
		foreach tval [angband info tval] {
			if {![info exists Value($tval)]} {
				error "forgot to Manage $tval"
			}
		}
	}
	
	set fileName [file join $Angband(dirTK) config value]
	if {[file exists $fileName]} {
		source $fileName
	}
}

# NSValueManager::CloseModule --
#
#	Called before the game exits. Dumps all values to the tk/config/value
#	file.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc CloseModule {} {

	global Angband
	variable Value

	if {[catch {open [file join $Angband(dirTK) config value] w} fileId]} {
		set msg "The following error occurred while attempting to open "
		append msg "the \"value\" file for writing:\n\n$fileId"
		tk_messageBox -title Oops -message $msg
		return
	}

	puts $fileId "# Automatically generated. Do not edit.\n"

	foreach name [lsort [array names Value]] {
		set value [Get $name]
		puts $fileId "Manage $name \"$value\""
	}

	close $fileId
}

# NSValueManager::AddClient --
#
#	Description
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc AddClient {name command} {

	variable Command
	variable ValuePriv

	set clientId [incr ValuePriv(clientId)]
	set Command($name,$clientId) $command
	return $clientId
}

# NSValueManager::RemoveClient --
#
#	Description
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc RemoveClient {name clientId} {

	variable Command

	unset Command($name,$clientId)
}

# NSValueManager::Manage --
#
#	Description
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Manage {name value} {

	variable Value

	set Value($name) $value
}

# NSValueManager::Set --
#
#	Description
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Set {name value} {

	variable Value

	set Value($name) $value
	Changed $name
}

# NSValueManager::Get --
#
#	Description
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Get name {

	variable Value

	return $Value($name)
}

# NSValueManager::Changed --
#
#	Description
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Changed name {

	variable Command

	foreach name [array names Command $name,*] {
		catch {uplevel #0 eval $Command($name)} err
	}
}

# namespace eval NSValueManager
}

namespace eval NSColorPreferences {

proc Get value {

	set index [NSValueManager::Get $value]
	return [angband palette $index]	
}

# namespace eval NSColorPreferences
}

# Value --
#
#	Convenience interface to NSValueManager::Get/Set
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Value {name args} {

	# Set info
	if {[llength $args]} {
		NSValueManager::Set $name [lindex $args 0]

	# Get info
	} else {
		return [NSValueManager::Get $name]
	}
}

proc ListBackgroundChanged canvas {

	$canvas configure -background [NSColorPreferences::Get listBG]
}

proc DumpValueManager {} {

	set win .dumpvalue
	toplevel $win
	text $win.text
	pack $win.text

	foreach name [lsort [array names NSValueManager::Value]] {
		set value [NSValueManager::Get $name]
		$win.text insert end "Manage $name $value\n"
	}
}

# setg --
#
#	A namespace with commands called when the tk/config/setting file
#	is sourced.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

namespace eval setg {

proc one {keyword value} {

	# Never set cheating options
	if {[string match cheat* $keyword]} return

	# Ignore errors, such as outdated settings
	catch {
		Setting $keyword $value
	}
}

# namespace eval setg
}

# Setting --
#
#	Get or set the value of a setting. This one routine consolidates
#	all the different setting-related commands.
#
# Arguments:
#	arg1					about arg1
#
# Results:
#	What happened.

proc Setting {info args} {

	# Set
	if {[llength $args]} {
		switch -- $info {
			ambient_delay -
			monster_delay {
				Value $info [lindex $args 0]
			}
			scroll_follow -
			show_icons {
				Value $info [NSUtils::GetBoolean [lindex $args 0]]
			}
			default {
				angband setting $info [lindex $args 0]
			}
		}

	# Get
	} else {
		switch -- $info {
			ambient_delay {
				return [list [angband sound setting $info] "Ambient sound delay"]
			}
			monster_delay {
				return [list [angband sound setting $info] "Monster sound delay"]
			}
			scroll_follow {
				return [list [Value scroll_follow] "Keep character centered in the display"]
			}
			show_icons {
				return [list [Value show_icons] "Show icons in inventory/store list"]
			}
			default {
				return [angband setting $info]
			}
		}
	}
}

# First element is the title of this group of artifacts/monsters/objects.
# Second element is list of arguments to pass to the "a_info/r_info/k_info find"
# command to display artifacts/monsters/objects in the group.

Global groups,a_info {
	"Light Sources" "-tval TV_LITE"
	"Amulets" "-tval TV_AMULET"
	"Rings" "-tval TV_RING"
	"Dragon Scale Mail" "-tval TV_DRAG_ARMOR"
	"Hard Armour" "-tval TV_HARD_ARMOR"
	"Soft Armour" "-tval TV_SOFT_ARMOR"
	"Shields" "-tval TV_SHIELD"
	"Crown" "-tval TV_CROWN"
	"Helms" "-tval TV_HELM"
	"Cloaks" "-tval TV_CLOAK"
	"Gloves" "-tval TV_GLOVES"
	"Boots" "-tval TV_BOOTS"
	"Swords" "-tval TV_SWORD"
	"Polearms" "-tval TV_POLEARM"
	"Hafted" "-tval TV_HAFTED"
	"Bows" "-tval TV_BOW"
}

Global groups,k_info {
	"Sword" "-tval TV_SWORD"
	"Polearm" "-tval TV_POLEARM"
	"Hafted" "-tval TV_HAFTED"
	"Bow" "-tval TV_BOW"
	"Ammunition" "-tval TV_ARROW -tval TV_BOLT -tval TV_SHOT"
	"Shield" "-tval TV_SHIELD"
	"Crown" "-tval TV_CROWN"
	"Helm" "-tval TV_HELM"
	"Gloves" "-tval TV_GLOVES"
	"Boots" "-tval TV_BOOTS"
	"Cloak" "-tval TV_CLOAK"
	"Dragon Scale Mail" "-tval TV_DRAG_ARMOR"
	"Hard Armor" "-tval TV_HARD_ARMOR"
	"Soft Armor" "-tval TV_SOFT_ARMOR"
	"Ring" "-tval TV_RING"
	"Amulet" "-tval TV_AMULET"
	"Light Source" "-tval TV_FLASK -tval TV_LITE"
	"Potion" "-tval TV_POTION"
	"Scroll" "-tval TV_SCROLL"
	"Wand" "-tval TV_WAND"
	"Staff" "-tval TV_STAFF"
	"Rod" "-tval TV_ROD"
	"Life Book" "-tval TV_LIFE_BOOK"
	"Sorcery Book" "-tval TV_SORCERY_BOOK"
	"Nature Book" "-tval TV_NATURE_BOOK"
	"Chaos Book" "-tval TV_CHAOS_BOOK"
	"Death Book" "-tval TV_DEATH_BOOK"
	"Trump Book" "-tval TV_TRUMP_BOOK"
	"Arcane Book" "-tval TV_ARCANE_BOOK"
	"Spikes" "-tval TV_SPIKE"
	"Digging Tool" "-tval TV_DIGGING"
	"Chest" "-tval TV_CHEST"
	"Food" "-tval TV_FOOD"
	"Gold" "-tval TV_GOLD"
	"Skeleton" "-tval TV_SKELETON"
	"Junk" "-tval TV_BOTTLE -tval TV_JUNK"
}

Global groups,r_info {
	"Ancient Dragons" "-d_char D"
	"Angelic Beings" "-d_char A"
	"Birds" "-d_char B"
	"Canines" "-d_char C"
	"Creeping Coins" "-d_char $"
	"Demihumans" "-d_char h"
	"Dragons" "-d_char d"
	"Elementals" "-d_char E"
	"Energy Ball" "-d_char *"
	"Eyes/Beholders" "-d_char e"
	"Felines" "-d_char f"
	"Ghosts" "-d_char G"
	"Giant Ants" "-d_char a"
	"Giant Bats" "-d_char b"
	"Giant Centipedes" "-d_char c"
	"Giant Dragon Flies" "-d_char F"
	"Giant Lice" "-d_char l"
	"Giants" "-d_char P"
	"Golems" "-d_char g"
	"Humans" "-d_char p"
	"Hybrids" "-d_char H"
	"Hydras" "-d_char M"
	"Icky Things" "-d_char i"
	"Jellies" "-d_char j"
	"Killer Beetles" "-d_char K"
	"Kobolds" "-d_char k"
	"Lichs" "-d_char L"
	"Major Demons" "-d_char U"
	"Minor Demons" "-d_char u"
	"Molds" "-d_char m"
	"Multiplying Insects" "-d_char I"
	"Mushroom Patches" "-d_char ,"
	"Nagas" "-d_char n"
	"Ogres" "-d_char O"
	"Orcs" "-d_char o"
	"Quadropeds" "-d_char q"
	"Quylthulgs" "-d_char Q"
	"Reptiles/Amphibians" "-d_char R"
	"Rodents" "-d_char r"
	"Scorpions/Spiders" "-d_char S"
	"Skeletons" "-d_char s"
	"Snakes" "-d_char J"
	"Townspeople" "-d_char t"
	"Tricksters" "-d_char !?=.#|>(+"
	"Trolls" "-d_char T"
	"Vampires" "-d_char V"
	"Vortices" "-d_char v"
	"Water Dwellers" "-d_char ~"
	"Wights/Wraiths" "-d_char W"
	"Worms/Worm Masses" "-d_char w"
	"Xorns/Xarens" "-d_char X"
	"Yeeks" "-d_char y"
	"Yeti" "-d_char Y"
	"Zephyr Hounds" "-d_char Z"
	"Zombies/Mummies" "-d_char z"
	"Uniques" "-unique yes"
}

