#!/bin/bash
# $Header: /~worc1588/linux/saytime.sh,v 0.01 2004/05/15 14:50:00 ferret Exp $
# Written by ferret <james.noble@worc.ox.ac.uk> - http://ferret.vze.com/

# This program calls ${playerprog} ${format}, where each space-seperated item
# in ${format} is replace with ${prefix}${item}${suffix}.  Kinda.  For a
# clearer explanation, try playerprog="echo".

# FIXME: We should use command line options, even though the three "format"s
# will be hell.
# FIXME: One of those options should be to list all possible items that might
# be subsituted in the ${format} handed to ${playerprog}.
# FIXME: Some error checking for "numberprog" and "dateprog" wouldn't be too
# much to ask.



convertup () {
	local val="$1"
	local tens="$((val/10*10))"
	local units="$((val - tens))"

	case ${tens} in
		0)
			echo "${units}";;
		10)
			echo "1${units}";;
		*)
			if [ "${units}" == "0" ]
			then
				echo "${tens}"
			else
				echo "${tens} ${units}"
			fi;;
	esac
}


# "numberprog" must take an Arabic numeral as an argument, and output in some
# language.  For me, that language is English, however I have tried to keep
# this as flexible as possible.  For any sensible language I can imagine, the
# only real changes that should be necessary is whether to put "oh" in "twelve
# oh nine" (12:09).  Note that the number program has to respond when given
# 0-60.  Why not just up to 59? See `man date'.

# This first example uses a bash function defined towards the end of this
# script.  It converts Arabic numerals to Arabic numerals in a slightly more
# handlable format.  This is helpful if your audio files are named "17.mp3",
# etc.  If you look at the output from this when playerprog="echo", you'll see
# a problem - it won't work so well for non-English audio samples.  Here's an
# example in French:
#	20	= vingt			plays 20.mp3
#	1	= un			plays 1.mp3
#	21	= vingt et un	plays 20.mp3 and 1.mp3
# As you can see, it's impossible to get the "et" out.  Solutions to this
# problem would involve altering the "convert" function only, and would be
# highly language-specific.

#numberprog="convertup"


# The bsd-games package for your distribution probably contains a program
# called number which outputs the English version of Arabic numerals.  I use
# Gentoo, so I do `GAMES_TO_BUILD=number emerge bsd-games'.

numberprog="/usr/games/bin/number -l"


# The default program that "plays" the files.

playerprog="mpg123 -q"				# A good player for MP3s.
#playerprog="mpg321 -q"				# A freer but poorer quality MP3 player.
#playerprog="splay -f >/dev/null"	# MP3 player, comes with `mp3blaster'.
#playerprog="ogg123 -q"				# Player for OGG files.
#playerprog="madplay -Q"			# This MP3 player truncates my sounds. :(
#playerprog="cat >/dev/dsp"			# This should work for raw (.wav) files.
#playerprog="echo"					# For text output, use this.


# The program used for date.  Seriously, don't change this.

# FIXME: Support Solaris, BSD and any other non-GNU date program.
# FIXME: Command line option taking any time. At the moment, the first thing
# on the command line is used as the time.

time_to_use="$1"
[ -z $1 ] && time_to_use="now"
dateprog="date -d ${time_to_use}"


# See the description at the top for how to use prefix and suffix.

prefix="/usr/local/share/saytime/normal-"	# You need a trailing / for a directory.
suffix=".mp3"
#suffix=".ogg"
#suffix=".wav"
#prefix=""
#suffix=""


# Here, "format" is normally used, "format_nos" is used if there's no seconds,
# "format_nom" is used if there's no minutes, and "format_nosm" if there are
# neither minutes nor seconds.  If any of these last three are not set,
# "format" is used in its place.  The variables are:
#	@h = hours
#	@m = minutes
#	@s = seconds
#	@a = meridian (am/pm)
#	@A = capitalised meridian (AM/PM)


# A nice simple one for audio samples, to get you started.

format="thetimeis @h @m @a beep"
format_nos="${format}"
format_nom="${format}"
format_nosm="${format}"

# A more complicated one, to work like a speaking clock.

#format="at-the-tone-the-time-will-be @h @m and @s seconds threebeeps"
#format_nos=${format/and @s seconds/precisely}
#format_nom=${format/@m/oclock}
#format_nosm=${format_nos/@m/oclock}

# A written version of the speaking clock.

#format="At the tone, the time will @h @m and @s seconds.  Beep, beep, BEEP!"
#format_nos=${format/and @s seconds/precisely}
#format_nom=${format/@m/o\'clock}
#format_nosm=${format_nos/@m/o\'clock}

# A joke.  This is from the film "12:01".  If you haven't seen that, you don't
# know anything about anything.

#format="The time is @h @m @A.  Please wake up!  Wake up, wake up!
#
#Lazy boy. :)"
#format_nom=${format/@m/o'clock}
#format_nosm=${format_nom}
#format_nos="${format}"

###  Interesting stuff to alter ends here. :)  ###


# If you can come up with something cleaner than the next three dozen or so
# lines, please tell me.

minutes="`${dateprog} +%M`"
seconds="`${dateprog} +%S`"
hours="`${numberprog} \`${dateprog} +%l\``"

# Fix the leading 0. THIS IS IMPORTANT, since $((08)) and $((09)) in bash give
# an ERROR, as it thinks 0 is a prefix for numbers in octal (base 8). We need
# this in the convert() function, and it makes "numberprog" easier to program.
# "hours", above, doesn't have this problem because `date' doesn't pad it with
# a leading 0.
mins="`${numberprog} ${minutes/#0}`"
secs="`${numberprog} ${seconds/#0}`"

[ ${minutes} -gt 0 ] && [ ${minutes} -lt 10 ] && \
	mins="`${numberprog} 0` ${mins}"	# Make "12:09" do "twelve oh nine".

hours="${hours//-/ }"					# Change "fifty-nine" to "fifty nine",
mins="${mins//-/ }"						# etc.
secs="${secs//-/ }"

if [ "${minutes}" == "00" ]
then
	if [ "${seconds}" == "00" ]
	then
		format="${format_nosm}"
	else
		format="${format_nom//@s/${secs}}"
	fi
else
	if [ "${seconds}" == "00" ]
	then
		format="${format_nos//@m/${mins}}"
	else
		format="${format//@m/${mins}}"
		format="${format//@s/${secs}}"
	fi
fi

format="${format//@h/${hours}}"
format="${format//@a/$(${dateprog} +%P)}"
format="${format//@A/$(${dateprog} +%p)}"
format="${format//@m}"
format="${format//@s}"

for item in ${format}
do
	list="${list} ${prefix}${item}${suffix}"
done

${playerprog} ${list}

