#!/usr/bin/bash
# Lux Wine wrapper for RunImage container

shopt -s extglob

RED='\033[1;91m'
BLUE='\033[1;94m'
GREEN='\033[1;92m'
YELLOW='\033[1;33m'
RESETCOLOR='\033[1;00m'

LW_DIR="$HOME/.local/share/LuxWine"
MENU_APPS_DIR="$HOME/.local/share/applications"
LW_CFG="$LW_DIR/luwine.wcfg"
LWBIN_DIR="$LW_DIR/bin"
LWSRC='/opt/lwrap/bin/lux-wine'
HOME_ICONS="$HOME/.local/share/icons"
HOME_DESK_DIRS="$HOME/.local/share/desktop-directories"
HSTEAM_DESKF="$MENU_APPS_DIR/steam-lw.desktop"
HBIN_DIR="$HOME/.local/bin"
LWRUN_LN="$HBIN_DIR/lwrun"
OLDLWRAP="$LWBIN_DIR/lwrap"
LWRUN="$LWBIN_DIR/lwrun"
RUNIMAGE_LW="$LWBIN_DIR/runimage-lw"
PKGUPDFL="$LWBIN_DIR/.update"
HICOLOR_SIZES=(
    "512x512" "256x256" "192x192" "128x128"
    "96x96" "80x80" "72x72" "64x64" "48x48"
    "32x32" "24x24" "16x16"
)
LW_MIMETYPES=(
    'application/x-ms-dos-executable' 'application/x-wine-extension-msp'
    'application/x-msi' 'application/x-msdos-program' 'text/win-bat'
    'application/x-ms-shortcut' 'text/x-ms-regedit'
)

CFG_CHK_UPDATE="$(grep '^CHK_UPDATE=.*$' "$LW_CFG" 2>/dev/null)"
[ -n "$CFG_CHK_UPDATE" ] && \
eval "$CFG_CHK_UPDATE"||\
CHK_UPDATE='3'

[[ ! "$(LANG= tty|grep -v 'not a')" =~ tty|pts ]] && \
    NOT_TERM=1||NOT_TERM=0

error_msg() {
    echo -e "${RED}[ ERROR ][$(date +"%Y.%m.%d %T")]: $@ $RESETCOLOR" 1>&2
    if [ "$NOT_TERM" == 1 ]
        then notify-send -a 'Lux Wine Error' "$@" 2>/dev/null &
    fi
}

info_msg() {
    if [ "$QUIET_MODE" != 1 ]
        then
            echo -e "${GREEN}[ INFO ][$(date +"%Y.%m.%d %T")]: $@ $RESETCOLOR" 1>&2
            if [[ "$NOT_TERM" == 1 && "$NO_NOTIFY" != 1 ]]
                then notify-send -a 'Lux Wine Info' "$@" 2>/dev/null &
            fi
    fi
}

warn_msg() {
    if [ "$QUIET_MODE" != 1 ]
        then
            echo -e "${YELLOW}[ WARNING ][$(date +"%Y.%m.%d %T")]: $@ $RESETCOLOR" 1>&2
            if [[ "$NOT_TERM" == 1 && "$NO_NOTIFY" != 1 ]]
                then notify-send -a 'Lux Wine Warning' "$@" 2>/dev/null &
            fi
    fi
}

