#! /bin/sh
#############################################################################
# dekagen - a frontend to rip, convert, and name MP3 / Ogg
# Written by Martin Bayer <mbayer@zedat.fu-berlin.de>
#                         http://userpage.fu-berlin.de/~mbayer/tools/
# Portions based on ripenc-0.7 by Michael J. Parmeley
#----------------------------------------------------------------------------
# This is
VERSION='dekagen 1.0.2'
# created Di Jun 15 18:30:49 CEST 2004
#============================================================================
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#============================================================================
# Be sure you have already installed on your system:
# 1. cdda2wav, cdparanoia, dagrab, or tosha,
# 2. 8hz-mp3, bladeenc, l3enc, lame, mp3enc, or notlame,
#    or oggenc.
# You might also wish to install:
# 3. xmcd,
# 4. id3ed, id3tag, id3tool, or mp3info.
# See the file README for details.
#############################################################################
#
# Pre-set defaults:
#
RCDIR="${HOME}/.dekagen"	# per-user configuration directory
TEMPDIR=${RCDIR}		# per-user temporary data directory
SAVETO=${HOME}			# per-user file storage directory
ENCODER='oggenc'		# MP3/Ogg converter tool (command name or 'none')
RIPPER='cdparanoia'		# CDDA ripping tool (command name or 'none')
ID3TOOL='built-in'		# ID3 tagging tool (command name or 'built-in' or 'none')
BITRATE='128'			# MP3/Ogg nominal encoding bitrate (KBits)
METHOD='manual'			# 'manual' or 'cddb'
XMCDLIB=''			# $XMCD_LIBDIR
DEVICE='/dev/cdrom'		# device used for ripping
NCONVENT='artist-name_of_song.mp3'
SELEC='1'			# MP3/Ogg naming convention
WHOLE='no'			# rip whole CD ('yes' or 'no')
SMALL='no'			# small HD ('yes' or 'no')
#
#############################################################################

