#!/bin/bash

# Provides functions to query and validate values for serverconfig.xml

#################################
## Definition of options

serverconfig_ServerPort_QueryName() {
	echo "Base Port"
}
serverconfig_ServerPort_Type() {
	echo "number"
}
serverconfig_ServerPort_Default() {
	echo "25000"
}
serverconfig_ServerPort_Range() {
	echo "1024-65533"
}
serverconfig_ServerPort_Validate() {
	local I=${INSTANCE:-!}
	if [ $(checkGamePortUsed "$1" "$I") -eq 0 ]; then
		echo "1"
	else
		echo "0"
	fi
}
serverconfig_ServerPort_ErrorMessage() {
	echo "Illegal port number or port already in use by another instance."
}



serverconfig_ServerIsPublic_QueryName() {
	echo "Public server"
}
serverconfig_ServerIsPublic_Type() {
	echo "boolean"
}
serverconfig_ServerIsPublic_Default() {
	echo "true"
}
serverconfig_ServerIsPublic_ErrorMessage() {
	echo "Not a valid boolean given (true/false or yes/no or y/n)."
}



serverconfig_ServerName_QueryName() {
	echo "Server name"
}
serverconfig_ServerName_Type() {
	echo "string"
}
serverconfig_ServerName_Validate() {
	if [ ! -z "$1" ]; then
		echo "1"
	else
		echo "0"
	fi
}
serverconfig_ServerName_ErrorMessage() {
	echo "Server name cannot be empty."
}



serverconfig_ServerPassword_QueryName() {
	echo "Server password"
}
serverconfig_ServerPassword_Type() {
	echo "string"
}



serverconfig_ServerMaxPlayerCount_QueryName() {
	echo "Max players"
}
serverconfig_ServerMaxPlayerCount_Type() {
	echo "number"
}
serverconfig_ServerMaxPlayerCount_Default() {
	echo "4"
}
serverconfig_ServerMaxPlayerCount_Range() {
	echo "1-64"
}



serverconfig_GameWorld_QueryName() {
	echo "World name"
}
serverconfig_GameWorld_Type() {
	echo "enum"
}
serverconfig_GameWorld_Default() {
	echo "1"
}
serverconfig_GameWorld_Values() {
	config_allowed_values=("Navezgane" "MP Wasteland Horde" "MP Wasteland Skirmish" "MP Wasteland War")
}



serverconfig_GameName_QueryName() {
	echo "Game name"
}
serverconfig_GameName_Type() {
	echo "string"
}
serverconfig_GameName_Validate() {
	if [ ! -z "$1" ]; then
		echo "1"
	else
		echo "0"
	fi
}
serverconfig_GameName_ErrorMessage() {
	echo "Game name cannot be empty."
}



serverconfig_GameDifficulty_QueryName() {
	echo "Difficulty"
}
serverconfig_GameDifficulty_Type() {
	echo "number"
}
serverconfig_GameDifficulty_Default() {
	echo "2"
}
serverconfig_GameDifficulty_Range() {
	echo "0-4"
}
serverconfig_GameDifficulty_Values() {
	config_allowed_values=("Very easy" "Easy" "Medium" "Hard" "Very hard")
}



serverconfig_GameMode_QueryName() {
	echo "Game mode"
}
serverconfig_GameMode_Type() {
	echo "enum"
}
serverconfig_GameMode_Default() {
	echo "1"
}
serverconfig_GameMode_Values() {
	config_allowed_values=("GameModeSurvivalMP" "GameModeSurvivalSP")
}



serverconfig_ZombiesRun_QueryName() {
	echo "Zombies run"
}
serverconfig_ZombiesRun_Type() {
	echo "number"
}
serverconfig_ZombiesRun_Default() {
	echo "0"
}
serverconfig_ZombiesRun_Range() {
	echo "0-2"
}
serverconfig_ZombiesRun_Values() {
	config_allowed_values=("Default day/night walk/run" "Never run" "Always run")
}



