#!/bin/bash
#
#   BunsenLabs Conky selection and switcher script
#
#   Written by damo <damo@bunsenlabs.org> for BunsenLabs Linux, April 2015
#   Beta tested and stamped "zen" by <Sector11>
#   Rapackaged for Manjaro by napcok <napcok@gmail.com>, March 2016
#
########################################################################
#
#   Conkys must be in $CONKYPATH
#   The name must end with "conky" or "conkyrc"
#
#   When the dialog opens, any running conkys will be checkmarked.
#
#   Click "OK" and all running conkys are stopped, and all checkmarked
#   conkys are started
#
#   To stop a conky just uncheck it, and "OK"
#
#   Running conkys are saved to a session file, and can be run with
#   the "bl-conky-session" script. To start the default conky session at
#   login, add the following line to autostart:
#
#     (sleep 2s && bl-conky-session --autostart) &
#
#   Different saved-session files can be used by running the script with:
#
#           bl-conkyzen -f /path/to/sessionfile &
#           bl-conkyzen -z (opens gui entry dialog for filepath)
#
########################################################################

CONKYPATH="$HOME/.config/conky"
SESSIONFILE="$CONKYPATH/conky-sessionfile"
SESSIONS="$CONKYPATH/saved-sessions"    # to be used by a pipemenu
CRC="$HOME/.conkyrc"
BLDEFAULT="$CONKYPATH/MB-Default.conkyrc"

USAGE1="\v\tUSAGE:\tmb-conkyzen [OPTION]...FILES
\v\tWith no command option the script runs the gui
\v\t-h,--help   : this USAGE help
\t-f,--file   : FILEPATH : specify file to save session to
\t-z          : Run gui filename entry dialog for new saved session"

USAGE2="\v\tUSAGE:\tmb-conkyzen [OPTION]...FILES
\v\tWith no command option the script runs the gui
\v\t-h,--help   : this USAGE help
\t-f,--file   : FILEPATH : specify file to save session to
\t-z          : Run gui filename entry dialog for new saved session
\v\tWhen the dialog opens, any running conkys will be checkmarked.
\tClick \"OK\" and all running conkys are stopped, and all
\tcheckmarked conkys are started.
\v\tTo stop a conky just uncheck it, and \"OK\"
\v\tEXAMPLES:
\tSave session to a new saved-session file with:
\v\t\tbl-conkyzen -f sessionfile-name
\v\tTo start the default conky session at login, add the
\tfollowing line to autostart:
\v\t\t(sleep 2s && mb-conky-session --autostart) &\v"

### DIALOG VARIABLES
case $LANG in
    pl*)
        TITLE="Menedżer Conky"
        CANCEL="--button=Anuluj:1"
        CONKY_SESSIONFILE="Plik sesji Conky"
        FILENAME_IN_USE="Nazwa pliku już jest używana.\n\nNadpisać?"
        SAVE_SESSION="Zapisz sesję Conky"
        NEW_FILE="Nowy plik zapisanej sesji:"
        FILE_TO_SAVE="Plik do zapisania w <b>$CONKYPATH/</b>\n\n"
        SESS_SAVE="Wybierz pliki Conky, które mają być uruchomione.\nSesja zostanie zachowana w:\n <i>$SESSIONFILE</i>"
        SELECT="Wybór:CHK"
        CONF_FILE="Plik konfiguracyjny:TXT"
        NOTHING_SELECTED="Nic nie wybrano.\n\nWyłączyć działające Conky\ni wyjść?"
    ;;
    *)
        TITLE="Conky Manager"
        CANCEL="--button=Cancel:1"
        CONKY_SESSIONFILE="Conky sessionfile"
        FILENAME_IN_USE="Filename already in use\n\nOverwrite it?"
        SAVE_SESSION="Save Conky sessionfile"
        NEW_FILE="New saved session file:"
        FILE_TO_SAVE="File to be saved in <b>$CONKYPATH/</b>\n\n"
        SESS_SAVE="Choose Conky file, which you like to start.\nSession will be saved to:\n <i>$SESSIONFILE</i>"
        SELECT="Select:CHK"
        CONF_FILE="Conky Name:TXT"
        NOTHING_SELECTED="Nothing chosen.\n\nKill any running Conkys\nand exit?"
    ;;