if [ $# -ne 0 ] ;
then
	echo "This is ${VERSION}"
	echo "Usage: $0"
	echo
	exit
fi

dialog 2>&1 | grep 'backtitle' >/dev/null && alias dialog="dialog --backtitle '${VERSION}'" ;

trap forcequit INT
trap forcequit TERM
trap forcequit QUIT
trap forcequit HUP

forcequit ()
{
	# when aborting on ^c or "cancel", kill background encoding processes
	test -f ${TEMPDIR}/lock.encode && killbgjob
	cleantemp
	saverc
	echo 'Dekagen terminated on user request.' ;
exit 1
}

killbgjob ()
{
	rm ${TEMPDIR}/convers
	BCKGRNDP=$(cat ${TEMPDIR}/lock.encode 2>/dev/null) ;
	ps -o ppid,pid | awk '$1 == '"${BCKGRNDP}"' { print $2 }' >>${TEMPDIR}/lock.encode 2>/dev/null ;
	kill $(echo $(cat ${TEMPDIR}/lock.encode)) ;
	echo 'Background encoding processes aborted.' ;
	rm ${TEMPDIR}/lock.encode
}

cleantemp ()
{
	# remove temp data
	rm ${TEMPDIR}/ripname 2>/dev/null
	rm ${TEMPDIR}/cdnames 2>/dev/null
	rm ${TEMPDIR}/toc1 2>/dev/null
	rm ${TEMPDIR}/toc2 2>/dev/null
	rm ${TEMPDIR}/tracks 2>/dev/null
	rm ${TEMPDIR}/tmprip 2>/dev/null
	rm ${TEMPDIR}/tracknrs1 2>/dev/null
	rm ${TEMPDIR}/tracknrs2 2>/dev/null
	rm ${TEMPDIR}/msgs 2>/dev/null
}

saverc ()
{
	# save settings on disk
	echo SAVETO="'"${SAVETO}"'" > ${RCDIR}/dekagenrc
	echo RIPPER="'"${RIPPER}"'" >> ${RCDIR}/dekagenrc
	echo ENCODER="'"${ENCODER}"'" >> ${RCDIR}/dekagenrc
	echo ID3TOOL="'"${ID3TOOL}"'" >> ${RCDIR}/dekagenrc
	echo METHOD="'"${METHOD}"'" >> ${RCDIR}/dekagenrc
	echo XMCDLIB="'"${XMCDLIB}"'" >> ${RCDIR}/dekagenrc
	echo SELEC="'"${SELEC}"'" >> ${RCDIR}/dekagenrc
	echo NCONVENT="'"${NCONVENT}"'" >> ${RCDIR}/dekagenrc
	echo WHOLE="'"${WHOLE}"'" >> ${RCDIR}/dekagenrc
	echo SMALL="'"${SMALL}"'" >> ${RCDIR}/dekagenrc
	echo DEVICE="'"${DEVICE}"'" >> ${RCDIR}/dekagenrc
	echo BITRATE="'"${BITRATE}"'" >> ${RCDIR}/dekagenrc
}

findripper ()
{
	# don't forget to update this array when extending features
	for FNDRIP in ${RIPPER} cdparanoia cdda2wav dagrab tosha none
	do
		if [ "${FNDRIP}" = 'none' ] ;
		then
			RIPPER='none'
		elif (which ${FNDRIP} >/dev/null && test -x $(which ${FNDRIP}))
		then
			RIPPER=${FNDRIP}
			break
		fi
	done
}

findencoder ()
{
	# don't forget to update this array when extending features
	for FNDENC in ${ENCODER} oggenc lame bladeenc notlame mp3enc 8hz-mp3 l3enc none
	do
		if [ "${FNDENC}" = 'none' ] ;
		then
			ENCODER='none'
		elif (which ${FNDENC} >/dev/null && test -x $(which ${FNDENC}))
		then
			ENCODER=${FNDENC}
			break
		fi
	done
}

findid3tool ()
{
	# don't forget to update this array when extending features
	for FNDID3 in ${ID3TOOL} id3ed id3tag mp3info id3tool none
	do
		if [ "${FNDID3}" = 'none' ] ;
		then
			ID3TOOL='none'
		elif (which ${FNDID3} >/dev/null && test -x $(which ${FNDID3}))
		then
			ID3TOOL=${FNDID3}
			break
		fi
	done
}

checkoldrc ()
{
	# Make the .dekagen directory to store all the files used by dekagen
	if [ ! -d ${RCDIR} ] && [ -d ${HOME}/.dekagen ] ;
	then
		cp -r ${HOME}/.dekagen ${RCDIR}
		rm ${RCDIR}/dekagensed 2>/dev/null
	elif [ ! -d ${RCDIR} ] ;
	then
		mkdir -p ${RCDIR}
	fi
}

checkforsed ()
{
	# make file with sed rules
	echo '/^$/d' > ${RCDIR}/dekagensed
	echo "s/'//g" >> ${RCDIR}/dekagensed
	echo 's/"//g' >> ${RCDIR}/dekagensed
	echo 's/\*//g' >> ${RCDIR}/dekagensed
	echo 's/,//g' >> ${RCDIR}/dekagensed
	echo 's/)//g' >> ${RCDIR}/dekagensed
	echo 's/(//g' >> ${RCDIR}/dekagensed
	echo 's/\.//g' >> ${RCDIR}/dekagensed
	echo 's/\$//g' >> ${RCDIR}/dekagensed
	echo 's/&/and/g' >> ${RCDIR}/dekagensed
	echo 's/://g' >> ${RCDIR}/dekagensed
	echo 's/_*-_*/__/g' >> ${RCDIR}/dekagensed
	echo 's/\?//g' >> ${RCDIR}/dekagensed
	echo 's/^\ *//' >> ${RCDIR}/dekagensed
	echo 's/ /_/g' >> ${RCDIR}/dekagensed
	echo 's/^_*//' >> ${RCDIR}/dekagensed
	echo 's/_*$//' >> ${RCDIR}/dekagensed
}

checksaveto ()
{
	# check whether working directory already exists and is writable, fallback: $HOME
	if [ "${SAVETO}" != '' ] && [ ! -d ${SAVETO} ] ;
	then
		if dialog --title 'Question'\
			--yesno "${SAVETO} does not exist.\nDo you wish to create it?" 19 70 ;
		then
			mkdir -p ${SAVETO} && return
			dialog --title 'Error'\
				--msgbox "Cannot create ${SAVETO}." 19 70 ;
			SAVETO=''
		else
			SAVETO=''
		fi
	elif [ "${SAVETO}" != '' ] && [ ! -w ${SAVETO} ] ;
	then
		dialog --title 'Error'\
			--msgbox "You have no write access to ${SAVETO}." 19 70 ;
		SAVETO=''
	fi
	if [ "${SAVETO}" = '' ] && [ "${OLDSAVETO}" != '' ] ;
	then
		SAVETO=${OLDSAVETO}
	fi
	if [ "${SAVETO}" = '' ] || [ ! -d ${SAVETO} ] || [ ! -w ${SAVETO} ] ;
	then
		SAVETO=${HOME}
	fi
}

checkdevice ()
{
	# check whether $DEVICE is pointing to a device, fallback: /dev/cdrom
	if [ ! -e ${DEVICE} ] ;
	then
		dialog --title 'Error' \
			--msgbox "Device ${DEVICE} does not seem to exist." 19 70 ;
		DEVICE=''
	fi
	if [ "${DEVICE}" = '' ] && [ "${TEMPDEVICE}" != '' ] ;
	then
		DEVICE=${TEMPDEVICE}
	elif [ "${DEVICE}" = '' ] ;
	then
		DEVICE='/dev/cdrom'
	fi
}

checkripper ()
{
	# check whether $RIPPER is installed and executable
	if [ "${RIPPER}" != 'none' ] && ! (which ${RIPPER} >/dev/null && test -x $(which ${RIPPER}))
	then
		dialog --title 'Error' --msgbox \
			"${RIPPER} is not installed or not executable." 19 70 ;
		CHR=''
	fi
	if [ "${CHR}" = '' ] && [ "${TEMPRIPPER}" != '' ] ;
	then
		RIPPER=${TEMPRIPPER}
	elif [ "${CHR}" = '' ] && [ "${RIPPER}" != 'none' ] ;
	then
		# try to find a ripper automatically
		findripper
	fi
}

checkencoder ()
{
	# check whether $ENCODER is installed and executable
	if [ "${ENCODER}" != 'none' ] && ! (which ${ENCODER} >/dev/null && test -x $(which ${ENCODER}))
	then
		dialog --title 'Error' --msgbox \
			"${ENCODER} is not installed or not executable." 19 70 ;
		OPT=''
	fi
	if [ "${OPT}" = '' ] && [ "${TEMPENCODER}" != '' ] ;
	then
		ENCODER=${TEMPENCODER}
	elif [ "${OPT}" = '' ] && [ "${ENCODER}" != 'none' ] ;
	then
		# try to find an encoder automatically
		findencoder
	fi
	if [ "${ENCODER}" != 'l3enc' ] && [ ${BITRATE} -gt 999 ] ;
	then
		BITRATE=$(expr ${BITRATE} / 1000)
	elif [ "${ENCODER}" = 'l3enc' ] && [ ${BITRATE} -le 999 ] ;
	then
		BITRATE=$(expr ${BITRATE} \* 1000)
	fi
	# $ID3TOOL might need to be adjusted
	TEMPID3TOOL=''
	ID3UTIL='0'
	checkid3tool
}

checkid3tool ()
{
	# check whether $ID3TOOL is installed and executable
	if [ "${ENCODER}" = 'none' ] ;
	then
		ID3TOOL='none'
	fi
	if [ "${ID3TOOL}" != 'none' ] && [ "${ID3TOOL}" != 'built-in' ] && [ "${ENCODER}" = 'oggenc' ] ;
	then
		dialog --title 'Error' --msgbox \
			'ID3 tags cannot be used with oggenc, only Built-In tagging.' 19 70 ;
		ID3TOOL='built-in'
	fi
	if [ "${ID3TOOL}" = 'built-in' ] && ! ([ "${ENCODER}" = 'lame' ] || [ "${ENCODER}" = 'notlame' ] || [ "${ENCODER}" = 'oggenc' ]) ;
	then
		dialog --title 'Error' --msgbox \
			'The Built-In tagging function can only be used with either lame, notlame, or oggenc.' 19 70 ;
		ID3UTIL=''
	fi
	if [ "${ID3TOOL}" != 'built-in' ] && [ "${ID3TOOL}" != 'none' ] && ! (which ${ID3TOOL} >/dev/null && test -x $(which ${ID3TOOL}))
	then
		dialog --title 'Error' --msgbox \
			"${ID3TOOL} is not installed or not executable." 19 70 ;
		ID3UTIL=''
	fi
	if [ "${ID3UTIL}" = '' ] && [ "${TEMPID3TOOL}" != '' ] ;
	then
		ID3TOOL=${TEMPID3TOOL}
	elif [ "${ID3UTIL}" = '' ] ;
	then
		if [ "${ENCODER}" = 'lame' ] || [ "${ENCODER}" = 'notlame' ] || [ "${ENCODER}" = 'oggenc' ] ;
		then
			ID3TOOL='built-in'
		else
			# try to find an ID3 tagging utility automatically
			findid3tool
		fi
	fi
}

getcddb ()
{
	# try to access CDDB...
	if [ "${XMCDLIB}" != '' ] ;
	then
		export XMCD_LIBDIR=${XMCDLIB}
	fi
	cda -batch -dev ${DEVICE} on
	cda -dev ${DEVICE} toc > ${TEMPDIR}/toc1
	grep '(unknown.*title)' ${TEMPDIR}/toc1 >/dev/null && cda -batch -offline -dev ${DEVICE} toc >${TEMPDIR}/toc1 2>/dev/null ;
	cda -batch -dev ${DEVICE} off
	if ! (grep '(unknown.*title)' ${TEMPDIR}/toc1 >/dev/null) && [ -s ${TEMPDIR}/toc1 ] ;
	then
		sed -e '/Total Time/d' -e '/Disc ID/d' -e '/Accessing CDDB/d' -e '/^Genre:.*$/d' -e '/^$/d' -e 's/\.//g' -e 's/\[//g' -e 's/\]//g' ${TEMPDIR}/toc1 > ${TEMPDIR}/toc2
		CHECKVARIOUS=$(sed -ne '1p' ${TEMPDIR}/toc2 | cut -d "/" -f1 | tr A-Z a-z | sed -e 's/ //g')
		if [ "${CHECKVARIOUS}" = 'variousartists' -o "${CHECKVARIOUS}" = 'soundtrack' -o "${CHECKVARIOUS}" = 'various' ] ;
		then
			ALBUM=$(sed -ne '1p' ${TEMPDIR}/toc2 | cut -d "/" -f2- | tr a-z A-Z)
			sed -e '1d' ${TEMPDIR}/toc2 | cut -d ' ' -f5- | tr A-Z a-z | sed -e 's/\//-/g' -e 's/ - /-/g' -e 's/ -- /-/g' -f ${RCDIR}/dekagensed > ${TEMPDIR}/cdnames
		else
			ARTIST=$(sed -ne '1p' ${TEMPDIR}/toc2 | cut -d "/" -f1)
			ALBUM=$(sed -ne '1p' ${TEMPDIR}/toc2 | cut -d "/" -f2-)
			sed -e '1d' ${TEMPDIR}/toc2 | cut -d ' ' -f5- | sed -e 's/\///g' -f ${RCDIR}/dekagensed > ${TEMPDIR}/cdnames
		fi
		rm ${TEMPDIR}/toc[1-2]
		test -s ${TEMPDIR}/cdnames || return ;
		if [ "${WHOLE}" = 'yes' ] ;
		then
			if [ "${ID3TOOL}" != 'none' ] ;
			then
				YEAR=$(dialog --inputbox 'Please enter the publishing year:' \
				19 70 3>&1 1>&2 2>&3) || return ;
			fi
			sed -e '=' ${TEMPDIR}/cdnames | sed -e 'N' -e 's/\n/ /g' >${TEMPDIR}/ripname
			confirm
		else
			newmenu
		fi
	else
		# ...or fall back to 'manual' method
		METHOD='manual'
		if [ "${WHOLE}" = 'yes' ] ;
		then
		WHOLE='no'
		manual
			WHOLE='yes'
		else
			manual
		fi
		METHOD='cddb'
	fi
}

newmenu ()
{
	# select songs from CDDB list
	test -f ${TEMPDIR}/ripname && rm ${TEMPDIR}/ripname
	sed -e /^$/d ${TEMPDIR}/cdnames | sed -e '=' | sed -e 'N' -e 's/\n/ /g' -e 's/$/ off/g' >${TEMPDIR}/tracks
	dialog --checklist 'Please select the song(s) you wish to rip/encode:' \
		19 70 12 $(cat ${TEMPDIR}/tracks) 2>${TEMPDIR}/tracknrs1 || return ;
	sed -e 's/\"//g' -e 's/$/\ /' ${TEMPDIR}/tracknrs1 | tr " " "\n" | sed -e '/^$/d' >${TEMPDIR}/tracknrs2
	cat ${TEMPDIR}/tracknrs2 | while read SONGNRS
		do
			sed -ne "${SONGNRS}"'P' ${TEMPDIR}/tracks | sed -e 's/ off$//' >>${TEMPDIR}/ripname
		done
	rm ${TEMPDIR}/tracknrs[1-2]
	test  -s ${TEMPDIR}/ripname || return ;
	if [ "${ID3TOOL}" != 'none' ] ;
	then
		YEAR=$(dialog --inputbox 'Please enter the publishing year:' \
			19 70 3>&1 1>&2 2>&3) || return ;
	fi
	confirm
}

manual ()
{
	# let user enter song title etc. manually
	test -f ${TEMPDIR}/ripname && rm ${TEMPDIR}/ripname
	ARTIST=$(dialog --inputbox 'Please enter the name of the artist or composer:' \
		19 70 3>&1 1>&2 2>&3) || return ;
	ALBUM=$(dialog --inputbox 'Please enter the title of the album:' \
		19 70 3>&1 1>&2 2>&3) || return ;
	if [ "${ID3TOOL}" != 'none' ] ;
	then
		YEAR=$(dialog --inputbox 'Please enter the publishing year:' \
			19 70 3>&1 1>&2 2>&3) || return ;
	fi
	SNUM='0'
	while [ "${SNUM}" != '' ] ;
	do
		SNUM=$(dialog --inputbox 'Please enter the track number of the song you wish to rip\n(leave it blank and hit return to continue):' \
			19 70 3>&1 1>&2 2>&3) || return ;
		if [ "${SNUM}" = '' ] ;
		then
			continue
		fi
		SNAME=$(dialog --inputbox "Please enter the name of the song number ${SNUM}:" \
			19 70 3>&1 1>&2 2>&3) || return ;
		SNAME=$(echo "${SNAME}" | sed -e 's/\//-/g' -f ${RCDIR}/dekagensed) ;
		echo "${SNUM} ${SNAME}" >>${TEMPDIR}/ripname
	done
	confirm
}

confirm ()
{
	# let user check his selection
	CONFMENU='' ;
	while [ "${CONFMENU}" != 'd' ] && [ "${CONFMENU}" != 'b' ] ;
	do
		test -s ${TEMPDIR}/ripname || return ;
		CONFMENU=$(dialog --menu 'You are going to start ripping/encoding NOW!' 19 70 5 \
			'd' 'Do it!' \
			'l' 'Show me what I have chosen' \
			's' 'Change selection (discard current selection)' \
			'b' 'Back to the main menu (nothing will be done)' 3>&1 1>&2 2>&3) || return ;
		case ${CONFMENU} in
			b)
				return
				;;
			s)
				if [ "${METHOD}" = 'manual' ] ;
				then
					manual
				else
					newmenu
				fi
			        ;;
			l)
				dialog --title 'These songs are going to be ripped/encoded:' \
					--textbox ${TEMPDIR}/ripname 19 70 ;
				;;
			d)
				rip
				;;
		esac
	done
}