serverconfig_ShowAllPlayersOnMap_QueryName() {
	echo "Show all players on map"
}
serverconfig_ShowAllPlayersOnMap_Type() {
	echo "boolean"
}
serverconfig_ShowAllPlayersOnMap_Default() {
	echo "true"
}
serverconfig_ShowAllPlayersOnMap_ErrorMessage() {
	echo "Not a valid boolean given (true/false or yes/no or y/n)."
}



serverconfig_BuildCreate_QueryName() {
	echo "Item spawn menu"
}
serverconfig_BuildCreate_Type() {
	echo "boolean"
}
serverconfig_BuildCreate_Default() {
	echo "true"
}
serverconfig_BuildCreate_ErrorMessage() {
	echo "Not a valid boolean given (true/false or yes/no or y/n)."
}



serverconfig_DayNightLength_QueryName() {
	echo "Length of one day"
}
serverconfig_DayNightLength_Type() {
	echo "number"
}
serverconfig_DayNightLength_Default() {
	echo "45"
}



serverconfig_FriendlyFire_QueryName() {
	echo "Friendly fire"
}
serverconfig_FriendlyFire_Type() {
	echo "boolean"
}
serverconfig_FriendlyFire_Default() {
	echo "false"
}
serverconfig_FriendlyFire_ErrorMessage() {
	echo "Not a valid boolean given (true/false or yes/no or y/n)."
}



serverconfig_DayCount_QueryName() {
	echo "Day Count (Horde)"
}
serverconfig_DayCount_Type() {
	echo "number"
}
serverconfig_DayCount_Default() {
	echo "3"
}



serverconfig_FragLimit_QueryName() {
	echo "Frag limit (DM)"
}
serverconfig_FragLimit_Type() {
	echo "number"
}
serverconfig_FragLimit_Default() {
	echo "5"
}



serverconfig_MatchLength_QueryName() {
	echo "Match length (DM)"
}
serverconfig_MatchLength_Type() {
	echo "number"
}
serverconfig_MatchLength_Default() {
	echo "15"
}



serverconfig_RebuildMap_QueryName() {
	echo "Rebuild map on round restart"
}
serverconfig_RebuildMap_Type() {
	echo "boolean"
}
serverconfig_RebuildMap_Default() {
	echo "false"
}
serverconfig_RebuildMap_ErrorMessage() {
	echo "Not a valid boolean given (true/false or yes/no or y/n)."
}



serverconfig_ControlPanelEnabled_QueryName() {
	echo "Enable control panel"
}
serverconfig_ControlPanelEnabled_Type() {
	echo "boolean"
}
serverconfig_ControlPanelEnabled_Default() {
	echo "false"
}
serverconfig_ControlPanelEnabled_ErrorMessage() {
	echo "Not a valid boolean given (true/false or yes/no or y/n)."
}



serverconfig_ControlPanelPort_QueryName() {
	echo "Control panel port"
}
serverconfig_ControlPanelPort_Type() {
	echo "number"
}
serverconfig_ControlPanelPort_Default() {
	echo "8080"
}
serverconfig_ControlPanelPort_Range() {
	echo "1024-65535"
}
serverconfig_ControlPanelPort_Validate() {
	local I=${INSTANCE:-!}
	if [ $(checkTCPPortUsed "$1" "$I") -eq 0 ]; then
		echo "1"
	else
		echo "0"
	fi
}
serverconfig_ControlPanelPort_ErrorMessage() {
	echo "Illegal port number or port already in use by another instance."
}



serverconfig_ControlPanelPassword_QueryName() {
	echo "Control panel password"
}
serverconfig_ControlPanelPassword_Type() {
	echo "string"
}



serverconfig_TelnetPort_QueryName() {
	echo "Telnet port"
}
serverconfig_TelnetPort_Type() {
	echo "number"
}
serverconfig_TelnetPort_Default() {
	echo "8081"
}
serverconfig_TelnetPort_Range() {
	echo "1024-65535"
}
serverconfig_TelnetPort_Validate() {
	local I=${INSTANCE:-!}
	if [ $(checkTCPPortUsed "$1" "$I") -eq 0 ]; then
		echo "1"
	else
		echo "0"
	fi
}
serverconfig_TelnetPort_ErrorMessage() {
	echo "Illegal port number or port already in use by another instance."
}