make_install() {
    add_path() {
        check_path() {
            if [ "$1" == "$F_RC" ]
                then grep -om1 '^set -U fish_user_paths "$HOME/.local/bin"' "$1" &>/dev/null
                else grep -om1 '^export PATH=.*/.local/bin' "$1" &>/dev/null
            fi
        }
        if [ "$1" == "$F_RC" ]
            then check_path "$1"||(mkdir -p "$(dirname "$1")" && echo -e '\nset -U fish_user_paths "$HOME/.local/bin"' >> "$1")
            else check_path "$1"||echo -e '\nexport PATH="$HOME/.local/bin:$PATH"' >> "$1"
        fi
    }
    F_RC="$HOME/.config/fish/config.fish"
    B_RC="$HOME/.bashrc"
    Z_RC="$HOME/.zshrc"
    if [ "$1" == "force" ]
        then QUIET_MODE=1 uninstall_lw force
        else QUIET_MODE=1 uninstall_lw update
    fi
    grep -m1 '^Exec=".*"' -lr ./*|\
    xargs -d'\n' sed -i "s|^Exec=\".*\"|Exec=\"$LWRUN\"|g" 2>/dev/null
    install -Dm644 LuxWine.menu "$HOME/.config/menus/applications-merged/LuxWine.menu"
    if [ "$KDE_SESSION_VERSION" == 6 ]
        then install -Dm755 LuxWineService.desktop "$HOME/.local/share/kio/servicemenus/LuxWineService.desktop"
    elif [ "$KDE_SESSION_VERSION" == 5 ]
        then install -Dm755 LuxWineService.desktop "$HOME/.local/share/kservices5/ServiceMenus/LuxWineService.desktop"
    fi
    mkdir -p "$MENU_APPS_DIR"
    mkdir -p "$HOME_DESK_DIRS"
    cp -rf mime "$HOME/.local/share/mime"
    cp -rf applications "$MENU_APPS_DIR/LuxWine"
    cp -rf directories/* "$HOME_DESK_DIRS/"
    RSTEAM_DESKF="$RUNROOTFS/usr/share/applications/steam.desktop"
    if [[ -d "$RUNROOTFS" && -f "$RSTEAM_DESKF" ]]
        then
            cp -rf "$RSTEAM_DESKF" "$HSTEAM_DESKF"
            sed -i "s|^Exec.*steam.*|Exec='$HBIN_DIR/steam' %U|g" "$HSTEAM_DESKF"
            sed -i "s|^Name=Steam.*|Name=Steam (RunImage LW)|g" "$HSTEAM_DESKF"
            sed -i '/\[Desktop Entry\]/a StartupWMClass=Steam' "$HSTEAM_DESKF"
            sed -i '/RunOnDiscreteGpu/d;/PrefersNonDefaultGPU/d' "$HSTEAM_DESKF"
            HICNSTM="$HOME_ICONS/steam.png"
            for hi_icon_size in ${HICOLOR_SIZES[@]}
                do
                    HICONS_DIR="$HOME_ICONS/hicolor/$hi_icon_size/apps"
                    RSTEAM_ICON="$RUNROOTFS/usr/share/icons/hicolor/$hi_icon_size/apps/steam.png"
                    HSTEAM_ICON="$HICONS_DIR/steam.png"
                    if [[ -f "$RSTEAM_ICON" && ! -f "$HSTEAM_ICON" ]]
                        then
                            mkdir -p "$HICONS_DIR"
                            [ -L "$HSTEAM_ICON" ] && \
                                rm -f "$HSTEAM_ICON"
                            cp -rf "$RSTEAM_ICON" "$HSTEAM_ICON"
                    fi
                    if [[ -f "$RSTEAM_ICON" && ! -f "$HICNSTM" ]]
                        then
                            mkdir -p "$HOME_ICONS"
                            [ -L "$HICNSTM" ] && \
                                rm -f "$HICNSTM"
                            cp -rf "$RSTEAM_ICON" "$HICNSTM"
                    fi
            done
    fi
    [ "$INSIDE_RUNIMAGE" == 1 ] && \
        local INSTALL_SHELL="$(hostexec printenv SHELL)"||\
        local INSTALL_SHELL="$SHELL"
    case "$(basename "$INSTALL_SHELL")" in
        zsh) add_path "$Z_RC" ;;
        bash) add_path "$B_RC" ;;
        fish) add_path "$F_RC" ;;
    esac
    update-desktop-database -q "$MENU_APPS_DIR" &>/dev/null
    update-mime-database "$HOME/.local/share/mime" &>/dev/null
    for mimetype in "${LW_MIMETYPES[@]}"
        do xdg-mime default LuxWine.desktop "$mimetype" &>/dev/null
    done
    cp -rf registry_patch "$LW_DIR/"
    cp -rf LICENSE "$LW_DIR/"
    cp -rf themes "$LW_DIR/"
    cp -rf icons "$LW_DIR/"
    cp -rf gif "$LW_DIR/"
    cp -rf db "$LW_DIR/"
    LWRUNTIME="/opt/lwrap/runtime.tar.zst"
    if [ -f "$LWRUNTIME" ]
        then
            TMP_LW_CFG="$LW_DIR/tmp/luwine.wcfg"
            tar -xf "$LWRUNTIME" -C "$LW_DIR" && \
            [[ ! -f "$LW_CFG" && -f "$TMP_LW_CFG" ]] && \
                cp -f "$TMP_LW_CFG" "$LW_CFG"
    fi
    grep "$OLDLWRAP" -lr "$MENU_APPS_DIR"|\
    xargs -d'\n' sed -i "s|$OLDLWRAP|$LWRUN|g" 2>/dev/null
}

mv_lwrun() {
    if [ -w "$1" ]
        then mv -f "$1" "$2"
        else [ -L "$2" ] && rm -f "$2"
            cp -f "$1" "$2"
    fi
}

try_install_lwrun() {
    readrealpath() {
        if is_exe_exist readlink
            then readlink -f "$@" 2>/dev/null
        elif is_exe_exist realpath
            then realpath "$@" 2>/dev/null
        else return 1
        fi
    }
    ln_lwrun() {
        mkdir -p "$HBIN_DIR"
        if [ "$(readrealpath "$LWRUN_LN")" != "$LWRUN" ]
            then
                info_msg "Update lwrun link..."
                ln -sf "$LWRUN" "$LWRUN_LN"
        fi
        for steam in {steam,steam-native}
            do
                STEAM_LN="$HBIN_DIR/$steam"
                if [ "$(readrealpath "$STEAM_LN")" != "$LWRUN" ]
                    then
                        info_msg "Update $steam link..."
                        ln -sf "$LWRUN" "$STEAM_LN"
                fi
        done
        if [ "$(readrealpath "$RUNIMAGE_LW")" != "$LWRUN" ]
            then
                info_msg "Update runimage link..."
                mkdir -p "$LWBIN_DIR"
                ln -sf "$LWRUN" "$RUNIMAGE_LW"
                ln -sf "$LWRUN" "$HBIN_DIR/runimage-lw"
        fi
        XTERM_LN="$LWBIN_DIR/xterm"
        if [ "$(readrealpath "$XTERM_LN")" != "$LWRUN" ]
            then
                mkdir -p "$LWBIN_DIR"
                ln -sf "$LWRUN" "$XTERM_LN"
        fi
        LWRAP_LN="$LWBIN_DIR/lwrap"
        if [ "$(readrealpath "$LWRAP_LN")" != "$LWRUN" ]
            then
                mkdir -p "$LWBIN_DIR"
                ln -sf "$LWRUN" "$LWRAP_LN"
        fi
    }
    if [[ "$RUNSRC" =~ "lwrun" && -f "$REALRUNSRC" && "$LWLN_ONLY" != 1 && \
        "$REALRUNSRC" != "$LWRUN" && ! "${REALRUNSRC,,}" =~ .*/(run$|cdrom/lwrun|sr[0-9]/lwrun)$ && \
        ! "$REALRUNSRC" =~ ^/(usr/bin|bin|opt)/lwrun$ ]]
        then
            info_msg "Installing lwrun..."
            mkdir -p "$LWBIN_DIR"
            if mv_lwrun "$REALRUNSRC" "$LWRUN"
                then
                    ln_lwrun
                    info_msg "lwrun installed!"
                    try_shutdown_lw && \
                    return 0||return 1
                else
                    error_msg "Failed to install lwrun!"
                    is_lwrun && \
                    return 1||exit 1
            fi
    elif [[ "$REALRUNSRC" != "$(readrealpath "$LWRUN")" ]] && \
        [[ "${REALRUNSRC,,}" =~ .*/(run|cdrom.*/lwrun|sr[0-9]/lwrun)$ ||\
           "$REALRUNSRC" =~ ^/(usr/bin|bin|opt)/lwrun$ ||\
           "$RUNSRC" =~ .*/RunDir/lwrun$ || "$LWLN_ONLY" == 1 ]]
        then
            mkdir -p "$LWBIN_DIR"
            ln -sf "$REALRUNSRC" "$LWRUN"
            ln_lwrun
            [ "$LWLN_ONLY" != 1 ] && \
            return 0||exit
    fi
}

