#!/bin/sh
#
# Script for changing background image (window manager independent)
#
# OPERATION MODE :
#
# When the script is launched without argument, it reads its config file
# and display either the SETBGFILE file if defined or the NEXTBGFILE from
# the background spool (it peeks the first one if no definition is found).
# If the -e or -w options are set, instead of being displayed, the file is
# copied into defaults file respectly for Enlightenment or Window Maker.
# Then, the next file to be displayed is caculated (if SETBGFILE is not set)
# and the configuration is saved.
#
# Options behavior :
# -p is used to search the previous image displayed (current image is set
#    in BGFILE of the configuration file) and saved as the next image in
#    the configuration file.
# -k is used to keep current image as permanent for as long as you don't
#    use -r. -k sets SETBGFILE.
# -s is used to set a particular file as permanent background (for as long
#    as you don't use -r). -s sets SETBGFILE.
# -x is used to display the selected image with -p, -k or -s in background.
# -v is used to display the selected image with -p, -k or -s in a window
#    or at command line if xv is not installed. The 'app' parameter is
#    optional and is the name of the viewer you want to use.
# -r unsets the SETBGFILE variable so that automatic changing of backgrounds
#    continues...
#
# You can edit your configuration file (~/.bgrc) to change each field.
# Aspect options are taken from wmsetbg options. These options are looked
# for in the jpeg files' comments. If you don't want to change the files'
# comments, use the -o option, else you'll need the rdjpgcom program.
#
# For questions, mail to : tnemeth@free.fr
#

# Global vars
#
VERSION="1.0.2"
BG="OTHER"
CFGFILE=$HOME/.bgrc
DEBUG=0
SAVE=1
SHOW=1
PREV=0
COMM=""
VIEWER=xv


# File vars
#
BGFILE=""
SETBGFILE=""
PREVBGFILE=""
OLDBGFILE=""
NEXTBGFILE=""
FILE=""


# Default configuration : saved in config file and user modifiable
#
BGSPOOL=/usr/local/share/backgrounds
WMBG=$HOME/GNUstep/Library/WindowMaker/Backgrounds/background.jpg
EBG=$HOME/.enlightenment/backgrounds/background.jpg


# debug function
#
do_debug () {
    if [ $DEBUG = 1 ]; then
        echo "$1"
    fi
}


# Source config file (current configuration)
#
do_loadcfg () {
    if [ -f $CFGFILE ]; then
        do_debug "Loading file..."
        . $CFGFILE
    fi

    if [ "$SETBGFILE" != "" ]; then
        SAVE=0
        COMM=$PREVASPECT
    else
        PREVBGFILE=$BGFILE
        BGFILE=$NEXTBGFILE
    fi

    # If configuration do not exist, peek the first file
    if [ "$BGFILE" = "" -a "$SETBGFILE" = "" ]; then
        do_debug "No config file : looking for 1st file in spool..."
        BGFILE=`ls -1 $BGSPOOL | head -n 1`
        BGFILE=$BGFILE
    else
        do_debug "Configuration loaded."
    fi

    do_debug \
"  SETBGFILE  = $SETBGFILE
  BGFILE     = $BGFILE (sourced NEXTBGFILE)
  PREVBGFILE = $PREVBGFILE (sourced BGFILE)
  BGSPOOL    = $BGSPOOL
  WMBG       = $WMBG
  EBG        = $EBG
  PREVASPECT = $PREVASPECT"
}


# Get previous background image
#
do_getprevbg () {
    if [ "$SETBGFILE" = "" ]; then
        # PREVBGFILE is current/previous session's displayed file
        # BGFILE     is the file that should be displayed now
        do_debug "Searching background previous to [$PREVBGFILE]..."
        OLDBGFILE=`ls -1 $BGSPOOL | grep -B 1 $PREVBGFILE | head -n 1`
        if [ "$OLDBGFILE" = "$PREVBGFILE" -o "$OLDBGFILE" = "" ]; then
            do_debug "Could not find previous : getting last file of spool..."
            OLDBGFILE=`ls -1 $BGSPOOL | tail -n 1`
        fi
        BGFILE=$PREVBGFILE
        PREVBGFILE=$OLDBGFILE
        PREV=1
        do_debug "Found previous background."
    else
        do_debug "SETBGFILE exist : no change until option -r is used."
    fi
}


