#!/usr/bin/env python3

import appdirs
import pathlib
import shutil
import simpleaudio
import sys
import tkinter
import tkinter.filedialog
import tkinter.ttk

global_root = None
file_dialog_root = None

def get_db():
    return pathlib.Path(appdirs.user_data_dir("soundboard", "Charles Daniels"))

def play_sound(name):

    # guarantee the database exists
    get_db().mkdir(exist_ok=True)

    # Get the path to the sound file.
    sound_path = [x for x in get_db().glob("{}*".format(name))][0]

    # load and play the sound
    wav    = simpleaudio.WaveObject.from_wave_file(str(sound_path))
    player = wav.play()
    player.wait_done()

def add_sound_from_file(path, GUI=False):
    if GUI:
        # when loading a file via the GUI, use the path argument as the initial
        # directory, and display a file picker dialog limited to just WAV
        # files, since that's all we support
        tkinter.Tk().withdraw()
        path = tkinter.filedialog.askopenfilename(
                initialdir=str(path),
                filetypes=[("Audio Files", "*.wav")],
                title="Choose a File")

        if path == ():
            # user selected "cancel"
            return

    path = pathlib.Path(path)

    # guarantee the database exists
    get_db().mkdir(exist_ok=True)

    # copy file into database
    shutil.copy(str(path), str(get_db() / path.name))

def from_file_callback():
    # load the sound file
    add_sound_from_file("./", GUI=True)

    # close the file picker dialog
    global file_dialog_root
    file_dialog_root.destroy()

    # kick over and restart the main window
    global global_root
    global_root.destroy()
    show_GUI()


def show_add_new_dialog():
    root = tkinter.Tk()
    root.title("add new sound clip")

    # allow this window to be closed
    global file_dialog_root
    file_dialog_root = root

    # "From File" button
    from_file_btn  = tkinter.ttk.Button(root, text="Add From File",
            command = from_file_callback)
    from_file_btn.grid(row = 0, column = 0)

    root.mainloop()

def show_GUI():
    root = tkinter.Tk()
    root.title("soundboard")

    # this will let us close and restart the GUI from elsewhere
    global global_root
    global_root = root

    # "add new" button
    add_new_btn = tkinter.ttk.Button(root, text="Add New",
            command=show_add_new_dialog)
    add_new_btn.grid(row=0, column=0)

    # exit button
    exit_btn = tkinter.ttk.Button(root, text="Exit", command=sys.exit)
    exit_btn.grid(row=1, column=0)

    # put a separator after the "Add New" button
    sep = tkinter.ttk.Separator(root, orient=tkinter.HORIZONTAL)
    sep.grid(row=2, column=0, sticky="ew")

    # generate a button for each element
    row = 3
    for path in get_db().glob("*"):
        if not path.is_file:
            continue

        # callback will be the function that get's called when the button is
        # clicked, in this case it just calls play_sound on the file that
        # corresponds to this button
        def callback(arg = path.stem):
            play_sound(arg)

        # create the button
        btn = tkinter.ttk.Button(root, text=path.stem, command=callback)

        btn.grid(column=0, row=row)

        row += 1

    root.mainloop()

def main():
    show_GUI()


if __name__ == "__main__":
    main()
