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

# gettext functions
if [[ -x "/usr/bin/gettext.sh" ]] ; then
    . gettext.sh
else
    # make it compatible
    eval_gettext(){
        echo "$@"
    }
fi
TEXTDOMAIN="elive-tools"
export TEXTDOMAIN

# ignore if we are in e16
if [[ -n "$EROOT" ]] ; then
    exit
fi
if [[ -z "$E_HOME_DIR" ]] || [[ "$E_HOME_DIR" = "$HOME/.e/e" ]] ; then
    # el_error "This desktop is not Enlightenment 17 ? exiting..."
    exit
fi

has_glxinfo_ecomorph_compatibility=1
# INJECTED ECOMORPH DETECTOR CODE {{{
ECOMP_BIN_PATH="/usr/local/bin/" # For window decorators and ecomp
PLUGIN_PATH="/usr/local/lib/ecomp/"
GLXINFO="/usr/bin/glxinfo"
#KWIN="/usr/bin/kwin"
#METACITY="/usr/bin/metacity"
ECOMP_NAME="ecomorph" # Final name for ecomp (ecomp.real)

# For Xgl LD_PRELOAD
LIBGL_NVIDIA="/usr/lib/nvidia/libGL.so.1.2.xlibmesa"
LIBGL_FGLRX="/usr/lib/fglrx/libGL.so.1.2.xlibmesa"

# Minimum amount of memory (in kilo bytes) that nVidia cards need
# to be allowed to start
# Set to 262144 to require 256MB
NVIDIA_MEMORY="65536" # 64MB
NVIDIA_SETTINGS="nvidia-settings" # Assume it's in the path by default

# For detecting what driver is in use, the + is for one or more /'s
XORG_DRIVER_PATH="/usr/lib/xorg/modules/drivers/+"

#FALLBACKWM="${METACITY}"
#FALLBACKWM_OPTIONS="--replace $@"

# Driver whitelist
WHITELIST="nvidia intel ati radeon i810"

# blacklist based on the pci ids
# See http://wiki.ecomp-fusion.org/Hardware/Blacklist for details
T="   1002:5954 1002:5854 1002:5955" # ati rs480
T="$T 1002:4153" # ATI Rv350
T="$T 8086:2982 8086:2992 8086:29a2 8086:2a02 8086:2a12"  # intel 965
T="$T 8086:2972" # i965 (x3000)
T="$T 1002:3152 1002:3150 1002:5462 1002:5653 " # ati X300 X600,X600 X700
BLACKLIST_PCIIDS="$T"
unset T

ECOMP_OPTIONS="--ignore-desktop-hints --replace"
ECOMP_PLUGINS=""
ENV=""

# Use emerald by default if it exist
#USE_EMERALD="yes"

# No indirect by default
INDIRECT="no"

# Set to yes to enable verbose
VERBOSE="yes"

# Echos the arguments if verbose
verbose()
{
    if [ "x$VERBOSE" = "xyes" ]; then
        printf "$*"
    fi
}


# Check for non power of two texture support
check_npot_texture()
{
    verbose "Checking for non power of two support: "
    if glxinfo 2> /dev/null | grep -qsE '(GL_ARB_texture_non_power_of_two|GL_NV_texture_rectangle|GL_EXT_texture_rectangle|GL_ARB_texture_rectangle)' ; then
        verbose "present. \n";
        return 0;
    else
        verbose "Not present. \n"
        return 1;
    fi

}

# Check for presence of FBConfig
check_fbconfig()
{
    verbose "Checking for FBConfig: "
    if [ "$INDIRECT" = "yes" ]; then
        $GLXINFO -i | grep -q "GLX.*fbconfig"
        FB=$?
    else
        $GLXINFO | grep -q "GLX.*fbconfig"
        FB=$?
    fi

    if [ $FB = "0" ]; then
        unset FB
        verbose "present. \n"
        return 0;
    else
        unset FB
        verbose "not present. \n"
        return 1;
    fi
}


