#!/bin/bash

# te2mp3.sh
# (c) 2006 The Evangelist
#
# htttp://www.the-evangelist.info
#
# Changelog and notes at the end of file


# FUNCTIONS -------------------------------------------

copyright () {
  clear
  echo -e "$GREEN\n\n **************\n te2mp3.sh v$VERSION\n **************\n"
  echo -e "$CYAN(c) The Evangelist\n"
  echo -e "URL: http://www.metal-madness.net\n"
  echo -e "URL: http://www.the-evangelist.info\n"
  echo -e "$WHITE\n-------------------------------------------------------\n"
}


required () {
  echo -e "\n---------------------------------------------------------------------"
  echo -e "bash       -> Necessary to run this script (Mandatory)"
  echo -e "cueprint   -> get info from CUE files (Mandatory)"
  echo -e "lame       -> for compressing MP3 files (Mandatory)"
  echo -e "shntool    -> for xtracting WAV from compress files (Mandatory)"
  echo -e "perl       -> For renaming white spaces to underscores (Mandatory)"
  echo -e "mac        -> for decompressing  APE files (Optional)"
  echo -e "flac       -> for decompressing FLAC files (Optional)"
  echo -e "wavpack    -> for decompressing   WV files (Optional)"
  echo -e "              hope in future versions will not be necessary"
  echo -e "---------------------------------------------------------------------\n"
}


usage () {
  echo -e "$WHITE\nUsage:\n"
  echo -e "\t$0 -c CUE_file -f sound_file [-y YEAR] [-g genre] [-o output_directory] [-u] [-r] [-l]\n"
  echo -e "\t$0 [-l] [-o output_directory] -b batch_file\n"
  echo -e "\t$0 -c Marduk_-_Nightwing.cue -f Marduk_-_Nightwing.flac\n"
  echo -e "\t$0 -c Marduk_-_Nightwing.cue -f Marduk_-_Nightwing.flac -y 1998\n"
  echo -e "\t$0 -c Marduk_-_Nightwing.cue -f Marduk_-_Nightwing.flac -y 1998 -g 138 \n"
  echo -e "\t$0 -c Marduk_-_Nightwing.cue -f Marduk_-_Nightwing.flac -y 1998 -o /home/the_evangelist/music -g 138 -u \n"
  echo -e "\t$0 -b batch_file\n"
  echo -e "\n\nNOTE: -u = change espaces for underscores (Optional)\n"
  echo -e "NOTE: -g = Genre, to see list 'id3v2 -L' (Optional)\n"
  echo -e "NOTE: -r = do not remove temporaly CUE and WAV files (default is remove)\n"
  echo -e "NOTE: -l = create a letter (first letter of band name) directory before band name directory:"
  echo -e "NOTE: in Batch mode -l and -o MUST be before -b option)\n"
  echo -e "NOTE: -b = Batch mode has this format (for each file to process):\n"
  echo -e "\tAUDIO file (including path to)"
  echo -e "\tCUE file (including path to)"
  echo -e "\tYEAR"
  echo -e "\tGENRE (to see list 'id3v2 -L')"
  echo -e "\tUNDERSCORE (1 = yes, any other = no)\n"
  required
}


check_output () {
  ###
  ### Check if we can write in output directory
  ###
  touch $OUTPUT > /dev/null 2>&1
  if [ $? -eq 1 ]
  then
     echo -e "$RED\n\n --- ERROR ---\n\n"
     echo -e "I can NOT write in destination path ($OUTPUT)$WHITE\n\n"
     exit -1
  fi
}


