import os
import itertools
import csv
import numpy as np
from sklearn import preprocessing
from sklearn.preprocessing import normalize
from sklearn.feature_selection import RFE
from sklearn.svm import SVR
from sklearn import neighbors, datasets
from imblearn.under_sampling import     EditedNearestNeighbours
from gamera.core import *
from gamera.toolkits.musicstaves import *
from gamerafeatures import Gamerafeatures
from gamera.core import Dim, FloatPoint, RGBPixel
from sklearn.svm import SVC
from sklearn.model_selection import StratifiedKFold
from sklearn.feature_selection import RFECV
from sklearn.datasets import make_classification


init_gamera()
names = []
with open('featurerssep.csv', 'r') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=',', quotechar='"')
    data = []
    ystr = []
    for i, row in enumerate(spamreader):
        items = []
        if i == 0:
            names = row
            names.remove(names[0])
        else:
            for j, item in enumerate(row):
                if j == 0:
                    ystr.append(item)
                else:
                    items.append(float(item))
        if items:
            data.append(items)

dicty = {}
revdict = {}
ynum = []
i=0
for s in ystr:
    if s in dicty:
        dicty[s][1] = dicty[s][1] + 1
        ynum.append(dicty[s][0])
    else:
        i = i + 1
        dicty[s] = [i, 1]
        revdict[i] = s
        ynum.append(dicty[s][0])
#
#print numy
#print y

x = np.array(data)
y = np.array(ynum)

xxnames = [50, 31, 27,  7, 29, 39, 25, 19,  1, 34, 23, 30, 17, 13, 20,  1, 28,  1,  3, 46,  9, 38, 12, 41, 18, 6, 45,  1, 51,  1,  1, 26, 42,  1, 14, 22, 21, 40, 35, 24,  1,  8, 44, 15, 33, 37, 16, 47, 49, 32, 36,  1, 48,  1,  4,  1,  1, 43,  5,  2,  1, 11,  1, 10,  1]
select = [i for i,v in enumerate(xxnames) if v < 5]

xt = x.T[select]
x= xt.T

min_max_scaler = preprocessing.MinMaxScaler()
min_max_scaler.fit_transform(x)
scaled = min_max_scaler.transform(x)


crosspercent = 0.08
crossnum = int(crosspercent*len(y))
rand = int(os.urandom(4).encode('hex'), 16)
np.random.seed(rand)

print "estimate"
indices = np.random.permutation(len(scaled))
X_train = scaled[indices[:-crossnum]]
y_train = y[indices[:-crossnum]]
X_test  = scaled[indices[-crossnum:]]
y_test  = y[indices[-crossnum:]]

xlearn =  scaled[indices]
ylearn =  y[indices]

n_neighbors = 7

print names




## Create the RFE object and compute a cross-validated score.
## The "accuracy" scoring is proportional to the number of correct
## classifications
#estimator = SVR(kernel="linear")
#selector = RFE(estimator, 15, step=1, verbose=10)
#selector = selector.fit(xlearn, ylearn)
#print selector.ranking_

#for weights in ['uniform', 'distance']:
#    clf = neighbors.KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
#               metric_params=None, n_jobs=1, n_neighbors=n_neighbors, weights=weights, p=2)
#    clf.fit(X_train, y_train)
#
#    print clf.predict(X_test) - y_test
#
#enn = EditedNearestNeighbours(random_state=42, n_neighbors=n_neighbors)
#X_res, y_res = enn.fit_sample(X_train, y_train)
#
#
#
#for weights in ['uniform', 'distance']:
#    clf = neighbors.KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
#               metric_params=None, n_jobs=1, n_neighbors=n_neighbors, weights=weights, p=2)
#    clf.fit(X_res, y_res)
#
#    print clf.predict(X_test) - y_test

test = []
image = load_image('C:/Users/Radim/OneDrive/Documents/Projects/notes/OMRnotes/tests/notes/79a5904e-8f3b-44cd-9235-b2da79f4975d.png')
imgbin = image.to_onebit()
angle, rotation_angle_and_accuracy1 = imgbin.rotation_angle_projections(-2.5, 2.5, 0.0)
imgrot = image.rotate(angle, None, 1)
imgbinrot = imgrot.to_onebit()
musicstaves0 = imgbinrot.MusicStaves_linetracking(staffline_height=0, staffspace_height=0)
scale = (20 / float(musicstaves0.staffspace_height + musicstaves0.staffline_height))
imgscale = imgrot.scale(scale, 0)
imgbinscale = imgscale.to_onebit()
musicstaves1 = imgbinscale.MusicStaves_linetracking(staffline_height=0, staffspace_height=0)
musicstaves1.remove_staves(u'all', 5, u'runlength', 0, 0)
musicstaves1_image0 = musicstaves1.image.image_copy()
imgrgb = musicstaves1_image0.to_rgb()
seg = musicstaves1_image0.cc_analysis()

bgf = Gamerafeatures(Image([0,0], [1,1]))
#bgf.disableallfeatures()
#bgf.modifyfeature("moments", True, 7)
#bgf.modifyfeature("moments", True, 8)
#bgf.modifyfeature("nholes", True, 1)
#bgf.modifyfeature("nholes_extended", True, 1)
#bgf.modifyfeature("nholes_extended", True, 2)
#bgf.modifyfeature("nholes_extended", True, 7)
#bgf.modifyfeature("skeleton_features", True, 1)
#bgf.modifyfeature("top_bottom", True, 1)
#bgf.modifyfeature("volume16regions", True, 0)
#bgf.modifyfeature("volume16regions", True, 4)
#bgf.modifyfeature("volume16regions", True, 15)

bgf.disableallfeatures()
for n in names:
    namesplit = n.split('#')
    if namesplit[0] in bgf.names:
        bgf.modifyfeature(namesplit[0], True, int(namesplit[1]))
    else:
        print 'undefined feature'


sch = [s for s in seg if s.nrows > 10 and s.ncols > 10]
for s in sch:
    bg = Gamerafeatures(s, bgf.enabler)
    sstr = bg.getdata()
    row = []
    for sx in sstr:
        row.append(float(sx))
    test.append(row)

testnp = np.array(test)
tt= testnp.T[select]
testnp = tt.T
scaledtest = min_max_scaler.transform(testnp)

clf = neighbors.KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
               metric_params=None, n_jobs=1, n_neighbors=n_neighbors, weights='uniform' , p=2)
clf.fit(xlearn, ylearn)
predict = clf.predict(scaledtest)


for i, s in enumerate(sch):
    imgrgb.draw_text(FloatPoint(s.ul_x, s.ul_y), str(revdict[predict[i]]),
                                     RGBPixel(255, 0, 0), 6, 2, False, True, 0)

imgrgb.save_PNG("class.png")

print len(dicty)
print len(y)



#print scaled[0]
