#!/bin/ash
# wallpaper slideshow for rox pinboard
# Copyright (C) James Budiono 2012
# License: GNU GPL Version 3 or later
#
# I wrote this before realising that Nathan's Wallpaper Setter already has the same function
# but anyway, here it is - a one-file version of the wallpaper slideshow.
# 131129 internationalization by L18L

# std localisation stanza
export TEXTDOMAIN=fatdog
. gettext.sh
# performance tweak - use "C" if there is no localisation
! [ -e $TEXTDOMAINDIR/${LANG%.*}/LC_MESSAGES/$TEXTDOMAIN.mo ] &&
! [ -e $TEXTDOMAINDIR/${LANG%_*}/LC_MESSAGES/$TEXTDOMAIN.mo ] && LANG=C

### configuration
GTKDIALOG=gtkdialog
APPTITLE="$(gettext 'Wallpaper Slideshow')"
PIDFILE=/tmp/wallpaper_slideshow.$USER
CONFIG_FILE=$HOME/.config/wallpaper_slideshow

DEFAULT_DURATION=10					# in seconds
DEFAULT_DIR=/usr/share/backgrounds	# puppy standard background images

### config variables - defaults, this will be overriden by CONFIG_FILE
PICS_DURATION=$DEFAULT_DURATION		# how long the pics should display
PICS_DIR=$DEFAULT_DIR				# picture directory 
PICS_STYLE=Stretch					# Centre, Scale, Stretch, Tile (and Fit in latest git)
SORT_FLAG=-R						# -R for randomised display, -r for reversed order, or blank for normal sorted order

### actual command to set background
# $1-filename, $2-style
rox_set_background() {
rox --RPC << EOF
<?xml version="1.0"?>
<env:Envelope xmlns:env="http://www.w3.org/2001/12/soap-envelope">
	<env:Body xmlns="http://rox.sourceforge.net/SOAP/ROX-Filer">
		<SetBackdrop>
			<Filename>$1</Filename>
			<Style>$2</Style>
		</SetBackdrop>
	</env:Body>
</env:Envelope>
EOF
}

### start slideshow - stop previous one; then run slideshow in background
start_slideshow() {
	# sanity checks
	stop_slideshow
	
	# run in background
	while true; do 
		[ -e $CONFIG_FILE ] && . $CONFIG_FILE	# reload config at every iteration
		while read f; do
			case "$f" in
				"") break ;;
				*) 	rox_set_background "$f" $PICS_STYLE
					sleep $PICS_DURATION ;;
			esac
		done << EOF
$(find "$PICS_DIR"/ -maxdepth 1 -type f | sort $SORT_FLAG)		
EOF
	done &
	
	# keep background pid file so that we can kill it
	echo $! > $PIDFILE
}

### stop slideshow - kill the currently running background process
stop_slideshow() {
	if [ -e $PIDFILE ]; then
		read p < $PIDFILE
		kill $p 2> /dev/null
		rm $PIDFILE
	fi
}