rip()
{
	# lets do it :-)
	TEMPSAVETO=${SAVETO}
	ARTIST=$(echo "${ARTIST}" | sed -e 's/\//-/g' -f ${RCDIR}/dekagensed) ;
	ALBUM=$(echo "${ALBUM}" | sed -e 's/\//-/g' -f ${RCDIR}/dekagensed) ;
	YEAR=$(printf '%04d' ${YEAR} 2>/dev/null) ;
	cat ${TEMPDIR}/ripname | while read NUM TITLE
		do
			FORMATNUM=$(printf '%02d' ${NUM})
			if [ "${CHECKVARIOUS}" = 'variousartists' -o "${CHECKVARIOUS}" = 'soundtrack' -o "${CHECKVARIOUS}" = 'various' ] ;
			then
				ARTIST='VARIOUS_ARTIST_CD'
				case ${SELEC} in
					1)
						NAME=$(echo "${TITLE}" | tr A-Z a-z)
						;;
					2)
						NAME=$(echo "${FORMATNUM}-${TITLE}" | tr A-Z a-z)
						;;
					3)
						NAME="${TITLE}"
						;;
					4)
						NAME="${FORMATNUM}-${TITLE}"
						;;
					*)
						NAME=$(echo "${TITLE}" | tr A-Z a-z)
						;;
				esac
			else
				case ${SELEC} in
					1)
						NAME=$(echo "${ARTIST}-${TITLE}" | tr A-Z a-z)
						;;
					2)
						NAME=$(echo "${FORMATNUM}-${ARTIST}-${TITLE}" | tr A-Z a-z)
						;;
					3)
						NAME="${ARTIST}-${TITLE}"
						;;
					4)
						NAME="${FORMATNUM}-${ARTIST}-${TITLE}"
						;;
					5)
						NAME=$(echo "${FORMATNUM}-${TITLE}" | tr A-Z a-z)
						mkdir -p "${SAVETO}/"$(echo "${ARTIST}--${ALBUM}" | tr A-Z a-z)
						SAVETO="${SAVETO}/"$(echo "${ARTIST}--${ALBUM}" | tr A-Z a-z)
						;;
					6)
						NAME=$(echo "${FORMATNUM}-${TITLE}" | tr A-Z a-z)
						mkdir -p "${SAVETO}/"$(echo "${ARTIST}/${ALBUM}" | tr A-Z a-z)
						SAVETO="${SAVETO}/"$(echo "${ARTIST}/${ALBUM}" | tr A-Z a-z)
						;;
					7)
						NAME=$(echo "${ARTIST}-${ALBUM}-${FORMATNUM}-${TITLE}" | tr A-Z a-z)
						;;
					8)
						NAME="${TITLE}"
						mkdir -p "${SAVETO}/${ARTIST}--${ALBUM}"
						SAVETO="${SAVETO}/${ARTIST}--${ALBUM}"
						;;
					*)
						NAME=$(echo "${ARTIST}-${TITLE}" | tr A-Z a-z)
				esac
			fi
			echo
			echo "Now ripping the song ${TITLE} by ${ARTIST} from the album ${ALBUM}." ;
			echo
			case ${RIPPER} in
				cdparanoia)
					cdparanoia -d ${DEVICE} -w ${NUM} "${SAVETO}/${NAME}.wav"
					;;
				cdda2wav)
					cdda2wav -H -Q -D ${DEVICE} -t ${NUM} "${SAVETO}/${NAME}.wav"
					;;
				dagrab)
					dagrab -d ${DEVICE} -f "${SAVETO}/${NAME}.wav" ${NUM}
					;;
				tosha)
					tosha -q -f wav -d ${DEVICE} -t ${NUM} -o "${SAVETO}/${NAME}.wav"
					;;
				none)
					echo 'Not ripping.'
					;;
				*)
					echo 'Cannot rip from CD.'
					;;
			esac
			echo "${SAVETO}/${NAME}.wav*${ALBUM}*${ARTIST}*${TITLE}*${NUM}*${YEAR}" >> ${TEMPDIR}/convers ;
			if [ "${ENCODER}" != 'none' ] && [ "${SMALL}" = 'yes' ] ;
			then
				echo "Currently converting the song ${TITLE} by ${ARTIST} from the album ${ALBUM}." ;
				encodeit
			elif [ "${ENCODER}" != 'none' ] && [ "${SMALL}" != 'yes' ] && [ ! -f ${TEMPDIR}/lock.encode ] ;
			then
				encodeit >> ${TEMPDIR}/encode.log 2>&1 &
				echo $! > ${TEMPDIR}/lock.encode
			fi
			SAVETO=${TEMPSAVETO}
		done
}

