# Convert between different formats.
# Usage: convert <FORMAT> [FILES]
convert()
{
  local IFS=$'\n'
  local targets=("${@:2}")
  local format="${1}"
  local total=${#targets[@]}
  local count=0
  local failed=0

  # Report no format.
  if [[ "${format}" = "" ]]; then
    echo -e "${color_bred}No format specified.${color_default}"
    echo "Usage: convert <FORMAT> [FILES]"
    return 2
  fi

  # All files by default.
  if [[ "${targets}" = "" ]]; then
    targets=($(ls --classify | grep -v /$))
    total=${#targets[@]}
  fi

  # Process.
  for target in "${targets[@]}"; do
    # Increment counter.
    ((count++))

    # Define context names and status.
    local from="${target##*.}"
    local to="${format}"
    local status="[${count}/${total}] ${target} -> ${target%.*}.${to}"

    # Show status.
    echo -e "${status}"

    # Support multiple inputs.
    [[ "${to}" = "mp3" ]] && from=""

    # Send convert.
    case "${from}-${to}" in
      "gz-xz"|"tgz-txz")
        _convert_gz-xz "${target}"
        ;;
      "xz-gz"|"txz-tgz")
        _convert_xz-gz "${target}"
        ;;
      "-mp3")
        _convert_mp3 "${target}"
        ;;
      *)
        echo -e "${color_yellow}Conversion ${from}-${to} not supported.${color_default}"
        false
        ;;
    esac

    # Increment failed on error.
    if [[ $? != 0 ]]; then
      _convert_error "${target}"
      ((failed++))
    fi
  done

  # Report result.
  if [[ ${count} -gt 1 ]] || [[ "${*}" = "" ]]; then
    if [[ ${failed} = 0 ]]; then
      echo -e "${color_green}All successful.${color_default}"
    else
      echo -e "${color_bred}Items failed to convert: ${failed}.${color_default}"
    fi
  fi
}

_convert_error()
{
  echo -e "${color_bred}${1}: failed.${color_default}"
}

_convert_gz-xz()
{
  pv "${1}" | gzip -d | xz -9e > "${1%.gz}.xz"
}

_convert_xz-gz()
{
  pv "${1}" | xz -d | gzip -1 > "${1%.xz}.gz"
}

_convert_mp3()
{
  ffmpeg -i "${1}" -c:a libmp3lame -b:a 320k -f mp3 "${1%.*}.mp3"
}

# Export.
export -f convert _convert_gz-xz _convert_xz-gz