# WINE - Set default value for WINEDLLOVERRIDES
# USAGE: wine_dlloverrides_default
# RETURN: the default value to use for WINEDLLOVERRIDES,
#         if it is not set in the user environment.
wine_dlloverrides_default() {
	# A default value can be set from the game script, using the variable WINE_DLLOVERRIDES_DEFAULT
	local wine_dlloverrides
	wine_dlloverrides=$(context_value 'WINE_DLLOVERRIDES_DEFAULT')

	# Fall back on a default value
	if [ -z "$wine_dlloverrides" ]; then
		local wineprefix_tweaks
		wineprefix_tweaks=$(wine_wineprefix_tweaks)
		if printf '%s' "$wineprefix_tweaks" | grep --quiet --fixed-strings --line-regexp --regexp='mono'; then
			## If Mono is going to be used in the WINE prefix, "mscoree" should not be disabled.
			wine_dlloverrides='winemenubuilder.exe,mshtml='
		else
			wine_dlloverrides='winemenubuilder.exe,mscoree,mshtml='
		fi
	fi

	printf '%s' "$wine_dlloverrides"
}

# WINE launcher - Set the WINE prefix environment
# USAGE: wine_launcher_wineprefix_environment
wine_launcher_wineprefix_environment() {
	# Set compatibility links to legacy paths
	## TODO: env --chdir could be used instead of cd in a subshell.
	cat <<- 'EOF'
	# Set compatibility link to a legacy user path
	wineprefix_legacy_link() {
	    path_current="$1"
	    path_legacy="$2"

	    user_directory="${WINEPREFIX}/drive_c/users/${USER}"
	    (
	        cd "$user_directory"
	        if [ ! -e "$path_current" ]; then
	            path_current_parent=$(dirname "$path_current")
	            mkdir --parents "$path_current_parent"
	            mv "$path_legacy" "$path_current"
	        fi
	        path_legacy_parent=$(dirname "$path_legacy")
	        mkdir --parents "$path_legacy_parent"
	        ## Warning: the use of a link to an absolute path means that the WINE prefix can not be moved around without breaking the link.
	        ## Using a link to a relative path would be better, but harder to implement when $path_legacy includes several path components (like "Local Settings/Application Data").
	        ln --symbolic "${user_directory}/${path_current}" "$path_legacy"
	    )
	    unset user_directory path_current_parent

	    unset path_current path_legacy
	}

	EOF

	# Compute WINE prefix architecture
	local option_package wine_architecture
	option_package=$(option_value 'package')
	case "$option_package" in
		('arch')
			## Arch Linux WINE is built in wow64 mode,
			## in that mode win32 prefixes can not be created.
			wine_architecture='win64'
		;;
		(*)
			local package package_architecture
			package=$(current_package)
			package_architecture=$(package_architecture "$package")
			case "$package_architecture" in
				('32')
					wine_architecture='win32'
				;;
				('64')
					wine_architecture='win64'
				;;
			esac
		;;
	esac

	# Set variables used for WINE prefix
	local wine_dlloverrides_default
	wine_dlloverrides_default=$(wine_dlloverrides_default)
	cat <<- EOF
	# Set variables used for WINE prefix
	export WINEARCH='$wine_architecture'
	export WINEDEBUG="\${WINEDEBUG:=-all}"
	export WINEPREFIX="\$PATH_WINEPREFIX"
	## Disable some WINE anti-features
	## - creation of desktop entries
	## - installation of Mono
	## - installation of Gecko
	export WINEDLLOVERRIDES="\${WINEDLLOVERRIDES:=${wine_dlloverrides_default}}"
	## Work around WINE bug 41639 - Wine with freetype 2.7 causes font rendering issues
	## cf. https://bugs.winehq.org/show_bug.cgi?id=41639
	export FREETYPE_PROPERTIES='truetype:interpreter-version=35'

	EOF
}