uninstall_lw() {
    if [ "$1" == "force" ] || is_lw || is_lwrun
        then
            info_msg "Removing Lux Wine..."
            rm -f "$HSTEAM_DESKF"
            rm -rf "$MENU_APPS_DIR/LuxWine"
            rm -rf "$HOME_DESK_DIRS/LuxWine"*
            rm -f "$HOME/.config/menus/applications-merged/LuxWine.menu"
            rm -rf "$HOME/.local/share/kservices5/ServiceMenus/LuxWine"*
            rm -rf "$HOME/.local/share/kio/servicemenus/LuxWine"*
            rm -f "$OLDLWRAP"
            rm -f "$LWBIN_DIR/lux-wine"
            rm -f "$LWBIN_DIR/bash"
            rm -f "$LWBIN_DIR/lwexec"
            rm -f "$HBIN_DIR/lwrap"
            if [ "$1" == "update" ]
                then
                    rm -rf "$LW_DIR/db"
                    rm -rf "$LW_DIR/gif"
                    rm -rf "$LW_DIR/icons"
                    rm -rf "$LW_DIR/themes"
                    rm -f "$LW_DIR/LICENSE"
                    rm -f "$LW_DIR/.lwcfgchksum"
                    rm -rf "$LW_DIR/registry_patch"
                else
                    chmod u+rw -R "$LWBIN_DIR/overlayfs/lux-wine/workdir" 2>/dev/null
                    rm -rf "$LW_DIR"
                    rm -rf "$HOME/LuxWine"
                    rm -rf "$LWRUN_LN"
                    rm -rf "$HBIN_DIR/runimage-lw"
                    rm -rf "$MENU_APPS_DIR/LuxWine"*
                    rm -rf "$HOME/Desktop/LuxWine.desktop"
                    rm_broken_link "$HBIN_DIR"
                    rm_broken_link "$HOME_ICONS"
            fi
    fi
    info_msg "Lux Wine removed!"
}