encodeit ()
{
	# generate mp3 / ogg and label it with name (id3) tag
	AIO='0'
	while [ "${AIO}" != '' ]  ;
	do
		AIO=$(head -n1 ${TEMPDIR}/convers) ;
		EIN=$(echo "${AIO}" | cut -s -d '*' -f1) ;
		ENEW=$(echo "${EIN}" | sed -e 's/\.wav$/\.mp3/') ;
		if [ "${ID3TOOL}" != 'none' ] && [ "${ENCODER}" != 'none' ] ;
		then
			ID3ALBUM=$(echo "${AIO}" | cut -s -d '*' -f2 | sed -e 's/_/ /g' -e 's/-/ /g') ;
			ID3ARTIST=$(echo "${AIO}" | cut -s -d '*' -f3 | sed -e 's/_/ /g' -e 's/-/ /g') ;
			ID3TITLE=$(echo "${AIO}" | cut -s -d '*' -f4 | sed -e 's/_/ /g' -e 's/-/ /g') ;
			ID3NUM=$(echo "${AIO}" | cut -s -d '*' -f5) ;
			ID3YEAR=$(echo "${AIO}" | cut -s -d '*' -f6) ;
			case ${ENCODER} in
				bladeenc)
					bladeenc -delete -quit -quiet -br "${BITRATE}" "${EIN}" </dev/null
					;;
				8hz-mp3)
					8hz-mp3 -b ${BITRATE} "${EIN}" "${ENEW}"
					rm "${EIN}"
					;;
				mp3enc)
					mp3enc -br ${BITRATE} -if "${EIN}" -of "${ENEW}"
					rm "${EIN}"
					;;
				l3enc)
					l3enc -br ${BITRATE} "${EIN}" "${ENEW}"
					rm "${EIN}"
					;;
				lame)
					if [ "${ID3TOOL}" = 'built-in' ] ;
					then
						lame -S -h -b ${BITRATE} --tl "${ID3ALBUM}" --ta "${ID3ARTIST}" --tt "${ID3TITLE}" --tn "${ID3NUM}" --ty "${ID3YEAR}" "${EIN}" "${ENEW}" ;
					else
						lame -S -h -b ${BITRATE} "${EIN}" "${ENEW}" ;
					fi
					rm "${EIN}"
					;;
				notlame)
					if [ "${ID3TOOL}" = 'built-in' ] ;
					then
						notlame -S -h -b ${BITRATE} --tl "${ID3ALBUM}" --ta "${ID3ARTIST}" --tt "${ID3TITLE}" --tn "${ID3NUM}" --ty "${ID3YEAR}" "${EIN}" "${ENEW}" ;
					else
						notlame -S -h -b ${BITRATE} "${EIN}" "${ENEW}" ;
					fi
					rm "${EIN}"
					;;
				oggenc)
					EOGG=$(echo "${EIN}" | sed -e 's/\.wav$/\.ogg/') ;
					oggenc --quiet -b ${BITRATE} -o "${EOGG}" -l "${ID3ALBUM}" -a "${ID3ARTIST}" -t "${ID3TITLE}" -N "${ID3NUM}" -d "${ID3YEAR}" "${EIN}"
					rm "${EIN}"
					;;
			esac
			case ${ID3TOOL} in
				id3ed)
					id3ed -a "${ID3ALBUM}" -n "${ID3ARTIST}" -s "${ID3TITLE}" -k "${ID3NUM}" -y "${ID3YEAR}" -q "${ENEW}" ;
					;;
				id3tool)
					id3tool -c "${ID3NUM}" -a "${ID3ALBUM}" -r "${ID3ARTIST}" -t "${ID3TITLE}" -y "${ID3YEAR}" "${ENEW}" ;
					;;
				id3tag)
					id3tag -A"${ID3ALBUM}" -a"${ID3ARTIST}" -s"${ID3TITLE}" -t"${ID3NUM}" -y"${ID3YEAR}" "${ENEW}" ;
					;;
				mp3info)
					mp3info -l "${ID3ALBUM}" -a "${ID3ARTIST}" -t "${ID3TITLE}" -n "${ID3NUM}" -y "${ID3YEAR}" "${ENEW}" ;
					;;
				*)
					# this should catch also the "built-in" option
					;;
			esac
		else
			case ${ENCODER} in
				bladeenc)
					bladeenc -delete -quit -quiet -br ${BITRATE} "${EIN}" </dev/null
					;;
				8hz-mp3)
					8hz-mp3 -b ${BITRATE} "${EIN}" "${ENEW}"
					rm "${EIN}"
					;;
				mp3enc)
					mp3enc -br ${BITRATE} -if "${EIN}" -of "${ENEW}"
					rm "${EIN}"
					;;
				l3enc)
					l3enc -br ${BITRATE} "${EIN}" "${ENEW}"
					rm "${EIN}"
					;;
				lame)
					lame -S -h -b ${BITRATE} "${EIN}" "${ENEW}"
					rm "${EIN}"
					;;
				notlame)
					notlame -S -h -b ${BITRATE} "${EIN}" "${ENEW}"
					rm "${EIN}"
					;;
				oggenc)
					oggenc --quiet -b ${BITRATE} "${EIN}"
					rm "${EIN}"
					;;
				none)
					echo 'Not encoding.'
					;;
				*)
					echo 'Cannot convert to MP3/Ogg.'
					;;
			esac
		fi
		sed -e '1d' ${TEMPDIR}/convers >>${TEMPDIR}/converstemp
		mv ${TEMPDIR}/converstemp ${TEMPDIR}/convers
		AIO=$(head -n1 ${TEMPDIR}/convers) ;
	done
	rm -f ${TEMPDIR}/lock.encode
}

