#!/bin/bash

#      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2012
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License version 3
#    as published by the Free Software Foundation.
#
#    It 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 software; see the file COPYING.gplv3. If not, write to
#    the Free Software Foundation, 51 Franklin Street, Fifth Floor,
#    Boston, MA 02110-1301, USA.

# The next two will be filled later.
DIR="";
OUT="";

MODE_FIND='ext';
MODE_TYPE='guess';
MODE_PATH='keep';

METADATA=true;
LENGTH=true;

CMD_VORBISCOMMENT='vorbiscomment';
CMD_OGGZ_COMMENT='oggz-comment';
CMD_OGGZ_INFO='oggzinfo';
CMD_METAFLAC='metaflac';
CMD_RAUM_INFO='raum-info';
CMD_ID3TOOL='id3tool';
CMD_MP32VCLT='mp32vclt';
CMD_METAFLAC2TIME='metaflac2time';
CMD_TEMPFILE='tempfile'

EXTS='ogg mp3 wav flac spx oga raum mid midi aac opus';

export NX_COMMANDS='';

PACKAGE_LIST=''
PACKAGE_INSTALL_COMMAND='';

# WARNING:
# This is a a big hack. Do not try this at home!
# Passing by tempfile is done as bash does not allow
# to modify vars in error handlers in non-local way.

_isinnx() {
 echo " $NX_COMMANDS " | if grep " $1 " 2> /dev/null > /dev/null
 then
  return 0
 else
  return 1
 fi
}

on_startup() {
 NX_COMMANDS_FILE=`$CMD_TEMPFILE`
}

on_exit() {
 NX_COMMANDS=`cat "$NX_COMMANDS_FILE"`
 rm -f "$NX_COMMANDS_FILE" 2> /dev/null

 if [ "$NX_COMMANDS" != '' ]
 then
  {
   echo
   echo 'Warning: The following commands have not been found.'
   echo '         Playlist meta data may not be complet.'
   _pkgs=''
   for _cmd in $NX_COMMANDS
   do
    _pkg=''

    for _i in $PACKAGE_LIST
    do
     _n=`echo "$_i" | cut -d: -f1`
     _p=`echo "$_i" | cut -d: -f2`

     [ "$_p" = '' ] && _p="$_n"

     if [ "$_n" = "$_cmd" ]
     then
      _pkg="$_p"
      break
     fi
    done

    if [ "$_pkg" = '' ]
    then
     _pkg_text=''
    else
     _pkgs="$_pkg $_pkgs"
     _pkg_text=" (can be found in package $_pkg)"
    fi
    echo " * $_cmd$_pkg_text"
   done

   if [ "$_pkgs" != '' -a "$PACKAGE_INSTALL_COMMAND" != '' ]
   then
    echo 'To correct those problems try to run the following command as root:'
    printf "  $PACKAGE_INSTALL_COMMAND\n" "$_pkgs"
   fi
  } >&2
 fi
}

#command_not_found_handle=command_not_found_handle

command_not_found_handle() {
 cmd="$1"
 NX_COMMANDS=`cat "$NX_COMMANDS_FILE"`

 if _isinnx "$cmd"
 then
  :; # ignore
 else
  NX_COMMANDS="$NX_COMMANDS $cmd"
 fi

 echo "$NX_COMMANDS" > "$NX_COMMANDS_FILE"

 return 0;
}

if [ -f /etc/dir2vclt.conf ]; then
    . /etc/dir2vclt.conf
fi

if [ -f ~/.dir2vclt.conf ]; then
    . ~/.dir2vclt.conf
fi

while [ "$1" != '' ]
do
 _p="$1"
 shift;
 case "$_p" in
  '--metadata')
   METADATA=true
  ;;
  '--no-metadata')
   METADATA=false
  ;;
  '--length')
   LENGTH=true
  ;;
  '--no-length')
   LENGTH=false
  ;;
  '--path-mode=keep')
   MODE_PATH='keep';
  ;;
  '--path-mode=absolute')
   MODE_PATH='absolute';
  ;;
  '--path-mode='*)
   echo "Unknown print mode."
   exit 1;
  ;;
  '--help'|'-h')
   echo "Usage: $0 [OPTIONS] {dir|file} [output]"
   echo
   echo "Options:"
   echo "-h --help               - Print this help."
   echo "   --metadata           - Add meta data to playlist."
   echo "   --no-metadata        - Do not add meta data to playlist."
   echo "   --length             - Add playback length to playlist."
   echo "   --no-length          - Do not add playback length to playlist."
   echo "   --path-mode=keep     - Keep filenames as they are."
   echo "   --path-mode=absolute - Try to make filenames absolute." 
   exit 0
  ;;
  *)
   if [ "$DIR" = '' ]
   then
    DIR="$_p"
   elif [ "$OUT" = '' ]
   then
    OUT="$_p"
   else
    echo "Too many parameters."
    exit 1;
   fi
  ;;
 esac
