#!/usr/bin/perl -w
# Automatically generate playlists for all albums described by oggs/mp3s
# under the given directory.
# TODO: support mp3s too

use strict;
use utf8;

sub usage {
    print @_ if @_;
    chomp(my $me = `basename $0`);
    print <<EOF;
Usage: $me path-to-files
EOF
    exit 1;
}

# regex for comment name & comment
my $commentnamere = qr/([\x20-\x3c\x3e-\x7d]+)/;
my $commentre = qr/$commentnamere=(.*)/;

my $vc = `which vorbiscomment`
    or die "Couldn't find vorbiscomment - maybe it's not installed?";
chomp $vc;

my $path = shift @ARGV
    or usage();

my @files = `find "$path" -name "*.ogg"`;
my %albums;
foreach (@files) {
    chomp;
    # Get the Vorbis comments into a hash, and file the hash away by album.
    my @comments = `$vc -l "$_"`
	or die "vorbiscomment failed with exit status $?";
    my $commenthash = {};
    foreach my $comment (@comments) {
	$comment =~ /$commentre/;
	my $cn = $1;
	{
	    local ($1, $2);	# avoid clobbering these
	    $cn =~ s/.*/\L$&/;	# make the comment names uniform in case
	}
	$commenthash->{$cn} = $2 
	    # don't replace it if the lowercase one exists already
	    unless ($1 ne $cn && exists($commenthash->{$cn}));
    }
    # we hope this comment isn't already in use... *shrug*
    s/^$path\/?//;
    $commenthash->{"__filename"} = $_;

    if (exists($commenthash->{"album"})) {
	my $albumname = $commenthash->{"album"};
	my $playlist;
	# get the album's playlist, or create a new one
	if (exists($albums{$albumname})) {
	    $playlist = $albums{$albumname};
	} else {
	    $playlist = [];
	    $albums{$albumname} = $playlist;
	}
	# add this song's hash to the playlist
	push @{$playlist}, $commenthash;
    } else {
	warn "discarding $_ as it has no album comment\n";
    }
}

foreach my $albumname (keys %albums) {
    print STDERR "processing $albumname\n";
    my @album = sort
	    { $a->{"tracknumber"} <=> $b->{"tracknumber"} }
	    @{$albums{$albumname}};
    my $albumnamecpy = $albumname;
    $albumnamecpy =~ s/\s/-/g;
    my $artistnamecpy = $album[0]->{"artist"}; # assume all the others are the same
    $artistnamecpy =~ s/\s/-/g;
    my $playlistfilename = $artistnamecpy."_".$albumnamecpy.".m3u";
    open(LISTFILE, ">$playlistfilename");
    foreach my $track (@album) { print LISTFILE $track->{"__filename"}."\n"; }
    close(LISTFILE);
}
