from tkinter import *
# from tkinter.ttk import *
from tkinter import messagebox
from tkinter import filedialog
from tkinter import scrolledtext as st
import numpy as np
import functions as fx
import os
import librosa
import eval
from PIL import ImageTk, Image
import soundfile as sf
from playsound import playsound

def browse_audio():
    # Vyber slozky s nahravkami k analyze
    global audio_path 	# pristup k promenne
    filename = filedialog.askdirectory() 	#otevreni dialogoveho okna pro vyber souboru
    audio_path.set(filename)			# ulozeni cesty k souboru	
    out.insert('end', '\n\nVybrana slozka s nahravkami: '+ filename)	
    #startbutton['state']='normal'


def browse_anot():
    # Vyber slozky s anotacemi
    global anot_path	# pristup k promenne
    filename = filedialog.askdirectory()	#otevreni dialogoveho okna pro vyber souboru
    anot_path.set(filename)			# ulozeni cesty k souboru
    out.insert('end', '\n\nVybrana slozka s anotacemi: '+ filename)	


################################################ FUNKCE BEAT TRACKINGU  ###########################################

def parsWin_lib():
    # otevre nove okno obsahujici mozne parametry k upraveni (analogicky ve vsech parsWin funkcich)
    parsWindow = Toplevel(root)
    parsWindow.title('Nastaveni parametru')
    lab = Label(parsWindow, text="Zadejte parametry", font="bold")
    lab.grid(column=0, row=0)
    lbl = Label(parsWindow, text="Vychozi tempo pro odhad (def: 120 BPM): ")
    lbl.grid(column=0, row=2, sticky=W)
    p1 = Entry(parsWindow, width=10)
    p1.grid(column=1, row=2, sticky=EW)
    lb2 = Label(parsWindow, text="Tempo skladby (def: system vypocita): ")
    lb2.grid(column=0, row=3, sticky=W)
    p2 = Entry(parsWindow, width=10)
    p2.grid(column=1, row=3, sticky=EW)
    lb2 = Label(parsWindow, text="Volnost rozlozeni odhadnutych dob \nokolo Vychoziho tempa (0-100)(def: 100): ")
    lb2.grid(column=0, row=4, sticky=W)
    p3 = Entry(parsWindow, width=10)
    p3.grid(column=1, row=4, sticky=EW)

    def close_window():
	#pri zavreni okna s parametry se tyto ulozi do globalnich promennych (analogicky ve vsech parsWin funkcich)
        global par1, par2, par3
        par1 = p1.get()
        par2 = p2.get()
        par3 = p3.get()
        parsWindow.destroy()

    B = Button(parsWindow, text="OK", command=close_window)
    B.grid(column=0, row=5)
    col_count, row_count = parsWindow.grid_size()

    # uprava sirky radku a vysky sloupcu (ve vsech parsWin funkcich)
    for col in range(col_count):
        parsWindow.grid_columnconfigure(col, minsize=10)

    for row in range(row_count):
        parsWindow.grid_rowconfigure(row, minsize=5)

def run_librosa():
    # funkce spoustejici knihovnu Librosa
    L = {}
    print('Librosa running...')
    # zmenitelne promenne s jejich def hodnotami
    startBPM = 120
    bpm = None
    tightness = 100.0

    # aktualizace parametru zmenenych uzivatelem
    # ulozeni danych hodnot do promennych
    if par1 is not '':
        startBPM = int(par1)
    if par2 is not '':
        bpm = int(par2)
    if par3 is not '':
        tightness = int(par3)


    # cyklus, v nemz projdou vsechny nahravky ze slozky audio_path touto knihovnou
    for song_full in forAnalysis:
        if os.path.isdir(song_full):		# preskakuje adresare
            continue
        song = song_full.split('.')
        try:
            if song[-1] != 'wav':		# bere v potaz pouze .wav soubory
                continue
        except:
            continue
        file ='/'.join((audio_path.get(), song_full))
        x, samplrt = librosa.load(file)		# nacteni souboru
        nic, L[song[0]] = fx.beattrack_librosa(x, samplrt, start_bpm=startBPM, bpm=bpm, tightness=tightness) # ziskani casu dob, ulozeni do slovniku
        fx.ulozto('outputs/Librosa', song_full, '.txt', L[song[0]])	# ulozeni casu dob do .txt souboru
    beat_times['Librosa'] = L 	# ulozeni slovniku casu dob do slovniku
    return beat_times

