#!/usr/bin/perl

#
# I wrote this to help me rename a group of mp3 files based on a list of
# tracks from a website.
#
# So, this script examines a newline-separated list of 
# track names and renames the files in the current directory based on that.
#
# This could be improved in some ways. The parts specific to audio files
# should probably be optional. But it works for me, so I'll leave it alone for
# now.
#
# Colin McCabe
# 2005/11/12 
#

use strict;

my $mp3_to_flac=0;
if ($ARGV[0] eq "-f") {
    $mp3_to_flac=1
}

#Make sure there are no non-mp3 files in the directory
my $non_mp3_files = 
    `find -maxdepth 1 -noleaf | grep -v mp3\$ | grep -v ^.\$ `;
if ($non_mp3_files) {
    my $non_flac_files = 
        `find -maxdepth 1 -noleaf | grep -v flac\$ | grep -v ^.\$ `;
    if ($non_flac_files) {
        my $non_wav_files = 
            `find -maxdepth 1 -noleaf | grep -v wav\$ | grep -v ^.\$ `;
        if ($non_wav_files) {
            die "Non mp3 or flac or wav files or subdirectories found in this directory!";
        }
    }
}

#Get input from the user
my @cooked_lines;
my @input_lines = <STDIN>;

foreach my $line (@input_lines) {
    chomp($line);

    if ($line =~ '/') {
        die "can't use slashes in filenames";
    }

    $line =~ s/[\t ]*$//; # strip trailing whitespace

    if ($mp3_to_flac == 1) {
        $line =~ s/\.mp3$/\.flac/;
    }

    if ($line =~ '\w') {
        #Make sure this track title contains a number.
        die "The name of this file does not contain a number." 
            unless ($line =~ '[0-9]');
	#If the line has some non-whitespace component, add it to the list of
	#input lines
	$line = TrimWhitespace($line);
	push (@cooked_lines, $line);
        #print "processing line..." . "\"" . $line . "\"\n"
    }
}

#Make sure we have the right number of mp3s in this folder
my $files_in_folder = `find | grep -v ^.\$ | wc -l`;
chomp $files_in_folder;
my $number_of_input_lines = scalar(@input_lines);
if ($files_in_folder != $number_of_input_lines) {
    die "$files_in_folder mp3s in the folder, but $number_of_input_lines input lines given!";
}


open(FIND_OUTPUT, "find . -maxdepth 1 | grep -v ^.\$ | sort -n | ");
my $find_line;
my $i = 0;
while (defined($find_line = <FIND_OUTPUT>)) {
    chomp $find_line;
    my $final_name = $input_lines[$i];
    print "renaming \"$find_line\" to \"$final_name\"\n";
    if (system("mv \"$find_line\" \"$final_name\"")) {
	print "error!\n";
    }
    $i = $i + 1;
}
print "** rename complete **\n";
exit 0;

#Replace multiple whitespace characters with a single one
sub TrimWhitespace
{
    my $file_name = @_[0];
    my $old_file_name;
    do
    {
	$old_file_name = $file_name;
	$file_name =~ s#\s\s# #g;
    } while ($file_name ne $old_file_name);
    return "$file_name";
}
