#!/usr/bin/env bash

# Function to run a game with FEXLoader
fex_load() {
    local gameDir="$1"
    local exeName="$2"
    export SPD_SOCKET=/run/user/1000/speech-dispatcher/speechd.sock
    pushd "$HOME/.local/games/$gameDir"
    if [[ "$(uname -m)" != "x86_64" ]]; then
        export FEX_NO_SANDBOX=1
        export MESA_GL_VERSION_OVERRIDE=3.2
        FEX_NO_SANDBOX=1 MESA_GL_VERSION_OVERRIDE=3.2 BOX64_DYNAREC_STRONGMEM=1 DISPLAY=:0 FEXLoader ./$exeName
    else
        export MESA_GL_VERSION_OVERRIDE=3.2
        MESA_GL_VERSION_OVERRIDE=3.2 DISPLAY=:0 ./$exeName
    fi
    popd
}

# Function to run a Windows game with wine via FEXBash
run_wine() {
    local gameDir="$1"
    local exeName="$2"
    local needNvda="${3:-}"
    pushd "$HOME/.local/games/$gameDir"
    if [[ "$(uname -m)" != "x86_64" ]]; then
        if [[ ${#needNvda} > 1 ]]; then
            systemctl --user start ${needNvda}.service
            FEXBash -c "wine \"$exeName\""
            systemctl --user stop ${needNvda}.service
        else
            FEXBash -c "wine $exeName"
        fi
    else
        if [[ ${#needNvda} > 1 ]]; then
            systemctl --user start ${needNvda}.service
            wine "$exeName"
            systemctl --user stop ${needNvda}.service
        else
            wine "$exeName"
        fi
    fi
    popd
}

# Function to handle downloadable games with installation
setup_and_run_downloadable() {
    local zipName="$1"
    local gameDir="$2"
    local executable="$3"
    local fallbackUrl="$4"
    local needNvda="$5"
    local zipPath=~/Downloads/"$zipName"
    local extractDir="$HOME/.local/games/$gameDir"
    if [[ -e "$zipPath" ]]; then
        # Recreate extractDir
        rm -rf "$extractDir"
        mkdir -p "$extractDir"
        # Get the first path component of each file in the zip
        mapfile -t topDirs < <(unzip -l "$zipPath" | awk 'NR>3 {print $4}' | grep '/$' | cut -d/ -f1 | sort -u | grep -v '^$')
        if [[ ${#topDirs[@]} -eq 1 ]]; then
            # Zip has a single top-level dir �se it as final dir
        unzip -q "$zipPath" -d ~/.local/games
        else
        # Unzips file into the given directory without creating a subdirectory
        unzip -q "$zipPath" -d "$extractDir"
        fi
        # Copy NVDA DLLs
        for i in 32 64; do
            find "$extractDir" -type f -name "nvdaControllerClient${i}.dll" -exec cp -v "$HOME/.local/games/nvda/nvdaControllerClient${i}.dll" '{}' \;
        done
        rm -f "$zipPath"
    fi
    if [[ -e "$extractDir/$executable" ]]; then
        run_wine "${extractDir##*/}" "./$executable" "$needNvda"
    else
        run_web "$fallbackUrl"
    fi
}

# Function to handle all web-based games
run_web() {
    orca &
    exec brave "$1"
}

# Function to handle unpacked web games
# Function to handle unpacked web games
setup_and_run_web_game() {
    local zipName="$1"
    local gameDir="$2"
    local htmlPath="$3"
    local fallbackUrl="$4"
    local zipPath=~/Downloads/"$zipName"
    local extractDir="$HOME/.local/games/$gameDir"
    if [[ -e "$zipPath" ]]; then
        # Recreate extractDir
        rm -rf "$extractDir"
        mkdir -p "$extractDir"
        # Get the first path component of each file in the zip
        mapfile -t topDirs < <(unzip -l "$zipPath" | awk 'NR>3 {print $4}' | grep '/$' | cut -d/ -f1 | sort -u | grep -v '^$')
        if [[ ${#topDirs[@]} -eq 1 ]]; then
            # Zip has a single top-level dir - extract to ~/.local/games
            unzip -q "$zipPath" -d "$HOME/.local/games"
        else
            # Unzips file into the given directory
            unzip -q "$zipPath" -d "$extractDir"
        fi
        rm -f "$zipPath"
    fi
    if [[ -e "$extractDir/$htmlPath" ]]; then
        run_web "$extractDir/$htmlPath"
    else
        run_web "$fallbackUrl"
    fi
}

# Function to run native applications
run_native() {
    local gameDir="$1"
    local exeName="$2"
    pushd "/home/stormux/.local/games/$gameDir"
    case "${exeName##*.}" in
      "py")
        python3 "$exeName"
      ;;
      "py")
        ./"$exeName"
      ;;
    esac
    popd
}

# Initial setup
if [[ -e /etc/X11/xorg.conf.d/10-headless.conf ]]; then
    export LIBGL_ALWAYS_SOFTWARE=1
fi

[ -f /etc/xprofile ] && . /etc/xprofile
[ -f ~/.xprofile ] && . ~/.xprofile
if [[ "$(uname -m)" != "x86_64" ]]; then
    export BOX64_PATH="$HOME/.fex-emu/RootFS/ArchLinux/usr/bin"
    export BOX64_NOBANNER=1
    export BOX64_DYNAREC_STRONGMEM=1
fi
export MESA_GL_VERSION_OVERRIDE=3.2
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
export DBUS_SESSION_BUS_PID
exec dwm &
xbindkeys


# Main game launcher
case "$GAME" in
  "Apple 2e")
    exec mame apple2ee -sl1 echoii -flop1 ~/.local/games/apple2e/Echo\ II\ -\ Textalker\ DOS\ 3.3.dsk -samplerate 48000 -sound pulse
    ;;
  "Audio Disc")
    run_wine "audiodisc" "disco.exe"
  ;;
  "BallBouncer")
    fex_load BallBouncer BallBouncer
  ;;
  "Battle of the Hunter")
    run_wine "Battle of the Hunter" "bth.exe" "nvda2speechd"
  ;;
  "blueman-manager")
    orca &
    blueman-manager
  ;;
  "Bokurano Daibouken")
    	/home/stormux/.local/files/clipboard_translator.sh play.exe bokurano-daibouken &
     	run_wine "bk" "play.exe"
     	killall speech-dispatcher
  ;;
  "Bokurano Daibouken 2")
    	/home/stormux/.local/files/clipboard_translator.sh play.exe bokurano-daibouken2 &
     	run_wine "bk2" "play.exe"
     	killall speech-dispatcher
  ;;
  "Bokurano Daibouken 3")
    if [[ -d /home/stormux/.local/games/bk3/dict ]] || [[ -e ~/Downloads/dict.dat ]]; then
      	[[ -e ~/Downloads/dict.dat ]] && mv ~/Downloads/dict.dat /home/stormux/.local/games/bk3/
      	run_wine "bk3" "play.exe" "nvda2speechd"
    else
      	/home/stormux/.local/files/clipboard_translator.sh play.exe bokurano-daibouken3 &
      	run_wine "bk3" "play.exe"
    fi
    killall speech-dispatcher
  ;;
  "Bop It")
    ~/.local/files/speak_window_title.sh bop.exe &
    run_wine "BopIt" "bop.exe"
  ;;
  "Brave")
    run_web ""  # Runs brave without a specific URL
  ;;
  "Challenge of the Horse")
    run_wine "Challenge of the Horse" "game.exe" "nvda2speechd"
  ;;
  "Clashes of the Sky")
    run_wine "clashes_of_the_sky" "clash.exe" "nvda2speechd"
  ;;
  "Constant Motion")
    run_wine "ConstantMotion" "cm.exe" "nvda2speechd"
  ;;
  "Crazy Party")
    run_wine "Crazy-Party-beta82" "Crazy\ Party.exe" "nvda2speechd-important"
  ;;
  "Doom")
    pushd /home/stormux/.local/games/doom/toby-doom-launcher
    git pull -q
    orca &
    exec "./Toby Doom Launcher.py"
    popd
  ;;
  "Dosbox")
    exec dosbox-x -fastlaunch -conf /opt/talking-dosbox/dosbox-x.conf
  ;;
  "Fantasy Story 2")
    pushd "/home/stormux/.local/games/Fantasy Story 2/FS2_3.0_Linux"
    if [[ "$(uname -m)" != "x86_64" ]]; then
        FEXBash './fs2.x86_64'
    else
        './fs2.x86_64'
    fi
    popd
  ;;
  "Golf")
    run_wine "golf" "golf.exe"
  ;;
  "Horseshoes")
    pushd /home/stormux/.local/games/horseshoes
    ./horseshoes
    popd
  ;;
  "Haunted House")
    pushd /home/stormux/.local/games/haunted-house
    ./runner haunted-house
    popd
  ;;
  "Haunted Party")
    setup_and_run_downloadable "hp.zip" "hp" "hp.exe" "https://tunmi13.itch.io/haunted-party" "nvda2speechd"
  ;;
  "Kaskade")
    setup_and_run_downloadable "battlefield-2d-win.zip" "bf" "bf.exe" "https://tunmi13.itch.io/kaskade" "nvda2speechd"
  ;;
  "Mach1")
    run_wine "mach1" "mach1.exe"
  ;;
  "Manamon 2")
    run_wine "Manamon 2" "rpg.exe" "nvda2speechd"
  ;;
  "Mine Racer")
    pushd /home/stormux/.local/games/Mineracer
    ./mineracer
    popd
  ;;
  "Oh Shit")
    run_wine "oh_shit" "OhShit.exe" "nvda2speechd"
  ;;
  "Pong")
    run_wine "pong" "pong.exe"
  ;;
  "Q9 Action Game")
    run_wine "Q9 Action Game" "q9.exe"
  ;;
  "Retro Arch")
    /usr/bin/retroarch --accessibility
    killall speech-dispatcher
  ;;
  "River Raiders")
    run_wine "River Raiders" "raid.exe"
  ;;
  "RS Games")
    run_wine "RS Games Client" "rsg.exe" "nvda2speechd-important"
  ;;
  "Scramble")
    run_wine "scramble_win32" "scramble.exe" "nvda2speechd"
  ;;
  "Screaming Strike 2")
    run_wine "Screaming Strike 2" "play.exe" "nvda2speechd"
  ;;
  "Scrolling Battles")
    run_wine "Scrolling Battles" "sb.exe" "nvda2speechd"
  ;;
  "Shadow Line")
    run_wine "ShadowRine_FullVoice" "play_sr.exe" "nvda2speechd"
  ;;
  "Shooter")
    run_wine "shooter" "Shooter.exe" "nvda2speechd"
  ;;
  "Side Party")
    setup_and_run_downloadable "sideparty-win.zip" "SideParty" "SideParty.exe" "https://masonasons.itch.io/sideparty" "nvda2speechd"
  ;;
  "Skateboarder Pro")
    run_wine "sb_pro_rw" "sb_pro.exe" "nvda2speechd"
  ;;
  "Sketchbook (Your World)")
    run_wine "SBYW" "SBYW.exe" "nvda2speechd-important"
  ;;
  "SoundRTS")
    run_native "SoundRTS" "soundrts.py"
  ;;
  "Steam")
    orca &
    exec steam -bigpicture
  ;;
  "Super Egg Hunt")
  run_wine "super egg hunt" "superegghunt.exe"
  ;;
  "Super Liam")
  run_wine "Super Liam" "sl.exe"
  ;;
  "The Blind Swordsman")
    if [[ "$(uname -m)" != "x86_64" ]]; then
        FEXBash -c 'wine ~/.local/games/TheBlindSwordsman.exe'
    else
        wine ~/.local/games/TheBlindSwordsman.exe
    fi
  ;;
  "The Tornado Chicken")
    fex_load "The Tornado Chicken" "Ttc"
  ;;
  "Top Speed 3")
    run_wine "Top Speed 3" "TopSpeed.exe"
  ;;
  "Toy Mania")
    if [[ -e ~/Downloads/ToyMania_windows_portable_password_is_GrateCollector.7z ]]; then
        rm -rf ~/.local/games/ToyMania
        mkdir -p ~/.local/games/ToyMania
        7z x ~/Downloads/ToyMania_windows_portable_password_is_GrateCollector.7z -o/home/stormux/.local/games/ToyMania -pGrateCollector
        rm -f ~/Downloads/ToyMania_windows_portable_password_is_GrateCollector.7z
    fi
    if [[ -e ~/.local/games/ToyMania/tm.exe ]]; then
        cp ~/.local/games/nvda/nvdaControllerClient64.dll ~/.local/games/ToyMania/lib/nvdaControllerClient64.dll
        systemctl --user start nvda2speechd-important.service
        pushd ~/.local/games/ToyMania
        if [[ "$(uname -m)" != "x86_64" ]]; then
            exec FEXBash -c 'wine ./tm.exe'
        else
            exec wine ./tm.exe
        fi
        popd
        systemctl --user stop nvda2speechd-important.service
    else
        orca &
        exec brave "https://tsatria03.itch.io/toymania"
    fi
    ;;
  "Upheaval")
    setup_and_run_downloadable "upheaval-linux-console.zip" "Upheaval" "Upheaval_Command_Line" "https://leonegaming.itch.io/upheaval"
  ;;
  "Villains From Beyond")
    run_wine "villains from beyond" "game.exe"
  ;;
  "Warsim")
    setup_and_run_downloadable "Warsim Full Game.zip" "Warsim" "Warsim.exe" "https://huw2k8.itch.io/warsim"
  ;;
  "Wheels of Prio")
    fex_load "Wheels of Prio" "Wp"
  ;;
  "Wicked Quest")
    run_native "wicked-quest" "wicked_quest.py"
  ;;
  "Zombowl")
    run_native "zombowl" "zombowl.py"
  ;;
  "https://shiftbacktick.itch.io/periphery-synthetic-ep")
    setup_and_run_web_game "periphery-synthetic-ep-html5.zip" "periphery-synthetic-ep" "index.html" "$GAME"
  ;;
  "https://"*)
    run_web "$GAME"
  ;;
  "DISK_ONLY:"*)
    DISK_PATH="${GAME#DISK_ONLY:}"
    xbindkeys
    exec mame apple2ee -sl1 echoii -flop1 "$DISK_PATH" -samplerate 48000 -sound pulse
  ;;
  *".dsk")
    xbindkeys
    exec mame apple2ee -sl1 echoii -flop1 ~/.local/games/apple2e/Echo\ II\ -\ Textalker\ DOS\ 3.3.dsk -flop2 "$GAME" -samplerate 48000 -sound pulse
  ;;
  *"/Roms/"*)
    exec mednafen -sounddriver sdl -sound 1 "$GAME"
  ;;
  *)
    echo "No valid game specified in \$GAME"
    sleep 5
  ;;
esac

# Make sure X goes down after game ends
pkill -15 Xorg