done

[ "$DIR" = '' ] && DIR='.'
[ "$OUT" = '' -o "$OUT" = '-' ] && OUT='/dev/stdout';

on_startup

{
 {
  case "$MODE_FIND" in
   'ext')
    _ext="`echo $EXTS | sed 's/  */\\\|/g'`";
    find "$DIR" \( -type f -o -type l \) -iregex ".*\($_ext\)$"
   ;;
   *)
    exit 1;
   ;;
  esac;
 }    | \
 sort | \
 while read _file
 do
  _type='unknown';
  case "$MODE_TYPE" in
   'guess')
    case "$_file" in
     *.ogg)  _type='ogg_vorbis'; ;;
     *.wav)  _type='riff_wave';  ;;
     *.spx)  _type='ogg_speex';  ;;
     *.flac) _type='flac';       ;;
     *.raum) _type='raum';       ;;
     *.mid)  _type='midi_file';  ;;
     *.midi) _type='midi_file';  ;;
     *.mp3)  _type='id3';        ;;
     *.opus) _type='ogg_opus';   ;;
    esac;
   ;;
   *)
    exit 1;
   ;;
  esac;

  _codec="$_type";

  {
   if $METADATA
   then
    case "$_type" in
     'ogg_vorbis')
      $CMD_VORBISCOMMENT -l "$_file" 2> /dev/null
     ;;
     'ogg_speex')
      $CMD_OGGZ_COMMENT -l "$_file" | \
      tail -n +3               | \
      sed 's/^\t*//; s/: /=/'
     ;;
     'flac')
      $CMD_METAFLAC --list --block-type=VORBIS_COMMENT "$_file" | \
      grep '^ *comment\['                                  | \
      sed 's/^.*: //'
     ;;
     'raum')
      $CMD_RAUM_INFO "$_file"                           | \
      grep '^pkg [0-9]*: Stream #[0-9]*: Meta '    | \
      sed 's/^pkg [0-9]*: Stream #[0-9]*: Meta //'
     ;;
     'id3')
      $CMD_ID3TOOL "$_file" 2> /dev/null | \
      sed 's/:\t\t*/:/'             | \
      sed 's/ *$//'                 | \
      while IFS=':' read _t _d
      do
       _t=`echo $_t | tr a-z A-Z`
       case "$_t" in
        'SONG TITLE')
         echo "TITLE=$_d"
        ;;
        # 1:1 mapping:
        'ARTIST'|'ALBUM'|'YEAR')
         echo "$_t=$_d"
        ;;
        'NOTE')
         echo "COMMENT=$_d"
        ;;
        'GENRE')
         _d=`echo "$_d" | cut -d' ' -f1`
         echo "GENRE=$_d"
        ;;
        # ignore the rest at the moment
       esac;
      done
     ;;
    esac;
   fi

   if $LENGTH
   then
    case "$_type" in
#     *.wav)  _type='riff_wave';  ;;
     'flac')
      $CMD_METAFLAC --list --block-type=STREAMINFO "$_file" | \
      $CMD_METAFLAC2TIME
      _codec='unknown'; # suppres output of SIGNALINFO
     ;;
#     *.raum) _type='raum';       ;;
#     *.mid)  _type='midi_file';  ;;
#     *.midi) _type='midi_file';  ;;
     'ogg_vorbis'|'ogg_speex')
      $CMD_OGGZ_INFO -l "$_file"            | \
      grep '^Content-Duration: '            | \
      sed 's/^Content-Duration: /LENGTH=/'
     ;;
     'id3')
      $CMD_MP32VCLT --no-del "$_file"
      _codec='unknown'; # suppres output of SIGNALINFO
     ;;
    esac;
   fi

   case "$MODE_PATH" in
    'keep')
     echo 'FILENAME='"$_file";
    ;;
    'absolute')
     echo "$_file" | if grep "^/" 2> /dev/null > /dev/null
     then
      echo 'FILENAME='"$_file";
     else
      # make semi abselute
      _file="`pwd`/$_file"
      # strip all //
      _file=`echo "$_file" | sed 's#//#/#g'`
      # strip all .../a/../...
      while echo "$_file" | grep '/\.\./' > /dev/null
      do
       _file=`echo "$_file" | sed 's#/[^/][^/]*/../#/#'`
      done
      echo 'FILENAME='"$_file";
     fi
    ;;
   esac

   if [ "$_codec" != 'unknown' ]
   then
    echo 'SIGNALINFO=codec:'"$_codec";
   fi
   echo '=='
  }
 done
} > "$OUT";

on_exit

#ll