main ()
{
	# main menu
	MENU='' ;
	while [ "${MENU}" != 'q' ] ;
	do
        	if [ -f ${TEMPDIR}/lock.encode ] ;
        	then
        	        echo 'There is currently an encoding process running in the background.' >${TEMPDIR}/msgs
        	else
        	        echo 'There is no encoding process running in the background.' >${TEMPDIR}/msgs
        	fi
        	if [ -s ${TEMPDIR}/encode.log ] ;
        	then
        	        SIZE=$(ls -sh ${TEMPDIR}/encode.log | awk '{ print $1 }')
        	        echo "Your encode log file is ${SIZE} bytes long." >>${TEMPDIR}/msgs
        	else
        	        echo 'There is no encode log file.' >>${TEMPDIR}/msgs
        	fi
		MENU=$(dialog --menu "$(cat ${TEMPDIR}/msgs)" 19 70 10 \
			's' 'Start' \
			'e' 'Show details of encoding process' \
			'v' 'Show the encode log' \
			'd' 'Delete the encode log' \
			'l' 'List the files in the working directory' \
			'p' 'Preferences' \
			'h' 'Help (show manual page)' \
			'a' 'About dekagen' \
			'q' 'Quit (safe exit)' 3>&1 1>&2 2>&3) || forcequit ;
		rm ${TEMPDIR}/msgs

		case ${MENU} in
			v) # view encolde log
				if [ -s ${TEMPDIR}/encode.log ] ;
				then
					dialog --title 'Content of your encode log:' \
						--textbox ${TEMPDIR}/encode.log 19 70 ;
				else
					dialog --title 'Message' \
						--msgbox 'There is no encode log file to view.' 19 70 ;
				fi
				;;
			e) # show details of encoding process
				if [ ! -f ${TEMPDIR}/lock.encode ] ;
				then
					dialog --title 'Message' \
						--msgbox 'There is no encoding process running.' 19 70 ;
				else
					echo >${TEMPDIR}/tmprip
					echo 'Encoder      PID     CPU Usage  CPU Time  Elapsed Time' >>${TEMPDIR}/tmprip
					BCKGRNDP=$(cat ${TEMPDIR}/lock.encode 2>/dev/null) ;
					ps -o comm,pid,pcpu,time,etime,ppid | awk '$6 == '"${BCKGRNDP}"' \
						{ print $1"      "$2"          "$3"  "$4"         "$5 }' >>${TEMPDIR}/tmprip 2>/dev/null ;
					STATUSINC=$(wc -l ${TEMPDIR}/convers | awk '{ print $1 }') ;
					STATUS=$(expr ${STATUSINC} - 1) ;
					CURRENT=$(sed -ne '1p' ${TEMPDIR}/convers | cut -s -d '*' -f1) ;
					echo >>${TEMPDIR}/tmprip
					echo 'File currently being encoded:' >>${TEMPDIR}/tmprip
					echo "${CURRENT}" >>${TEMPDIR}/tmprip
					echo >>${TEMPDIR}/tmprip
					case ${STATUS} in
						0)
							echo 'There are no more songs in the queue.' >>${TEMPDIR}/tmprip
							;;
						1)
							echo 'This song still needs to be encoded:' >>${TEMPDIR}/tmprip
							;;
						*)
							echo "These ${STATUS} songs still need to be encoded:" >>${TEMPDIR}/tmprip
							;;
					esac
					sed -ne '2,$p' ${TEMPDIR}/convers | cut -s -d '*' -f1 >>${TEMPDIR}/tmprip ;
					dialog --title 'Currently running encoding processes:' \
						--textbox ${TEMPDIR}/tmprip 19 70 ;
					rm ${TEMPDIR}/tmprip
				fi
				;;
			d) # delete encode log
				if [ ! -f ${TEMPDIR}/encode.log ] ;
				then
					dialog --title 'Message' \
						--msgbox 'There is no encode log file.' 19 70 ;
				elif [ -f ${TEMPDIR}/lock.encode ] ;
				then
					dialog --title 'Question'\
						--yesno 'Deleting the encode log while an encoding process is running
