#!/bin/bash

# ======================================================================
# Archivo:       iniciar-blender-selector
# Ruta:          /usr/local/bin/
# Autor:         Charlie Martínez® <cmartinez@quirinux.org>
# Licencia:      https://www.gnu.org/licenses/gpl-2.0.txt
# Propósito:     Inicia Blender. Si hay más de una versión instalada (apt,
#                blender-old, blender-legacy o Flatpak), pregunta cuál
#                iniciar. Lo usa blender.desktop.
# Distribución:  Quirinux 2.x
# ======================================================================

#
# Copyright (c) 2019-2025 Charlie Martínez, derechos reservados.
# Licencia: https://www.gnu.org/licenses/gpl-2.0.txt
# Usos autorizados y no autorizados de la marca Quirinux:
# Ver https://www.quirinux.org/aviso-legal
#

# Uso:  iniciar-blender-selector [archivos a abrir...]
#   - una sola versión instalada   -> la inicia
#   - varias versiones instaladas  -> muestra un selector para elegir
#
# Versiones que detecta:
#   apt     Blender de la distro        (paquete blender)         /usr/bin/blender
#   old     Blender 2.79b               (paquete blender-old)     /opt/blender-2.79*/blender
#   legacy  Blender 2.83.x              (paquete blender-legacy)  /opt/blender-2.83*/blender
#   flatpak Blender de Flathub          (org.blender.Blender)

# ----------------------------------------------------------------------
# Traducciones
# ----------------------------------------------------------------------

LANG_CODE="${LANG%%_*}"
SUPPORTED_LANGS="es en gl pt fr it de ru hu"

# Idioma por defecto
[[ " $SUPPORTED_LANGS " =~ " $LANG_CODE " ]] || LANG_CODE="en"

declare -A TXT

# Español

TXT[es.select_title]="Elegir versión de Blender"
TXT[es.select_col]="Versiones de Blender instaladas"
TXT[es.select_text]="Se detectaron varias versiones de Blender. ¿Cuál quieres iniciar?"
TXT[es.opt_apt]="Blender del sistema (apt) - versión %s"
TXT[es.opt_old]="Blender Old (apt) - versión %s - interfaz antigua"
TXT[es.opt_legacy]="Blender Legacy (apt) - versión %s - para equipos sin GPU"
TXT[es.opt_flatpak]="Blender Flatpak (Flathub) - versión %s"

# English

TXT[en.select_title]="Choose Blender version"
TXT[en.select_col]="Installed Blender versions"
TXT[en.select_text]="Several Blender versions were detected. Which one do you want to start?"
TXT[en.opt_apt]="System Blender (apt) - version %s"
TXT[en.opt_old]="Blender Old (apt) - version %s - old interface"
TXT[en.opt_legacy]="Blender Legacy (apt) - version %s - for computers without a GPU"
TXT[en.opt_flatpak]="Blender Flatpak (Flathub) - version %s"

# Galego

TXT[gl.select_title]="Escoller a versión de Blender"
TXT[gl.select_col]="Versións de Blender instaladas"
TXT[gl.select_text]="Detectáronse varias versións de Blender. Cal queres iniciar?"
TXT[gl.opt_apt]="Blender do sistema (apt) - versión %s"
TXT[gl.opt_old]="Blender Old (apt) - versión %s - interface antiga"
TXT[gl.opt_legacy]="Blender Legacy (apt) - versión %s - para equipos sen GPU"
TXT[gl.opt_flatpak]="Blender Flatpak (Flathub) - versión %s"

# Português

TXT[pt.select_title]="Escolher a versão do Blender"
TXT[pt.select_col]="Versões do Blender instaladas"
TXT[pt.select_text]="Foram detectadas várias versões do Blender. Qual deseja iniciar?"
TXT[pt.opt_apt]="Blender do sistema (apt) - versão %s"
TXT[pt.opt_old]="Blender Old (apt) - versão %s - interface antiga"
TXT[pt.opt_legacy]="Blender Legacy (apt) - versão %s - para computadores sem GPU"
TXT[pt.opt_flatpak]="Blender Flatpak (Flathub) - versão %s"