def parsWin_mT():
    # otevre nove okno obsahujici mozne parametry k upraveni
    parsWindow = Toplevel(root)
    parsWindow.title('Nastaveni parametru')
    lab = Label(parsWindow, text="Zadejte parametry", font="bold")
    lab.grid(column=0, row=0)
    lbl = Label(parsWindow, text="Pocet ramcu za sekundu (def: 100): ")
    lbl.grid(column=0, row=2, sticky=W)
    p1 = Entry(parsWindow, width=10)
    p1.grid(column=1, row=2, sticky=EW)
    lb2 = Label(parsWindow, text="Nejmensi mozne tempo v BPM (def: 55): ")
    lb2.grid(column=0, row=3, sticky=W)
    p2 = Entry(parsWindow, width=10)
    p2.grid(column=1, row=3, sticky=EW)
    lb2 = Label(parsWindow, text="Nejvetsi mozne tempo v BPM (def: 215): ")
    lb2.grid(column=0, row=4, sticky=W)
    p3 = Entry(parsWindow, width=10)
    p3.grid(column=1, row=4, sticky=EW)
    lb2 = Label(parsWindow, text="Sirka plovouciho okna v s: (def: 6): ")
    lb2.grid(column=0, row=5, sticky=W)
    p4 = Entry(parsWindow, width=10)
    p4.grid(column=1, row=5, sticky=EW)
    lb2 = Label(parsWindow, text="Metoda pouzita pro odhad tempa (def: autocor.):")
    lb2.grid(column=0, row=6, sticky=W)
    methods = ['autocorrelation', 'comb filter']
    method_chosen.set(methods[0])
    method_menu = OptionMenu(parsWindow, method_chosen, *methods)
    method_menu.grid(column=1, row=6, sticky=EW)

    def close_window():
        global par4, par5, par6, par777
        par4 = p1.get()
        par5 = p2.get()
        par6 = p3.get()
        par777 = p4.get()

        parsWindow.destroy()

    B = Button(parsWindow, text="OK", command=close_window)
    B.grid(column=0, row=7)

    col_count, row_count = parsWindow.grid_size()

    for col in range(col_count):
        parsWindow.grid_columnconfigure(col, minsize=10)

    for row in range(row_count):
        parsWindow.grid_rowconfigure(row, minsize=5)

def run_mT():
    MT = {}
    print('Madmom T running...')

    # zmenitelne promenne s jejich def hodnotami
    fps = 100
    min_bpm = 55.0
    max_bpm = 215.0
    look_ahead = 6
    m = method_chosen.get()
    if m == 'autocorrelation' or m == '':
        method = 'acf'
    elif m == 'comb filter':
        method = 'comb'


    # aktualizace parametru zmenenych uzivatelem
    # ulozeni danych hodnot do promennych
    if par4 is not '':
        fps = int(par4)
    if par5 is not '':
        min_bpm = int(par5)
    if par6 is not '':
        max_bpm = int(par6)
    if par777 is not '':
        look_ahead = float(par777)


    # cyklus, v nemz projdou vsechny nahravky ze slozky audio_path touto knihovnou
    for song_full in forAnalysis:
        if os.path.isdir(song_full):
            continue
        song = song_full.split('.')
        try:
            if song[-1] != 'wav':
                continue
        except:
            continue
        file ='/'.join((audio_path.get(), song_full))
        beats = fx.beattrack_madmom(file, 'T', fps=fps, min_bpm=min_bpm, method=method, max_bpm=max_bpm, look_ahead=look_ahead/2)
        MT[song[0]] = beats[0]
        fx.ulozto('outputs/Madmom Beat Tracker', song_full, '.txt', MT[song[0]])
    beat_times['Madmom Beat Tracker'] = MT
    return beat_times


def parsWin_mD():
    parsWindow = Toplevel(root)
    parsWindow.title('Nastaveni parametru')
    lab = Label(parsWindow, text="Zadejte parametry", font="bold")
    lab.grid(column=0, row=0)
    lbl = Label(parsWindow, text="Pocet ramcu za sekundu (def: 100): ")
    lbl.grid(column=0, row=2, sticky=W)
    p1 = Entry(parsWindow, width=10)
    p1.grid(column=1, row=2, sticky=EW)


    def close_window():
        global par7
        par7 = p1.get()
        parsWindow.destroy()

    B = Button(parsWindow, text="OK", command=close_window)
    B.grid(column=0, row=6)

    col_count, row_count = parsWindow.grid_size()

    for col in range(col_count):
        parsWindow.grid_columnconfigure(col, minsize=10)

    for row in range(row_count):
        parsWindow.grid_rowconfigure(row, minsize=5)

def run_mD():
    MD = {}
    print('Madmom D running...')

    # zmenitelne promenne s jejich def hodnotami
    fps = 100


    # aktualizace parametru zmenenych uzivatelem
    # ulozeni danych hodnot do promennych
    if par7 is not '':
        fps = int(par7)

     # cyklus, v nemz projdou vsechny nahravky ze slozky audio_path touto knihovnou
    for song_full in forAnalysis:
        if os.path.isdir(song_full):
            continue
        song = song_full.split('.')
        try:
            if song[-1] != 'wav':
                continue
        except:
            continue
        file ='/'.join((audio_path.get(), song_full))
        beats = fx.beattrack_madmom(file, 'D', fps=fps)
        MD[song[0]] = beats[0]
        fx.ulozto('outputs/Madmom Beat Detector', song_full, '.txt', MD[song[0]])
    beat_times['Madmom Beat Detector'] = MD
    return beat_times