# Print the actions that should be run when initialising the WINE prefix.
# USAGE: wine_wineprefix_init_actions
wine_wineprefix_init_actions() {
	local game_id
	game_id=$(game_id)
	cat <<- EOF
	# Link the game prefix into the WINE prefix.
	ln --symbolic \\
	    "\$PATH_PREFIX" \\
	    "\${WINEPREFIX}/drive_c/${game_id}"

	EOF
	cat <<- 'EOF'
	# Remove most links pointing outside of the WINE prefix.
	rm "$WINEPREFIX/dosdevices/z:"
	find "$WINEPREFIX/drive_c/users/$(whoami)" -type l | while read -r directory; do
	    rm "$directory"
	    mkdir "$directory"
	done
	unset directory

	# Set symbolic links to the legacy paths.
	wineprefix_legacy_link 'AppData/Roaming' 'Application Data'
	wineprefix_legacy_link 'AppData/Local' 'Local Settings/Application Data'
	wineprefix_legacy_link 'Documents' 'My Documents'

	EOF

	# Include custom actions set from the game script.
	wineprefix_init_custom
}

# Set custom actions to run on WINE prefix initialisation.
# USAGE: wineprefix_init_custom
wineprefix_init_custom() {
	# This function prints nothing by default,
	# it should be overridden from game scripts to have any effect.
	return 0
}

# Generate the WINE prefix.
# USAGE: wine_launcher_wineprefix_generate
wine_launcher_wineprefix_generate() {
	cat <<- 'EOF'
	# Generate the WINE prefix.
	if ! [ -e "${WINEPREFIX}/system.reg" ]; then
	EOF

	## An extra level of indentation is added to all text output by the following group of commands.
	{
		cat <<- 'EOF'
		mkdir --parents "$(dirname "$WINEPREFIX")"

		# Use LANG=C to avoid localized directory names.
		LANG=C $(wine_command) wineboot.exe --init 2>/dev/null

		# Wait until the WINE prefix creation is complete.
		printf "Waiting for the WINE prefix initialization to complete, it might take a couple seconds…\\n"
		while [ ! -f "${WINEPREFIX}/system.reg" ]; do
		    sleep 1s
		done

		EOF

		# Print the actions that should be run when initialising the WINE prefix.
		wine_wineprefix_init_actions
		local game_engine
		game_engine=$(game_engine)
		case "$game_engine" in
			('unity3d')
				wine_wineprefix_init_actions_unity3d
			;;
		esac

		# If required, install Mono in the prefix.
		local wineprefix_tweaks
		wineprefix_tweaks=$(wine_wineprefix_tweaks)
		if printf '%s' "$wineprefix_tweaks" | grep --quiet --fixed-strings --line-regexp --regexp='mono'; then
			wine_wineprefix_tweak_mono_install
		fi

		# Run initial winetricks call.
		local winetricks_verbs
		winetricks_verbs=$(wine_winetricks_verbs)
		if [ -n "$winetricks_verbs" ]; then
			cat <<- EOF
			# Run the initial winetricks call.
			winetricks_wrapper ${winetricks_verbs}

			EOF
		fi

		# Load registry scripts.
		regedit_initial

		# Set Direct3D renderer.
		wine_launcher_renderer

	} | sed 's/^/\t/;s/^\s*$//'

	cat <<- 'EOF'
	fi

	EOF
}

# WINE launcher - Handle paths diversion from WINE prefix to persistent storage
# USAGE: wine_launcher_wineprefix_persistent
wine_launcher_wineprefix_persistent() {
	local persistent_directories
	persistent_directories=$(wine_persistent_directories)
	if [ -n "$persistent_directories" ]; then
		cat <<- EOF
		# Divert paths from the WINE prefix to persistent storage
		WINE_PERSISTENT_DIRECTORIES="$persistent_directories"
		EOF
		cat <<- 'EOF'
		while read -r directory; do
		    if [ -z "$directory" ]; then
		        continue
		    fi
		    persistent_path_diversion "${WINEPREFIX}/drive_c" "${PATH_PERSISTENT}/wineprefix" "$directory"
		done <<- EOL
		$(printf '%s' "$WINE_PERSISTENT_DIRECTORIES")
		EOL
		unset directory

		EOF
		return 0
	fi
}