# Define background file with context
#
do_definefile () {
    if [ "$FILE" != "" ]; then
        IMGFILE=$FILE
    elif [ "$SETBGFILE" != "" ]; then
        IMGFILE=$SETBGFILE
    else
        IMGFILE=$BGSPOOL/$BGFILE
    fi
    if [ -f $IMGFILE ]; then
        do_debug "Background image : $IMGFILE"
    else
        echo "Error : file [$IMGFILE] do not exist." > /dev/stderr
    fi
}


# Get aspect information
#
do_getaspect () {
    if [ "$COMM" = "" ]; then
        COMM=`rdjpgcom $IMGFILE`
    fi
    do_debug "  COMM = $COMM"
}


# Create command lines
#
do_wmsetbg () {
    COMMAND="$WMSETBG --back-color black"
    TILEOPT="--tile"
    SCALOPT="--scale"
    MAXSOPT="--maxscale"
    do_debug "Set command to $WMSETBG (wmsetbg)."
}

do_esetbg () {
    COMMAND=$ESETROOT
    TILEOPT=""
    SCALOPT="-s"
    MAXSOPT="-s"
    do_debug "Set command to $ESETROOT (esetroot)."
}

do_xvsetbg () {
    COMMAND="xv -root -quit -noresetroot"
    TILEOPT=""
    SCALOPT="-max"
    MAXSOPT="-maxpect -bg black"
    do_debug "Set command to xv."
}

do_cmdsetopts () {
    case $COMM in
        "tile")     OPTS=$TILEOPT;;
        "scale")    OPTS=$SCALOPT;;
        "maxscale") OPTS=$MAXSOPT;;
    esac
}


# Set background image
#
do_setbgimage () {
    do_definefile

    if [ "$BG" != "OTHER" -a $PREV = 0 ]; then
        do_debug "Copy background image to specific file [$BG]..."
        cp $IMGFILE $BG
    else
        do_debug "Using command for non-specific window manager"
        do_getaspect
        OPTS=""
        if [ "$COMMAND" = "" ]; then
            do_debug "No default command..."
            WMSETBG=`which wmsetbg`
            ESETROOT=`which Esetroot`
            if [ "$WMSETBG" != "" -a -x "$WMSETBG" ]; then
                do_wmsetbg
            elif [ "$ESETROOT" != "" -a -x "$ESETROOT" ]; then
                do_esetbg
            else
                do_xvsetbg
            fi
#            do_xvsetbg
        fi
        do_cmdsetopts
        do_debug "  CMD = $COMMAND $OPTS $IMGFILE"
        $COMMAND $OPTS $IMGFILE
    fi
}


# Display image without putting it in background
#
do_displayimage () {
    do_definefile
    VIEWOK=`which $VIEWER`
    if [ "$VIEWOK" != "" ]; then
        $VIEWER $IMGFILE
    else
        echo "Error : $VIEWER not found..." > /dev/stderr
        echo "$IMGFILE"
    fi
}


# Write down informations to configuration file
#
do_writefile () {
    do_debug "$1"
    cat << EOF > $CFGFILE
# Configuration file for chgbkg $VERSION
#

# Backgrounds spool directory
#
BGSPOOL=$BGSPOOL

# Command used to display backgrounds
#
COMMAND="$COMMAND"

# Command option for tiled images
#
TILEOPT="$TILEOPT"

# Command option for scaled images
#
SCALOPT="$SCALOPT"

# Command option for maxscaled images
#
MAXSOPT="$MAXSOPT"

# Currently displayed background file (do not modify)
#
BGFILE=$BGFILE

# Next file to be displayed (do not modify)
#
NEXTBGFILE=$NEXTBGFILE

# File to set when using Window Maker
#
WMBG=$WMBG

# File to set when using Enlightenment
#
EBG=$EBG

# Aspect of currently displayed background
#
PREVASPECT=$COMM

# Permanent backgound file
#
SETBGFILE=$SETBGFILE
EOF
}


