# Print the name of the renderer to use for Direct3D
# USAGE: wine_renderer_name
wine_renderer_name() {
	# Fetch the preferred renderer from the game script,
	# if it is explicitely set.
	local direct3d_renderer
	direct3d_renderer="${WINE_DIRECT3D_RENDERER:-}"

	# Fall back on the default renderer for the current game engine
	if [ -z "$direct3d_renderer" ]; then
		local game_engine
		game_engine=$(game_engine)
		case "$game_engine" in
			('unrealengine4')
				direct3d_renderer=$(unrealengine4_wine_renderer_name_default)
			;;
		esac
	fi

	# Fall back to using the default renderer
	if [ -z "$direct3d_renderer" ]; then
		direct3d_renderer='default'
	fi

	# Convert "wined3d" alias to "wined3d/gl"
	if [ "$direct3d_renderer" = 'wined3d' ]; then
		direct3d_renderer='wined3d/gl'
	fi

	# Check that an allowed value has been set
	case "$direct3d_renderer" in
		( \
			'default' | \
			'wined3d/gl' | \
			'wined3d/gdi' | \
			'wined3d/vulkan' | \
			'dxvk' | \
			'vkd3d' \
		)
			printf '%s' "$direct3d_renderer"
			return 0
		;;
		(*)
			error_unknown_wine_renderer "$direct3d_renderer"
			return 1
		;;
	esac
}

# WINE launcher - Set the correct Direct3D renderer
# USAGE: wine_launcher_renderer
wine_launcher_renderer() {
	local direct3d_renderer
	direct3d_renderer=$(wine_renderer_name)

	case "$direct3d_renderer" in
		('default')
			# Nothing to do here.
		;;
		( \
			'wined3d/gl' | \
			'wined3d/gdi' | \
			'wined3d/vulkan' \
		)
			local wined3d_backend
			wined3d_backend=$(printf '%s' "$direct3d_renderer" | cut --delimiter='/' --fields=2)
			wine_launcher_renderer_wined3d "$wined3d_backend"
		;;
		('dxvk')
			wine_launcher_renderer_dxvk
		;;
		('vkd3d')
			wine_launcher_renderer_vkd3d
		;;
	esac
}

# Use WineD3D with a specific backend for Direct3D rendering.
# USAGE: wine_launcher_renderer_wined3d $wined3d_backend
## TODO: Check if the forced 1s waiting time is still useful.
wine_launcher_renderer_wined3d() {
	local wined3d_backend
	wined3d_backend="$1"
	cat <<- EOF
	# Use WineD3D for Direct3D rendering, with the "$wined3d_backend" backend.
	wined3d_backend="$wined3d_backend"
	EOF
	cat <<- 'EOF'
	if command -v winetricks >/dev/null 2>&1; then
	    winetricks_wrapper renderer=$wined3d_backend
	else
	    message="\\033[1;33mWarning:\\033[0m\\n"
	    message="${message}WineD3D backend could not be set to ${wined3d_backend}.\\n"
	    message="${message}The game might run with display or performance issues.\\n"
	    printf "\\n${message}\\n"
	fi
	unset wined3d_backend
	# Wait a bit to ensure there is no lingering wine process.
	sleep 1s

	EOF
}

# Use DXVK for Direct3D rendering.
# USAGE: wine_launcher_renderer_dxvk
## TODO: Check if the forced 1s waiting time is still useful.
wine_launcher_renderer_dxvk() {
	cat <<- 'EOF'
	# Use DXVK for Direct3D rendering.
	if command -v dxvk-setup >/dev/null 2>&1; then
	    ## Compute the correct dxvk-setup options
	    ## based on the current WINE origin
	    wine_path_full=$(realpath "$(wine_command)")
	    case "$wine_path_full" in
	        ('/usr/bin/wine-stable')
	            dxvk_options='--stable'
	        ;;
	        ('/usr/bin/wine-development')
	            dxvk_options='--development'
	        ;;
	        ('/opt/wine-devel/bin/wine')
	            dxvk_options='--upstream'
	        ;;
	        ('/opt/wine-staging/bin/wine')
	            dxvk_options='--upstream-staging'
	        ;;
	        (*)
	            dxvk_options='--stable'
	        ;;
	    esac
	    ## Run dxvk-setup, spawning a terminal if required
	    ## to ensure it is not silently running in the background.
	    if [ -t 0 ]; then
	        dxvk-setup install $dxvk_options
	    else
	        $(terminal_wrapper) -e \
	            env \
	            WINEARCH="$WINEARCH" \
	            WINEDEBUG="$WINEDEBUG" \
	            WINEPREFIX="$WINEPREFIX" \
	            dxvk-setup install $dxvk_options
	    fi
	elif command -v winetricks >/dev/null 2>&1; then
	    winetricks_wrapper dxvk
	else
	    message="\\033[1;33mWarning:\\033[0m\\n"
	    message="${message}DXVK patches could not be installed in the WINE prefix.\\n"
	    message="${message}The game might run with display or performance issues.\\n"
	    printf "\\n${message}\\n"
	fi
	# Wait a bit to ensure there is no lingering wine process.
	sleep 1s

	EOF
}

# Use vkd3d for Direct3D rendering.
# USAGE: wine_launcher_renderer_vkd3d
## TODO: Check if the forced 1s waiting time is still useful.
wine_launcher_renderer_vkd3d() {
	cat <<- 'EOF'
	# Use vkd3d for Direct3D rendering.
	if command -v winetricks >/dev/null 2>&1; then
	    winetricks_wrapper vkd3d
	else
	    message="\\033[1;33mWarning:\\033[0m\\n"
	    message="${message}vkd3d patches could not be installed in the WINE prefix.\\n"
	    message="${message}The game might run with display or performance issues.\\n"
	    printf "\\n${message}\\n"
	fi
	# Wait a bit to ensure there is no lingering wine process.
	sleep 1s

	EOF
}