is_net_conn() {
    if is_exe_exist nc
        then nc -zw1 github.com 443 &>/dev/null
    elif is_exe_exist ping
        then ping -c 1 github.com &>/dev/null
    elif is_exe_exist curl
        then curl -Ifs github.com &>/dev/null
    elif is_exe_exist wget
        then wget -q --spider github.com &>/dev/null
    else return 1
    fi
}

is_lw() { [ -f "$MENU_APPS_DIR/LuxWine/LuxWine.desktop" ] ; }

is_old_lw() { [ -x "$LWBIN_DIR/lux-wine" ] ; }

is_lwrun() { [ -x "$LWRUN" ] ; }

install_lw() {
    TMP_LW="/tmp/lux-wine.$RANDOM"
    if [ -d "/opt/lwrap" ]
        then
            info_msg "Installing Lux Wine..."
            (mkdir -p "$TMP_LW" && \
            cp -rf "/opt/lwrap"/!(runtime.tar.zst|prefix_backups) "$TMP_LW" && \
            cd "$TMP_LW" && \
            make_install "$1"
            [ -d "$TMP_LW" ] && rm -rf "$TMP_LW")
    fi
    if is_lw
        then info_msg "Lux Wine installed!"
        else
            error_msg "Failed to install Lux Wine!"
            exit 1
    fi
}

