use MP3::Tag; # import module
use LWP::UserAgent; # import module

$debug=0;
$base="http://www.gracenote.com";
$proxy='http://10.1.51.10';

$tagversion='ID3v2';
if($ARGV[0])
{
    $tagversion=$ARGV[0];
}
print "First list existing $tagversion tags:\n\n";

@files = <*.mp3>; # find MP3 files in current directory

%tags=();

sub dosearch()
{
    print("Enter search (artist + title):");
    $search = <STDIN>;
    chomp $search;
    print "Searching for $search\n";
    @hits = search($search);
    $hits = $#hits +1;
    print("$hits hits\n");
    $x=0;
    foreach(@hits)
    {
        print "$x . ".($$_{'title'})."\n";
        $x++;
    }
    if($hits>0)
    {
	$go = 1;
	while($go)
	{
	    print "Choose number:";
	    $num = <STDIN>;
	    chomp $num;
	    $choice = $hits[$num];
	    showalbum($$choice{'url'});
	    print "Choose another?";
	    $ans=<STDIN>;
	    if($ans=~/n/)
	    {
		$go=0;
	    }
	}
    }
        
}

sub debug($)
{
    ($msg)=@_;
    print $msg if $debug;
}

sub showalbum($)
{
    my ($url)=@_;
    my $ua = LWP::UserAgent->new();				
    if($proxy)
    {
        $ua->proxy('http' => $proxy);
    }

    debug("Getting $url\n");	
    my $req = HTTP::Request->new(GET => $url);
    my $response = $ua->request($req);			
    if ($response->is_success) {		
        @matches = ();
        my $data = $response->content;
        @lines = split /\n/,$data;
        $go=0;
        foreach(@lines)
        {
            if(/<table class="tracklist"/)
            {
                $go = 1;
            }
            last if($go && /<\/table>/);
            if ($go){
                s/<[^>]*>//g;
                s/^\s+//;
		s/^(\d+)\./$1. /;
		if (/^\d+/)
		{
		    print "$_\n";
		    push @matches,$_;
		}
            }
        }
	if($#matches!=$#files)
	{
	    print "Warning: Number of tracks doesn't match\n";
	    print "Expected:".($#files+1)."\nFound:".($#matches+1)."\n";
	}
    }
    else
    {
        die ("Bad request:$response->status_line\n");
    }
}

sub search($)
{
    ($search)=@_;
    my $ua = LWP::UserAgent->new();
    if($proxy)
    {
        $ua->proxy('http' => $proxy);
    }
    my $url= "$base/music/search.html?f=disc&f=artist&q=$search";
    debug("Getting $url\n");	
    my $req = HTTP::Request->new(GET => $url);
    my $response = $ua->request($req);			
    if ($response->is_success) {		
        @matches = ();
        my $data = $response->content;
        
        @lines = split /<!-- START ITEM -->/, $data ;
        foreach (@lines)
        {
            $line=$_;
            last if (/<!-- LIST END -->/);
            if(/<!-- END ITEM -->/)
            {
                $line=~s/<!-- END ITEM -->.*//;
                if (/<A HREF="(.*)" >(.*)<\/A>/)
                {
                    my %album=();
                    $album{'url'}="$base$1";
                    $album{'title'}=$2;
                    debug("$album{'title'} = $album{'url'}\n");
                    push @matches,\%album;
                }
            }
            
        }
    }
    else
    {
        die ("Bad request:$response->status_line\n");
    }
    
    return @matches;
}


sub editnames()
{
    print "\nEdit track names:\n";

    $idx=0;
    foreach (@files) { 
	$filename=$_;
	$mp3 = $tags{$filename};
	$tag = $mp3->{$tagversion}; 
	$title=$matches[$idx];
	$idx++;
	$title =~s/^\s*\d+\.\s+//;
	if($title=~/--/)
	{
	    $artist=$title;
	    $artist=~s/^.*--\s*//;
	    $title=~s/\s*--.*$//;
	}
	$tag->title($title);
	if($album)
	{
	    $tag->album($album);
	}
        
	if($artist)
	{
	    $tag->artist($artist);
	}

    } 
    print "New details:\n";
    printdetails();
}


sub printdetails()
{
    foreach (@files) {
	$filename=$_;
	$mp3 = $tags{$filename};
	$tag = $mp3->{$tagversion};
	print $filename, "\t", $tag->artist, "\t", $tag->album, "\t", $tag->title, "\n";
    }

}

sub renamefiles()
{
    foreach (@files) {
	$filename=$_;
	$mp3 = $tags{$filename};
	$tag = $mp3->{$tagversion};

	
	$track = $tag->track;
	if(!$track)
	{
	    if($_=~/^(\d+)/)
	    {
		$track=$1;
	    }
	    elsif($_=~/Track\s*(\d+)/i)
	    {
		$track=$1;
	    }
	}
	if($track=~/^\d$/)
	{
	    $track="0$track";
	}
	
	$title = $mp3->{$tagversion}->title;
	if($title=~/^$/)
	{
	    print "No title found - skipping\n";
	}
	else
	{
	    print "Title:'$title'\n";
	    if($track)
	    {
		$newname = "$track - $title.mp3";	
	    }
	    else
	    {
		$newname = "$title.mp3";
	    }
	    $newname = ~ s/?//g;
	    $newname =~ s/\// /g;
	    print "$_\t -> $newname\n";
	    rename ("$_",$newname);
	    $undo.=qq{mv "$newname" "$_"\n};
	
	}
	
    } 
    print "\n\nTo undo:\n\n$undo";
}


sub closetags()
{
    foreach (@files) { 
	$filename=$_;
	$mp3 = $tags{$filename};
	$mp3->close();
    }
}




# loop over file list and load tag information
foreach (@files) { 
    $filename=$_;
    $tags{$filename} = MP3::Tag->new($filename);
    $mp3 = $tags{$filename};
    $mp3->get_tags(); 
#print "TAGS:".$mp3;
    if (!exists $mp3->{$tagversion}) { 
        print "Creating new tag for $filename\n";
        $mp3->new_tag($tagversion);
        $gentitle=$_;
        $gentitle=~s/.mp3//i;
        $mp3->{$tagversion}->title($gentitle);
        
    }
}
printdetails();
print "\nEdit?(y/n)";
$ans = <STDIN>;
if($ans=~/y/i)
{
    closetags();
    
    dosearch();
    editnames();
    printdetails();



    print "\nSave?(y/n)";
    $ans = <STDIN>;
    if($ans=~/y/i)
    {
	print "Saving....\n";
	foreach (@files) { 
	    $filename=$_;
	    $mp3 = $tags{$filename};
	    $tag = $mp3->{$tagversion};
	    $tag->write_tag();
	}
	print "Done \n";
	
    }   
}
print "\nRename files?(y/n)";
$ans = <STDIN>;
if($ans=~/y/i)
{
    renamefiles();
}
closetags();