# Configuration saving switch
#
do_savecfg () {
    if [ $SAVE = 1 ]; then
        if [ "$SETBGFILE" != "" ]; then
            do_writefile "Writing config with fixed background file..."
        elif [ $PREV = 1 ]; then
            NEXTBGFILE=$BGFILE
            BGFILE=$PREVBGFILE
            do_writefile "Writing config with previous background file..."
        else
            NEXTBGFILE=`ls -1 $BGSPOOL | grep -A 1 $BGFILE | tail -n 1`
            if [ "$NEXTBGFILE" = "$BGFILE" -o "$NEXTBGFILE" = "" ]; then
                NEXTBGFILE=`ls -1 $BGSPOOL | head -n 1`
            fi
            do_writefile "Writing config for next time..."
        fi
    else
        do_debug "Keeping actual config."
    fi
}


# Verify SETBGFILE
#
do_verify () {
    START=`echo "$SETBGFILE" | sed -e 's/\(.\).*/\1/'`
    if [ "$START" != "/" ]; then
        do_debug "Set file has no full path..."
        SETBGFILE=$PWD/$SETBGFILE
    fi
}


# Help display function
#
do_help () {
    cat << EOF
chgbkg $VERSION - Thomas Nemeth, 2002
Usage : chgbkg [-d] [-h] [-k] [-p] [-e|-w] [-s file] [-f file] [-o opt] [-r] [-x] [-v app]
 -d      : debug mode for development purposes
 -h      : this help
 -k      : keep current background image as permanent
 -p      : go back to previous background but do not display it
 -e      : set background for Enlightenment
 -w      : set background for Window Maker
 -s file : set file as permanent background
 -f file : set file as background
 -o opt  : set aspect to 'opt' (tile, scale, maxscale)
 -r      : remove saved permanent background file
 -x      : show background (if used with -p/-k/-s)
 -v app  : view background in window (used with -p/-k/-s)

If neither -e nor -w are set, the background is set with an image
viewer (in order : wmsetbg, Esetroot, xv). Images should be in jpg
format and have a comment to know how they have to be displayed
(tile, scale or maxscale).
Some options are mutualy exclusive. Options -x and -v should be used
at the END of the options' list.

For more informations : head -n 36 `which chgbkg`

EOF
    exit
}




################################
###      CODE PRINCIPAL      ###
################################


# Vérification du mode de débogage
#
if [ "$1" = "-d" ]; then
    DEBUG=1
    shift
fi

# Chargement de la configuration
#
do_loadcfg

# Traitement des arguments
#
while [ "$1" != "" ]; do
    ARG="$1"
    case "$ARG" in
        "-d") DEBUG=1;;
        "-h") do_help;;
        "-k") SETBGFILE=$BGSPOOL/$PREVBGFILE
              COMM=$PREVASPECT
              SHOW=0;;
        "-p") do_getprevbg
              SHOW=0;;
        "-x") SHOW=1;;
        "-v") if [ "$2" != "" ]; then
                  VIEWER="$2"
              fi
              SHOW=2;;
        "-e") BG=$EBG;;
        "-w") BG=$WMBG;;
        "-s") SETBGFILE="$2"
              do_verify
              SHOW=0
              SAVE=1
              shift;;
        "-f") FILE="$2"
              shift;;
        "-o") if [ "$2" = "scale" -o "$2" = "tile" -o "$2" = "maxscale" ]; then
                  COMM="$2"
              else
                  echo "Error : unknown aspect option." > /dev/stderr
                  exit
              fi
              shift;;
        "-r") SETBGFILE=""
              SHOW=0
              SAVE=1
              PREV=1;;
        *)    echo "Error : unknown argument [$ARG]..." > /dev/stderr
    esac
    do_debug "  ARG : $ARG"
    shift
done


# Traitements
#
do_debug "  SHOW = $SHOW, BG = $BG, SAVE = $SAVE, PREV = $PREV"
if [ $SHOW = 1 ]; then
    do_setbgimage
elif [ $SHOW = 2 ]; then
    do_displayimage
fi
if [ "$FILE" = "" ]; then
    do_savecfg
fi