serverconfig_TelnetPassword_QueryName() {
	echo "Telnet password"
}
serverconfig_TelnetPassword_Type() {
	echo "string"
}
serverconfig_TelnetPassword_Validate() {
	if [ -z $1 ]; then
		echo "0"
	else
		echo "1"
	fi
}
serverconfig_TelnetPassword_ErrorMessage() {
	echo "Telnet must have a password set to function."
}



serverconfig_DisableNAT_QueryName() {
	echo "Disable NAT"
}
serverconfig_DisableNAT_Type() {
	echo "boolean"
}
serverconfig_DisableNAT_Default() {
	echo "true"
}
serverconfig_DisableNAT_ErrorMessage() {
	echo "Not a valid boolean given (true/false or yes/no or y/n)."
}




serverconfig_DropOnDeath_QueryName() {
	echo "Drop on Death"
}
serverconfig_DropOnDeath_Type() {
	echo "number"
}
serverconfig_DropOnDeath_Default() {
	echo "0"
}
serverconfig_DropOnDeath_Range() {
	echo "0-3"
}
serverconfig_DropOnDeath_Values() {
	config_allowed_values=("Everything" "Toolbelt only" "Backpack only" "Delete all")
}


serverconfig_DropOnQuit_QueryName() {
	echo "Drop on Quit"
}
serverconfig_DropOnQuit_Type() {
	echo "number"
}
serverconfig_DropOnQuit_Default() {
	echo "0"
}
serverconfig_DropOnQuit_Range() {
	echo "0-3"
}
serverconfig_DropOnQuit_Values() {
	config_allowed_values=("Nothing" "Everything" "Toolbelt only" "Backpack only")
}




serverconfig_CraftTimer_QueryName() {
	echo "Craft speed"
}
serverconfig_CraftTimer_Type() {
	echo "number"
}
serverconfig_CraftTimer_Default() {
	echo "1"
}
serverconfig_CraftTimer_Range() {
	echo "0-2"
}
serverconfig_CraftTimer_Values() {
	config_allowed_values=("Instant" "Normal" "Double")
}


serverconfig_LootTimer_QueryName() {
	echo "Loot open speed"
}
serverconfig_LootTimer_Type() {
	echo "number"
}
serverconfig_LootTimer_Default() {
	echo "1"
}
serverconfig_LootTimer_Range() {
	echo "0-2"
}
serverconfig_LootTimer_Values() {
	config_allowed_values=("Instant" "Normal" "Double")
}




serverconfig_PlayerDamageGiven_QueryName() {
	echo "Damage Player->Zombies"
}
serverconfig_PlayerDamageGiven_Type() {
	echo "number"
}
serverconfig_PlayerDamageGiven_Default() {
	echo "2"
}
serverconfig_PlayerDamageGiven_Range() {
	echo "0-4"
}
serverconfig_PlayerDamageGiven_Values() {
	config_allowed_values=("50%" "75%" "100%" "150%" "200%")
}


serverconfig_PlayerDamageRecieved_QueryName() {
	echo "Damage Zombies->Player"
}
serverconfig_PlayerDamageRecieved_Type() {
	echo "number"
}
serverconfig_PlayerDamageRecieved_Default() {
	echo "2"
}
serverconfig_PlayerDamageRecieved_Range() {
	echo "0-4"
}
serverconfig_PlayerDamageRecieved_Values() {
	config_allowed_values=("50%" "75%" "100%" "150%" "200%")
}


serverconfig_EnemySenseMemory_QueryName() {
	echo "Sense memory (seconds)"
}
serverconfig_EnemySenseMemory_Type() {
	echo "number"
}
serverconfig_EnemySenseMemory_Default() {
	echo "60"
}


