+$topmenu //= $menu;
+
+# Connect to MPD.
+$sock = MPD::connect();
+die("MPD version $MPD::major.$MPD::minor.$MPD::revision insufficient.")
+ unless MPD::min_version(MPD_MJR_MIN, MPD_MNR_MIN, MPD_REV_MIN);
+
+if ($mode eq "top") {
+ my %current;
+ my %state;
+
+ $menu //= "MenuMPD";
+
+ MPD::exec("status");
+ while (<$sock>) {
+ last if (/^OK/);
+ die($_) if (/^ACK/);
+
+ if (/^(\w+): (.*)$/) {
+ $state{$1} = $2;
+ }
+ }
+
+ MPD::exec("currentsong");
+ while (<$sock>) {
+ last if (/^OK/);
+ die($_) if (/^ACK/);
+
+ if (/^(\w+): (.*)$/) {
+ add_track_metadata(\%current, $1, $2);
+ }
+ }
+
+ my $playstate = $state{state} eq "play" ? "Playing"
+ : $state{state} eq "stop" ? "Stopped"
+ : $state{state} eq "pause" ? "Paused"
+ : "Unknown";
+ fvwm_cmd("AddToMenu", $menu, $playstate, "Title");
+
+ if (exists($current{file})) {
+ top_track_cover(\%current);
+ top_track_title(\%current);
+ top_track_artist(\%current);
+ top_track_album(\%current);
+ } else {
+ fvwm_cmd("AddToMenu", $menu, "[current track unavailable]");
+ }
+
+ if ($state{state} =~ /^p/) {
+ my $pp = $state{state} eq "pause" ? "lay" : "ause";
+
+ fvwm_cmd("AddToMenu", $menu, "", "Nop");
+ fvwm_cmd("AddToMenu", $menu, "Next%next.svg:16x16%",
+ "Exec", "exec", "$FindBin::Bin/mpdexec.pl", "next");
+ fvwm_cmd("AddToMenu", $menu, "P$pp%p$pp.svg:16x16%",
+ "Exec", "exec", "$FindBin::Bin/mpdexec.pl", "p$pp");
+ fvwm_cmd("AddToMenu", $menu, "Stop%stop.svg:16x16%",
+ "Exec", "exec", "$FindBin::Bin/mpdexec.pl", "stop");
+ fvwm_cmd("AddToMenu", $menu, "Prev%prev.svg:16x16%",
+ "Exec", "exec", "$FindBin::Bin/mpdexec.pl", "previous");
+ } elsif ($state{state} eq "stop") {
+ fvwm_cmd("AddToMenu", $menu, "", "Nop");
+ fvwm_cmd("AddToMenu", $menu, "Play%play.svg:16x16%",
+ "Exec", "exec", "$FindBin::Bin/mpdexec.pl", "play");
+ }
+} elsif ($mode eq "album") {
+ my $matches = get_tracks_by_release_mbid($albumid);
+ my @notqueued = ();
+
+ $menu //= "MenuMPDAlbum";
+
+ my $track_max = max(map { $_->{Track} } values %$matches);
+ my $disc_max = max(map { $_->{Disc} } values %$matches);
+
+ # CDs have a max of 99 tracks and I hope 100+-disc-releases
+ # don't exist so this is fine.
+ my $track_digits = $track_max >= 10 ? 2 : 1;
+ my $disc_digits = $disc_max > 1 ? $disc_max >= 10 ? 2 : 1 : 0;
+ my $currentdisc;
+
+ fvwm_cmd("AddToMenu", $menu);
+ fvwm_cmd("+", "Release not found", "Title") unless keys %$matches;
+ foreach my $file (sort { albumsort($matches, $a, $b) } keys %$matches) {
+ my $entry = $matches->{$file};
+
+ # Format disc/track numbers
+ $entry->{trackfmt} = sprintf("%*.*s%.*s%*d\t",
+ $disc_digits, $disc_digits, $entry->{Disc},
+ $disc_digits, "-",
+ $track_digits, $entry->{Track});
+ $entry->{trackfmt} =~ s/ /\N{U+2007}/g;
+
+ unless (exists $entry->{Id}) {
+ my ($id) = get_ids_by_filename($file);
+ if (defined $id) {
+ $entry->{Id} = $id;
+ } else {
+ push @notqueued, $entry;
+ next;
+ }
+ }
+
+ if (defined $currentdisc && $currentdisc != $entry->{Disc}) {
+ fvwm_cmd("+", "", "Nop");
+ }
+ $currentdisc = $entry->{Disc};