esac
DLG="yad --center --undecorated --borders=20 --image=conky "
DLGDEC="yad --center  --borders=20 "
WINICON="--window-icon=distributor-logo-mabox --image=conky "
OK="--button=OK:0"


########## FUNCTIONS ###################################################
conkyRunning(){    # find running conkys
    # make blank tempfile, to save running conky paths
    TEMPFILE=$(mktemp --tmpdir conky.XXXX)
    if [[ $(pidof conky) ]];then
        # test if default conky was started
        for ARG in $(ps aux | grep  [c]onky | awk '{print $(NF-1)}');do
            if [[ $ARG = "conky" ]]; then
                echo "$CRC" >> "$TEMPFILE"  # 'conky -q' probably used
            else                            # send conky filepath to tempfile
                for ARG in $(ps aux | grep  [c]onkyrc | awk '{print $(NF)}');do
                    if [[ $ARG != "-q" ]];then
                        echo "$ARG" >> "$TEMPFILE"
                    fi
                done
            fi
        done
    fi
    # remove any duplicates in tempfile
    TEMPFILE2=$(mktemp --tmpdir conky.XXXX)
    awk '!x[$0]++' "$TEMPFILE" > "$TEMPFILE2" && mv "$TEMPFILE2" "$TEMPFILE"
}

fillArrays(){
    if (( $1 != 0 ));then
        num="$1"    # 1st arg: array index
    else
        num=0   # '~/.conkyrc' added to array
    fi

    if (( $num == 0 ));then
        cPATH="$CRC"
        cARR="$USER/.conkyrc"
    else
        cPATH="$2"   # 2nd arg: full filepath to conky
        cARR="$3"    # 3rd arg: displayed name: "directory/*conky(rc)"
    fi

    conkysPath[$num]="$cPATH"
    conkysArr[$num]="$cARR"
    if grep -qx "$cPATH" "$TEMPFILE";then # if conky is running (read from tempfile)
        checkArr[$num]="TRUE"       # make checkmark in dialog
    else
        checkArr[$num]="FALSE"
    fi
}

findConky(){
# search dirs for conkys files - looking for "conky" in the name
# if "*conky(rc)" then display it
    num=0   # added default .conkyrc
    fillArrays $num "$CRC" "$USER/.conkyrc"
    num=1
    # find files in CONKYPATH with conky in the name
    for x in $(find "$CONKYPATH" -type f );do
        f=$(basename "$x")    # filename from filepath
        if [[ $f = *conkyrc ]] || [[ $f = *conky ]];then    # filename ends with *conky or *conkyrc
            # get directory/conkyname to display in list
            CONKY=$( echo "$x" | awk -F"/" '{print $(NF-1)"/"$NF}')
            fillArrays $num "$x" "$CONKY"
            num=$(($num+1))
        fi
    done
}

writeSessions(){    # save a new sessionfile name for use by a menu
    SESSIONFILE="$CONKYPATH/$1"
    echo "sessionfile= $SESSIONFILE"
    if ! [[ -f $SESSIONS ]];then
        > "$SESSIONS"
    fi
    if grep -qx "$SESSIONFILE" "$SESSIONS";then # session was previously saved
        if [[ $2 = "-z" ]];then    # input was from input dialog, so ask OK?
            $DLG $WINICON --title="$CONKY_SESSIONFILE" --text="$FILENAME_IN_USE" $CANCEL $OK
            if (( $? == 1 ));then
                exit 0
            fi
        else    # commandline is being used
            echo "Session was previously saved with the same name. Overwrite it? (y|N)"
            read ans
            case "$ans" in
                y|Y )   break
                        ;;
                *   )   exit 0
                        ;;
            esac
        fi
    else
        cp "$SESSIONS" "$SESSIONS.bkp"
        echo "$SESSIONFILE" >> "$SESSIONS"
    fi
}
######## END FUNCTIONS #################################################