def parsWin_DBN():
    parsWindow = Toplevel(root)
    parsWindow.title('Nastaveni parametru')
    lab = Label(parsWindow, text="Zadejte parametry", font="bold")
    lab.grid(column=0, row=0)
    lbl = Label(parsWindow, text="Pocet ramcu za sekundu (def: 100): ")
    lbl.grid(column=0, row=2, sticky=W)
    p1 = Entry(parsWindow, width=10)
    p1.grid(column=1, row=2, sticky=EW)
    lb2 = Label(parsWindow, text="Nejmensi mozne tempo v BPM (def: 55): ")
    lb2.grid(column=0, row=3, sticky=W)
    p2 = Entry(parsWindow, width=10)
    p2.grid(column=1, row=3, sticky=EW)
    lb2 = Label(parsWindow, text="Nejvetsi mozne tempo v BPM (def: 215): ")
    lb2.grid(column=0, row=4, sticky=W)
    p3 = Entry(parsWindow, width=10)
    p3.grid(column=1, row=4, sticky=EW)


    def close_window():
        global par8, par9, par10
        par10 = p1.get()
        par8 = p2.get()
        par9 = p3.get()
        parsWindow.destroy()

    B = Button(parsWindow, text="OK", command=close_window)
    B.grid(column=0, row=6)

    col_count, row_count = parsWindow.grid_size()

    for col in range(col_count):
        parsWindow.grid_columnconfigure(col, minsize=10)

    for row in range(row_count):
        parsWindow.grid_rowconfigure(row, minsize=5)

def run_DBN():
    DBN = {}
    print('DBN running...')

    # zmenitelne promenne s jejich def hodnotami
    fps = 100
    min_bpm = 55.0
    max_bpm = 215.0

    # aktualizace parametru zmenenych uzivatelem
    # ulozeni danych hodnot do promennych
    if par10 is not '':
        fps = int(par10)
    if par8 is not '':
        min_bpm = int(par8)
    if par9 is not '':
        max_bpm = int(par9)

     # cyklus, v nemz projdou vsechny nahravky ze slozky audio_path touto knihovnou
    for song_full in forAnalysis:
        if os.path.isdir(song_full):
            continue
        song = song_full.split('.')
        try:
            if song[-1] != 'wav':
                continue
        except:
            continue
        file ='/'.join((audio_path.get(), song_full))
        beats = fx.beattrack_madmom(file, 'DBN', fps=fps, min_bpm=min_bpm, max_bpm=max_bpm)
        DBN[song[0]] = beats[0]
        fx.ulozto('outputs/Dynamic Bayessian Network', song_full, '.txt', DBN[song[0]])
    beat_times['Dynamic Bayessian Network'] = DBN
    return beat_times


def parsWin_es():
    parsWindow = Toplevel(root)
    parsWindow.title('Nastaveni parametru')
    lab = Label(parsWindow, text="Zadejte parametry", font="bold")
    lab.grid(column=0, row=0)
    lbl = Label(parsWindow, text="Maximalni tempo v BPM (def: 208): ")
    lbl.grid(column=0, row=2, sticky=W)
    p1 = Entry(parsWindow, width=10)
    p1.grid(column=1, row=2, sticky=EW)
    lb2 = Label(parsWindow, text="Minimalni tempo v BPM (def: 40): ")
    lb2.grid(column=0, row=3, sticky=W)
    p2 = Entry(parsWindow, width=10)
    p2.grid(column=1, row=3, sticky=EW)


    def close_window():
        global par12, par13
        par12 = p1.get()
        par13 = p2.get()
        parsWindow.destroy()

    B = Button(parsWindow, text="OK", command=close_window)
    B.grid(column=0, row=6)

    col_count, row_count = parsWindow.grid_size()

    for col in range(col_count):
        parsWindow.grid_columnconfigure(col, minsize=10)

    for row in range(row_count):
        parsWindow.grid_rowconfigure(row, minsize=5)


def run_es():
    E = {}
    print('Essentia running...')

    min_bpm = 40
    max_bpm = 208

    if par13 is not '':
        min_bpm = int(par13)
    if par12 is not '':
        max_bpm = int(par12)

     # cyklus, v nemz projdou vsechny nahravky ze slozky audio_path touto knihovnou
    for song_full in forAnalysis:
        if os.path.isdir(song_full):
            continue
        song = song_full.split('.')
        try:
            if song[-1] != 'wav':
                continue
        except:
            continue
        file ='/'.join((audio_path.get(), song_full))
        E[song[0]], nic = fx.beattrack_essentia(file, max=max_bpm, min=min_bpm)
        fx.ulozto('outputs/Essentia', song_full, '.txt', E[song[0]])
    beat_times['Essentia'] = E
    return beat_times