serverconfig_EnemySpawnMode_QueryName() {
	echo "Spawn mode"
}
serverconfig_EnemySpawnMode_Type() {
	echo "number"
}
serverconfig_EnemySpawnMode_Default() {
	echo "3"
}
serverconfig_EnemySpawnMode_Range() {
	echo "0-5"
}
serverconfig_EnemySpawnMode_Values() {
	config_allowed_values=("Disabled" "50%" "75%" "100%" "125%" "150%")
}


serverconfig_EnemyDifficulty_QueryName() {
	echo "Enemy difficulty"
}
serverconfig_EnemyDifficulty_Type() {
	echo "number"
}
serverconfig_EnemyDifficulty_Default() {
	echo "0"
}
serverconfig_EnemyDifficulty_Range() {
	echo "0-1"
}
serverconfig_EnemyDifficulty_Values() {
	config_allowed_values=("Normal" "Feral")
}




serverconfig_NightPercentage_QueryName() {
	echo "Night percentage"
}
serverconfig_NightPercentage_Type() {
	echo "number"
}
serverconfig_NightPercentage_Default() {
	echo "35"
}
serverconfig_NightPercentage_Range() {
	echo "10-90"
}



serverconfig_BlockDurabilityModifier_QueryName() {
	echo "Block durability (%)"
}
serverconfig_BlockDurabilityModifier_Type() {
	echo "number"
}
serverconfig_BlockDurabilityModifier_Default() {
	echo "100"
}




serverconfig_LootAbundance_QueryName() {
	echo "Loot abundance (%)"
}
serverconfig_LootAbundance_Type() {
	echo "number"
}
serverconfig_LootAbundance_Default() {
	echo "100"
}


serverconfig_LootRespawnDays_QueryName() {
	echo "Loot respawn delay (days)"
}
serverconfig_LootRespawnDays_Type() {
	echo "number"
}
serverconfig_LootRespawnDays_Default() {
	echo "7"
}




serverconfig_LandClaimSize_QueryName() {
	echo "Land claim size"
}
serverconfig_LandClaimSize_Type() {
	echo "number"
}
serverconfig_LandClaimSize_Default() {
	echo "7"
}


serverconfig_LandClaimDeadZone_QueryName() {
	echo "Minimum keystone distance"
}
serverconfig_LandClaimDeadZone_Type() {
	echo "number"
}
serverconfig_LandClaimDeadZone_Default() {
	echo "30"
}


serverconfig_LandClaimExpiryTime_QueryName() {
	echo "Claim expiry time (days)"
}
serverconfig_LandClaimExpiryTime_Type() {
	echo "number"
}
serverconfig_LandClaimExpiryTime_Default() {
	echo "3"
}


serverconfig_LandClaimDecayMode_QueryName() {
	echo "Claim decay mode"
}
serverconfig_LandClaimDecayMode_Type() {
	echo "number"
}
serverconfig_LandClaimDecayMode_Default() {
	echo "0"
}
serverconfig_LandClaimDecayMode_Range() {
	echo "0-2"
}
serverconfig_LandClaimDecayMode_Values() {
	config_allowed_values=("Linear" "Exponential" "Full protection")
}


serverconfig_LandClaimOnlineDurabilityModifier_QueryName() {
	echo "Claim durability modifier - online"
}
serverconfig_LandClaimOnlineDurabilityModifier_Type() {
	echo "number"
}
serverconfig_LandClaimOnlineDurabilityModifier_Default() {
	echo "4"
}


serverconfig_LandClaimOfflineDurabilityModifier_QueryName() {
	echo "Claim durability modifier - offline"
}
serverconfig_LandClaimOfflineDurabilityModifier_Type() {
	echo "number"
}
serverconfig_LandClaimOfflineDurabilityModifier_Default() {
	echo "4"
}




serverconfig_AirDropFrequency_QueryName() {
	echo "Airdrop delay (hours)"
}
serverconfig_AirDropFrequency_Type() {
	echo "number"
}
serverconfig_AirDropFrequency_Default() {
	echo "24"
}




#################################
## Edit option functions