# get args passed to script (session can be saved to a different file)
for arg in "$@";do
    case "$arg" in
        -h|--help   ) echo -e "$USAGE2"
                      echo
                      exit 0
                      ;;
        -f|--files  ) if [[ $2 ]];then
                        SESSIONFILE="$2"    # sessionfile has been specified
                        writeSessions "$SESSIONFILE"    # if sessionfile is new, write name to saved-sessions
                        break
                      else
                        echo
                        echo -e "\tNo saved-session file specified!"
                        echo -e "$USAGE1"
                        echo
                        exit 1
                      fi
                      ;;
        -z          ) SPATH=$($DLGDEC $WINICON --entry \
                        --title="$SAVE_SESSION" \
                        --entry-label="$NEW_FILE" \
                        --text="$FILE_TO_SAVE" \
                        $OK $CANCEL \
                        )
                      (( $? == 1 )) && exit 0
                      if [[ -z $SPATH ]];then     # entry was empty
                          $DLG $WINICON --title="Conky sessionfile" --text="No file specified for new saved session\n\nExiting..." $OK
                          exit 1
                      else
                          writeSessions "$SPATH" "-z"   # saved session file from input dialog
                      fi
                      ;;
                 *  ) if ! [[ $arg ]];then
                        SESSIONFILE="$SESSIONFILE" # sessionfile is default
                        break
                      else
                        echo -e "$USAGE1"
                        exit 1
                      fi
                      ;;
    esac
done

# test for ~/.conkyrc, create a link to the default conky if necessary
if ! [[ -e $CRC ]];then
    if [[ -e $BLDEFAULT ]];then
        ln -s "$BLDEFAULT" "$CRC"
    else
        echo "Default conkyrc not found"
    fi
fi

# get conky directories in .conky, add to array
conkyRunning
findConky

# loop through arrays, and build list text for yad dialog
unset LISTCONKY
for ((j=0; j<${#conkysArr[*]}; j++));do
  LISTCONKY="$LISTCONKY${checkArr[j]} ${conkysArr[j]} "
done

while ! [[ $RET ]];do
    ## Populate dialog from array, get return value(s)
    RET=$($DLGDEC $WINICON --list --title="$TITLE" \
        --text="$SESS_SAVE" \
        --checklist --width=400 --height=500 --multiple \
        --column="$SELECT" --column="$CONF_FILE" $LISTCONKY \
        --separator=":" \
        $CANCEL $OK \
        )

    if [[ $? == 1 ]]; then # cancel button pressed
        # restore previous saved-sessions file
        [[ -f $SESSIONS.bkp ]] && mv "$SESSIONS.bkp" "$SESSIONS"
        rm "$TEMPFILE"
        exit 0
    fi
    if ! [[ $RET ]];then  # No conkys chosen
        MSG="$NOTHING_SELECTED"
        $DLG $WINICON --title="$TITLE" --text="$MSG" $OK $CANCEL
        if [[ $? = 1 ]];then
            # restore previous saved-sessions file
            mv "$SESSIONS.bkp" "$SESSIONS"
            rm "$TEMPFILE"
            continue
        else
            killall conky
            exit 0
        fi
    else
        > "$SESSIONFILE"    # Create new session file
        # loop through returned choices, add to array
        i=0
        OIFS=$IFS   # save Internal Field Separator
        IFS=":"     # separator is ":" in returned choices
        for name in $RET; do
            retConky[$i]="$name"
            i=$(($i+1))
        done
        IFS=$OIFS   # reset IFS back to default

        # kill all conkys
        if [[ $(pidof conky) ]];then
            killall conky
        fi

        # Find the chosen conkys and start them
        for name in ${retConky[*]};do       # loop through checkmarked conky names
            for ((j=0; j<${#conkysPath[*]}; j++));do  # traverse through elements
                for f in ${conkysPath[j]};do    # compare with choice from dialog
                    display=$( echo "$f" | awk -F"/" '{print $(NF-1)"/"$NF}')
                    if [[ $display = $name ]];then
                        echo -e "conky -c $f & sleep 1s" >> "$SESSIONFILE"
                        #start the conky (adjust the sleep time if required)
                        conky -c "$f" & sleep 1s
                    fi
                done
            done
        done
    fi
done
rm "$TEMPFILE"

exit 0
