#!/bin/bash

GAME_BINARY="ut-bin"
SYSTEM_DIR="System"

# Additional commandline options for mods etc.
CMD_ARGS=()

# don't use US keyboard layout
#NOUSLAYOUT="true"

resolve_link() {
    local path target dir
    path="$1"

    [ -L "$path" ] || return 1

    target="$(LC_ALL=C ls -l "$path" 2>/dev/null)"
    target="${target##* -> }"

    case "$target" in
        /*) printf '%s\n' "$target" ;;
        *)
            dir="$(dirname "$path")"
            printf '%s\n' "$dir/$target"
            ;;
    esac
}

LANG=POSIX
export LANG
script="$0"
count=0
while [ -L "$script" ]
do
    script="$(resolve_link "$script")"
    count=$((count + 1))
    if [ "$count" -gt 100 ]
    then
        echo "Too many symbolic links"
        exit 1
    fi
done

GAME_DIR="$(cd "$(dirname "$script")" && pwd)"
GAME_SYSTEM_DIR="${GAME_DIR}/${SYSTEM_DIR}"
USER_UT_DIR="${HOME}/.loki/ut/${SYSTEM_DIR}"
SYSTEM_DEFAULT_GLIDE="${GAME_SYSTEM_DIR}/Default-glide.ini"
SYSTEM_DEFAULT_OPENGL="${GAME_SYSTEM_DIR}/Default-opengl.ini"
SYSTEM_DEFAULT_USER="${GAME_SYSTEM_DIR}/DefUser.ini"
USER_UT_INI="${USER_UT_DIR}/UnrealTournament.ini"
USER_USER_INI="${USER_UT_DIR}/User.ini"

if [ ! -d "${USER_UT_DIR}" ]
then
    mkdir -p "${USER_UT_DIR}"
fi

detect_renderer() {
    if [ -e /usr/lib/libglide2x.so ] || [ -e /usr/local/lib/libglide2x.so ]; then
        echo "glide"
    else
        echo "opengl"
    fi
}

install_ini_profile() {
    local renderer="$1"

    case "$renderer" in
        glide)
            if [ -r "${SYSTEM_DEFAULT_GLIDE}" ]; then
                cp -f "${SYSTEM_DEFAULT_GLIDE}" "${USER_UT_INI}"
                return 0
            fi
            ;;
        opengl)
            if [ -r "${SYSTEM_DEFAULT_OPENGL}" ]; then
                cp -f "${SYSTEM_DEFAULT_OPENGL}" "${USER_UT_INI}"
                return 0
            fi
            ;;
    esac

    return 1
}

if [ ! -f "${USER_UT_INI}" ]; then
    RENDERER="$(detect_renderer)"
    install_ini_profile "${RENDERER}" || {
        echo "Failed to install renderer profile: ${RENDERER}"
        exit 1
    }
    sed -i \
        -e 's/^AudioDevice=ALAudio.ALAudioSubsystem$/AudioDevice=Audio.GenericAudioSubsystem/' \
        -e 's/^CacheSizeMegs=4$/CacheSizeMegs=32/' \
        -e 's/^FullscreenViewportX=640$/FullscreenViewportX=800/' \
        -e 's/^FullscreenViewportY=480$/FullscreenViewportY=600/' \
        -e 's/^UseSpatial=False$/UseSpatial=True/' \
        -e 's/^UseReverb=False$/UseReverb=True/' \
        -e 's/^OutputRate=22050Hz$/OutputRate=44100Hz/' \
        -e 's/^ConfiguredInternetSpeed=20000$/ConfiguredInternetSpeed=25000/' \
        "${USER_UT_INI}"
fi

# Remove passwords from UnrealTournament.ini
if [ -r "${USER_UT_INI}" ]
then
    sed -i \
        -e 's/^\(SavedPasswords\[[0-9]*\]=\).*/\1/' \
        -e 's/^\(PasswordHistory\[[0-9]*\]=\).*/\1/' \
        "${USER_UT_INI}"
fi


set_random_ut_name() {
    local target_file="$1"

    [ -n "$target_file" ] || return 1
    [ -f "$target_file" ] || return 1

    local names='
Phobos
Vortex
Raptor
Hexer
Cobra
Grendel
Nyx
Blitz
Talon
Havoc
Stryker
Wraith
Nova
Reaper
Goliath
Drift
Razor
Pixel
Onyx
Fury
'

    local count=$(printf '%s\n' "$names" | sed '/^$/d' | wc -l)
    local idx=$(( (RANDOM % count) + 1 ))
    local base_name=$(printf '%s\n' "$names" | sed '/^$/d' | sed -n "${idx}p")
    local suffix=$(printf '%02d' $((RANDOM % 100)))
    local new_name="${base_name}${suffix}"

    sed -i "s/^Name=Player$/Name=${new_name}/" "$target_file"
}

if [ ! -f "${USER_USER_INI}" ]; then
    if [ ! -r "${SYSTEM_DEFAULT_USER}" ]; then
        echo "Missing ${SYSTEM_DEFAULT_USER}"
        exit 1
    fi
    cp -f "${SYSTEM_DEFAULT_USER}" "${USER_USER_INI}"
    set_random_ut_name "${USER_USER_INI}"
fi

trap "setxkbmap" EXIT

# games run better with US keyboard layout
OLD_XKB_LAYOUT=""
OLD_XKB_VARIANT=""
OLD_XKB_OPTIONS=""

if [ -z "$NOUSLAYOUT" ] && command -v setxkbmap >/dev/null 2>&1; then
    OLD_XKB_LAYOUT="$(setxkbmap -query 2>/dev/null | awk '$1=="layout:" {print $2}')"
    OLD_XKB_VARIANT="$(setxkbmap -query 2>/dev/null | awk '$1=="variant:" {print $2}')"
    OLD_XKB_OPTIONS="$(setxkbmap -query 2>/dev/null | awk '$1=="options:" {$1=""; sub(/^ /,""); print}')"

    restore_xkb() {
        if [ -n "$OLD_XKB_LAYOUT" ]; then
            if [ -n "$OLD_XKB_VARIANT" ]; then
                setxkbmap -layout "$OLD_XKB_LAYOUT" -variant "$OLD_XKB_VARIANT" >/dev/null 2>&1 || true
            else
                setxkbmap -layout "$OLD_XKB_LAYOUT" >/dev/null 2>&1 || true
            fi

            if [ -n "$OLD_XKB_OPTIONS" ]; then
                setxkbmap -option "$OLD_XKB_OPTIONS" >/dev/null 2>&1 || true
            else
                setxkbmap -option >/dev/null 2>&1 || true
            fi
        fi
    }

    trap restore_xkb EXIT
    setxkbmap -symbols 'us(pc101)'
fi

LD_LIBRARY_PATH="${GAME_SYSTEM_DIR}:${LD_LIBRARY_PATH}"
export LD_LIBRARY_PATH

cd "${GAME_SYSTEM_DIR}" || exit 1

# start the game
if nice -n -5 true >/dev/null 2>&1; then
    echo "Launching UT99 with elevated priority"
    exec nice -n -5 -- "./$GAME_BINARY" "${CMD_ARGS[@]}" "$@"
else
    echo "Negative nice not permitted, launching normally"
    exec "./$GAME_BINARY" "${CMD_ARGS[@]}" "$@"
fi
