#!/usr/bin/perl
#
# m3u2pla - generate playlists for iriver T20/T50/S10/E100
#
# Usage: m3u2pla [-e perl_expression] [-v] [playlist.m3u...]
# 
# Converts given simple m3u playlists (or standard input) to iriver
# .pla format.  The playlists should contain only bare filenames, one
# per line.  URLs are not recognized.  Empty lines, m3u comments and
# leading/trailing whitespace are stripped from the input.
#
# Each song filename goes, by default, through a path prefix
# substitution.  This substitution changes a local path prefix to a
# player path prefix.  Change these prefixes to match your directory
# names (see below).
#
# Optionally, an arbitrary Perl expression can be given with the '-e'
# option.  This expression is then evaluated for each input filename
# (available as $_ in the expression) instead of the default
# substitution.
#
# The '-v' switch causes the script to print each input filename and
# the corresponding substituted filename to standard error.
#
# Written by Petteri Hintsanen <petterih@iki.fi>.  This script is in
# public domain.  Do whatever you want with it, but remember that
# there is NO WARRANTY.
#
# See http://iki.fi/petterih/iriver-t50.html for more information and
# examples.
#
# $Id: m3u2pla 17 2009-08-25 20:43:17Z phintsan $
#

use strict;
use Encode;
use warnings;
use Getopt::Std;

#
# path prefixes for the default substition (change these)
#

# prefix removed from all filenames in the given (m3u) playlists
my $LOCAL_PREFIX = '/home/my/music/files';

# prefix added to all playlist filenames (you can use slashes here,
# backslash conversion is done separately)
my $IRIVER_PREFIX = '/Music'; 

# character encoding used in m3u files, change this if you don't use
# UTF-8
my $M3U_ENCODING = 'UTF-8';



my $expr = 's{^$LOCAL_PREFIX}{$IRIVER_PREFIX}';
my @dirlens;
my @songs;

our($opt_e);
our($opt_v);
getopts('e:v');
$expr = $opt_e if (defined($opt_e)); # override default substitution

while (<>) {
    my $song = decode($M3U_ENCODING, $_);
    # strip comments and whitespace
    chomp $song;
    $song =~ s/#.*//;
    $song =~ s/^\s+//;
    $song =~ s/\s+$//;
    next if (length($song) == 0);
    printf STDERR "$song -> " if ($opt_v);

    {
        local $_ = $song;
        eval $expr;
        die $@ if $@;
        $song = $_;
    }

    $song =~ s{/}{\\}g;         # FAT uses backslashes
    printf STDERR "$song\n" if ($opt_v);

    # player wants to know where the filename begins
    push @dirlens, rindex($song, "\\") + 2; # one-based indexing
    push @songs, encode("UTF-16BE", $song);
}

# print header frame
print pack "Na508", scalar @songs, "iriver UMS PLA";

# print song frames
while (@songs) { 
    my $song = shift @songs;
    my $dirlen = shift @dirlens;
    print pack "na510", $dirlen, $song;
}
