from defs import paths as pt
from defs import stats
import numpy as np
import pandas as pd
import os

import matplotlib.pyplot as plt
import sklearn
import matplotlib

matplotlib.use('Agg')

print('*start*')
# vytvori cesty pro jednotlive metody klastrovani
if not os.path.exists('data/kmeans'):
    os.makedirs('data/kmeans')
if not os.path.exists('data/affi'):
    os.makedirs('data/affi')
if not os.path.exists('data/spec'):
    os.makedirs('data/spec')
names = pt.listdir('data/_wavs')

for i, name in enumerate(names):
    fts_sts = stats.FeatsStats()
    fts_sts.load('data/' + pt.stat(name))
    # soubor parametru je omezen na smerodatnou odchyvlku a mir parametry podle vysledku korelace
    stdevs, nms = fts_sts.get_stdev(set='corr')

    if i == 0:
        matrix = stdevs
    else:
        matrix = np.vstack((matrix, stdevs))

lbls = ('RMS [-]', 'BPM [-]', 'SPEKTRALNI CENTROID [-]', 'PULZACE [-]', 'VYSKA TONU [-]', 'MFCC03 [-]',
          'MFCC06 [-]', 'MFCC07 [-]', 'MFCC08 [-]', 'MFCC09 [-]', 'MFCC10 [-]', 'MFCC11 [-]', 'MFCC12 [-]')

# trijita iterace postupuje tak aby se kombinoval kazdy parametr s kazdym ale ne sam se sebou a pouze jednou
# jsou pouzity metody kmeans, affinity propagation a spectral clustering
# kmeans a spectral clustering maji pevne nastaveny pocet trid
paths = ('data/kmeans/', 'data/affi/', 'data/spec/')
for path in paths:
    for n in range(len(matrix.T)):
        for i in range(n, len(matrix.T)):
            if n == i:
                continue
            else:
                obs = np.vstack((matrix[:, n], matrix[:, i]))
                name_x = nms[n]
                name_y = nms[i]
                # parametry jsou skalovany od -1 do 1
                min_max_scaler = sklearn.preprocessing.MinMaxScaler(feature_range=(-1, 1))
                features_scaled = min_max_scaler.fit_transform(obs.T)

                if path == 'data/kmeans/':
                    model = sklearn.cluster.KMeans(n_clusters=3, random_state=None)

                elif path == 'data/affi/':
                    model = sklearn.cluster.AffinityPropagation(random_state=None)

                else:
                    model = sklearn.cluster.SpectralClustering(n_clusters=3, random_state=None)

                labels = model.fit_predict(features_scaled)

                # prislusnost k tride a skalovana hodnota parametru se uklada do csv souboru
                pd.DataFrame({'wav': names,
                              'label': labels,
                              name_x: features_scaled[:, 0],
                              name_y: features_scaled[:, 1]
                              }).to_csv(path+name_x+'_'+name_y+'.csv', index=False)

                fig = plt.figure()
                # tridy odpovidaji barvam, RGBCMYKOB
                plt.scatter(features_scaled[labels == 0, 0], features_scaled[labels == 0, 1], c='r')
                plt.scatter(features_scaled[labels == 1, 0], features_scaled[labels == 1, 1], c='g')
                plt.scatter(features_scaled[labels == 2, 0], features_scaled[labels == 2, 1], c='b')
                plt.scatter(features_scaled[labels == 3, 0], features_scaled[labels == 3, 1], c='c')
                plt.scatter(features_scaled[labels == 4, 0], features_scaled[labels == 4, 1], c='m')
                plt.scatter(features_scaled[labels == 5, 0], features_scaled[labels == 5, 1], c='y')
                plt.scatter(features_scaled[labels == 6, 0], features_scaled[labels == 6, 1], c='k')
                plt.scatter(features_scaled[labels == 7, 0], features_scaled[labels == 7, 1], c='tab:orange')
                plt.scatter(features_scaled[labels == 8, 0], features_scaled[labels == 8, 1], c='tab:brown')
                plt.xlabel(lbls[n])
                plt.ylabel(lbls[i])
                # vysledek se uklada jako xy graf do souboru
                plt.savefig(path+name_x+'_'+name_y+'.png')
                plt.close(fig)
                fig.clf()
                print('Tisk ' + path + str(name_x) + '_' + str(name_y)+'.png')