# Français

TXT[fr.select_title]="Choisir la version de Blender"
TXT[fr.select_col]="Versions de Blender installées"
TXT[fr.select_text]="Plusieurs versions de Blender ont été détectées. Laquelle souhaitez-vous lancer ?"
TXT[fr.opt_apt]="Blender du système (apt) - version %s"
TXT[fr.opt_old]="Blender Old (apt) - version %s - ancienne interface"
TXT[fr.opt_legacy]="Blender Legacy (apt) - version %s - pour ordinateurs sans GPU"
TXT[fr.opt_flatpak]="Blender Flatpak (Flathub) - version %s"

# Italiano

TXT[it.select_title]="Scegli la versione di Blender"
TXT[it.select_col]="Versioni di Blender installate"
TXT[it.select_text]="Sono state rilevate più versioni di Blender. Quale vuoi avviare?"
TXT[it.opt_apt]="Blender di sistema (apt) - versione %s"
TXT[it.opt_old]="Blender Old (apt) - versione %s - interfaccia vecchia"
TXT[it.opt_legacy]="Blender Legacy (apt) - versione %s - per computer senza GPU"
TXT[it.opt_flatpak]="Blender Flatpak (Flathub) - versione %s"

# Deutsch

TXT[de.select_title]="Blender-Version auswählen"
TXT[de.select_col]="Installierte Blender-Versionen"
TXT[de.select_text]="Es wurden mehrere Blender-Versionen gefunden. Welche möchten Sie starten?"
TXT[de.opt_apt]="System-Blender (apt) – Version %s"
TXT[de.opt_old]="Blender Old (apt) – Version %s – alte Oberfläche"
TXT[de.opt_legacy]="Blender Legacy (apt) – Version %s – für Rechner ohne GPU"
TXT[de.opt_flatpak]="Blender Flatpak (Flathub) – Version %s"

# Русский

TXT[ru.select_title]="Выбор версии Blender"
TXT[ru.select_col]="Установленные версии Blender"
TXT[ru.select_text]="Обнаружено несколько версий Blender. Какую запустить?"
TXT[ru.opt_apt]="Blender из системы (apt) — версия %s"
TXT[ru.opt_old]="Blender Old (apt) — версия %s — старый интерфейс"
TXT[ru.opt_legacy]="Blender Legacy (apt) — версия %s — для компьютеров без GPU"
TXT[ru.opt_flatpak]="Blender Flatpak (Flathub) — версия %s"

# Magyar

TXT[hu.select_title]="Blender-verzió kiválasztása"
TXT[hu.select_col]="Telepített Blender-verziók"
TXT[hu.select_text]="Több Blender-verzió is telepítve van. Melyiket szeretné elindítani?"
TXT[hu.opt_apt]="Rendszer Blender (apt) – verzió %s"
TXT[hu.opt_old]="Blender Old (apt) – verzió %s – régi felület"
TXT[hu.opt_legacy]="Blender Legacy (apt) – verzió %s – GPU nélküli gépekhez"
TXT[hu.opt_flatpak]="Blender Flatpak (Flathub) – verzió %s"

# ----------------------------------------------------------------------
# Detección de instalaciones de Blender (apt, old, legacy y Flatpak)
# ----------------------------------------------------------------------
APP_CMD="blender"           # ejecutable de la versión apt (distro)
APT_PKG="blender"           # paquete apt (distro)
FLATPAK_ID="org.blender.Blender"
OLD_GLOB="/opt/blender-2.79*"       # blender-old
LEGACY_GLOB="/opt/blender-2.83*"    # blender-legacy

HAS_NATIVE=0
HAS_OLD=0
HAS_LEGACY=0
HAS_FLATPAK=0
NATIVE_VER=""
OLD_VER=""
LEGACY_VER=""
FLATPAK_VER=""
OLD_DIR=""
LEGACY_DIR=""