configEditServer() {
	local CV
	
	echo "Server"
	echo "--------------------------------"
	for CV in \
			ServerName ServerPassword ServerIsPublic ServerPort ServerMaxPlayerCount \
			DisableNAT \
			; do
		$1 $CV
	done
	echo
}

configEditRemoteControl() {
	local CV
	
	echo "Remote control"
	echo "--------------------------------"
	for CV in \
			ControlPanelEnabled ControlPanelPort ControlPanelPassword \
			TelnetPort TelnetPassword \
			; do
		if [ "$CV" = "TelnetPort" ]; then
			echo
			echo "NOTE: Telnet will always be enabled for management purposes!"
			echo "Make sure you block external access to this port!"
			echo
		fi
		$1 $CV
	done
	echo
}

configEditGameType() {
	local CV
	
	echo "Game type"
	echo "--------------------------------"
	for CV in \
			GameName GameWorld GameMode \
			; do
		$1 $CV
	done
	echo
}

configEditGameTypeSpecific() {
	local CV
	
	echo "Options for specific game types"
	echo "--------------------------------"
	for CV in \
			DayCount FragLimit MatchLength RebuildMap \
			; do
		$1 $CV
	done
	echo
}

configEditGeneric() {
	local CV
	
	echo "Generic options"
	echo "--------------------------------"
	for CV in \
			ShowAllPlayersOnMap FriendlyFire BuildCreate \
			BlockDurabilityModifier \
			; do
		$1 $CV
	done
	echo
}

configEditDropLoot() {
	local CV
	
	echo "Drop and Loot"
	echo "--------------------------------"
	for CV in \
			DropOnDeath DropOnQuit \
			LootAbundance LootRespawnDays AirDropFrequency \
			; do
		$1 $CV
	done
	echo
}

configEditTimes() {
	local CV
	
	echo "Times / Durations"
	echo "--------------------------------"
	for CV in \
			CraftTimer LootTimer \
			DayNightLength NightPercentage \
			; do
		$1 $CV
	done
	echo
}

configEditDifficulty() {
	local CV
	
	echo "Difficulty"
	echo "--------------------------------"
	for CV in \
			GameDifficulty ZombiesRun \
			PlayerDamageGiven PlayerDamageRecieved EnemySenseMemory EnemySpawnMode EnemyDifficulty \
			; do
		$1 $CV
	done
	echo
}

configEditLandClaim() {
	local CV
	
	echo "Land claim options"
	echo "--------------------------------"
	for CV in \
			LandClaimSize LandClaimDeadZone LandClaimExpiryTime LandClaimDecayMode \
			LandClaimOnlineDurabilityModifier LandClaimOfflineDurabilityModifier \
			; do
		$1 $CV
	done
	echo
}

configEditAll() {
	configEditServer "$1"
	configEditRemoteControl "$1"
	configEditGameType "$1"
	configEditGameTypeSpecific "$1"
	configEditGeneric "$1"
	configEditDropLoot "$1"
	configEditTimes "$1"
	configEditDifficulty "$1"
	configEditLandClaim "$1"
}





#################################
## Generic worker functions