try_dl_lwrun() {
    try_dllwrun_mirror() {
        local GIT_LWRUN_VERSION='continuous'
        local GIT_LWRUN="https://github.com/VHSgunzo/lwrun/releases"
        local GIT_HF_LWRUN="https://huggingface.co/lux-wine/lwrun/resolve/main/releases"
        local YC_LWRUN="https://storage.yandexcloud.net/lwrun"
        local lwrunurl=(
            "$YC_LWRUN/releases/$GIT_LWRUN_VERSION/lwrun"
            "$GIT_HF_LWRUN/$GIT_LWRUN_VERSION/lwrun"
            "$GIT_LWRUN/download/$GIT_LWRUN_VERSION/lwrun"
        )
        for url in "${lwrunurl[@]}"
            do
                try_dl "$url" "$TMP_LWRUN" && \
                    return 0
        done
        return 1
    }
    local ret=1
    TMP_LWRUN="$LW_DIR/tmp/lwrun"
    info_msg "Downloading lwrun..."
    if try_dllwrun_mirror
       then
            info_msg "lwrun downloaded!"
            chmod +x "$TMP_LWRUN"
            exec "$TMP_LWRUN"
            ret=0
        else
            error_msg "Failed to download lwrun!"
            [ -f "$TMP_LWRUN" ] && \
                rm -rf "$TMP_LWRUN"*
            exit 1
    fi
    return $ret
}

yn_case() {
    while true
        do
            read -p "$(echo -e "${RED}$1 ${GREEN}(y/n) ${BLUE}> $RESETCOLOR")" yn
            case $yn in
                [Yy] ) return 0 ;;
                [Nn] ) return 1 ;;
            esac
    done
}

gui_question() {
    if is_exe_exist yad
        then yad --image="dialog-question" --button="NO:1" --button="YES:0" --title="$1" \
                --text="$2" --center --on-top --fixed --selectable-labels
    elif is_exe_exist zenity
        then zenity --question --title="$1" --no-wrap --text="$2"
    else return 1
    fi
    return $?
}

is_update() {
    [ "$FORCE_UPDATE" == 1 ] && \
        return 0
    local IS_UPD_TITLE="Update ${1}..."
    [ -n "$2" ] && \
        local IS_UPD_TEXT="$2"||\
        local IS_UPD_TEXT="$1 update is available!\nDo you want to update now?"
    if [ "$NOT_TERM" != 1 ]
        then yn_case "$IS_UPD_TEXT"||return 1
        else gui_question "$IS_UPD_TITLE" "$IS_UPD_TEXT"||return 1
    fi
    return $?
}

try_shutdown_lw() {
    if [ -n "$(pgrep -fa lux-wine|grep -E "$LWSRC|$LW_DIR/bin/lux-wine"|grep -v grep)" ]
        then
            if [ "$FORCE_UPDATE" != 1 ]
                then
                    local qtext="You need to restart Lux Wine!\nDo you want to turn it off now?"
                    if [ "$NOT_TERM" != 1 ]
                        then yn_case "$qtext"
                        else gui_question "Restart Lux Wine..." "$qtext"
                    fi
            fi
            if [ "$?" == 0 ]
                then
                    info_msg "Shutdown Lux Wine..."
                    if [ -x "$LWSRC" ]
                        then "$LWSRC" -exit
                        else return 1
                    fi
                else return 1
            fi
    fi
    return 0
}

no_color() { sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2};?)?)?[mGK]//g" ; }

update_lwrun() (
    local ret=1
    if is_update "RunImage" "Do you want to check updates for RunImage packages?"
        then
            mkdir -p "$LWBIN_DIR"
            date '+%y.%m.%d.%H%M%S' > "$PKGUPDFL"
            [ "$NOT_TERM" == 1 ] && \
                IN_TERM=(
                    "xterm" "-fa" "Monospace"
                    "-fs" "11" "-geometry" "130x45"
                    "-bg" "black" "-fg" "white" \
                    "-T" "Updating RunImage packages..." "-e"
                )||unset IN_TERM
            HOSTEXEC_ARGS=(hostexec env RIM_RUN_IN_ONE=0)
            "${HOSTEXEC_ARGS[@]}" ls "$RUNIMAGE_LW" &>/dev/null||\
            "${HOSTEXEC_ARGS[@]}" LWLN_ONLY=1 "$RUNSRC"
            if mountpoint -q /usr/share/icons
                then HOSTEXEC_ARGS+=(LWRUN_UPDATE=1 "$RUNIMAGE_LW")
                else unset HOSTEXEC_ARGS
            fi
            "${HOSTEXEC_ARGS[@]}" "${IN_TERM[@]}" rim-update
            ret="$?"
    fi
    return $ret
)