def parsWin_aub():
    parsWindow = Toplevel(root)
    parsWindow.title('Nastaveni parametru')
    lab = Label(parsWindow, text="Zadejte parametr", font="bold")
    lab.grid(column=0, row=0)
    lbl = Label(parsWindow, text="Sirka okna ve vzorcich (def: 1024): ")
    lbl.grid(column=0, row=2, sticky=W)
    p1 = Entry(parsWindow, width=10)
    p1.grid(column=1, row=2, sticky=EW)


    def close_window():
        global par11
        par11 = p1.get()
        parsWindow.destroy()

    B = Button(parsWindow, text="OK", command=close_window)
    B.grid(column=0, row=6)

    col_count, row_count = parsWindow.grid_size()

    for col in range(col_count):
        parsWindow.grid_columnconfigure(col, minsize=10)

    for row in range(row_count):
        parsWindow.grid_rowconfigure(row, minsize=5)

def run_aub():
    A = {}
    print('Aubio running...')

    # zmenitelne promenne s jejich def hodnotami
    w_size = 1024

    # aktualizace parametru zmenenych uzivatelem
    # ulozeni danych hodnot do promennych
    if par11 is not '':
        w_size = int(par11)

     # cyklus, v nemz projdou vsechny nahravky ze slozky audio_path touto knihovnou
    for song_full in forAnalysis:
        if os.path.isdir(song_full):
            continue
        song = song_full.split('.')
        try:
            if song[-1] != 'wav':
                continue
        except:
            continue
        file ='/'.join((audio_path.get(), song_full))
        A[song[0]] = fx.beattrack_aubio(file, win_s=w_size)
        fx.ulozto('outputs/Aubio', song_full, '.txt', A[song[0]])
    beat_times['Aubio'] = A
    return beat_times
#
#
#
# Moznost vlozeni dalsiho systemu: 
# 1) nize vytvorit odpovidajici policko v GUI (a ev. i tlacitko Parametry)   
# 2) vytvorit funkci pro otevreni okna s parametry parsWin_<novysystem>, napr:
#
#	def parsWin_<novysystem>():
#	    parsWindow = Toplevel(root)
#	    parsWindow.title('Nastaveni parametru')
#	    lab = Label(parsWindow, text="Zadejte parametry", font="bold")
#	    lab.grid(column=0, row=0)
#		
#	    lbl = Label(parsWindow, text="Parametr A noveho systemu: ")
#	    lbl.grid(column=0, row=2, sticky=W)
#	    p1 = Entry(parsWindow, width=10)
#	    p1.grid(column=1, row=2, sticky=EW)
#	    ..... analogicky pro dalsi parametry
#
#	    def close_window():	
#		global parXX
#		parXX = p1.get()
#		parsWindow.destroy()
#
#	    B = Button(parsWindow, text="OK", command=close_window)
#	    B.grid(column=0, row=6)
# 
# 3) pridat funkci run_<novysystem>, ktera pripadne aktualizuje parametry a provede analyzu nahravek pomoci noveho systemu, napr: 
#
#	def run_<novysystem>():
#
#	    def beattrack_novysystem(file, parametr)
#		# samotna funkce pro detekci dob
#		......
#		return beattimes

#	    X = {}
#	    print('System X running...')
#
#	    # zmenitelne parametry s jejich def hodnotami
#	    parametr = 0
#
#	    # aktualizace parametru zmenenych uzivatelem
#	    # ulozeni danych hodnot do promennych
#	    if parXX is not '':
#		parametr = int(parXX)
#
#	     # cyklus, v nemz projdou vsechny nahravky ze slozky audio_path touto knihovnou
#	    for song_full in forAnalysis:
#		if os.path.isdir(song_full):
#		    continue
#		song = song_full.split('.')
#		try:
#		    if song[-1] != 'wav':
#		        continue
#		except:
#		    continue
#		file ='/'.join((audio_path.get(), song_full))
#		X[song[0]] = beattrack_novysystem(file, parametr)
#		fx.ulozto('outputs/Aubio', song_full, '.txt', X[song[0]])
#	    beat_times['<novysystem>'] = X
#	    return beat_times
# 4) 
#

################################################## FUNKCE OVLADANI GUI ###################################