# Versión de un paquete apt instalado, sin epoch ni sufijos de empaquetado
# (1:3.4.1+dfsg-2 -> 3.4.1). Vacío si el paquete no está instalado.
_apt_ver() {
    local v
    v=$(dpkg-query -W -f='${db:Status-Status}\t${Version}\n' "$1" 2>/dev/null \
        | awk -F'\t' '$1 == "installed" {print $2; exit}')
    v="${v#*:}"
    v="${v%%[+~-]*}"
    echo "$v"
}

# Devuelve la carpeta (si hay varias, la última) de /opt que cumple el patrón
# y contiene un ejecutable "blender"
_buscar_opt() {
    local d found=""
    for d in $1; do
        [[ -x "$d/blender" ]] && found="$d"
    done
    [[ -n "$found" ]] && echo "$found"
}

_detectar() {
    # Blender de la distro (paquete blender) o cualquier "blender" en el PATH
    if command -v "$APP_CMD" >/dev/null 2>&1; then
        HAS_NATIVE=1
        NATIVE_VER=$(_apt_ver "$APT_PKG")
        # Respaldo: si no viene de un paquete .deb, se le pregunta al ejecutable
        if [[ -z "$NATIVE_VER" ]]; then
            NATIVE_VER=$(timeout 10 "$APP_CMD" --version 2>/dev/null \
                | grep -oE '[0-9]+(\.[0-9]+)+' | head -n1)
        fi
    fi

    # blender-old: la versión se toma del nombre de la carpeta (/opt/blender-2.79b)
    OLD_DIR=$(_buscar_opt "$OLD_GLOB")
    if [[ -n "$OLD_DIR" ]]; then
        HAS_OLD=1
        OLD_VER="${OLD_DIR##*/blender-}"
    fi

    # blender-legacy: ídem (/opt/blender-2.83.20)
    LEGACY_DIR=$(_buscar_opt "$LEGACY_GLOB")
    if [[ -n "$LEGACY_DIR" ]]; then
        HAS_LEGACY=1
        LEGACY_VER="${LEGACY_DIR##*/blender-}"
    fi

    # Blender instalado desde Flathub (sistema o usuario)
    if command -v flatpak >/dev/null 2>&1 && flatpak info "$FLATPAK_ID" >/dev/null 2>&1; then
        HAS_FLATPAK=1
        # flatpak traduce las etiquetas ("Versión:" en español): forzar idioma neutro
        FLATPAK_VER=$(LC_ALL=C LANGUAGE=C flatpak info "$FLATPAK_ID" 2>/dev/null \
            | sed -n 's/^[[:space:]]*Version:[[:space:]]*//p' | head -n1)
        # Respaldo: "flatpak list" (columnas separadas por tabulador, sin depender del idioma)
        if [[ -z "$FLATPAK_VER" ]]; then
            FLATPAK_VER=$(LC_ALL=C LANGUAGE=C flatpak list --app --columns=application,version 2>/dev/null \
                | awk -F'\t' -v id="$FLATPAK_ID" '$1 == id {print $2}' | head -n1)
        fi
    fi
}

# ----------------------------------------------------------------------
# Flatpak
# ----------------------------------------------------------------------

# Flatpak añade sus carpetas de aplicaciones DELANTE de /usr/local/share en
# XDG_DATA_DIRS, así que su org.blender.Blender.desktop gana al del sistema.
# Una copia oculta en ~/.local/share/applications (que se lee antes que todo)
# lo oculta de verdad, y en el menú queda solo el lanzador oficial de Quirinux.
# La copia se toma de /etc/skel (la misma que reciben los usuarios nuevos).
_ocultar_lanzador_flatpak() {
    local src="/etc/skel/.local/share/applications/${FLATPAK_ID}.desktop"
    local dstdir="${XDG_DATA_HOME:-$HOME/.local/share}/applications"
    local dst="$dstdir/${FLATPAK_ID}.desktop"

    [[ ! -e "$dst" ]] || return 0
    mkdir -p "$dstdir" 2>/dev/null || return 0

    if [[ -f "$src" ]]; then
        cp -f "$src" "$dst" 2>/dev/null
    else
        cat > "$dst" 2>/dev/null << DESKTOP
[Desktop Entry]
Type=Application
Name=Blender (Flatpak)
Exec=iniciar-blender-selector %f
NoDisplay=true
Hidden=true
DESKTOP
    fi
    return 0
}

