# Print the list of all icon identifiers.
# USAGE: icons_list_all
# RETURN: a list of icons identifiers, one per line,
#         or an empty string if no icon seems to be set
icons_list_all() {
	local applications_list
	applications_list=$(applications_list)
	# Return early if there is no application set for the current game
	if [ -z "$applications_list" ]; then
		return 0
	fi

	local icons_list application application_icons_list
	icons_list=''
	for application in $applications_list; do
		application_icons_list=$(application_icons_list "$application")
		icons_list="$icons_list $application_icons_list"
	done

	if [ -n "$icons_list" ]; then
		printf '%s\n' $icons_list
	fi
}

# Print the list of icon identifiers for the given application.
# USAGE: application_icons_list $application
# RETURN: a space-separated list of icons identifiers,
#         or an empty string if no icon seems to be set
application_icons_list() {
	local application
	application="$1"

	# Use the value of APP_xxx_ICONS_LIST if it is set.
	local icons_list
	icons_list=$(context_value "${application}_ICONS_LIST")

	# Fall back on the default value of a single APP_xxx_ICON icon.
	if [ -z "$icons_list" ]; then
		local default_icon
		default_icon=$(context_name "${application}_ICON")
		## If a value is explicitly set for APP_xxx_ICON,
		## it is considered to be the only icon for the current application.
		if [ -n "$default_icon" ]; then
			icons_list="$default_icon"
		fi
	fi

	# Try to guess a value from the game engine.
	if [ -z "$icons_list" ]; then
		local game_engine
		game_engine=$(game_engine)
		case "$game_engine" in
			('gamemaker')
				icons_list="${application}_ICON"
			;;
			('unity3d')
				## It is expected that Unity3D games always come with a single icon.
				icons_list="${application}_ICON"
			;;
		esac
	fi

	# Try to guess a value from the application type.
	if [ -z "$icons_list" ]; then
		local application_type
		## This is allowed to fail, as the binary file might not be available yet.
		application_type=$(application_type "$application" 2>/dev/null) || true
		## TODO: Mono binaries usually include an icon too.
		case "$application_type" in
			('wine')
				## If no value is explicitly set for the icon of a WINE application,
				## the game binary is used as a fallback icons source.
				icons_list="${application}_ICON"
			;;
		esac
	fi

	# Try to guess a value from the binary name.
	if [ -z "$icons_list" ]; then
		local application_exe
		application_exe=$(application_exe "$application")
		case "$application_exe" in
			(*'.exe')
				## This is most probably a WINE or Mono binary,
				## the game binary is used as a fallback icons source.
				icons_list="${application}_ICON"
			;;
		esac
	fi

	printf '%s' "$icons_list"
}

# Print the application identifier for the given icon
# USAGE: icon_application $icon
# RETURN: the application identifier
icon_application() {
	local icon
	icon="$1"

	# Look for an application identifier that share the same prefix than the given icon identifier.
	local application application_identifier applications_list
	applications_list=$(applications_list)
	## The applications list should not be empty.
	if [ -z "$applications_list" ]; then
		error_applications_list_empty
		return 1
	fi
	for application in $applications_list; do
		case "$icon" in
			("${application}_"*)
				application_identifier="$application"
				break
			;;
		esac
	done

	# Throw an error if no valid application identifier could be found.
	if [ -z "${application_identifier:-}" ]; then
		error_icon_application_not_found "$icon"
		return 1
	fi

	printf '%s' "$application_identifier"
}

# Print the path to the source file for the given icon
# USAGE: icon_path $icon
# RETURN: the path to the file used to extract icons from,
#         it is relative to CONTENT_PATH_DEFAULT
icon_path() {
	local icon
	icon="$1"

	local icon_path
	icon_path=$(context_value "$icon")

	# Try to guess a value from the game engine.
	if [ -z "$icon_path" ]; then
		local game_engine
		game_engine=$(game_engine)
		case "$game_engine" in
			('gamemaker')
				icon_path=$(icon_path_gamemaker)
			;;
			('unity3d')
				icon_path=$(unity3d_icon_path "$icon")
			;;
		esac
	fi

	# Try to guess a value from the application type.
	if [ -z "$icon_path" ]; then
		local application application_type
		application=$(icon_application "$icon")
		## This is allowed to fail, as the binary file might not be available yet.
		application_type=$(application_type "$application" 2>/dev/null) || true
		case "$application_type" in
			('wine')
				icon_path=$(icon_wine_path "$icon")
			;;
		esac
	fi

	# Try to guess a value from the binary name.
	if [ -z "$icon_path" ]; then
		local application_exe
		application_exe=$(application_exe "$application")
		case "$application_exe" in
			(*'.exe')
				## This is most probably a WINE or Mono binary,
				## the game binary is used as a fallback icons source.
				icon_path=$(icon_wine_path "$icon")
			;;
		esac
	fi

	# Check that the path to the icon is not empty
	if [ -z "$icon_path" ]; then
		error_icon_path_empty "$icon"
		return 1
	fi

	printf '%s' "$icon_path"
}

# Print the wrestool options string for the given .exe icon
# USAGE: icon_wrestool_options $icon
# RETURN: the options string to pass to wrestool
icon_wrestool_options() {
	local icon
	icon="$1"

	# Check that the given icon is a .exe file
	if ! icon_path "$icon" | grep --quiet '\.exe$'; then
		error_icon_unexpected_type "$icon" '*.exe'
		return 1
	fi

	local wrestool_options
	wrestool_options=$(get_value "${icon}_WRESTOOL_OPTIONS")

	# Fall back on a default value based on the game engine
	if [ -z "$wrestool_options" ]; then
		local game_engine
		game_engine=$(game_engine)
		case "$game_engine" in
			('unrealengine4')
				wrestool_options=$(unrealengine4_icon_wrestool_options_default)
			;;
			(*)
				wrestool_options='--type=14'
			;;
		esac
	fi

	printf '%s' "$wrestool_options"
}

