import os
import numpy as np
import functions as fx
import matplotlib as plt
import json


def main(fwin, sig, th, audio_path='audio', anot_path='annotations' ):
    print('\nEvaluating...')
    
    # nacteni anotaci a vyslednych detekovanych dob a jejich serazeni dle abecedy
    list_of_annotations = os.listdir(anot_path)
    list_of_annotations.sort()
    used_libraries = os.listdir('outputs')
    used_libraries.sort()

    # vytvoreni prazdnych slovniku a seznamu pro ukladani hodnoticich velicin
    f_means = []
    prec_means = []
    rec_means = []
    c_means = []
    p_means = []
    g_means = []
    f_means_dic = {}
    prec_means_dic = {}
    rec_means_dic = {}
    c_means_dic = {}
    p_means_dic = {}
    g_means_dic = {}
    missing_songs = []
    missing_anots = []

    for k in range(len(used_libraries)):
        list_of_btdet = os.listdir('/'.join(('outputs', used_libraries[k])))
        
        f_mean = 0
        prec_mean = 0
        rec_mean = 0
        c_mean = 0
        p_mean = 0
        g_mean = 0
	
	# kontrola, zda se pro kazdou nahravku nalezne anotace, a obracene (+ ulozeni nazvu nesparovanych nahravek/anotaci),
	# zachovani pouze dvojic nahravka+anotace
        for song_detected in [x for x in list_of_btdet]:
            if song_detected not in list_of_annotations:
                list_of_btdet.remove(song_detected)
                missing_anots.append(song_detected)
        list_of_btdet.sort()
        for anot_detected in [x for x in list_of_annotations]:
            if anot_detected not in list_of_btdet:
                list_of_annotations.remove(anot_detected)
                missing_songs.append(anot_detected)
        list_of_annotations.sort()

        for l in range(len(list_of_annotations)):
            if list_of_annotations[l] != list_of_btdet[l]:
                print('K nahravce '+ list_of_btdet[l].split('.')[0] + ' nenalezena anotace!')
                continue
            else:
 		# nacteni anotace a nahravky a vypocet hodnoticich velicin
                anot = np.loadtxt('/'.join((anot_path, list_of_annotations[l])))
                btdet = np.loadtxt('/'.join(('outputs', used_libraries[k], list_of_btdet[l])))
                # tmp1, resR = fx.evaluate(btdet, anot)     #realtivni odchylky
                fscore = fx.vseOnset(btdet, anot, win=fwin)  #Fscore, precision, recall
                f_mean += fscore[0]
                prec_mean += fscore[1]
                rec_mean += fscore[2]
                c = fx.cemgil(btdet, anot, sig=sig)          #cemgil
                c_mean += c[0]
                g = fx.goto(btdet, anot)            #goto
                g_mean += g
                p = fx.pscore(btdet, anot, th=th)          #Pscore
                p_mean += p
                kam = ''.join(('results/', used_libraries[k]))
                # fx.ulozto(kam, songs[l], '_relativeErrs.txt', resR)
                os.makedirs(kam, exist_ok=True)
                souborRes2 = ''.join((kam, '/', list_of_btdet[l].split('.')[0], '_evaluated.txt'))

                with open(souborRes2, 'w+') as file:
		    # zapis vsech vysledku pro danou knihovnu a nahravku do souboru 
                    file.write('F-score:\n')
                    file.write('%.2f %%' % (fscore[0]*100))
                    file.write('\n\nPrecision:\n')
                    file.write('%.2f %%' % (fscore[1]*100))
                    file.write('\n\nRecall:\n')
                    file.write('%.2f %%' % (fscore[2]*100))
                    file.write('\n\nCemgil:\n')
                    file.write('%.2f %%' % (c[0]*100))
                    file.write('\n\nP-score:\n')
                    file.write('%.2f %%' % (p*100))
                    file.write('\n\nGoto:\n')
                    file.write('%.1f ' % g)
	
	# krkolomne dvojite ukladani prumeru vysledku, jednou do seznamu, podruhe do slovniku, pro dalsi zpracovani
        f_means.append(f_mean/len(list_of_annotations)*100)
        prec_means.append(prec_mean / len(list_of_annotations) * 100)
        rec_means.append(rec_mean / len(list_of_annotations) * 100)
        c_means.append(c_mean / len(list_of_annotations) * 100)
        p_means.append(p_mean / len(list_of_annotations) * 100)
        g_means.append(g_mean / len(list_of_annotations) * 100)

        f_means_dic[used_libraries[k]] = f_mean / len(list_of_annotations) * 100
        prec_means_dic[used_libraries[k]] = prec_mean / len(list_of_annotations) * 100
        rec_means_dic[used_libraries[k]] = rec_mean / len(list_of_annotations) * 100
        c_means_dic[used_libraries[k]] = c_mean / len(list_of_annotations) * 100
        p_means_dic[used_libraries[k]] = p_mean / len(list_of_annotations) * 100
        g_means_dic[used_libraries[k]] = g_mean / len(list_of_annotations) * 100
        resultfile = ('results/' + used_libraries[k] + '_results.txt')

	# zapis vsech vysledku pro danou knihovnu na celem datasetu
        with open(resultfile, 'w') as file:
            file.write('CELKOVE VYSLEDKY:\n\n')
            file.write('F-score:\n')
            file.write('%.2f %%' % (f_mean/len(list_of_annotations)*100))
            file.write('\n\nPrecision:\n')
            file.write('%.2f %%' % (prec_mean / len(list_of_annotations)*100))
            file.write('\n\nRecall:\n')
            file.write('%.2f %%' % (rec_mean / len(list_of_annotations)*100))
            file.write('\n\nCemgil:\n')
            file.write('%.2f %%' % (c_mean / len(list_of_annotations) * 100))
            file.write('\n\nP-score:\n')
            file.write('%.2f %%' % (p_mean / len(list_of_annotations) * 100))
            file.write('\n\nGoto:\n')
            file.write('%.1f ' % (g_mean / len(list_of_annotations)))

    # vykresleni peti sloupcovych grafu
    fx.eval_subplot([f_means, prec_means, rec_means, c_means, p_means], used_libraries,
                    ['F-score', 'Precision','Recall','Cemgil score','P-score'])
    
    # funkce vraci slovnik slovniku vysledku
    return {'F-score':f_means_dic, 'Cemgil score': c_means_dic, 'Precision':prec_means_dic, 'Recall': rec_means_dic, 'Goto': g_means_dic, 'P-score': p_means_dic}, missing_songs, missing_anots


if __name__ == '__main__':
    main(audio_path='audio', anot_path='annotations', fwin=0.05, sig=0.04, th=0.2)