will disable writing any more information to the log file until
encoding processes for all files currently in the queue and for
files that are added to the queue while the current encoding is
running are completed.

Are you sure you want to do this?' 19 70 \
						&& rm -f ${TEMPDIR}/encode.log ;
				else
					rm ${TEMPDIR}/encode.log
				fi
				;;
			p) # setup preferences
				if [ -f ${TEMPDIR}/lock.encode ] ;
				then
					dialog --title 'Message' \
						--msgbox 'Preferences cannot be changed while an encoding process is running.' 19 70 ;
				else
					setup
					saverc
				fi
				;;
			l) # list
                        	ls -lF ${SAVETO}/ >${TEMPDIR}/tmprip
				dialog --title "Content of ${SAVETO}:" --textbox ${TEMPDIR}/tmprip 19 70 ;
                        	rm ${TEMPDIR}/tmprip
                        	;;
                	s) # start
                        	if [ "${METHOD}" = 'cddb' ] ;
                        	then
                        	        getcddb
                        	else
                                	manual
                        	fi
                        	;;

	                h) # show manual page
                        	man dekagen 2>&1 | col -bx >${TEMPDIR}/tmprip
				dialog --title 'dekagen manual page' --textbox ${TEMPDIR}/tmprip 19 70 ;
                        	rm ${TEMPDIR}/tmprip
                        	;;

			a) # about
				cat >${TEMPDIR}/tmprip <<- %%

   Dekagen written by Martin Bayer <mbayer@zedat.fu-berlin.de>

                 The latest version can be found at
      http://userpage.fu-berlin.de/~mbayer/tools/dekagen.html

  This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version
     2 of the License, or (at your option) any later version.
     This program is distributed in the hope that it will be
   useful, but WITHOUT ANY WARRANTY; without even the implied
     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE. See the GNU General Public License for more details.