def graph_win():
    # otevre okno s moznostmi pro vykresleni grafu
    graphWindow = Toplevel(root)
    graphWindow.title('Nastaveni grafu')
    graphmenu = ['Waveform', 'Spectrogram'] # vyber typu grafu
    songmenu = [] 
    for song_full in forAnalysis:
        if os.path.isdir(song_full):
            continue
        song = song_full.split('.')
        try:
            if song[-1] != 'wav':
                continue
        except:
            continue
        songmenu.append(song_full) # nacteni vsech dostupnych nahravek do rolovaciho menu

    Label(graphWindow, text='Vyberte nahravku: ').grid(column=0, row=0, sticky=W)
    drawsong = StringVar(graphWindow) 
    drawsong.set(songmenu[0]) # nastaveni prvni polozky v rolovacim menu jako prvni polozky seznamu nahravek
    songs_menu = OptionMenu(graphWindow, drawsong, *songmenu) # vytvoreni rolovaciho menu
    songs_menu.grid(column=1, row=0, sticky=E)

    Label(graphWindow, text='Vyberte pouzity system: ').grid(column=0, row=1, sticky=W)
    drawlib = StringVar(graphWindow)
    all_libs = os.listdir('outputs')
    drawlib.set(all_libs[0])
    libs_menu = OptionMenu(graphWindow, drawlib, *all_libs)
    libs_menu.grid(column=1, row=1, sticky=E)

    Label(graphWindow, text='Vyberte typ grafu: ').grid(column=0, row=2, sticky=W)
    drawgraph = StringVar(graphWindow)
    drawgraph.set(graphmenu[0])
    graph_menu = OptionMenu(graphWindow, drawgraph, *graphmenu)
    graph_menu.grid(column=1, row=2, sticky=E)

    def ok():
	# po stisknuti tlacitka Zobraz graf se zacne vykreslovat prislusny graf v novem okne
        global s, l, g
        graphShow = Toplevel(root)
        graphShow.title('Graf detekovanych dob')
        canvas = Canvas(graphShow, width=600, height=350)
        canvas.grid()
        s = drawsong.get()
        file = audio_path.get() + '/' + s
        x, samplrt = librosa.load(file)
        l = drawlib.get()
        g = drawgraph.get()
        bttimes = np.loadtxt('outputs/' + l + '/' + s.split('.')[0] +'.txt')
        if g == 'Waveform':
            fx.graf_modul_cas(x, bttimes, s.split('.')[0], lib=l)
            img1 = ImageTk.PhotoImage(Image.open('modulcas.png').resize((600, 275)))
            canvas.create_image(300, 175, image=img1)
            graphShow.img1 = img1
            graphWindow.destroy()
        elif g == 'Spectrogram':
            fx.spektrogram_w_lines(file, beat_times[l][s.split('.')[0]], s.split('.')[0], lib=l)
            img1 = ImageTk.PhotoImage(Image.open('specgr.png').resize((600, 275)))
            canvas.create_image(300, 170, image=img1)
            graphShow.img1 = img1
            graphWindow.destroy()
        #else:
            #fx.graf_melspect(file, samplrt, beat_times[l][s.split('.')[0]])
            #img1 = ImageTk.PhotoImage(Image.open('melspecgr.png').resize((600, 275)))
            #canvas.create_image(300, 170, image=img1)
            #graphShow.img1 = img1
            #graphWindow.destroy()

    Okbutt = Button(graphWindow, text='Zobraz graf', command=ok)
    Okbutt.grid(column=0, row=3, columnspan=2)


def start_analysis():
    # funkce vyvolana tlacikem Spustit analyzu, spousti analyzu...
    audpath = audio_path.get() # nacteni adresare s nahravkami
    if audpath == '':
        messagebox.showinfo("Zprava", "Vyberte prosim slozku s nahravkami. \nJinak analyzu nelze provest.")
    else:
        global forAnalysis
        forAnalysis = os.listdir(audio_path.get()) # nacteni vsech nahravek z adresare
        global beat_times, used_libs
        beat_times = {}
        check = 0 
	# pokud uzivatel zaskrtl jmeno dane knihovny, spusti se ji odpovidajici funkce
        if var1.get() == 1:
            used_libs.append('Librosa')
            run_librosa()
            check += 1
        if var2.get() == 1:
            used_libs.append('Madmom Beat Tracker')
            run_mT()
            check += 1
        if var3.get() == 1:
            used_libs.append('Madmom Beat Detector')
            run_mD()
            check += 1
        if var4.get() == 1:
            used_libs.append('Essentia')
            run_es()
            check += 1
        if var5.get() == 1:
            used_libs.append('Aubio')
            run_aub()
            check += 1
        if var6.get() == 1:
            used_libs.append('Dynamic Bayessian Network')
            run_DBN()
            check += 1

	# pri pridani nove funkce detekce dob, nutno odkomentovat sem: 
#	if var7.get() == 1:
#            used_libs.append('Novy system')
#            run_<novysystem>()
#            check += 1

        if check > 0:
	    # Po dokonceni analyzy pomoci aspon jedne knihovny, umozni se vykreslovani grafu a prehrani skladby
            graphs['state'] = 'normal'
            playbutton['state'] = 'normal'
            #evalbutton['state'] = 'normal' 
            messagebox.showinfo("Zprava", "Analyza dokoncena. Vysledky naleznete ve slozce /output.")
        else:
            messagebox.showinfo("Zprava", "Nevybrali jste zadnou knihovnu. \nAnalyzu nelze provest.")

