#!/bin/sh -eu

# vorbistagedit -- allows batch editing of vorbis comments with an editor
#
# (c) 2006 martin f. krafft <vorbistagedit@pobox.madduck.net>
# Released under the terms of the artistic licence.

VERSION=0.2
RELEASE=2006.05.06.1137


ME=${0##*/}

versioninfo() {
  echo "vorbistagedit $VERSION ($RELEASE)" >&2
  echo "vorbistagedit is (c) 2006 martin f. krafft" >&2
  echo and released under the terms of the Artistic Licence. >&2
}

usage() {
  versioninfo
  echo
  echo Usage: $ME file1.ogg [file2.ogg [file3.ogg ...]] >&2
  echo
  echo If no filenames are given, the list of filenames >&2
  echo is read from stdin, one per line. >&2
}

for opt in $(getopt -n $ME -l version,help -o vVh? -- $@); do
  case $opt in
    --version|-V|-v)
      versioninfo
      exit 0;;
    --help|-h|-\?)
      usage
      exit 0;;
    --) :;;
    -*)
      exit 1;;
    *) :;;
  esac
done

if ! command -v vorbiscomment >/dev/null; then
  echo "$ME: vorbiscomment not found in \$PATH." >&2
  exit -1
fi

old_IFS="$IFS"
IFS="
"
[ $# -eq 0 ] && set -- $(cat)
IFS="$old_IFS"

if [ $# -eq 0 ]; then
  echo "$ME: no files given." >&2
  exit 0
fi

TMPFILE=$(mktemp /tmp/vorbistagedit.XXXXXX)
trap "rm -f $TMPFILE" 0

cat <<_eof > $TMPFILE
# vorbistagedit
#
# Edit the lines in this file to your desire, but
# DO NOT touch lines starting with a colon (:)!
#
# We are in directory:
#  $(pwd)

_eof

for i in "$@"; do
  case "$i" in
    *.ogg)
      if [ ! -r "$i" ]; then
        echo "$ME: unreadable file - $i" >&2
        exit 1
      fi

      echo ": $i"
      vorbiscomment -l "$i"
      echo
      ;;

    *)
      echo "$ME: invalid argument - $i" >&2
      exit 2
      ;;
  esac
done >> $TMPFILE
echo : EOF >> $TMPFILE

MD5SUM=$(md5sum $TMPFILE)

${EDITOR:-editor} $TMPFILE </dev/tty

if [ "$MD5SUM" = "$(md5sum $TMPFILE)" ]; then
  echo "$ME: no changes, exiting..." >&2
  exit 0
fi

declare -a tags

write_tags() {
  local file="$1"; shift
  for tag; do echo "$tag"; done | vorbiscomment -w "$file"
}

while read line; do
  case "$line" in
    ': EOF')
      write_tags "$file" "${tags[@]}";;

    :*)
      if [ -n "${file:-}" ]; then
        write_tags "$file" "${tags[@]}"
        tags=()
      fi
      file="${line#: }";;

    *=*)
      tags[${#tags[@]}]="$line";;

    *|'#*') :;;
  esac
done < $TMPFILE

rm -f $TMPFILE
trap - 0

exit 0