# List all defined config editing parts
# Returns:
#   List of config funcs
listConfigEditFuncs() {
	local CV
	for CV in $(declare -F | cut -d\  -f3 | grep "^configEdit.*$"); do
		CV=${CV#configEdit}
		printf "%s " "$CV"
	done
}


# List all defined config options
# Returns:
#   List of defined config options
listConfigValues() {
	local CV
	for CV in $(declare -F | cut -d\  -f3 | grep "^serverconfig_.*_Type$"); do
		CV=${CV#serverconfig_}
		CV=${CV%_Type}
		printf "%s " "$CV"
	done
}


# Validate the given value for the given option
# Params:
#   1: Option name
#   2: Value
# Returns:
#   0/1: invalid/valid
isValidOptionValue() {
	local TYPE=$(serverconfig_$1_Type)
	local RANGE=""

	if [ "$TYPE" = "enum" ]; then
		TYPE="number"
		serverconfig_$1_Values
		RANGE=1-${#config_allowed_values[@]}
	else
		if [ "$(type -t serverconfig_$1_Range)" = "function" ]; then
			RANGE=$(serverconfig_$1_Range)
		fi
	fi

	case "$TYPE" in
		number)
			if [ $(isANumber "$2") -eq 0 ]; then
				echo "0"
				return
			fi
			if [ ! -z "$RANGE" ]; then
				local MIN=$(cut -d- -f1 <<< "$RANGE")
				local MAX=$(cut -d- -f2 <<< "$RANGE")
				if [ $2 -lt $MIN -o $2 -gt $MAX ]; then
					echo "0"
					return
				fi
			fi
			;;
		boolean)
			if [ $(isABool "$2") -eq 0 ]; then
				echo "0"
				return
			fi
			;;
		string)
			;;
	esac
	

	if [ "$(type -t serverconfig_$1_Validate)" = "function" ]; then
		if [ $(serverconfig_$1_Validate "$2") -eq 0 ]; then
			echo "0"
			return
		fi
	fi
	
	echo "1"
}

