#!/bin/bash
SOURCE="$0"
source /usr/lib/elive-tools/functions
EL_REPORTS="1"
el_make_environment
. gettext.sh
TEXTDOMAIN="elive-tools"
export TEXTDOMAIN

# Lock system (good one) {{{
lockfile="/tmp/.$(basename $0)-${USER}.lock"

exit_ok(){
    rm -f "$lockfile"
}
exit_error(){
    rm -f "$lockfile"
}

if [[ -r "$lockfile" ]] ; then
    PROCCESS="$(cat $lockfile)"
else
    PROCCESS=" "
fi
if (ps up $PROCCESS) 1>/dev/null 2>&1 ; then
    echo -e "E: $(basename "$0" ) already running"
    exit
else
    echo $$ > "$lockfile"
fi

# traps needs to be after the lock verification, in order to not remove it when we are already running
trap "exit_ok" EXIT
trap "exit_error" 1 3 5 6 14 15 ERR TERM

# SET the lock file
echo "$$" > "$lockfile"


# end lock system }}}

main(){
    # pre {{{

    if grep -Fqs "thanatests" /proc/cmdline ; then
        EL_REPORTS=0 el_warning "We are in thanatests mode, exiting..."
        exit
    fi

    script="$( mktemp )"

    on_exit rm -f "$script"

    if ! el_dependencies_check "gksu|zenity|yad" ; then
        el_dependencies_install "gksu|zenity|yad"
        if ! el_dependencies_check gksu ; then
            el_error "we depend on gksu but we cannot install gksu because requires gksu? hum..."
        fi
    fi

    # }}}

    # mode basic or advanced {{{
    #if zenity --question --text="Do you want to use the basic and easier interface instead of the advanced and complete one?" ; then
    $yad --on-top --image="gtk-dialog-question" --text="$( eval_gettext "Do you want to use the basic and simpler interface instead of the advanced and complete one? With the Advanced mode you have more options." )" --button=gtk-quit:0 --button="Advanced!gtk-no:2" --button="Basic!gtk-yes:1"
    case "$?" in
        1)
            is_basic_mode=1
            ;;
        2)
            unset is_basic_mode
            ;;
        *)
            exit
            ;;
    esac

    # if zenity --question --text="$( eval_gettext "Do you want to use the basic and simpler interface instead of the advanced and complete one?" )" ; then
    #     is_basic_mode=1
    # fi

    # }}}
    # language conf {{{
    # ask for preselected language to use
    if [[ "$LANG" = *"_"* ]] ; then
        language="$LANG"
    else
        language="en_US"
    fi
    language="${language%% *}"
    language="${language%%.*}"

    if ((is_basic_mode)) ; then
        result="$( { echo "Other" ; echo "${language}" ; cat /etc/locale.gen | grep -vE "(^#|@)" | grep -F " UTF-8" | awk '{print $1}' | sed -E -e 's|\.UTF-8.*$||g' -e 's|UTF-8.*$||g' -e 's|^\s+||g' ; } | sort -u | psort -- -p "Other" -p "_${language##*_}$" -p "^${language%%_*}_" | zenity --width=180 --height=380 --list --text="Select your LANGUAGE.\nYour actual one is '${language}'" --column="language__COUNTRY" 2>/dev/null || echo cancel )"

        # [[ "$result" = "cancel" ]] && exit  # do not exit on first dialog because the tool will not exit cleanly, languages will be not configured correctly
        if [[ "$result" = "cancel" ]] ; then
            result="$language"
        fi

        if [[ -n "$result" ]] && [[ "$result" != "Other" ]] ; then
            result="${result}.UTF-8"
            export LANG="$result"

            # configure language
            if [[ "$LANG" = *UTF* ]] ; then
                el_explain 0 "Configuring system language to __${LANG}__..."

                cat > "$script" -- <<EOF
#!/bin/bash
echo "LANG=$LANG" > /etc/default/locale
# handle cases like en_US.UTF-8 (encoding is UTF-8) or vi_VN (encoding is UTF-8)
if [[ "$LANG" == *.* ]] ; then
    encoding="${LANG#*.}"
else
    encoding="UTF-8"
fi
if ! grep -qs "^${LANG} \${encoding}$" /etc/locale.gen ; then
    sed -i -e "s|# ${LANG} \${encoding}|${LANG} \${encoding}|" /etc/locale.gen
    locale-gen --keep-existing > /dev/null 2>&1
    update-locale
fi
echo -e "locales\tlocales/default_environment_locale\tselect\t${LANG}" | debconf-set-selections
echo -e "locales\tlocales/default_environment_locale\tselect\t${LANG}" | debconf-set-selections

# reconfigure console locale
dpkg-reconfigure -f noninteractive -p critical console-setup

# force reload configurations on console
setupcon --force

EOF

                chmod +x "$script"
                gksu "$script" || exit
                rm -f "$script"

            else
                el_warning "Is your language not in UTF-8? ignoring language configuration..."
            fi

        fi
    fi

    # fallback / reconfigure
    if ! ((is_basic_mode)) || [[ "${result}" = "Other" ]] || [[ -z "$LANG" ]] ; then
        urxvt -e bash -c "gksu dpkg-reconfigure locales"
        urxvt -e bash -c "gksu dpkg-reconfigure -f noninteractive -p critical console-setup"
    fi

    # get conf
    source /etc/default/locale

    # e17
    if [[ -n "$E_START" ]] ; then
        LANG="$( enlightenment_remote -lang-get )"
        # remove extra leading blank chars
        read -r LANG <<< "$LANG"
        LANG="${LANG/.utf8/.UTF-8}"
    fi

    # }}}


    # keyboard conf {{{
    # get conf
    source /etc/default/keyboard

    # if our lang is like es_ES, set the keyboard simply to it
    if [[ "$( echo "${LANG%.*}" | awk -v FS="_" '{print toupper($1)}' )" = "$( echo "${LANG%.*}" | awk -v FS="_" '{print toupper($2)}' )" ]] ; then
        kbmap="$( echo "${LANG%.*}" | awk -v FS="_" '{print $1}' )"
    else
        kbmap="$( setxkbmap -print -verbose 10 | grep -F "layout:" | awk '{print $2}' )"
    fi


    if ((is_basic_mode)) ; then
        result="$( { sed '/^! layout$/,/^ *$/!d;//d' "/usr/share/X11/xkb/rules/base.lst" | sed -E -e 's|^\s+||g' | sort -u | awk '{code = $1 ; $1 = "" ; print code"\n"$0}' | sed -e 's|^\s*||g'   ; echo -e "Other\nConfigure" ; } | zenity --width=340 --height=380 --list --text="Change your keyboard? Actual is '${kbmap}'" --column="Code" --column="Layout"  2>/dev/null || echo "cancel" )"
        # always set the keyboard to default when when we "validate" without selection:
        [[ -z "$result" ]] && [[ -n "$kbmap" ]] && result="$kbmap"

        if [[ "$result" = "cancel" ]] ; then
            result="$kbmap"
        else
            if [[ -n "$result" ]] && [[ "$result" != "cancel" ]] && [[ "$result" != "Other" ]] ; then
                result="$( echo "$result" | awk '{print $1}' )"

                # select a variant keyboard if needed
                XKBVARIANT="$( { echo -e "Normal\nNormal defaults for '$result'" ; sed '/^! variant$/,/^ *$/!d;//d' "/usr/share/X11/xkb/rules/base.lst" | awk -v lang="$result" '{if ($2 == lang":") print $0}' | sed -E -e 's|^\s+||g' | sort -u | awk '{$2 = "" ; code = $1 ; $1 = "" ; print code"\n"$0}' | sed -e 's|^  ||g' ; echo -e "Other\n$(eval_gettext "Other (keyboard variants by country and other configurations)")" ; } | zenity --width=440 --height=380 --list --text="Select your variant for '${result}', or just Cancel" --column="Variant" --column="Description" 2>/dev/null )"
                XKBVARIANT="$( echo "$XKBVARIANT" | awk '{print $1}' )"

                if [[ "$XKBVARIANT" = "Other" ]] ; then
                    zenity --info --text="$( eval_gettext "For other keyboard types like 'latam' for South America or many more options, you need to re-run this tool and choose the 'Advanced' mode." )"
                    unset XKBVARIANT
                fi

                if [[ -z "$XKBVARIANT" ]] || [[ "$XKBVARIANT" = "Normal"* ]] || ! echo "$XKBVARIANT" | grep -qs "[[:alpha:]]" ; then
                    unset XKBVARIANT
                fi
            fi
        fi

        # set US variant to altgr if empty
        if [[ -z "$XKBVARIANT" ]] && [[ "$result" = "us" ]] ; then
            XKBVARIANT="altgr-intl"
        fi

        # set the keyboard
        if [[ -n "$result" ]] && [[ "$result" != "cancel" ]] && [[ "$result" != "Other" ]] ; then
            XKBLAYOUT="$result"
            if ! setxkbmap "$XKBLAYOUT" -model "$XKBMODEL" -variant "$XKBVARIANT" -option "$XKBOPTIONS" ; then
                el_error "unable to set keyboard:\nlayout = $XKBLAYOUT\nmodel = $XKBMODEL\nvariant = $XKBVARIANT\noptions = $XKBOPTIONS\n$( setxkbmap "$XKBLAYOUT" -model "$XKBMODEL" -variant "$XKBVARIANT" -option "$XKBOPTIONS" 2>&1 )"
            fi

        fi
    fi

    # fallback / reconfigure
    if ! ((is_basic_mode)) || [[ "${result}" = "Other" ]] ; then
        urxvt -e bash -c "gksu dpkg-reconfigure keyboard-configuration"
        source /etc/default/keyboard
        if ! setxkbmap "$XKBLAYOUT" -model "$XKBMODEL" -variant "$XKBVARIANT" -option "$XKBOPTIONS" ; then
                el_error "unable to set keyboard:\nlayout = $XKBLAYOUT\nmodel = $XKBMODEL\nvariant = $XKBVARIANT\noptions = $XKBOPTIONS\n$( setxkbmap "$XKBLAYOUT" -model "$XKBMODEL" -variant "$XKBVARIANT" -option "$XKBOPTIONS" 2>&1 )"
        fi
    fi

    # }}}
    # Get xkb values set {{{
    while read -ru 3 line
    do
        # layout
        if [[ "$line" = layout:* ]] ; then
            k_layout="${line#*:}"
            # do we have something useful?
            if echo "$k_layout" | sed -e 's|,||g' | grep -qs "[[:alpha:]]" ; then
                # remove last comma
                k_layout="${k_layout%,}"
                # remove extra leading blank chars
                read -r k_layout <<< "$k_layout"
            else
                unset k_layout
            fi
        fi

        # variant
        if [[ "$line" = variant:* ]] ; then
            k_variant="${line#*:}"
            # do we have something useful?
            if echo "$k_variant" | sed -e 's|,||g' | grep -qs "[[:alpha:]]" ; then
                # remove last comma
                k_variant="${k_variant%,}"
                # remove extra leading blank chars
                read -r k_variant <<< "$k_variant"
            else
                unset k_variant
            fi
        fi

        # options
        if [[ "$line" = options:* ]] ; then
            k_options="${line#*:}"
            # do we have something useful?
            if echo "$k_options" | sed -e 's|,||g' | grep -qs "[[:alpha:]]" ; then
                # remove extra leading blank chars
                read -r k_options <<< "$k_options"
            else
                unset k_options
            fi
        fi

    done 3<<< "$( setxkbmap -print -verbose 10 )"

    # - Get xkb values set }}}
    # keyboard set configurations {{{

    # configure xserver-xorg values, preseeds.d is run from the install with a dpkg-reconfigure for filename
    cat > "$script" -- <<EOF
#!/bin/bash
source /usr/lib/elive-tools/functions

echo -e "xserver-xorg\txserver-xorg/config/inputdevice/keyboard/layout\tselect\t${k_layout%%,*}" | debconf-set-selections

# configure keyboard
el_explain 0 "Configuring keyboard, layout  __${k_layout%%,*}__"
el_explain 0 "Configuring keyboard, variant __${k_variant%%,*}__"
el_explain 0 "Configuring keyboard, options __${k_options%%,*}__"

sed -i "s|^XKBLAYOUT.*$|XKBLAYOUT=\"${k_layout%%,*}\"|g" /etc/default/keyboard
sed -i "s|^XKBVARIANT.*$|XKBVARIANT=\"${k_variant%%,*}\"|g" /etc/default/keyboard
sed -i "s|^XKBOPTIONS.*$|XKBOPTIONS=\"${k_options}\"|g" /etc/default/keyboard

dpkg-reconfigure -f noninteractive -p critical keyboard-configuration
dpkg-reconfigure -f noninteractive -p critical xserver-xorg
EOF
    chmod +x "$script"
    gksu "$script" || exit
    rm -f "$script"

    # }}}

    # warn user that extra configurations are needed
    # e24+
    if [[ -n "$E_START" ]] ; then
        zenity --info --text="$( eval_gettext "You've set your preferred language and keyboard. To activate them, select them in your desktop settings." )"
    else
        # just say ok
        if ! grep -Fqs "boot=live" /proc/cmdline ; then
            zenity --info --text="$( eval_gettext "Changes have been saved. To apply the new settings, you must reboot your computer or log in again on your desktop." )"
        fi
    fi

}

#
#  MAIN
#
main "$@"

# vim: set foldmethod=marker :