### main gui
# returns true of gui wants to exit, otherwise false
interactive() {
	local STYLE_STRETCH STYLE_CENTRE STYLE_SCALE STYLE_TILE
	local ORDER_RANDOM ORDER_REVERSE ORDER_NORMAL
	local active=" active=\"true\"" 
	
	# set flags for display
	case $PICS_STYLE in
		$(gettext 'Stretch')) STYLE_STRETCH=$active	;;
		$(gettext 'Centre'))  STYLE_CENTRE=$active	;;
		$(gettext 'Scale'))   STYLE_SCALE=$active	;;
		$(gettext 'Tile'))    STYLE_TILE=$active	;;
	esac
	
	case $SORT_FLAG in 
		-R) ORDER_RANDOM=$active	;;
		-r)	ORDER_REVERSE=$active	;;
		"") ORDER_NORMAL=$active	;;
	esac
	
	export gui=$(cat << EOF
<window title="$APPTITLE" window_position="1">
<vbox>
		<hbox>
			<vbox>
				<frame $(gettext 'Choose folder containing the images for slideshow')>		
				<chooser>
					<height>300</height>
					<width>500</width>
					<default>$PICS_DIR</default>
					<variable>NEW_PICS_DIR</variable>
				</chooser>
				</frame>
				<frame $(gettext 'Current folder')>
					<text><label>$PICS_DIR</label></text>
				</frame>
			</vbox>
			<vbox>
				<frame $(gettext 'Choose display mode')>
					<radiobutton$STYLE_CENTRE>
						<label>$(gettext 'Centre')</label>
						<variable>STYLE_CENTRE</variable>
					</radiobutton>
					<radiobutton$STYLE_SCALE>
						<label>$(gettext 'Scale')</label>
						<variable>STYLE_SCALE</variable>
					</radiobutton>
					<radiobutton$STYLE_STRETCH>
						<label>$(gettext 'Stretch')</label>
						<variable>STYLE_STRETCH</variable>
					</radiobutton>				
					<radiobutton$STYLE_TILE>
						<label>$(gettext 'Tile')</label>
						<variable>STYLE_TILE</variable>
					</radiobutton>	
				</frame>
				<frame $(gettext 'Choose image order')>
					<radiobutton$ORDER_NORMAL>
						<label>$(gettext 'Alphabetical A to Z')</label>
						<variable>ORDER_NORMAL</variable>
					</radiobutton>
					<radiobutton$ORDER_REVERSE>
						<label>$(gettext 'Reverse Alphabetical Z to A')</label>
						<variable>ORDER_REVERSE</variable>
					</radiobutton>
					<radiobutton$ORDER_RANDOM>
						<label>$(gettext 'Random order')</label>
						<variable>ORDER_RANDOM</variable>
					</radiobutton>
				</frame>
				<frame $(gettext 'Duration per image, in seconds')>
					<entry>
						<default>$PICS_DURATION</default>
						<variable>PICS_DURATION</variable>
					</entry>
				</frame>
			</vbox>
		</hbox>
	<hbox>
		<button><label>$(gettext 'Start slideshow')</label></button>
		<button><label>$(gettext 'Stop slideshow')</label></button>
		<button><label>$(gettext 'Save settings')</label></button>
		<button><label>$(gettext 'Exit')</label></button>
	</hbox>
</vbox></window>
EOF
)
	eval $($GTKDIALOG -p gui)
	
	# interpret results
	case $STYLE_STRETCH in true) PICS_STYLE=Stretch ;; esac
	case $STYLE_SCALE in true) PICS_STYLE=Scale ;; esac
	case $STYLE_CENTRE in true) PICS_STYLE=Centre ;; esac
	case $STYLE_TILE in true) PICS_STYLE=Tile ;; esac
	
	case $ORDER_NORMAL in true) SORT_FLAG="" ;; esac
	case $ORDER_REVERSE in true) SORT_FLAG=-r ;; esac
	case $ORDER_RANDOM in true) SORT_FLAG=-R ;; esac

	case "$NEW_PICS_DIR" in "") ;; *) PICS_DIR="$NEW_PICS_DIR" ;; esac	
	[ ! -d "$PICS_DIR" ] && PICS_DIR="${PICS_DIR%/*}"
	
	case $PICS_DURATION in ""|0) PICS_DURATION=$DEFAULT_DURATION;; esac
	
	# do action based on results
	case $EXIT in
		$(gettext 'Start slideshow')) start_slideshow; return 1 ;;
		$(gettext 'Stop slideshow'))  stop_slideshow; return 1 ;;
		$(gettext 'Save settings'))   save_config; return 1 ;;
	esac
	return 0
}
save_config() {
	{
		echo PICS_DIR=\"$PICS_DIR\"
		echo PICS_STYLE=$PICS_STYLE
		echo SORT_FLAG=$SORT_FLAG
		echo PICS_DURATION=$PICS_DURATION
	} | tee $CONFIG_FILE
}

############ main #############
# load config, if not use default
[ -e $CONFIG_FILE ] && . $CONFIG_FILE
case $1 in 
	start) start_slideshow ;;
	stop) stop_slideshow ;;
	*)	while true; do
			interactive && break
		done ;;
esac