# Query for the value of a single config option
# Will be stored in $configCurrent_$1
# Params:
#   1: Option name
configQueryValue() {
	local TYPE=$(serverconfig_$1_Type)
	local NAME=""
	local RANGE=""
	local DEFAULT=""
	local currentValName=configCurrent_$1

	if [ "$(type -t serverconfig_$1_Values)" = "function" ]; then
		echo "$(serverconfig_$1_QueryName), options:"
		serverconfig_$1_Values
		NAME="Select option"
		if [ "$TYPE" = "enum" ]; then
			local OPTOFFSET=1
		else
			local OPTOFFSET=0
		fi
		for (( i=$OPTOFFSET; i < ${#config_allowed_values[@]}+$OPTOFFSET; i++ )); do
			printf "  %2d: %s\n" $i "${config_allowed_values[$i-$OPTOFFSET]}"
		done
	else
		NAME=$(serverconfig_$1_QueryName)
	fi

	if [ "$TYPE" = "enum" ]; then
		RANGE=1-${#config_allowed_values[@]}
		if [ ! -z "${!currentValName}" ]; then
			for (( i=1; i < ${#config_allowed_values[@]}+1; i++ )); do
				if [ "${!currentValName}" = "${config_allowed_values[$i-1]}" ]; then
					DEFAULT=$i
				fi
			done
			export $currentValName=
		fi
	else
		if [ "$(type -t serverconfig_$1_Range)" = "function" ]; then
			RANGE=$(serverconfig_$1_Range)
		fi
	fi

	if [ -z "$DEFAULT" ]; then
		if [ ! -z "${!currentValName}" ]; then
			DEFAULT=${!currentValName}
		else
			if [ "$(type -t serverconfig_$1_Default)" = "function" ]; then
				DEFAULT=$(serverconfig_$1_Default)
			fi
		fi
	fi

	local prompt=$(printf "%s" "$NAME")
	if [ ! -z "$RANGE" ]; then
		prompt=$(printf "%s (%s)" "$prompt" "$RANGE")
	fi
	if [ ! -z "$DEFAULT" ]; then
		prompt=$(printf "%s [%s]" "$prompt" "$DEFAULT")
	fi
	prompt=$(printf "%s:" "$prompt")
	prompt=$(printf "%-*s " 40 "$prompt")

	while : ; do
		read -p "$prompt" $currentValName
		export $currentValName="${!currentValName:-$DEFAULT}"
		if [ $(isValidOptionValue "$1" "${!currentValName}") -eq 0 ]; then
			if [ "$(type -t serverconfig_$1_ErrorMessage)" = "function" ]; then
				serverconfig_$1_ErrorMessage "${!currentValName}"
			fi
		fi
		[ $(isValidOptionValue "$1" "${!currentValName}") -eq 1 ] && break
	done
	
	if [ "$TYPE" = "boolean" ]; then
		if [ $(getBool ${!currentValName}) -eq 1 ]; then
			export $currentValName="true"
		else
			export $currentValName="false"
		fi
	fi
	if [ "$TYPE" = "enum" ]; then
		export $currentValName="${config_allowed_values[$currentValName-1]}"
	fi
	echo
}

# Set parameters for current instance that have forced values:
#  - TelnetEnabled must be set so that management scripts can work
#  - AdminFileName is made to point to the local instance admins.xml
#  - SaveGameFolder is made to point to the instance folder
# Params:
#   1: Instance name
configSetAutoParameters() {
	configCurrent_TelnetEnabled=true
	configCurrent_AdminFileName=admins.xml
	configCurrent_SaveGameFolder="$(getInstancePath "$1")"
}


# Print defined config value
# Params:
#   1: Config option
printConfigValue() {
	local currentValName=configCurrent_$1
	printf "%-25s = %s\n" "$(serverconfig_$1_QueryName)" "${!currentValName}"
}

# Query for an instance name (will be saved in $INSTANCE)
readInstanceName() {
	until [ $(isValidInstanceName "$INSTANCE") -eq 1 ]; do
		read -p "Instance name: " INSTANCE
		if [ $(isValidInstanceName "$INSTANCE") -eq 0 ]; then
			echo "Invalid instance name, may only contain:"
			echo " - letters (A-Z / a-z)"
			echo " - digits (0-9)"
			echo " - underscores (_)"
			echo " - hyphens (-)"
		fi
	done
}

# Undefine the current config values
unsetAllConfigValues() {
	local CV
	for CV in $(listConfigValues); do
		local currentValName=configCurrent_$CV
		export $currentValName=
	done
}

# Load all config values from the config.xml of the given instance
# Params:
#   1: Instance name
loadCurrentConfigValues() {
	local CV
	for CV in $(listConfigValues); do
		local currentValName=configCurrent_$CV
		local cfile=$(getInstancePath "$1")/config.xml
		local XPATH="/ServerSettings/property[@name='$CV']/@value"
		local VAL=$($XMLSTARLET sel -t -v "$XPATH" $cfile)
		if [ ! -z "$VAL" ]; then
			export $currentValName="$VAL"
		fi
	done
}

# Save all config values to the config.xml of the given instance
# Params:
#   1: Instance name
saveCurrentConfigValues() {
	local CV
	for CV in $(listConfigValues) TelnetEnabled AdminFileName SaveGameFolder; do
		local currentValName=configCurrent_$CV
		local val="${!currentValName}"
		local cfile=$(getInstancePath "$1")/config.xml

		XPATHBASE="/ServerSettings/property[@name='$CV']"

		if [ -z $($XMLSTARLET sel -t -v "$XPATHBASE/@name" $cfile) ]; then
			$XMLSTARLET ed -L \
				-s "/ServerSettings" -t elem -n "property" -v "" \
				-i "/ServerSettings/property[not(@name)]" -t attr -n "name" -v "$CV" \
				-i "$XPATHBASE" -t attr -n "value" -v "$val" \
				$cfile
		else
			$XMLSTARLET ed -L \
				-u "$XPATHBASE/@value" -v "$val" \
				$cfile
		fi
	done
}

# Check if the config template exists
# Returns:
#   0/1: no/yes
configTemplateExists() {
	if [ -f $SDTD_BASE/templates/config.xml ]; then
		echo 1
	else
		echo 0
	fi
}

# Get a single value from a serverconfig
# Params:
#   1: Instance name
#   2: Property name
# Returns:
#   Property value
getConfigValue() {
	local CONF=$(getInstancePath $1)/config.xml
	$XMLSTARLET sel -t -v "/ServerSettings/property[@name='$2']/@value" $CONF
}

# Update a single value in a serverconfig
# Params:
#   1: Instance name
#   2: Property name
#   3: New value
setConfigValue() {
	local CONF=$(getInstancePath $1)/config.xml
	$XMLSTARLET ed -L -u "/ServerSettings/property[@name='$2']/@value" -v "$3" $CONF
}