# Check for TFP
check_tfp()
{
    verbose "Checking for texture_from_pixmap: "
    if [ $($GLXINFO 2>/dev/null | grep -F GLX_EXT_texture_from_pixmap -c) -gt 2 ] ; then
        verbose "present. \n"
        return 0;
    else
        verbose "not present. \n"
        if [ "$INDIRECT" = "yes" ]; then
            unset LIBGL_ALWAYS_INDIRECT
            INDIRECT="no"
            return 1;
        else
            verbose "Trying again with indirect rendering:\n";
            INDIRECT="yes"
            export LIBGL_ALWAYS_INDIRECT=1
            check_tfp;
            return $?
        fi
    fi
}

# Check wether the composite extension is present
check_composite()
{
    verbose "Checking for Composite extension: "
    if xdpyinfo -queryExtensions | grep -Fq Composite ; then
        verbose "present. \n";
        return 0;
    else
        verbose "not present. \n";
        return 1;
    fi
}

# Detects if Xgl is running
check_xgl()
{
    verbose "Checking for Xgl: "
    if xvinfo | grep -Fq Xgl ; then
        verbose "present. \n"
        return 0;
    else
        verbose "not present. \n"
        return 1;
    fi
}

# Check if the nVidia card has enough video ram to make sense
check_nvidia_memory()
{
    MEM=$(${NVIDIA_SETTINGS} -q VideoRam | egrep Attribute\ \'VideoRam\'\ .*: | cut -d: -f3 | sed 's/[^0-9]//g')
    if [ $MEM -lt $NVIDIA_MEMORY ]; then
        verbose "Less than ${NVIDIA_MEMORY}kb of memory and nVidia";
        return 1;
    fi
    return 0;
}

# Check for existence if NV-GLX
check_nvidia()
{
    if [ ! -z $NVIDIA_INTERNAL_TEST ]; then
        return $NVIDIA_INTERNAL_TEST;
    fi
    verbose "Checking for nVidia: "
    if xdpyinfo | grep -q NV-GLX ; then
        verbose "present. \n"
        NVIDIA_INTERNAL_TEST=0
        return 0;
    else
        verbose "not present. \n"
        NVIDIA_INTERNAL_TEST=1
        return 1;
    fi
}

# Check if the max texture size is large enough compared to the resolution
check_texture_size()
{
    TEXTURE_LIMIT=$(glxinfo -l | grep GL_MAX_TEXTURE_SIZE | sed 's/.*=[^0-9]//g' | sort -Vu | awk '{print $1}' )
    RESOLUTION=$(xdpyinfo  | grep -i dimensions: | sed 's/[^0-9]*pixels.*(.*).*//' | sed 's/[^0-9x]*//')
    VRES=$(echo $RESOLUTION | sed 's/.*x//')
    HRES=$(echo $RESOLUTION | sed 's/x.*//')
    verbose "Comparing resolution ($RESOLUTION) to maximum 3D texture size ($TEXTURE_LIMIT): ";
    if [ $VRES -gt $TEXTURE_LIMIT ] || [ $HRES -gt $TEXTURE_LIMIT ]; then
        verbose "Failed.\n"
        return 1;
    fi
    verbose "Passed.\n"
    return 0
}

# check driver whitelist
running_under_whitelisted_driver()
{
    LOG=$(xset q|grep "Log file"|awk '{print $3}')
    if [ -z "$LOG" ];then
        verbose "AIEEEEH, no Log file found \n"
        verbose "$(xset q) \n"
        return 0
    fi
    for DRV in ${WHITELIST}; do
        if egrep -q "Loading ${XORG_DRIVER_PATH}${DRV}_drv\.so" $LOG &&
            ! egrep -q "Unloading ${XORG_DRIVER_PATH}${DRV}_drv\.so" $LOG;
    then
        return 0
    fi
done
verbose "No whitelisted driver found\n"
return 1
}

# check pciid blacklist
have_blacklisted_pciid()
{
    OUTPUT=$(lspci -n)
    for ID in ${BLACKLIST_PCIIDS}; do
        if echo "$OUTPUT" | egrep -q "$ID"; then
            verbose "Blacklisted PCIID '$ID' found \n"
            return 0
        fi
    done
    OUTPUT=$(lspci -vn | grep -i VGA)
    verbose "Detected PCI ID for VGA: $OUTPUT\n"
    return 1
}

build_env()
{
    if check_nvidia; then
        ENV="__GL_YIELD=NOTHING "
    fi
    if [ "$INDIRECT" = "yes" ]; then
        ENV="$ENV LIBGL_ALWAYS_INDIRECT=1 "
    fi
    if check_xgl; then
        if [ -f ${LIBGL_NVIDIA} ]; then
            ENV="$ENV LD_PRELOAD=${LIBGL_NVIDIA}"
            verbose "Enabling Xgl with nVidia drivers...\n"
        fi
        if [ -f ${LIBGL_FGLRX} ]; then
            ENV="$ENV LD_PRELOAD=${LIBGL_FGLRX}"
            verbose "Enabling Xgl with fglrx ATi drivers...\n"
        fi
    fi

    ENV="$ENV FROM_WRAPPER=yes"

    if [ -n "$ENV" ]; then
        export $ENV
    fi
}

build_args()
{
    if [ $INDIRECT = "yes" ]; then
        ECOMP_OPTIONS="$ECOMP_OPTIONS --indirect-rendering "
    fi
    if check_nvidia; then
        ECOMP_OPTIONS="$ECOMP_OPTIONS --loose-binding"
    fi
}

####################
# Execution begins here.
#set -x

# Read configuration from XDG paths
#if [ -z "$XDG_CONFIG_DIRS" ]; then
#test -f /etc/xdg/ecomp/ecomp-manager && . /etc/xdg/ecomp/ecomp-manager
#else
#test -f $XDG_CONFIG_DIRS/ecomp/ecomp-manager && . $XDG_CONFIG_DIRS/ecomp/ecomp-manager
#fi

#if [ -z "$XDG_CONFIG_HOME" ]; then
#test -f $HOME/.config/ecomp/ecomp-manager && . $HOME/.config/ecomp/ecomp-manager
#else
#test -f $XDG_CONFIG_HOME/ecomp/ecomp-manager && .  $XDG_CONFIG_HOME/ecomp/ecomp-manager
#fi


#if [ "x$LIBGL_ALWAYS_INDIRECT" = "x1" ]; then
#INDIRECT="yes";
#fi



# }}}

abort_with_fallback_wm(){
    if ((is_elive_helper)) ; then
        case "$1" in
            virtual)
                zenity --error --text="$( eval_gettext "These special features require 3D accelerated drivers which don't work on virtual machines. Use Elive on a real computer to have these features." )"
                ;;
            traditional)
                zenity --error --text="$( eval_gettext "These special features require 3D accelerated drivers. You are using a standard driver that is more compatible and can make your graphical interface work but is insufficient to enable the special effects. This can happen with very old computers or very recent ones, you can try a different version of Elive using different driver setups." )"
                ;;
            nvidia)
                zenity --error --text="$( eval_gettext "These special features require 3D accelerated drivers. You are using an Nvidia driver which appears to be incompatible." )"
                ;;
            flags)
                zenity --error --text="$( eval_gettext "These special features require 3D accelerated drivers. But the driver you use doesn't appear to have the required features to make Ecomorph work properly. Maybe you can try with a different driver, also a newer version of Elive might solve the problem using updated drivers." )"
                ;;
            driver)
                zenity --error --text="$( eval_gettext "These special features require compatible 3D accelerated drivers. Try to load the Ecomorph module manually, if it works correctly on your computer, report this issue to the Elive BTS." )"
                ;;
            multiscreens)
                zenity --error --text="$( eval_gettext "The Ecomorph module may not work well with multiple screens. Help improve this feature by accessing the source code on GitHub at github.com/Elive." )"
                ;;
        esac
    fi

    unset has_glxinfo_ecomorph_compatibility
}



