#!/usr/bin/env bash
# $Id: mp3riplabel,v 1.22 2017/09/05 06:34:08 friedman Exp $

# Requires python-eyed3 0.7.5 or later fedora rpm for mp3 files
# Requires metaflac for flac files

######
## mp3
######

eyed3()
{
    set eyeD3 ${1+"$@"}
    case $VERBOSE in
        '' ) "$@" ;;
        *  ) (set -x; "$@") ;;
    esac
}

info_mp3()
{
    track=$1
    file=`file_template "$track"`

    # Can't use these two options together.
    # Don't use our eye3d function above.
    eyeD3 -v          "$file"
    eyeD3 -P lameinfo "$file"
}

label_mp3()
{
    track=$1
    title=$2
    shift; shift

    comment=$defcomment
    comment_empty=
    case ${1+isset}:$1 in
        isset:-* | : ) : ;;
        isset:   )
            comment=
            comment_empty=t
            shift ;;
        isset:?* )
            comment=$1
            shift ;;
    esac
    case $comment_empty:$comment in
        t: | :?* )
            set fnord --comment="$comment" ${1+"$@"}
            shift ;;
    esac

    file=`file_template "$track"`
    touch -r "$file" .stamp

    echo ----------------------------------------
    echo "$file"
    {
        case $reset_tags in
            '' ) : ;;
            *  ) (
                    set fnord
                    for tag in $reset_tags ; do
                        case $tag in
                            TXXX:* ) set "$@" --user-text-frame ${tag#TXXX:}: ;;
                            APIC   ) set "$@" --remove-images ;;
                            *      ) set "$@" --text-frame $tag: ;;
                        esac
                    done
                    shift
                    eyed3 "$@" "$file"
                ) ;;
        esac

        set fnord "$@"
        for tag in "$front_cover_image:FRONT_COVER:" \
                    "$back_cover_image:BACK_COVER:"  \
                       "$leaflet_image:LEAFLET:"     \
                         "$other_image:OTHER:"
        do
            case $tag in
                :*: ) : ;;
                *   ) set "$@" --add-image="$tag" ;;
            esac
        done
        shift

        eyed3 \
            --encoding       utf16           \
            --to-v2.3                        \
            --artist         "$author"       \
            --album          "$album"        \
            --disc-num       "$disc"         \
            --disc-total     "$disc_total"   \
            --track          "$track"        \
            --track-total    "$track_total"  \
            --title          "$title"        \
            --recording-date "$year"         \
            --genre          "$genre"        \
            ${1+"$@"} \
            "$file"
    } > /dev/null

    touch -r .stamp "$file"
    rm -f .stamp
}

rename_mp3()
{
    track=$1
    old=`file_template "$track"`

    fmt="%A - %a`discstr` - %n - %t"

    echo ----------------------------------------
    echo "$old"
    {
        eyed3 -v \
            --rename      "$fmt" \
            --fs-encoding "utf8" \
            "$old"
    } > /dev/null
}

######
## flac
######

info_flac()
{
    track=$1
    file=`file_template "$track"`

    echo "$file:"
    metaflac --export-tags-to - "$file"
    echo
}

label_flac()
{
    track=$1
    title=$2
    shift; shift

    file=`file_template "$track"`

    set fnord "$@"

    for tag in $reset_tags ; do
        set "$@" --remove-tag=$tag
    done

    for comment in   "ARTIST=$author"       \
                      "ALBUM=$album"        \
                      "TITLE=$title"        \
                       "DATE=$year"         \
                      "GENRE=$genre"        \
                "TRACKNUMBER=$track"        \
                 "TRACKTOTAL=$track_total"  \
                 "DISCNUMBER=$disc"         \
                  "DISCTOTAL=$disc_total"
    do
         tag=${comment%%=*}
        data=${comment#*=}

        case $data in
            "" ) : ;;
            *  ) set "$@" --remove-tag "$tag" --set-tag "$comment" ;;
        esac
    done

    for tag in "3||||$front_cover_image" \
               "4||||$back_cover_image"  \
               "5||||$leaflet_image"     \
               "0||||$other_image"
    do
        case $tag in
            ?"||||"?* ) set "$@" --import-picture-from "$tag" ;;
        esac
    done

    shift

    echo "Tagging: $file"
    metaflac \
        --preserve-modtime \
        "$@" "$file"
}