is_exe_exist() { command -v "$@" &>/dev/null ; }

which_exe() { command -v "$@" ; }

check_url_stat_code() {
    if is_exe_exist curl
        then curl -sL -o /dev/null -I -w "%{http_code}" "$@" 2>/dev/null
    elif is_exe_exist wget
        then wget --no-check-certificate --server-response \
                --spider "$@"|& awk '/^  HTTP/{print$2}'|tail -1
    else return 1
    fi
}

is_url() {
    [ ! -n "$1" ] && \
        return 1
    if [ -n "$2" ]
        then [ "$(check_url_stat_code "$1")" == "$2" ]
        else [ "$(check_url_stat_code "$1")" == "200" ]
    fi
}

try_dl() {
    err_no_downloader() {
        error_msg "Downloader not found!"
        exit 1
    }
    rm_fail_dl() {
        [ -f "$FILEDIR/$FILENAME" ] && \
            rm -rf "$FILEDIR/$FILENAME" \
            "$FILEDIR/$FILENAME"*.aria2
    }
    dl_ret() {
        if [ "$1" != 0 ]
            then
                rm_fail_dl
                dl_repeat && \
                try_dl "$URL" "$FILEDIR/$FILENAME"||\
                return 1
            else return 0
        fi
    }
    dl_repeat() {
        [ "$NO_DL_REPEAT" == 1 ] && \
            return 1
        DL_REP_TITLE="Download interrupted!"
        DL_REP_TEXT="Failed to download: $FILENAME from $(echo "$URL"|awk -F/ '{print$3"/"$4}') \nWould you like to repeat it?"
        if [[ "$NOT_TERM" != 1 || "$NO_DL_GUI" == 1 ]]
            then
                yn_case "$DL_REP_TEXT"||return 1
        elif is_exe_exist yad
            then
                yad --image="dialog-error" --button="CANCEL:1" --center \
                    --button="REPEAT:0" --title="$DL_REP_TITLE" \
                    --text="$DL_REP_TEXT" --on-top --fixed
        elif is_exe_exist zenity
            then
                zenity --question --title="$DL_REP_TITLE" --no-wrap \
                    --text="$DL_REP_TEXT"
        else return 1
        fi
    }
    if [ -n "$1" ]
        then
            URL="$1"
            if [ -n "$2" ]
                then
                    if [ -d "$2" ]
                        then
                            FILEDIR="$2"
                            FILENAME="$(basename "$1")"
                        else
                            FILEDIR="$(dirname "$2")"
                            FILENAME="$(basename "$2")"
                    fi
                else
                    FILEDIR="."
                    FILENAME="$(basename "$1")"
            fi
            if is_url "$URL"
                then
                    WGET_ARGS=(--no-check-certificate --content-disposition -t 3 -T 5 -w 0.5 "$URL" -O "$FILEDIR/$FILENAME")
                    [ ! -d "$FILEDIR" ] && \
                        mkdir -p "$FILEDIR"
                    if [[ "$NOT_TERM" == 1 && "$NO_DL_GUI" != 1 ]] && \
                        (is_exe_exist yad||is_exe_exist zenity)
                        then
                            set -o pipefail
                            dl_progress() {
                                [[ "$URL" =~ '&key=' ]] && \
                                    local URL="$(echo "$URL"|sed "s|\&key=.*||g")"
                                [[ "$URL" =~ '&' && ! "$URL" =~ '&amp;' ]] && \
                                    local URL="$(echo "$URL"|sed "s|\&|\&amp;|g")"
                                if is_exe_exist yad
                                    then
                                        yad --progress --percentage=0 --text="Download:\t$FILENAME\n$URL" \
                                            --auto-close --no-escape --selectable-labels --auto-kill \
                                            --center --on-top --fixed --no-buttons --undecorated --skip-taskbar
                                elif is_exe_exist zenity
                                    then
                                        zenity --progress --text="Connecting to $URL" --width=650 --height=40 \
                                            --auto-close --no-cancel --title="Download: $FILENAME"
                                else return 1
                                fi
                            }
                            dl_progress_pulsate() {
                                local ret=1
                                [[ "$URL" =~ '&key=' ]] && \
                                    local URL="$(echo "$URL"|sed "s|\&key=.*||g")"
                                [[ "$URL" =~ '&' && ! "$URL" =~ '&amp;' ]] && \
                                    local URL="$(echo "$URL"|sed "s|\&|\&amp;|g")"
                                if is_exe_exist yad
                                    then
                                        local yad_args=(
                                            --progress --pulsate --text="Download:\t$FILENAME\n$URL"
                                            --width=650 --height=40 --undecorated --skip-taskbar
                                            --no-buttons --text-align center --auto-close --auto-kill
                                            --center --fixed --on-top --no-escape --selectable-labels
                                        )
                                        "$@" &
                                        local exec_pid="$!"
                                        if [[ -n "$exec_pid" && -d "/proc/$exec_pid" ]]
                                            then
                                                (while [ -d "/proc/$exec_pid" ]
                                                    do echo -e "#\n" ; sleep 0.1 2>/dev/null
                                                done)|yad "${yad_args[@]}" &>/dev/null &
                                                local yad_pid="$!"
                                                wait "$exec_pid" &>/dev/null
                                                ret="$?"
                                                kill "$yad_pid" &>/dev/null
                                        fi
                                elif is_exe_exist zenity
                                    then
                                        "$@"|zenity --progress --pulsate --text="$URL" --width=650 --height=40 \
                                            --auto-close --no-cancel --title="Download: $FILENAME"
                                        ret="$?"
                                fi
                                return "$ret"
                            }
                            if [ "$NO_ARIA2C" != 1 ] && \
                                is_exe_exist aria2c
                                then
                                    aria2c --no-conf -R -x 13 -s 13 --allow-overwrite --summary-interval=1 -o \
                                        "$FILENAME" -d "$FILEDIR" "$URL"|grep --line-buffered 'ETA'|\
                                        sed -u 's|(.*)| &|g;s|(||g;s|)||g;s|\[||g;s|\]||g'|\
                                        awk '{print$3"\n#Downloading at "$3,$2,$5,$6;system("")}'|\
                                    dl_progress
                            elif is_exe_exist curl
                                then
                                    curl -R --progress-bar --insecure --fail -L "$URL" -o \
                                        "$FILEDIR/$FILENAME" |& tr '\r' '\n'|sed '0,/100/{/100/d;}'|\
                                        sed -ur 's|[# ]+||g;s|.*=.*||g;s|.*|#Downloading at &\n&|g'|\
                                    dl_progress
                            elif is_exe_exist wget2
                                then
                                    dl_progress_pulsate wget2 "${WGET_ARGS[@]}"
                            elif is_exe_exist wget
                                then
                                    wget "${WGET_ARGS[@]}"|& tr '\r' '\n'|\
                                        sed -u 's/.* \([0-9]\+%\)\ \+\([0-9,.]\+.\) \(.*\)/\1\n#Downloading at \1\ ETA: \3/; s/^20[0-9][0-9].*/#Done./'|\
                                    dl_progress
                            else
                                err_no_downloader
                            fi
                            dl_ret "${PIPESTATUS[0]}"||return 1
                        else
                            if [ "$NO_ARIA2C" != 1 ] && is_exe_exist aria2c
                                then
                                    aria2c --no-conf -R -x 13 -s 13 --allow-overwrite -d "$FILEDIR" -o "$FILENAME" "$URL"
                            elif is_exe_exist curl
                                then
                                    curl -R --progress-bar --insecure --fail -L "$URL" -o "$FILEDIR/$FILENAME"
                            elif is_exe_exist wget2
                                then
                                    wget2 -q --force-progress "${WGET_ARGS[@]}"
                            elif is_exe_exist wget
                                then
                                    wget -q --show-progress "${WGET_ARGS[@]}"
                            else
                                err_no_downloader
                            fi
                            dl_ret "$?"||return 1
                    fi
                else
                    error_msg "$FILENAME not found in $(echo "$URL"|awk -F/ '{print$3"/"$4}')"
                    return 1
            fi
        else
            error_msg "Specify download URL!"
            return 1
    fi
}

