#!/usr/bin/env bash
#
# This code is released in public domain by Dave Davenport <qball@gmpclient.org> 
#


ROFI=$(which rofi)
SED=$(which sed)
MKTEMP=$(which mktemp)

if [ -z "${SED}" ]
then
    echo "Did not find 'sed', script cannot continue."
    exit 1
fi
if [ -z "${MKTEMP}" ]
then
    echo "Did not find 'mktemp', script cannot continue."
    exit 1
fi
if [ -z "${ROFI}" ]
then
    echo "Did not find rofi, there is no point to continue."
    exit 1
fi

TMP_CONFIG_FILE=$(${MKTEMP})

##
# Array with parts to the found themes.
# And array with the printable name.
##
declare -a themes
declare -a theme_names

##
# Function that tries to find all installed rofi themes.
# This fills in #themes array and formats a displayable string #theme_names
##
function find_themes()
{
    DIRS=${XDG_DATA_DIRS}
    if [ -z "${XDG_DATA_DIRS}" ]
    then
        echo "XDG_DATA_DIRS needs to be set for this script to function."
        exit 1;
    fi
    # Add user dir.
    DIRS+="${HOME}/.local/share/"
    OLDIFS=${IFS}
    IFS=:
    for p in ${DIRS}; do 
        TD=${p}rofi/themes/
        if [ -d "${TD}" ]
        then
            for file in ${TD}/*.theme
            do
                if [ -f "${file}" ]
                then
                    themes+=(${file})
                    FN=$(basename ${file})
                    NAME=${FN%.*}
                    USER=$(${SED} -n 's/^! User: \(.*\)/\1/p' ${file} )
                    if [ -z "${USER}" ]
                    then
                        theme_names+=(${NAME})
                    else
                        theme_names+=("${NAME} by ${USER}")
                    fi
                fi
           done
        fi
    done
    IFS=${OLDIFS}

}

##
# Create a copy of rofi
##
function create_config_copy()
{
    ${ROFI} -dump-xresources > ${TMP_CONFIG_FILE}
}

###
# Print the list out so it can be displayed by rofi.
##
function create_theme_list()
{
    OLDIFS=${IFS}
    IFS='|'
    for themen in  ${theme_names[@]}
    do
        echo ${themen}
    done
    IFS=${OLDIFS}
}

##
# Thee indicate what entry is selected.
##
declare -i SELECTED

function select_theme () 
{
    local MORE_FLAGS=(-dmenu -format i -no-custom -p Theme -markup -config ${TMP_CONFIG_FILE})
    MORE_FLAGS+=(-kb-custom-1 "Alt-a")
    local CUR="default"
    while true
    do
        declare -i RTR
        declare -i RES
        local MESG="""You can preview themes by hitting <b>Enter</b>.
<b>Alt-a</b> to accept the new theme.
<b>Escape</b> to cancel
Current theme: <b>${CUR}</b>"""
        RES=$( create_theme_list | ${ROFI} ${MORE_FLAGS[@]} -mesg "${MESG}") 
        RTR=$?
        if [ ${RTR} = 10 ]
        then
            return 0;
        elif [ ${RTR} = 1 ] 
        then
            return 1;
        fi
        ${SED} -i '/#include .*/d' ${TMP_CONFIG_FILE}
        echo "#include \"${themes[${RES}]}\"" >> ${TMP_CONFIG_FILE}
        CUR=${theme_names[${RES}]}
        SELECTED=${RES}
    done
}

###
# Create if not exists, then removes #include of .theme file (if present) and add the selected theme to the end.
# Repeated calls should leave the config clean-ish
###
function set_theme()
{
    CDIR="${HOME}/.config/rofi/"
    if [ ! -d "${CDIR}" ]
    then
        mkdir -p ${CDIR}
    fi
    if [ -f "${CDIR}/config" ]
    then
        ${SED} -i "/#include \".*\.theme\"$/d" "${CDIR}/config"
    fi
    echo "#include \"${1}\"" >> "${CDIR}/config"

}

############################################################################################################
# Actual program execution
###########################################################################################################
##
# Find all themes
##
find_themes

##
# Do check if there are themes.
##
if [ ${#themes[@]} = 0 ]
then
    ${ROFI} -e "No themes found."
    exit 0
fi

##
# Create copy of config to play with in preview
##
create_config_copy

##
# Show the themes to user.
##
if select_theme && [ -n "${SELECTED}" ]
then
    # Set theme
    set_theme "${themes[${SELECTED}]}"
fi

##
# Remove temp. config.
##
rm ${TMP_CONFIG_FILE}