batch_process () {

  check_output

  # get an array of each line in the bacth file
  LIST=( $(cat "$BFILE") )
  # get the number of lines of the batch file
  LINES=${#LIST[@]}
  # get the modulus, must be LINES * 5
  MOD=$(($LINES % 5))
  # get number of files to process
  BATCHS=$(($LINES / 5))
  # Actual file to process
  BATCH=1

  # check if there are correct line number
  if [ $MOD == 0 ]
  then
     for (( b=0 ; b < $LINES ; b=b+5 ))
     do
         FILE=${LIST[$b]}
         CUE=${LIST[$b+1]}
         YEAR=${LIST[$b+2]}
         GENRE=${LIST[$b+3]}
         US=${LIST[$b+4]}
         echo -e "$ORANGE---------------------------------------------------------------------"
	 echo -e "Processing Batch $WHITE$BATCH$ORANGE out of $BATCHS"
	 echo -e "         CUE = $CUE\n        FILE = $FILE\n        YEAR = $YEAR\n       GENRE = $GENRE\n  UNDERSCORE = $US (1 = yes, rest = no)"
         echo -e "---------------------------------------------------------------------\n\n$WHITE"
         convert
	 BATCH=$(($BATCH + 1))
     done
  else
     echo -e "$RED\n\n *************\n --- ERROR ---\n *************\n\n\n"
     echo -e "Number of lines ($LINES) in batch file ($BFILE) is not correct\n\n$WHITE"
  fi

}

convert () {
   ###
   ### Make temporary CUEs
   ###
   CUE0="$OUTPUT/0.cue"
   CUE1="$OUTPUT/1.cue"
   # make copy of CUE file removing un necessary lines
   cp "$CUE" "$CUE1"
   # sometimes copying from VFAT has executable perms
   chmod 644 "$CUE1"
   # Find in which line is the First "FILE"
   LINE=$(egrep -m1 -n "^FILE"  "$CUE1" | cut -d: -f1)
   # remove X first lines (first line must be FILE), necesary for 'shntool split'
   tail -n+$LINE "$CUE1" > "$CUE0" 
   
   ###
   ### Variables
   ###
   
   # MP3 compressor
   MP3="lame"
   OPTIONS="-V2 --vbr-new -q0 --lowpass 19.7 --add-id3v2 "

   # Band name (perl for upcase first letter)
   BAND=$(cueprint -d "%P" $CUE1 | perl -pi -e 's/(\w+)/\u\L$1/g')
   # Change '/' for '-' to avoid directory problems
   # only perhaps in Split/collection CDs
   BAND=${BAND//\//-}
   
   # Album title (perl for upcase first letter)
   ALBUM=$(cueprint -d "%T" $CUE1 | perl -pi -e 's/(\w+)/\u\L$1/g')
   # Change '/' for '-' to avoid directory problems
   ALBUM=${ALBUM//\//-}
   
   # Number of tracks
   TRACKS=$(cueprint -d "%N" $CUE1)
   
   # array with track titles
   TRACK=( $(cueprint -t "%t\n" $CUE1 | perl -pi -e 's/(\w+)/\u\L$1/g') )
   
   # Extrack TRACKS from file
   #
   echo -e "$CYAN * Extrack from file $FILE to WAVE ... \n$WHITE"
   cat "$CUE0" | shntool split -n t -d "$OUTPUT" "$FILE"

   # add year to album dir if set
   if [ "$YEAR" != "" ]
   then 
      ALBUM_DIR="$YEAR - $ALBUM"
   else
      ALBUM_DIR="$ALBUM"
   fi

   # Check if i must create letter directory before Band directory
   if [ $LETTER -eq 1 ]
   then
      # get first letter of Band name
      L="${BAND:0:1}/"
   fi
   MP3_DIR="$OUTPUT/$L$BAND/$ALBUM_DIR"
   
   # Create Group/Album directory
   if [ ! -e "$MP3_DIR" ]
   then
      echo -e "\n$CYAN * Creating directory $MP3_DIR ... \n $WHITE"
      mkdir -p "$MP3_DIR"
   fi
   
   # convert to MP3 all tracks
   #
   for (( n=0 ; n <= $(( $TRACKS - 1 )) ; n++ )) {
      # Change '/' for '-' to avoid directory problems
      TRACK[$n]=${TRACK[$n]//\//-}
      NUM=$(printf "%02d" $(( $n + 1 )) )
      echo -e "\n$CYAN * Compressing $NUM-${TRACK[$n]}.mp3 ... \n $WHITE"
      $MP3 $OPTIONS --ta "$BAND" --tl "$ALBUM" --ty "$YEAR" --tt "${TRACK[$n]}" --tn $NUM --tg "$GENRE" "$OUTPUT/t0$NUM.wav" "$MP3_DIR/$NUM-${TRACK[$n]}.mp3"
   }

   # SubShell initiated
   (
   cd "$OUTPUT"
   # Check if i must remove temporal CUE and Wave files
   if [ $REMOVE -eq 1 ]
   then
      echo -e "\n$CYAN * Deleting temporal CUE and Wave files ... \n $WHITE"
      rm -f t0*.wav [0,1].cue
   fi

   # Check if i must rename white spaces to underscores
   if [ $US -eq 1 ]
   then
      echo -e "$CYAN * Changing white espaces to underscores ... \n $WHITE"
   
      # Check if letter directory was created to jump directory
      if [ $LETTER -eq 1 ]
      then
         cd "$L"
      fi
   
      # rename BAND 
      BAND1=${BAND// /_}
      # If different there is space, so rename
      if [ "$BAND" != "$BAND1" ]
      then
         # if dest dir exists move Album and delete Band name with spaces
         # This hack is for compressing more than 1 Album of the same Band
         if [ -e "$BAND1" ]
         then
            mv "$BAND/$ALBUM_DIR" "$BAND1"
            rmdir "$BAND"
         else
            mv "$BAND" "$BAND1"
         fi
      fi
      cd "$BAND1"

      # rename [YEAR -] ALBUM (Album directory)
      ALBUM_DIR1=${ALBUM_DIR// /_}
      # If different there is space, so rename
      if [ "$ALBUM_DIR" != "$ALBUM_DIR1" ]
      then
         # if Album exists do no rename, show error and enter correct directory for next step
         if [ -e "$ALBUM_DIR1" ]
         then
            echo -e "$RED\n\n *************\n --- ERROR ---\n *************\n\n"
            echo -e " I can NOT rename $ALBUM_DIR to $ALBUM_DIR1 because already exists.$WHITE\n\n"
            # Change to Album with espaces to rename mp3 files
            cd "$ALBUM_DIR"
         else
            mv "$ALBUM_DIR" "$ALBUM_DIR1"
            cd "$ALBUM_DIR1"
         fi
      fi

      # rename MP3 files
      for n in *.mp3;
      do
         SRC=$n
         DEST=${SRC// /_}
         # If different there is space, so rename
         if [ "$SRC" != "$DEST" ]
         then
            mv "$SRC" "$DEST"
         fi
      done;
   fi
   # SubShell end
   )
}


# SCRIPT  -----------------------------------------------------------------

###
### Defsult variables
###
VERSION="0.6.1"
REMOVE=1   # by default remove temporaly CUE and WAV files
US=0       # by default use espaces not underscrores
YEAR=""    # by default no year
GENRE="9"  # by default "Metal"
OUTPUT="." # by default current path
LETTER=0   # by default no make letter directory (b/bathory)
L=""       # by default no letter

###
### Colors
###
RED="\033[31m"
GREEN="\033[32m"
ORANGE="\033[33m"
CYAN="\033[36m"
WHITE="\033[37m"

# to read lines (newline separator)
IFS=$'\n'

copyright

###
### Parameters
###
if [ $# -lt 2 ]  # Script invoked without necessary command-line args?
then
  usage
  exit -1
fi

# If illegal option print in red
echo -e "$RED"

while getopts ":lo:b:c:f:y:g:ru" Option
do
  case $Option in
    l ) LETTER=1;;         # -l (letter directory "b/bathory")
    o ) OUTPUT="$OPTARG";; # -o OUTPUT
    b ) BFILE="$OPTARG"    # -b batch_process
        if [ -e $BFILE ]
	then
           batch_process
	else
	   echo -e "$RED\n\n *************\n --- ERROR ---\n *************\n\n\n"
	   echo -e "The Batch file ($BFILE) does NOT exists.\n\n$WHITE"
	fi
        exit 0;;	   # end of script
    c ) CUE="$OPTARG";;    # -c CUE
    f ) FILE="$OPTARG";;   # -f FILE
    y ) YEAR="$OPTARG";;   # -y YEAR
    g ) GENRE="$OPTARG";;  # -g GENRE
    r ) REMOVE=0;;         # -r (not remove temporaly CUE and WAV files)
    u ) US=1;;             # -u (underscore)
    * ) usage
        exit -1
	;;
  esac
