#!/bin/bash
#
# cartwall - A stupidly simple application for selecting and playing out audio clips
#
# Version: 0.0.8
# Status: Highly developmental
#
# Author: Tony Whitmore
# With contributions from:
# Alan "popey" Pope
#
# Homepage: The latest version of this script can be found at http://darcs.tonywhitmore.co.uk/
# License: You may freely use, modify and redistribute this script as long as you allow others to do the same.
# This script is provided without warranty or even fitness for purpose. Use at own risk.
#
# Description: Presents a menu allowing the user to select an audio clip for playing, suitable for
# playing back stings or music as part of a radio broadcast. The cartwall.sounds file should contain
# a list of audio files, one per line. The cartwall.conf file should contain any settings which
# differ from the defaults. Valid values include:
#	CARTWALL_TITLE		The title string shown on the screen
#	AUDIODEV		The output audio device to use
#	AUDIODRIVER		The audio driver to use
# This script assumes the following additional programs are in the user's path:
#   play cat
# In Debian/Ubuntu, these are the following packages:
#   sox coreutils
#
# Bugs/TODO: Add some error checking.
# Example: cartwall -s cartwall.sounds -c cartwall.conf
#

# Define some colours. From http://sterlinghamilton.artician.com/blog/2009/05/using-color-text-in-bash-scripts/
# Example usage:
# echo ${RedF}This text will be red!${Reset}
# echo ${BlueF}{$BoldOn}This will be blue and bold!${BoldOff} - and this is just blue!${Reset}
# echo ${RedB}${BlackF}This has a red background and black font!${Reset}and everything after the reset is normal text!

Escape="\033";

BlackF="${Escape}[30m"; RedF="${Escape}[31m"; GreenF="${Escape}[32m";
YellowF="${Escape}[33m"; BlueF="${Escape}[34m"; Purplef="${Escape}[35m";
CyanF="${Escape}[36m"; WhiteF="${Escape}[37m";

BlackB="${Escape}[40m"; RedB="${Escape}[41m"; GreenB="${Escape}[42m";
YellowB="${Escape}[43m"; BlueB="${Escape}[44m"; PurpleB="${Escape}[45m";
CyanB="${Escape}[46m"; WhiteB="${Escape}[47m";

BoldOn="${Escape}[1m"; BoldOff="${Escape}[22m";
ItalicsOn="${Escape}[3m"; ItalicsOff="${Escape}[23m";
UnderlineOn="${Escape}[4m"; UnderlineOff="${Escape}[24m";
BlinkOn="${Escape}[5m"; BlinkOff="${Escape}[25m";
InvertOn="${Escape}[7m"; InvertOff="${Escape}[27m";

Reset="${Escape}[0m";

# Check for command line options
while getopts c:s: opt; do
	case $opt in
		c)
			CONF_FILE=$OPTARG
		;;
		s)
			SOUNDS_FILE=$OPTARG
		;;
	esac
done

# Check for an existing sound file and if not present, exit
if [ -z $SOUNDS_FILE ]; then
	SOUNDS_FILE=cartwall.sounds
fi

if [ ! -f $SOUNDS_FILE ]; then
	echo "File $SOUNDS_FILE not found!"
	exit
fi

# Check for an existing configuration file and if not present, exit
if [ -z $CONF_FILE ]; then
	CONF_FILE=cartwall.conf
fi

if [ ! -f $CONF_FILE ]; then
	echo "Configuration file $CONF_FILE not found!"
	echo "Using defaults for all settings..."
	sleep 3
	CARTWALL_TITLE="Tony's Simple Cart Wall"
else
	. $CONF_FILE
fi

# Load the contents of the sounds file into an array
arr=(`cat $SOUNDS_FILE`)

if [ $PRECACHE == yes ]; then
	# Pre-load each file to force into memory/cache
	echo -n "Please wait. Pre-caching audio files"
	for i in ${arr[@]}; do
		# Only cache files that exist
		if [ -f $i ]; then
			cat $i >> /dev/null
			echo -n "."
		fi
	done
fi

while true; do

	# Reload the array (in case it has been modified)
	arr=(`cat $SOUNDS_FILE`)

	clear

	# Display the menu
	echo
	echo -e "${BoldOn}$CARTWALL_TITLE${Reset}"
	echo
	echo "Press Ctrl+C to stop playing the current sound cue or to quit this script."
	echo "To play clips consecutively, enter the relevant numbers separated by a space."
	echo
	if [ ! -z $AUDIODEV ]; then
		echo "Output audio device:" $AUDIODEV
		echo
	fi
	if [ ! -z $AUDIODRIVER ]; then
		echo "Audio driver:" $AUDIODRIVER
		echo
	fi

	COUNT=0

	# Produce the menu entry for each element in the array, checking if the source file exists
	for i in ${arr[@]}; do
		TITLE=`echo ${i##*/} | sed 's/\..*$//g' | sed 's/_/ /g' | sed 's/-/ /g'  `
		if [ ! -f $i ]; then
			echo -e "   $COUNT) $TITLE - ${RedB}${BlackF} WARNING: Source file $i not found! ${Reset}"
		else
			echo "   $COUNT) $TITLE"
		fi
		COUNT=`expr $COUNT + 1`
	done

	# Ask for a response from the user and store that response in an array
	echo
	echo -n "Enter a number: "

	read PLAY
	arr2=$(echo $PLAY | tr " " "\n")

	# For each element in the array, get the source filename from the sounds file array and append it to the list of files to be played
	unset FILENAMES
	for i in $arr2; do
		FILENAMES="$FILENAMES "${arr[$i]}""
	done

	echo
	echo -e "   ${GreenB}${BlackF} Now playing: $FILENAMES ${Reset}"
	play $FILENAMES

done
