import pygame, pathlib, random
import tkinter as tk


class MusicPlayer(tk.Tk):
    """
    A simple music player that uses the pygame music mixer.  I maintain
    a class "playlist" so I can be used to select music for a pygame.
    """
    music_folder = pathlib.Path('.') / 'music'  # Put mp3 files in subfolder named "music"
    playlist = []  # Class variable so can be accessed after player shuts down.

    def __init__(self, *args, title="Music Player", playmsg=None, **kvargs):
        super().__init__(*args, **kvargs)
        self.title("music")
        self.geometry("+900+300")
        tk.Label(
            self,
            text=title,
            font=('arial', 12, 'bold', 'italic')).grid(row=0, column=0, columnspan=2)
        # Make controls for constructing playlist and playing songs
        self.song_selections = []
        index = 0
        for index, song in enumerate(self.music_folder.glob("*.mp3")):
            # Checkboxes are used to select songs for playlist
            songtitle = pathlib.Path(song).name[:-4]
            var = tk.BooleanVar()
            var.song = song
            self.song_selections.append(var)
            tk.Checkbutton(self, text=songtitle, variable=var, command=self.update_playlist) \
                .grid(row=index + 1, column=0, sticky="w")

            # Button is used to immediately play song
            tk.Button(self, text="Play", command=lambda arg=song: self.play_song(arg)) \
                .grid(row=index + 1, column=1, padx=5, pady=2)

        # Play the playlist
        if playmsg is None:
            tk.Button(self, text="Play Selected", command=self.play_playlist) \
                .grid(row=index + 1, column=0, columnspan=2, sticky="ew")
        else:
            tk.Button(self, text=playmsg, fg="blue", command=self.destroy) \
                .grid(row=index + 2, column=0, columnspan=2, sticky="ew")

    def update_playlist(self):
        """Update the playlist to contain selected songs"""
        self.playlist.clear()
        for var in self.song_selections:
            if var.get():
                self.playlist.append(var.song)

    def play_playlist(self):
        """Play songs in playlist"""
        pygame.mixer.music.stop()
        if len(self.playlist) > 0:
            songs = random.sample(self.playlist, k=len(self.playlist))
            pygame.mixer.music.load(songs[0])
            for song in songs[1:]:
                pygame.mixer.music.queue(song)
            pygame.mixer.music.play()

    @staticmethod
    def play_song(song):
        """Play song now"""
        pygame.mixer.music.load(song)
        pygame.mixer.music.play()


if __name__ == "__main__":
    pygame.init()
    pygame.mixer.init()
    pygame.mixer.music.set_volume(0.7)
    MusicPlayer().mainloop()
