#!/bin/sh


SELF="$( basename $0 )"
VERSION="0.1"

usage() {
  cat <<EOF
Usage: $SELF [-o[N]] -f [bchunk-options] cue-file.cue [basename]

bchunkmulti v$VERSION, by B. Watson (urchlay@slackware.uk).

Licensed under the WTFPL: Do WTF you want with this. See
http://www.wtfpl.net/txt/copying/ for details.

This is a wrapper script for bchunk, to munge it into supporting
bin/cue files with multiple .bin files (one per track, usually).

We split up each FILE entry in the .cue file into a its own .cue,
then run bchunk once for each of the .cues we just made.

Options:

  -o         Convert audio tracks to ogg, with quality 7. Requires oggenc.
  -oN        As -o, but uses quality N, which must be a number from 0 to 9.
             See the -q option in the oggenc(1) man page.
  -f         Convert audio tracks to flac. Requires flac.
  -k         Keep .wav file after converting to ogg/flac. Normally it's
             deleted.
  --         Everything after this is treated as a filename. Useful if
             your .cue filename begins with a -.
  --help     Shows this help.
  --version  Shows version number.

Any other options passed to this script will be passed to bchunk.

$SELF also works fine on bin/cue files with only one .bin file.
EOF
}

while true; do
  case "$1" in
    --version) echo $VERSION ; exit 0 ;;
    --help)    usage ; exit 0 ;;
    -o)        OGGQ=7 ;;
    -o[-0-9]*) OGGQ="$( echo $1 | cut -b3 )" ;;
    -f)        FLAC=1 ;;
    -k)        KEEPWAV=1 ;;
    --)        break ;;
    -*)        bchunkopts="$bchunkopts $1" ;;
    *)         break ;;
  esac
  shift
done

[ -n "$OGGQ$FLAC" ] && bchunkopts="$bchunkopts -w"

cue_in="$1"
if [ -z "$cue_in" ]; then
  echo "$SELF: no .cue file argument given, try $SELF --help" 1>&2
  exit 1
fi

base="${2:-track}"

if [ -n "$3" ]; then
  echo "$SELF: too many filenames on command line, try $SELF --help" 1>&2
  exit 1
fi

# de-space-ify args
bchunkopts=$( echo $bchunkopts )

# check that the cue file at least exists and can be read
cat "$cue_in" >/dev/null || exit $?

# need this to let "read" read the initial spaces in the .cue file lines
IFS=""

# save old stdout
exec 3>&1

# use temp dir in the current dir (we're writing there anyway)
tmpdir="$( mktemp -d bcm.XXXXXX )"
[ -z "$tmpdir" ] && exit $?

# split up each track entry in the input .cue file into a separate .cue
# file containing only that track.
count=1
cat "$cue_in" | while read line; do
  case "$line" in
    FILE*) cue_out="$tmpdir/tmpcue$( printf '%02d' $count ).cue"
           exec > "$cue_out"
           count="$( expr $count + 1 )"
           ;;
  esac
  echo "$line"
done

# restore old stdout
exec 1>&3

# now convert each file to .iso or .wav (bchunk is smart enough
# to know which is which).
for cue_out in $tmpdir/tmpcue??.cue; do
  binfile="$( head -1 "$cue_out" | cut -d\" -f2 )"
  tracktmp="$tmpdir/tmp"

  # brand new empty dir for bchunk to write to, will contain only
  # one file after bchunk runs.
  rm -rf "$tracktmp"
  mkdir -p "$tracktmp"

  bchunk $bchunkopts "$binfile" "$cue_out" "$tracktmp"/"$base"

  if grep -q 'TRACK.*AUDIO' "$cue_out"; then
    # got audio track, convert to ogg and/or flac if requested
    if [ -n "$OGGQ$FLAC" ]; then
      [ -n "$OGGQ" ] && oggenc -q"$OGGQ" "$tracktmp"/*.wav
      [ -n "$FLAC" ] && flac "$tracktmp"/*.wav
      [ -z "$KEEPWAV" ] && rm -f "$tracktmp"/*.wav
    fi
  fi

  mv "$tracktmp"/* .

  rm -rf "$cue_out" "$tracktmp"
done

rmdir "$tmpdir"
exit 0