def pre_start_eval():
    # Okno otevrene po kliknuti na tlacitko Vyhodnoceni - umoznuje upraveni parametru evaluace
    parsWin_eval = Toplevel(root)
    parsWin_eval.title('Parametry evaluace')
    global fwin, sig, th
    fwin = DoubleVar()
    sig = DoubleVar()
    th = DoubleVar()
    w1 = Scale(parsWin_eval, from_=20, to=200, orient='horizontal', variable=fwin, resolution=5)
    w1.set(70)
    w1.grid(row=1, column=0)
    Label(parsWin_eval, text='Zvolte velikost okna \npro F-score [ms]:').grid(row=0, column=0)
    w2 = Scale(parsWin_eval, from_=10, to=100, orient='horizontal', variable=sig, resolution=5)
    w2.set(40)
    w2.grid(row=1, column=1)
    Label(parsWin_eval, text='Zvolte sirku Gaussova \nokna pro Cemgil score [ms]:').grid(row=0, column=1)
    w3 = Scale(parsWin_eval, from_=5, to=50, orient='horizontal', variable=th, resolution=5)
    w3.set(20)
    w3.grid(row=1, column=2)
    Label(parsWin_eval, text='Zvolte velikost okna \npro P-score [%]:').grid(row=0, column=2)

    def save_pars():
	# po kliknuti na Spustit evaluaci se zavre okno s parametry a spusti se evaluace
        start_eval()
        parsWin_eval.destroy()

    Button(parsWin_eval, command=save_pars, text='Spustit evaluaci').grid(row=3, column=1)


def start_eval():
    # spusteni samostatne funkce pro vyhodnoceni vysledku

    # results = eval.main(audio_path.get(), anot_path.get(), fwin=fwin.get()/1000, sig=sig.get(), th=th.get())
    apath = anot_path.get()
    if apath == '':
        messagebox.showinfo("Zprava", "Prosim zadejte slozku s anotacemi. \nJinak evaluaci nelze provest.")
    else:
	# spusteni evaluace 
        results, missing_songs, missing_anots = eval.main(fwin=fwin.get() / 1000, sig=sig.get()/1000, th=th.get()/100, audio_path=audio_path.get(), anot_path=anot_path.get())
        resWin = Toplevel(root)
        resWin.title('Vysledky')  # otevreni okna pro vysledky vykreslene do sloupcovych grafu, ktere se vytvori v ramci eval.main()
        canvas = Canvas(resWin, width=1500, height=900)
        canvas.grid()
        allfiles = [f for f in os.listdir('results/') if os.path.isfile('results/'+f)]
        grafiks=[]
        for file in allfiles:
            if file.split('.')[1] == 'png':
                grafiks.append(file)

	# vykresleni samotnych grafu
        w = 225
        h = 150
        img1 = ImageTk.PhotoImage(Image.open('results/'+ grafiks[0]).resize((450, 250)))
        canvas.create_image(w, h, image=img1)
        resWin.img1=img1
        img2 = ImageTk.PhotoImage(Image.open('results/'+ grafiks[1]).resize((450, 250)))
        canvas.create_image(w + 450, h, image=img2)
        resWin.img2 = img2
        img3 = ImageTk.PhotoImage(Image.open('results/'+ grafiks[2]).resize((450, 250)))
        canvas.create_image(w + 900, h, image=img3)
        resWin.img3 = img3
        img4 = ImageTk.PhotoImage(Image.open('results/'+ grafiks[3]).resize((450, 250)))
        canvas.create_image(w, h + 300, image=img4)
        resWin.img4 = img4
        img5 = ImageTk.PhotoImage(Image.open('results/'+ grafiks[4]).resize((450, 250)))
        canvas.create_image(w + 450, h + 300, image=img5)
        resWin.img5 = img5

	# vypsani vysledku do textoveho okna
        def tisk(dict_of_results):
            for score in dict_of_results:
                text = '\n\n' + score + ' pro jednotlive systemy:'
                out.insert('end', text)
                for lib in dict_of_results[score]:
                    value = dict_of_results[score][lib]
                    textt = '\n' + lib + ': %.2f' % value + ' % '
                    if score == 'Goto':
                        value = value/100
                        textt = '\n' + lib + ': %.2f' % value
                    out.insert('end', textt)

        tisk(results)
	# pro kontrolu - vypis nazvu pisni, k nimz nebyly nalezeny anotace a nazvu anotaci, k nimz nebyly nalezeny nahravky
        if missing_anots != []:
            out.insert('end', '\n\nNenalezene anotace k nasledujicim nahravkam: ')
            out.insert('end', missing_anots)
        if missing_songs != []:
            out.insert('end', '\n\nNenalezene nahravky k nasledujicim anotacim: ')
            out.insert('end', missing_songs)
        messagebox.showinfo("Zprava", "Vyhodnoceni dokonceno. Vysledky naleznete ve slozce /results.")