%%
				dialog --title "About ${VERSION}" --textbox ${TEMPDIR}/tmprip 19 70 ;
				rm ${TEMPDIR}/tmprip
				;;
			q) # quit
				if [ -f ${TEMPDIR}/lock.encode ] ;
                	        then
                	                dialog --title 'Question'\
                	                        --yesno 'You are going to leave dekagen, but there are still encoding
processes running in the background. Leave them as well?

Answering Yes will cause these processes to be terminated and
the encoding queue to be deleted. There is no way to resume
these operations.
Answering No will let these processes running in the
background. It is safe to restart dekagen later to view the log
file, or to add other songs to the queue.

Do you wish these processes to be terminated?' 19 70 \
                	                        && (killbgjob ; cleantemp ; saverc) ;
                	        else
                        		clear
                        		cleantemp
                        		saverc
				fi
				;;
		esac
	done
}

setup ()
{
	# setup options screen
	SETMENU='' ;
	while [ "${SETMENU}" != '1' ] ;
	do
		SETMENU=$(dialog --menu 'dekagen preferences' 19 70 12 \
			'1' 'Save settings and return to main menu' \
			'2' "Change working directory: ${SAVETO}" \
			'3' "Choose ripper: ${RIPPER}" \
			'4' "Choose encoder: ${ENCODER}" \
			'5' "Choose ID3 tag tool: ${ID3TOOL}" \
			'6' "Toggle between manual or CDDB naming: ${METHOD}" \
			'7' "Set XMCD_LIBDIR variable for cda: ${XMCDLIB}" \
			'8' "Set file naming convention: ${NCONVENT}" \
			'9' "Rip whole CD? ${WHOLE}" \
			'10' "Set small hard disk option? ${SMALL}" \
			'11' "Select your CD-ROM device: ${DEVICE}" \
			'12' "Set nominal bitrate for the encoded MP3/Ogg: ${BITRATE}" 3>&1 1>&2 2>&3) || return ;

		case ${SETMENU} in
			1) # leave preferences screen
				saverc
				;;
			2) # setup working directory
                	        OLDSAVETO=${SAVETO}
				SAVETO=$(dialog --inputbox "Please enter the full path to the directory in which all ripping
and encoding will be done
(currently ${SAVETO}):" 19 70 3>&1 1>&2 2>&3 | sed -e 's/\/$//' -f ${RCDIR}/dekagensed) ;
                	        checksaveto
                	        ;;
			3) # choose ripper
				TEMPRIPPER=${RIPPER}
				CHR=$(dialog --menu "Please choose your CD ripping tool\n(currently ${RIPPER}):" 19 70 6 \
					'1' 'cdparanoia' \
					'2' 'cdda2wav' \
					'3' 'tosha' \
					'4' 'dagrab' \
					'5' 'none (in case wav file exists and needs only to be encoded)' \
					3>&1 1>&2 2>&3) ;
				case ${CHR} in
					1)
						RIPPER='cdparanoia'
						;;
					2)
						RIPPER='cdda2wav'
						;;
					3)
						RIPPER='tosha'
						;;
					4)
						RIPPER='dagrab'
						;;
					5)
						RIPPER='none'
						;;
					*)
						CHR=''
						;;
				esac
				checkripper
                        	;;
			4) # choose encoder
				TEMPENCODER=${ENCODER}
				OPT=$(dialog --menu "Please choose your MP3/Ogg encoder\n(currently ${ENCODER}):" 19 70 9 \
					'1' 'bladeenc' \
					'2' '8hz-mp3' \
					'3' 'l3enc' \
					'4' 'lame' \
					'5' 'notlame' \
					'6' 'mp3enc' \
					'7' 'oggenc' \
					'8' 'none (do not start encoding automatically)' \
					 3>&1 1>&2 2>&3) ;
				case ${OPT} in
					1)
						ENCODER='bladeenc'
						;;
					2)
						ENCODER='8hz-mp3'
						;;
					3)
						ENCODER='l3enc'
						;;
					4)
						ENCODER='lame'
						;;
					5)
						ENCODER='notlame'
						;;
					6)
						ENCODER='mp3enc'
						;;
					7)
						ENCODER='oggenc'
						;;
					8)
						ENCODER='none'
						;;
					*)
						OPT=''
						;;
				esac
				checkencoder
				;;
			5) # choose id3 tag tool
				if [ "${ENCODER}" = 'none' ] ;
				then
					dialog --title 'Message' --msgbox \
						'An ID3 tagging tool can only be chosen after an encoder utility (option 4) was chosen.' 19 70 ;
				else
					TEMPID3TOOL=${ID3TOOL}
					ID3UTIL=$(dialog --menu "Please choose your ID3 tag tool.
The Built-In option will work only if you use an encoder
with a built-in ID3 engine (lame, notlame).
For Ogg-Vorbis, please use either None or Built-In.
(Current value: ${ID3TOOL}.)" 19 70 7 \
						'1' 'id3ed' \
						'2' 'id3tool' \
						'3' 'id3tag' \
						'4' 'mp3info' \
						'5' 'built-in (use tagging capability of your encoder)' \
						'6' 'none (do not name MP3 file with ID3 tag)' \
						3>&1 1>&2 2>&3) ;
					case ${ID3UTIL} in
						1)
							ID3TOOL='id3ed'
							;;
						2)
							ID3TOOL='id3tool'
							;;
						3)
							ID3TOOL='id3tag'
							;;
						4)
							ID3TOOL='mp3info'
							;;
						5)
							ID3TOOL='built-in'
							;;
						6)
							ID3TOOL='none'
							;;
						*)
							ID3UTIL=''
							;;
					esac
					checkid3tool
				fi
				;;
			6) # toggle cddb lookup
				if [ "${METHOD}" = 'cddb' ] ;
				then
					METHOD='manual'
					WHOLE='no'
				else
					METHOD='cddb'
					dialog --title 'Message' --msgbox \