main(){
    local tempfile has_updated_donors
    tempfile="/tmp/.${USER}-donors.txt"

    # disable this feature in low memory computers
    local memory cpubogomips

    memory="$( cat /proc/meminfo | grep -i Memtotal | tail -1 | awk '{print $2}' )"
    cpubogomips="$( grep bogomips /proc/cpuinfo | sed -e 's|^.*: ||g' -e 's|\..*$||g' | tr ' ' '\n' | grep "[[:digit:]]" | head -1 )"

    if [[ "${memory}" -lt "800000" ]] || [[ "$cpubogomips" -lt 2800 ]] ; then
        zenity --info --text="$( eval_gettext "Seems like you have a slow computer, if you feel your desktop gets slower with the special effects enabled, just disable the Ecomorph module." )"
    fi

    for arg in "$@"
    do
        case "$arg" in
            --elivehelper)
                is_elive_helper=1
                ;;
        esac
    done


    # give a preview of the theme
    #if el_verify_internet ; then
    #cd /tmp

    #if zenity --question --text="$( eval_gettext "Do you want to try the preview of the desktop theme on which we are currently working ?" )" ; then
    #curl -L -s -A Mozilla https://www.elivecd.org/elive_3.0_light_development.edj
    #sudo -H mv *edj /usr/share/enlightenment/data/themes/
    #sudo -H chown root:root /usr/share/enlightenment/data/themes/*edj
    #sudo -H chmod a+r /usr/share/enlightenment/data/themes/*edj

    #enlightenment_remote -restart
    #fi


    # give a preview of ecomorph

    # predetect ecomorph compatibility {{{
    # if we run under Xgl, we can skip some tests here
    if ! check_xgl; then
        # if vesa or vga are in use, do not even try glxinfo (LP#119341)
        if ! running_under_whitelisted_driver || have_blacklisted_pciid; then
            abort_with_fallback_wm driver
        fi
        # check if we have the required bits to run ecomp and if not,
        # fallback
        if ! check_tfp || ! check_npot_texture || ! check_composite || ! check_texture_size; then
            abort_with_fallback_wm flags
        fi

        if check_nvidia && ! check_nvidia_memory; then
            abort_with_fallback_wm nvidia
        fi

        if ! check_fbconfig; then
            abort_with_fallback_wm traditional
        fi
    fi

    # }}}
    source /etc/elive/machine-profile 2>/dev/null || true

    # abort in VM
    if [[ "$MACHINE_VIRTUAL" = "yes" ]] ; then
        abort_with_fallback_wm virtual
    fi

    if grep -qsi "VESA(.*): Creating default Display" /var/log/Xorg.0.log ; then
        abort_with_fallback_wm traditional
    fi

    screens_connected_names="$( LC_ALL="$EL_LC_EN" xrandr --query | grep " connected" | sed -e "s/\([A-Z0-9]\+\) connected.*/\1/" )"
    screens_connected_number="$( echo "$screens_connected_names" | wc -l )"
    if [[ "$screens_connected_number" -gt 1 ]] ; then
        abort_with_fallback_wm multiscreens
    fi


    # note: ecomp.sh is needed to detect if emodule-ecomorph is installed (not the lib but the module)
    if ((has_glxinfo_ecomorph_compatibility)) && [[ -x "$(which ecomorph)" ]] && [[ "$( which ecomp.sh )" ]] ; then
        if zenity --question --text="$( eval_gettext "Activate experimental visual effects? Your desktop will have extra features, look nicer, and in some cases be faster. You can deactivate them later by disabling the Ecomorph module." )" ; then
            #Some slow computers can also have the desktop slower.

            if ! grep -qsE "(^7\.|wheezy)" /etc/debian_version ; then
                if zenity --question --text="$( eval_gettext "This feature isn't ready on the new versions, we have an issue with library linking in the compilation. But you can help make it work if you know C programming or Makefiles compiling. Do you want to help us make it work?" )" ; then
                    web-launcher "https://forum.elivelinux.org/t/ecomorph-issue-to-include-it-in-newer-versions/1000"
                fi
                exit
            fi

            local message_warn_user
            message_warn_user="$( printf "$( eval_gettext "Note: If your desktop feels slower or shows any strange behavior, simply disable the Ecomorph module. You can also change the type of effects in the Ecomorph preferences." )" "" )"

            if [[ -s "$HOME/.ecomp/ecomp.cfg.normal" ]] && [[ -s "$HOME/.ecomp/ecomp.cfg.full" ]] ; then
                answer="$( zenity --width=580 --height=240 --list \
                    --text="$( eval_gettext "Select a profile for the visual effects" )\n\n${message_warn_user}" \
                    --column="$( eval_gettext "Type" )" --column="$( eval_gettext "Description" )" \
                    "normal" "$( eval_gettext "Default option, with simple effects, perfect for daily work" )" \
                    "full" "$( eval_gettext "Lots of random visual effects, perfect for demonstrations" )" \
                    "default" "$( eval_gettext "Use your previous settings" )" \
                    || echo cancel)"

                if [[ "$answer" = "cancel" ]] ; then
                    exit
                fi

                if [[ -n "$answer" ]] && [[ "$answer" != "default" ]] ; then
                    if [[ -s "$HOME/.ecomp/ecomp.cfg.${answer}" ]] ; then
                        cp -f "$HOME/.ecomp/ecomp.cfg.${answer}" "$HOME/.ecomp/ecomp.cfg"
                    fi
                fi
            else
                if ! [[ -s "$HOME/.ecomp/ecomp.cfg" ]] ; then
                    EL_DEBUG=0 elive-skel upgrade .ecomp
                fi
            fi

            #zenity --info --text="$message_warn_user" || true

            el_speak_text "starting metamorphosization"

            # just in case we still using it
            #cp "$HOME/.ecomp/ecomp.cfg-TESTING" "$HOME/.ecomp/ecomp.cfg" 2>/dev/null

            enlightenment_remote -module-load ecomorph
            enlightenment_remote -module-enable ecomorph
            sleep 1
            # module is loaded but ecomorph not started, so we can do it from here - updated version, it actually loads it
            #killall ecomorph 2>/dev/null || true
            #ecomorph ini inotify text regex move cube rotate switcher shift ring scale expo animation scaleaddon wobbly cubereflex thumbnail zoom  &>/dev/null &disown

            sync
            for i in $(seq 22)
            do
                sleep 1
                if pidof ecomorph 1>/dev/null 2>&1 ; then
                    enlightenment_remote -save
                    sleep 1
                    #enlightenment_remote -restart
                    sleep 5
                    #zenity --info --text="$( eval_gettext "Applications already opened will not be included in the Ecomorph layer - only the ones that you open from now on. To have Ecomorph fully functioning, log out and in again." )" || true
                    zenity --info --text="$( eval_gettext "Your opened applications will not be included in the Ecomorph layer, only the ones that you open from now on. If it does not work correctly, log out and back in again." )" || true
                    #sleep 10
                    #zenity --info --text="$( eval_gettext "In order to improve your experience you can enable some hotkeys to trigger special features like the Expo, the windows transparecy value, or the window switcher in your Enlightenment preferences, keybindings." )" || true
                    is_ecomorph_working=1
                    break
                fi
            done

            # not running ecomorph?
            if ! ((is_ecomorph_working)) ; then
                enlightenment_remote -module-disable ecomorph
                enlightenment_remote -module-unload ecomorph
                zenity --warning --text="$( eval_gettext "Ecomorph will probably not work on this computer due to your graphics hardware. You can try to manually enable the module in Settings/Modules, but if it still does not work, you will need to try using it on a different computer." )"

                exit
            fi


            # wait and tell the user if still wants to use it
            local message_want_to_continue_using
            message_want_to_continue_using="$( printf "$( eval_gettext "Special effects perform better and faster on some computers, but worse or slower on others. Do you want to keep the Ecomorph module enabled?" )" "" )"

            # wait 5 minutes before to ask if continue using it
            if ! grep -qs "boot=live" /proc/cmdline ; then
                enlightenment_remote -exec-cmd "sleep 300 ; if zenity --question --text='$message_want_to_continue_using' ; then true ; else enlightenment_remote -module-disable ecomorph || true ; fi "
            fi

            true
        fi
    fi



    # if we are debugging give it a little pause to see what is going on
    #if grep -qs "debug" /proc/cmdline ; then
        #echo -e "debug: sleep 2" 1>&2
        #sleep 2
    #fi

    exit 0
}

#
#  MAIN
#
main "$@"

# vim: set foldmethod=marker :