rm_broken_link() { find -L "$1" -type l -exec rm -rf {} \; 2>/dev/null ; }

try_update_old_lwrun() {
    if [ "$RUNIMAGE_VERSION" == '0.39.1' ]
        then
            runimage_lw() {
                [ "$NOT_TERM" != 1 ] && \
                    unset HOSTEXEC_IN_TERM||\
                    HOSTEXEC_IN_TERM=(
                        "xterm" "-fa" "Monospace"
                        "-fs" "11" "-geometry" "130x45"
                        "-bg" "black" "-fg" "white" \
                        "-T" "Updating RunImage packages..." "-e"
                    )
                "${HOSTEXEC_IN_TERM[@]}" hostexec ptyspawn importenv '$RUNPID' \
                    env DONT_NOTIFY=1 NO_RPIDSMON=1 RIM_CMPRS_LVL=22 RIM_UPDATE_CLEANUP=1 \
                    "$RUNIMAGE_LW" "$@"
            }
            info_msg "Checking the lwrun update..."
            if runimage_lw --rU
                then FORCE_UPDATE=1 try_shutdown_lw
            fi
            date '+%y.%m.%d.%H%M%S' > "$PKGUPDFL"
            return 1
    fi
}

print_help() {
    echo -e "
    ${RED}Usage:
        $RED┌──[$GREEN$RUNUSER$YELLOW@$BLUE${RUNHOSTNAME}$RED]─[$GREEN$PWD$RED]
        $RED└──╼ \$$GREEN lwrap ${BLUE}{args}

        ${BLUE}--lwrap-help $GREEN                   Show this usage info
        ${BLUE}--install    $YELLOW{force|local}$GREEN      Re/Install Lux Wine and lwrun
        ${BLUE}--update     $GREEN                   Update Lux Wine, lwrun and container packages
        ${BLUE}--uninstall  $YELLOW{force|update}$GREEN     Install Lux Wine and lwrun
        "
}

case "$1" in
    --lwrap-help) print_help ; exit ;;
    --uninstall ) uninstall_lw "$2" ; exit $? ;;
esac

if [ "$INSIDE_RUNIMAGE" == 1 ]
    then
        case "$1" in
            --install   ) try_install_lwrun
                          install_lw "$2"
                          try_update_old_lwrun
                          exit $? ;;
            --update    ) FORCE_UPDATE=1
                          update_lwrun
                          exit $? ;;
        esac
        try_install_lwrun
        (! is_lw || is_old_lw) && install_lw
        if [[ "$CHK_UPDATE" != 0 || "$FORCE_UPDATE" == 1 ]] && \
            is_net_conn
            then
                if [[ ! -f "$(find "$PKGUPDFL" -mtime -$CHK_UPDATE \
                    -print 2>/dev/null)" || "$FORCE_UPDATE" == 1 ]]
                    then update_lwrun && exit $?
                fi
        fi
        exec "$LWSRC" "$@"
    else
        if [ -x "$LWRUN" ]
            then exec "$LWRUN" "$@"
        elif is_net_conn
            then try_dl_lwrun
        else
            error_msg "lwrun not found, download and install it first!"
            exit 1
        fi
fi
exit $?