'Setting this option will work only if xmcd/cda is installed and
configured on your system.
To use xmcd/cda, you will need either a permanent connection to
the internet for access to the remote CDDB, or an already existing
entry in your local CDDB for the CD you are going to rip.' 19 70 ;
				fi
				;;
			7) # set xmcd path
				XMCDTEMP=${XMCDLIB}
				XMCDLIB=$(dialog --inputbox "Please enter the complete path to your xmcd library directory\n(currently ${XMCDLIB}):" \
					19 70 3>&1 1>&2 2>&3) || XMCDLIB=${XMCDTEMP} ;
				if [ ! -d ${XMCDLIB} ] ;
				then
					dialog --title 'Error' --msgbox "Directory ${XMCDLIB} does not seem to exist." 19 70 ;
					XMCDLIB=${XMCDTEMP}
				fi
				;;
			8) # set file naming convention
				TEMPSELEC=${SELEC}
				SELEC=$(dialog --menu "Please choose your preferred file naming convention.
Options 5, 6, 7, and 8 cannot be used with various artist CDs.
(Current value: ${SELEC}, ${NCONVENT}.)" 19 70 9 \
					'1' 'artist-name_of_song.mp3' \
					'2' 'track-artist-name_of_song.mp3' \
					'3' 'Artist-Name_Of_Song.mp3 (Capitalized)' \
					'4' 'track-Artist-Name_Of_Song.mp3 (Capitalized)' \
					'5' 'artist--album/track-name_of_song.mp3 (creates a directory)' \
					'6' 'artist/album/track-name_of_song.mp3 (creates directories)' \
					'7' 'artist-album-track-name_of_song.mp3' \
					'8' 'Artist--Album/Name_Of_Song.mp3 (directory and Capitalized)' \
					3>&1 1>&2 2>&3) ;
				if [ "${SELEC}" = '' ] && [ "${TEMPSELEC}" != '' ] ;
				then
					SELEC=${TEMPSELEC}
				elif [ "${SELEC}" = '' ] ;
				then
					SELEC='1'
				fi
				case ${SELEC} in
					1)
						NCONVENT='artist-name_of_song.mp3'
						;;
					2)
						NCONVENT='track-artist-name_of_song.mp3'
						;;
					3)
						NCONVENT='Artist-Name_Of_Song.mp3'
						;;
					4)
						NCONVENT='track-Artist-Name_Of_Song.mp3'
						;;
					5)
						NCONVENT='artist--album/track-name_of_song.mp3'
						;;
					6)
						NCONVENT='artist/album/track-name_of_song.mp3'
						;;
					7)
						NCONVENT='artist-album-track-name_of_song.mp3'
						;;
					8)
						NCONVENT='Artist--Album/Name_Of_Song.mp3'
						;;
					*)
						NCONVENT='artist-name_of_song.mp3'
						SELEC='1'
						;;
				esac
				;;
			9) # toggle ripping whole CD
                        	if [ "${METHOD}" = 'manual' ] && [ "${WHOLE}" = 'no' ] ;
                        	then
					dialog --title 'Message' \
						--msgbox 'Setting this option has no effect because you are using manual naming.' 19 70 ;
                        	elif [ "${METHOD}" = 'manual' ] ;
                        	then
                        		WHOLE='no'
                        	else
                        		if [ "${WHOLE}" = 'no' ] ;
                                	then
                                	        WHOLE='yes'
                                	else
                                	        WHOLE='no'
                                	fi
                        	fi
                        	;;
			10) # toggle small HD option
				if [ "${SMALL}" = "no" ] ;
				then
					SMALL='yes'
					dialog --title 'Message' --msgbox \
'Setting this option makes dekagen rip one song and then encode that
song, before ripping another one.
This is useful if you have only a small hard disk with not the
space for a whole CD on it.

This will also cause background encoding to be disabled.' 19 70 ;
				else
					SMALL='no'
				fi
				;;
			11) # set CD device
				TEMPDEVICE=${DEVICE}
				DEVICE=$(dialog --inputbox "Please enter the complete path of your CD device\n(currently ${DEVICE}):" \
					19 70 3>&1 1>&2 2>&3 | sed -e 's/\/$//' ) ;
				checkdevice
                        	;;
			12) # mp3 encoding bitrate
				TEMPBITRATE=${BITRATE}
				BITRATE=$(dialog --menu "Please choose your MP3/Ogg nominal encoding bitrate\n(currently ${BITRATE} KBits):" 19 70 11 \
					'64' '64 KBits' \
					'80' '80 KBits' \
					'96' '96 KBits' \
					'112' '112 KBits' \
					'128' '128 KBits' \
					'160' '160 KBits' \
					'192' '192 KBits' \
					'224' '224 KBits' \
					'256' '256 KBits' \
					'320' '320 KBits' \
					3>&1 1>&2 2>&3) ;
				if [ "${BITRATE}" = '' ] && [ "${TEMPBITRATE}" != '' ] ;
				then
					BITRATE=${TEMPBITRATE}
				elif [ "${BITRATE}" = '' ] ;
				then
					BITRATE='128'
				fi
				if [ "${ENCODER}" = 'l3enc' ] ;
				then
					BITRATE="${BITRATE}000"
				fi
				;;
		esac
	done
	return
}

# finished defining functions, program follows

checkoldrc
checkforsed

test -f ${RCDIR}/dekagenrc && . ${RCDIR}/dekagenrc

checksaveto
checkdevice
checkripper
checkencoder

test -f ${RCDIR}/dekagenrc || saverc

main


#EOF