def playme():
    # spusti se po stisknuti tlacitka Prehrat, vytvori nove okno pro vyber nahravky a systemu
    playWin = Toplevel(root)
    playWin.title('Nastaveni prehrani')
    songmenu = []
    for song_full in forAnalysis:
        if os.path.isdir(song_full):
            continue
        song = song_full.split('.')
        try:
            if song[-1] != 'wav':
                continue
        except:
            continue
        songmenu.append(song_full)

    Label(playWin, text='Prehrani nahravky s detekovanymi dobami', font="Calibri 10 bold").grid(column=0, row=0, sticky=EW, columnspan=2)

    Label(playWin, text='Vyberte nahravku: ').grid(column=0, row=1, sticky=W)
    playSong = StringVar(playWin)
    playSong.set(songmenu[0])
    songs_menu = OptionMenu(playWin, playSong, *songmenu)
    songs_menu.grid(column=1, row=1, sticky=E)

    Label(playWin, text='Vyberte pouzity system: ').grid(column=0, row=2, sticky=W)
    playLib = StringVar(playWin)
    playLib.set(used_libs[0])
    libs_menu = OptionMenu(playWin, playLib, *used_libs)
    libs_menu.grid(column=1, row=2, sticky=E)

    def ok():
	# po stisknuti tlacitka Prehrat se vytvori soubor se souctem prehravane pisne a detekovanych dob danym systemem
        songplayed = playSong.get()
        libplayed = playLib.get()
        file = audio_path.get() + '/' + songplayed
        x, samplrt = librosa.load(file)
        beats = beat_times[libplayed][songplayed.split('.')[0]]

        clicks = librosa.clicks(beats, sr=samplrt, length=len(x))  # vytvoreni stopy s clickem
        sf.write('with_click.wav', x + clicks, samplrt)  # ulozeni souboru s clickem
        playsound('with_click.wav')

    Okbutt = Button(playWin, text='Přehrát', command=ok)
    Okbutt.grid(column=0, row=3, columnspan=2)

####################################################################################################################################
############################################################ VYTVORENI GUI #########################################################
####################################################################################################################################

os.environ['LC_NUMERIC'] = 'en_US.UTF-8'
root = Tk()
root.title("DiplomovaPrace_Stankova_2020/2021")

myLabel = Label(root, text='System pro detekci rytmicke struktury skladeb', font="Calibri 14 bold")
myLabel.grid(column=0, row=0, columnspan=4, sticky=NSEW)

# definice promennych
var1 = IntVar()
var2 = IntVar()
var3 = IntVar()
var4 = IntVar()
var5 = IntVar()
var6 = IntVar()
par1 = ''
par2 = ''
par3 = ''
par4 = ''
par5 = ''
par6 = ''
par7 = ''
par8 = ''
par9 = ''
par10 = ''
par11 = ''
par12 = ''
par13 = ''
par777 = ''
audio_path = StringVar()
method_chosen = StringVar()
anot_path = StringVar()
drawsong = StringVar()
drawlib = StringVar()
drawgraph = StringVar()
used_libs = []


# tlacitka pro vyber slozek
dirs = LabelFrame(root, text='Volba adresaru: ', fg="grey")
dirs.grid(row=1, rowspan=2, columnspan=3, column=0, sticky=NSEW, padx=5, pady=5, ipadx=5, ipady=5)

Label(dirs, text='Vyberte slozku s datasetem: ').grid(column=0,row=0, sticky=W)
buttonBrowse = Button(dirs, text='Prochazet', command=browse_audio)
buttonBrowse.grid(row=0, column=1, sticky=E)

Label(dirs, text='Vyberte slozku s anotacemi: ').grid(column=0,row=1, sticky=W)
buttonAnot = Button(dirs, text="Prochazet", command=browse_anot)
buttonAnot.grid(row=1, column=1, sticky=E)

# zaskrtavaci policka s nazvy systemu a tlacitka pro upravu parametru

systChoice = LabelFrame(root, text='Volba a nastaveni systemu: ', fg="grey")
systChoice.grid(row=3, rowspan=6, columnspan=3, column=0, sticky=NSEW, padx=5, pady=5, ipadx=5, ipady=5)

c1 = Checkbutton(systChoice, text='Librosa', variable=var1, onvalue=1, offvalue=0)
c1.grid(column=0, row=4, sticky=W)
bt1 = Button(systChoice, text='Parametry', command=parsWin_lib)
bt1.grid(column=1, row=4, sticky=E)

c2 = Checkbutton(systChoice, text='Madmom Beat Tracker', variable=var2, onvalue=1, offvalue=0)
c2.grid(column=0, row=6, sticky=W)
bt2 = Button(systChoice, text='Parametry', command=parsWin_mT)
bt2.grid(column=1, row=6, sticky=E)