# Los archivos se reenvían con --file-forwarding (portal de documentos), igual
# que hace el lanzador original del Flatpak, para no depender de los permisos
# de acceso al sistema de archivos de cada usuario.
_iniciar_flatpak() {
    if (( $# )); then
        exec flatpak run --file-forwarding "$FLATPAK_ID" @@ "$@" @@
    else
        exec flatpak run "$FLATPAK_ID"
    fi
}

# ----------------------------------------------------------------------
# Blender de apt (distro, old y legacy)
# ----------------------------------------------------------------------

_iniciar_apt() {
    exec "$APP_CMD" "$@"
}

# Los lanzadores /usr/local/bin/blender-2.79b y blender-2.83 no reenvían los
# archivos recibidos, por eso se inicia directamente el ejecutable de /opt.
_iniciar_old() {
    exec "$OLD_DIR/blender" "$@"
}

_iniciar_legacy() {
    exec "$LEGACY_DIR/blender" "$@"
}

# ----------------------------------------------------------------------
# Selector (solo si hay más de una instalación)
# ----------------------------------------------------------------------

# Escribe en stdout "apt", "old", "legacy" o "flatpak"; sale sin iniciar nada
# si se cancela. $1 en adelante: identificadores disponibles, en orden.
_elegir() {
    local id label choice
    local -a rows=()

    # Sin zenity no se puede preguntar: se usa el primero disponible
    # (Blender de la distro si está; si no, old, legacy o Flatpak)
    if ! command -v zenity >/dev/null 2>&1; then
        echo "$1"
        return 0
    fi

    for id in "$@"; do
        case "$id" in
            apt)     printf -v label "${TXT[$LANG_CODE.opt_apt]}"     "${NATIVE_VER:-?}" ;;
            old)     printf -v label "${TXT[$LANG_CODE.opt_old]}"     "${OLD_VER:-?}" ;;
            legacy)  printf -v label "${TXT[$LANG_CODE.opt_legacy]}"  "${LEGACY_VER:-?}" ;;
            flatpak) printf -v label "${TXT[$LANG_CODE.opt_flatpak]}" "${FLATPAK_VER:-?}" ;;
        esac
        rows+=("$id" "$label")
    done

    choice=$(zenity --list \
        --title "${TXT[$LANG_CODE.select_title]}" \
        --text "${TXT[$LANG_CODE.select_text]}" \
        --width=700 --height=320 \
        --column "id" --column "${TXT[$LANG_CODE.select_col]}" \
        --hide-column=1 --print-column=1 \
        "${rows[@]}"
    ) || exit 0

    echo "$choice"
}

# ----------------------------------------------------------------------
# Principal
# ----------------------------------------------------------------------

_detectar
(( HAS_FLATPAK )) && _ocultar_lanzador_flatpak

OPCIONES=()
(( HAS_NATIVE ))  && OPCIONES+=(apt)
(( HAS_OLD ))     && OPCIONES+=(old)
(( HAS_LEGACY ))  && OPCIONES+=(legacy)
(( HAS_FLATPAK )) && OPCIONES+=(flatpak)

# Si no se detecta nada, se mantiene el comportamiento original (apt)
(( ${#OPCIONES[@]} )) || OPCIONES=(apt)

if (( ${#OPCIONES[@]} > 1 )); then
    ELEGIDA=$(_elegir "${OPCIONES[@]}")
else
    ELEGIDA="${OPCIONES[0]}"
fi

case "$ELEGIDA" in
    apt)     _iniciar_apt "$@" ;;
    old)     _iniciar_old "$@" ;;
    legacy)  _iniciar_legacy "$@" ;;
    flatpak) _iniciar_flatpak "$@" ;;
    *)       exit 0 ;;
esac