done

shift $(($OPTIND - 1))

# Restore print White
echo -e "$WHITE"

# CUE is mandatory
if [ "$CUE" == "" ]  # CUE file missing
then
  echo -e "$RED\n\n *************\n --- ERROR ---\n *************\n\n\n$WHITE"
  usage
  exit -1
fi

# FILE is mandatory
if [ "$FILE" == "" ]  # Audio File missing
then
  echo -e "$RED\n\n *************\n --- ERROR ---\n *************\n\n\n$WHITE"
  usage
  exit -1
fi

check_output

convert



# NOTES -------------------------------------------------------------------

# See: http://jthz.com/mp3/ for LAME options

# Known bug: Capitalize fails when tilde vowels are found


# CHANGELOG ---------------------------------------------------------------

# 2006-04-22 <-> v0.6.1
# * Fix Album name problem, change '/' for '-' in Album  name
# * Fix, check if Batch file exists if not show error and exit

# 2006-04-17 <-> v0.6
# * change all SED, now using builtin Bash Strings Manipulation
#    now script more portable and one external program less
# + added option -l to create directory before band name (b/bathory)
# + added more comments and corrected some grammar ;-)
# + Now illegal option is print in RED
# + Now -o OUTPUT can be used in Batch mode

# 2006-04-16 <-> v0.5
# * Reorganice script in functions
# + added batch process (-b ) to convert several files rapidly
# + added by default genre "Metal" (9), instead of nothing
# * Fix name problem, change '/' for '-' in title name and mp3 file
# * Fix problem (ALBUM_DIR) when year (-y) is NOT specified

# 2006-04-15 <-> v0.4.1
# * Fix problem with CUE, first line must be FILE "...."
#   now hope will be resolved forever ;-)
# - cueconvert no more needed

# 2006-04-14 <-> v0.4
# * Fix problem when renaming white spaces
# * Some fixes and improvements
# + added option -r to remove or not temporal CUE and WAV files
# + added required commands
# + added more comments

# 2006-04-13 <-> v0.3
# + added capitalize all words
#   NOTE: change perl to sed or something else
# * Fix CUE bug
# + added --add-id3v2 option to lame
#   force addition of version 2 tag

# 2006-04-12 <-> v0.2
# + added support for parameters (getopts)
# + added support for genre
# + added destination path (optional) default current
# * several bugfixes

# 2006-04-10 <-> v0.1
# First version