c3 = Checkbutton(systChoice, text='Madmom Beat Detector', variable=var3, onvalue=1, offvalue=0)
c3.grid(column=0, row=5, sticky=W)
bt3 = Button(systChoice, text='Parametry', command=parsWin_mD)
bt3.grid(column=1, row=5,sticky=E)

c4 = Checkbutton(systChoice, text='Essentia', variable=var4, onvalue=1, offvalue=0)
c4.grid(column=0, row=3, sticky=W)
bt13 = Button(systChoice, text='Parametry', command=parsWin_es)
bt13.grid(column=1, row=3,sticky=E)

c5 = Checkbutton(systChoice, text='Aubio', variable=var5, onvalue=1, offvalue=0)
c5.grid(column=0, row=1, sticky=W)
bt23 = Button(systChoice, text='Parametry', command=parsWin_aub)
bt23.grid(column=1, row=1, sticky=E)

c6 = Checkbutton(systChoice, text='Dynamic Bayessian Network', variable=var6, onvalue=1, offvalue=0)
c6.grid(column=0, row=2, sticky=W)
bt234 = Button(systChoice, text='Parametry', command=parsWin_DBN)
bt234.grid(column=1, row=2, sticky=E)
#
# Pro pridani dalsi knihovny staci vytvorit tlacitko c7 a vyse doplnit novou funkci run_<novysystem> 
#

butts = LabelFrame(root, text='Ovladaci panel ', fg="grey")
butts.grid(row=1, rowspan=7, columnspan=2, column=3, sticky=NSEW, padx=5, pady=5, ipadx=10, ipady=10)

# tlacitko spoustejici analyzu
startbutton = Button(butts, text='Spustit analyzu', command=start_analysis, bg='#99c79e', activebackground='#54d463')
# erran = Label(root, text="Vyberte slozku \ns nahravkami!", fg="grey", font="Calibri 8 italic")
startbutton.grid(column=0, row=0, sticky=NSEW, columnspan=2, rowspan=2)
# erran.grid(column=3, row=14, sticky=W)

# tlacitko pro vykresleni grafu
graphs = Button(butts, text='Vykreslit graf', command=graph_win, state=DISABLED, bg='#8dd3e2', activebackground='#3bb3ce')
graphs.grid(column=0, row=2, sticky=NSEW, columnspan=2, rowspan=2)
# erran3 = Label(root, text='Nejprve musi probehnout analyza.', fg="grey", font="Calibri 8 italic")
# erran3.grid(column=0, row=14, sticky=W)

# tlacitko spoustejici vyhodnoceni
evalbutton = Button(butts, text='Vyhodnotit', command=pre_start_eval, bg='#dde486', activebackground='#f9f271')
evalbutton.grid(column=0, row=4,  sticky =NSEW, columnspan=2, rowspan=2)
# erran2 = Label(root, text="Vyberte slozku \ns anotacemi!", fg="grey", font="Calibri 8 italic")
# erran2.grid(column=4, row=, sticky=W)

# tlacitko pro prehravani
playbutton = Button(butts, text='Prehrat', command=playme, state=DISABLED, bg='#e3b463', activebackground='#ffab1a')
playbutton.grid(column=0, row=6,  sticky =NSEW, columnspan=2, rowspan=2)

# textove okno
out = st.ScrolledText(root, height=15)
initmessage = 'System pripraven!\n\nPro spusteni analyzy prosim vyberte slozku s nahravkami.' \
              '\n\nPro spusteni vyhodnoceni prosim vyberte slozku s nahravkami \na slozku s anotacemi.' \
              '\n\nUPOZORNENI: Proces analyzy muze trvat i nekolik minut, v navaznosti na \n' \
              'pouzite systemy a velikost datasetu! '

out.grid(row=9, column=0, columnspan=4, padx=5, pady=5)
out.insert('end', initmessage)

# trida pro nastaveni sirky sloupcu a vysky radku
class WinEdit:
    def winedit(self):
        col_count, row_count = self.grid_size()
        for col in range(col_count):
            self.grid_columnconfigure(col, minsize=5)
            Grid.columnconfigure(self, col, weight=1)

        for row in range(row_count):
            self.grid_rowconfigure(row, minsize=7)
            Grid.rowconfigure(self, row, weight=1)


col_count, row_count = root.grid_size()
for col in range(col_count):
    root.grid_columnconfigure(col, minsize=10)
    Grid.columnconfigure(root, col, weight=1)

for row in range(row_count):
    root.grid_rowconfigure(row, minsize=20)
    Grid.rowconfigure(root, row, weight=1)

WinEdit.winedit(systChoice)
WinEdit.winedit(dirs)
WinEdit.winedit(butts)

root.mainloop()

