#!/usr/bin/perl -w
# usage:
# input file (use exact order of sections):
#
#
# [ artist ]
# The Name of the Band
# [ title ]
# Title of the CD or Compilation
# [ path ]
# /local/ogg
# [ tracks ]
# glob_pattern_for_track_1
# */blabla/*/song2.ogg
# ...
# [ end ]
#
# Output: m3u file, artist-title.m3u (sanitised filename)

use strict;
use File::Find;
use Getopt::Long;


my $P_section = q(\[ .* \]);
my $path = "/local/ogg";
my ($cmd, $m3u, $title, $artist,  @playlist, $ntracks, $nfound);
my $TRACK; # global

my %optctl = ();

sub print_help {
    print <<"EOF";
tracks2m3u.pl [opts] TRACKS

Create a m3u list from an ordered list of filename patterns. This is mainly
intended to make virtual mix albums.

The TRACKS listing has a strict format. Dump an empty file with --template.

options:
--help                 help (doh!)
--template             empty track listing to be filled in

EOF
exit(0);
}

sub write_template  {
    print <<"EOF";
[ artist ]
# The Name of the Band

[ title ]
# Title of the CD or Compilation

[ path ]
/local/ogg

[ tracks ]
# glob_pattern_for_track_1
# */blabla/*/song2.ogg


[ end ]
EOF
}



sub find_track ($$) {
    my ($dir,$track) = @_;
    # turn globs into regexs
    $_ = $track;
    s(\*)(.*)g;
    s(\.)(\.)g;
    s(\?)(.?)g;
    $TRACK = $_;
    print STDERR "# searching for '$TRACK'\n";
    return find(\&wanted, $dir); 
}

sub wanted {
    my $x;
    # use global $TRACK
    # $_ contains basename
    if ($File::Find::name =~ m($TRACK)) {
        $nfound++;      
        ($x = $File::Find::name) =~ s($path)();
        push @playlist, $x;
    }
}


# obsolete: locate_track (find_track is faster)
sub locate_track  {
    my $cmd = qq(locate "$_");
    print STDERR "# searching with '$cmd'\n";
    open LOC, qq($cmd|) or die "Failed to execute '$cmd',";
    while (<LOC>) {
        chomp;
        next unless /$path/;
        $nfound++;
        s($path)();
        push @playlist, $_;
        print $_,"\n";
    }
    close(LOC);
}


#------------------------------------------------------------
# main
#------------------------------------------------------------

&GetOptions(\%optctl,"template","help") or &print_help;

if ($optctl{help}) { &print_help; };

if ($optctl{template}) {
    &write_template;
    exit(0);
}


LINE:
while (<>) {
    chomp;
    # delete trailing space
    s(\s*$)();

    next if (/^ *$/ || /^ *#/);
    # print "xx: $_\n";                      
    # print "($_):matching $P_section:",m($P_section),"\n";

    if (m($P_section)) {
        print STDERR "====== New section $_ ======\n";
    }

    if (/^\[ artist \]/../^\[ title \]/) {{
        last if /$P_section/;
        $artist = $_;
        print STDERR "# Found artist = $artist\n";
        $_ = lc $artist;
        s([^A-Za-z0-9_])(_)g;
        $m3u = "$_-";
        print STDERR "# Write m3u = $m3u\n";
        next;
    }}

    if (/^\[ title \]/../^\[ path \]/) {{
        last if /$P_section/;
        $title = $_;
        print STDERR "# Found title = $title\n";
        $_ = lc $title;
        s([^A-Za-z0-9_])(_)g;
        $m3u .= "$_.m3u";
        print STDERR "# Write m3u = $m3u\n";
        next;
    }}

    if (/^\[ path \]/../^\[ tracks \]/) {{
        last if /$P_section/;
        $path = $_;
        print STDERR "# Found path = $path\n";
        next;
    }}
    #print "line: $_\n";
    #print "* in tracks section: ",(/\[ tracks \]/.../\[ end \]/) ? 1:0,"\n";
    if (/^\[ tracks \]/../^\[ end \]/||eof()) {{
        last if /$P_section/;
        $ntracks++;
        print STDERR "# track[$ntracks] = $_\n";
        # locate_track($_);
        # or
        find_track($path,$_);
    }}
}

open(M3U,">${m3u}") or die "Failed to open m3u $[m3u},";
foreach (@playlist) {
    print M3U "$_\n";
}
close(M3U);
print STDERR "# Found $nfound tracks out of $ntracks.\n";
print STDERR "# Wrote m3u file $m3u\n";

exit(0);