rename_flac()
{
    rename_generic "$@"
}

######
## ogg/vorbis
######

info_ogg()
{
    track=$1
    file=`file_template "$track"`

    echo "$file:"
    vorbiscomment --raw --list "$file"
    echo
}

label_ogg()
{
    track=$1
    title=$2
    shift; shift

    file=`file_template "$track"`

    set fnord "$@"

    for tag in $reset_tags ; do
        set "$@" --remove-tag=$tag
    done

    for comment in   "ARTIST=$author"       \
                      "ALBUM=$album"        \
                      "TITLE=$title"        \
                       "DATE=$year"         \
                      "GENRE=$genre"        \
                "TRACKNUMBER=$track"        \
                 "TRACKTOTAL=$track_total"  \
                 "DISCNUMBER=$disc"         \
                  "DISCTOTAL=$disc_total"
    do
         tag=${comment%%=*}
        data=${comment#*=}

        case $data in
            "" ) : ;;
            *  ) set "$@" --tag "$comment" ;;
        esac
    done

    shift

    echo "Tagging: $file"
    vorbiscomment \
        --write \
        --raw \
        "$@" \
        "$file"
}

rename_ogg()
{
    rename_generic "$@"
}

######
##
######

file_template()
{
    file_author=`file_filter "$author"`
     file_album=`file_filter "$album"`

    for f in \
        $file_author.$file_album?$1.*.$ext \
        track$1.*.$ext \
        track_$1.$ext \
        $1-*.$ext \
        $1.*.$ext \
        "$1 "*.$ext \
        *" - $1 - "*.$ext \
        *.$1.*.$ext \
        *-$1-*.$ext \
        *_$1_*.$ext \
        *" $1 "*.$ext
    do
        if [ -f "$f" ]; then
            echo "$f"
            return
        fi
    done
}

file_filter()
{
    echo "$*" \
        | sed -e "s/  *$//" \
              -e "s=/=_=g"
}

discstr()
{
    discstr=
    case $disc:$disc_total in
        : | 1:1 | 01:01 ) : ;;
        *:  ) echo   " (disc $disc)" ;;
        *:* ) printf " (disc %0${#disc_total}d of %d)" $disc $disc_total ;;
    esac
}

rename_generic()
{
    track=$1
    title=$2

    albumstr=$album`discstr`

    old=`file_template "$track"`
    new=`file_filter "$author - $albumstr - $track - $title.$ext"`

    # Quoting matters here, if $old contains wildcard chars!
    case $new in
        "$old" ) : ;;
        *      ) mv -v "$old" "$new" ;;
    esac
}

######
##
######

info()   {      info_$ext "$@"; }
label()  {     label_$ext "$@"; }
rename() { rename_generic "$@"; }

######
##
######

config()
{
                      ##############################
               author=''
                album=''

                 year=2000-01-01
                genre=
           defcomment=

          track_total=01

                 disc=01
           disc_total=01

    front_cover_image=
     back_cover_image=
        leaflet_image=
          other_image=

    # These are useful if you want to get rid of the track total or disc
    # total, which will not be removed if it already exists, even if the
    # explicit replacement is empty.
           reset_tags='' #'TPOS TRCK'

                  ext=mp3
}

doit()
{ :
           ##############################
   #$1 01 "Example Title"
}

main()
{
    LC_CTYPE=${LC_CTYPE-en_US.UTF-8}
    export LC_CTYPE

    config
    case $ext in
        mp3  ) type -p eyeD3    > /dev/null || exit $? ;;
        flac ) type -p metaflac > /dev/null || exit $? ;;
    esac

    case $# in
        0 ) set label rename ;;
    esac

    set -e
    for step in "$@"; do
        doit $step
    done
}

#main "$@"

# eof
