import sys, os, csv, configparser, codecs, platform
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.ticker as tick
import matplotlib.font_manager as fm
import pandas as pd
from pyfasttext import FastText #windows版ではコメントアウト
from operator import itemgetter
from statistics import variance
#import gensim
from PIL import Image  #使う
from matplotlib.font_manager import FontProperties

from PyQt5.QtWidgets import (QVBoxLayout, QLineEdit,QGridLayout,
 QApplication, QLabel, QMenu, QWidget, QHBoxLayout,QDialog,
 QAction, QTextEdit,QPushButton, qApp, QMessageBox, QInputDialog,
 QMainWindow, QFrame, QFileDialog, QCheckBox, QProgressBar,
 QListWidget, QCompleter, QComboBox, QTreeView,QAbstractItemView,
 QToolTip,QRadioButton,QButtonGroup)
from PyQt5.QtGui import (QIcon, QFont, QColor, QPixmap, QDrag, QPainter,
 QBrush, QPen,QStandardItem,QStandardItemModel,)
from PyQt5.QtCore import (QCoreApplication, Qt, QObject, pyqtSignal,
 QMimeData, QAbstractItemModel,QModelIndex)

import matplotlib as mpl
from matplotlib.font_manager import FontProperties

from main_config import main_Config
#font = {"family":"Noto Sans CJK JP"}
#mpl.rc('font', **font)

class Cognitive_map_result_SubWindow(QWidget):
    def __init__(self, project, word_a, word_b):
        super().__init__()

#        config=configparser.ConfigParser()
#        config.read('main.ini')
#        self.using_os=config['settings']["os"]
        self.mysql_id, self.mysql_pass, self.projects, self.root_path, self.using_os = main_Config()

        self.project = project
        self.wordA = word_a
        self.wordB = word_b
        self.x_label = ""
        self.y_label = ""

        self.cognitive_map_result_window()

        self.all_cosine_simirality()
        #self.test()



    def cognitive_map_result_window(self):
        self.w=QDialog()

        self.model=MyModel(self.project, self.wordA, self.wordB)
        self.view=View()
        self.view.setModel(self.model)
        self.view.setUniformRowHeights(True)
        self.view.setColumnWidth(0, 150)

        words_h_box=QHBoxLayout()

        x_axis_v_box=QVBoxLayout()
        x_axis_box=QHBoxLayout()
        x_axis_add_button=QPushButton("▼")
        x_axis_box.addStretch(1)
        x_axis_box.addWidget(x_axis_add_button)
        x_axis_box.addStretch(1)
        x_axis_word_box=QHBoxLayout()
        x_axis_label=QLabel("X軸の単語")
        self.x_axis_word=QLineEdit()
        x_axis_word_box.addWidget(x_axis_label)
        x_axis_word_box.addWidget(self.x_axis_word)
        x_axis_v_box.addLayout(x_axis_box)
        x_axis_v_box.addLayout(x_axis_word_box)
        x_axis_add_button.clicked.connect(self.add_x)

        y_axis_v_box=QVBoxLayout()
        y_axis_box=QHBoxLayout()
        y_axis_add_button=QPushButton("▼")
        y_axis_box.addStretch(1)
        y_axis_box.addWidget(y_axis_add_button)
        y_axis_box.addStretch(1)
        y_axis_word_box=QHBoxLayout()
        y_axis_label=QLabel("Y軸の単語")
        self.y_axis_word=QLineEdit()
        y_axis_word_box.addWidget(y_axis_label)
        y_axis_word_box.addWidget(self.y_axis_word)
        y_axis_v_box.addLayout(y_axis_box)
        y_axis_v_box.addLayout(y_axis_word_box)
        y_axis_add_button.clicked.connect(self.add_y)

        center=QLabel("×")

        words_h_box.addLayout(x_axis_v_box)
        #words_h_box.addStretch(1)
        #words_h_box.addWidget(center)
        #words_h_box.addStretch(1)
        words_h_box.addLayout(y_axis_v_box)

        csv_h_box=QHBoxLayout()
        plot_button=QPushButton("プロット")
        csv_push_button=QPushButton("csvで出力")
        close_button=QPushButton("閉じる")
        csv_h_box.addStretch(2)
        if os.name == "nt":
            pass
        else:
            csv_h_box.addWidget(plot_button)
        csv_h_box.addWidget(csv_push_button)
        csv_h_box.addWidget(close_button)
        plot_button.clicked.connect(self.plot)
        close_button.clicked.connect(self.w.close)
        csv_push_button.clicked.connect(self.make_csv)

        main_layout=QVBoxLayout()
        main_layout.addWidget(self.view)
        main_layout.addLayout(words_h_box)
        main_layout.addLayout(csv_h_box)

        self.w.setGeometry(700, 300, 800, 650)
        self.w.setWindowTitle('知覚マップの候補一覧')

        self.w.setLayout(main_layout)

    def make_csv(self):
        header = tuple(self.model.headers)
        content = self.model.items
        #print(header)
        #print(content)
        alls=[]
        alls.append(header)
        alls.extend(content)
        #print(alls)

        if len(content) == 0:
            message=QMessageBox.information(self,"お知らせ", "保存するデータがありません", QMessageBox.Ok)
            #print("保存するデータがありません")
        else:
            try:
                folder_path = folder_path = os.getcwd()
                ########################################################
                frame=QFileDialog.getSaveFileName(self, "保存フォルダーの選択", folder_path,filter=("csv files(*.csv)"))
                ########################################################
                save_file_path = frame[0]# + ".csv"

                system_os = platform.system()
                if system_os == "Darwin":
                    f = open(save_file_path, "w", encoding='utf-16')
                    write = csv.writer(f, dialect='excel-tab', lineterminator='\n')
                    write.writerows(alls)
                    f.close()
                elif os.name == "nt":
                    f = open(save_file_path, "w", encoding='utf-16')
                    write = csv.writer(f, dialect='excel-tab', lineterminator='\n')
                    write.writerows(alls)
                    f.close()
                else:
                    f = open(save_file_path, "w", encoding='utf-8')
                    write = csv.writer(f, lineterminator='\n')
                    write.writerows(alls)
                    f.close()
            except Exception as e:
                print(e)

    def plot(self):
        if self.x_label == "" or self.y_label == "":
            pass
        else:
            system_os = platform.system()
            if system_os == "Darwin":
                fp = FontProperties(fname=r'/System/Library/Fonts/ヒラギノ明朝 ProN.ttc')

                x=np.array(self.x_label)
                y=np.array(self.y_label)
                indexA=self.wordA
                df = pd.DataFrame({'x':x, 'y':y}, index=indexA)
                fig, ax = plt.subplots()
                df.plot('x', 'y', kind='scatter', ax=ax)
                plt.xlim(-1,1)
                plt.ylim(-1,1)
                plt.xlabel(self.x_axis_label, fontproperties=fp)
                plt.ylabel(self.y_axis_label, fontproperties=fp)
                plt.title(self.x_axis_label + " - "+  self.y_axis_label, fontproperties=fp)
                xmin, xmax = -1, 1
                plt.hlines([0],xmin,xmax)
                ymin, ymax = -1, 1
                plt.vlines([0],ymin,ymax)

                for k, v in df.iterrows():
                    ax.annotate(k, v, fontproperties=fp)

                plt.grid()
                plt.savefig(self.x_axis_label + " - "+  self.y_axis_label + ".png")
                img = Image.open(self.x_axis_label + " - "+  self.y_axis_label + ".png")
                img.show()


            elif self.using_os == "posix":

                #mpl.rcParams['font.family'] =  "TakaoExMincho"
                font_path = "/usr/share/fonts/truetype/takao-gothic/TakaoPGothic.ttf"
                font_prop = FontProperties(fname=font_path)
                mpl.rcParams['font.family'] = font_prop.get_name()

                x=np.array(self.x_label)
                y=np.array(self.y_label)
                indexA=self.wordA
                df = pd.DataFrame({'x':x, 'y':y}, index=indexA)
                fig, ax = plt.subplots()
                df.plot('x', 'y', kind='scatter', ax=ax)
                #plt.xlim(-1,1)
                #plt.ylim(-1,1)
                plt.xlabel(self.x_axis_label)
                plt.ylabel(self.y_axis_label)
                plt.title(self.x_axis_label + " - "+  self.y_axis_label)
                #xmin, xmax = -1, 1
                #plt.hlines([0],xmin,xmax)
                #ymin, ymax = -1, 1
                #plt.vlines([0],ymin,ymax)

                for k, v in df.iterrows():
                    ax.annotate(k, v)

                plt.grid()
                plt.show()

            elif self.using_os == "nt":
                fp = FontProperties(fname=r'C:/WINDOWS/Fonts/yumin.ttf')

                x=np.array(self.x_label)
                y=np.array(self.y_label)
                indexA=self.wordA
                df = pd.DataFrame({'x':x, 'y':y}, index=indexA)
                fig, ax = plt.subplots()
                df.plot('x', 'y', kind='scatter', ax=ax)
                plt.xlim(-1,1)
                plt.ylim(-1,1)
                plt.xlabel(self.x_axis_label, fontproperties=fp)
                plt.ylabel(self.y_axis_label, fontproperties=fp)
                plt.title(self.x_axis_label + " - "+  self.y_axis_label, fontproperties=fp)
                xmin, xmax = -1, 1
                plt.hlines([0],xmin,xmax)
                ymin, ymax = -1, 1
                plt.vlines([0],ymin,ymax)

                for k, v in df.iterrows():
                    ax.annotate(k, v, fontproperties=fp)

                plt.grid()
                plt.show()

    def add_x(self):
        for index in self.view.selectedIndexes():
            if index.column() == 0:
                n = index.row()
                self.x_axis_word.setText((self.model.items[n])[0])
                self.x_axis_label=(self.model.items[n])[0]
                self.x_label=self.model.items[n]
                self.x_label=list(self.x_label)
                #print(self.x_label)
                del self.x_label[0]
                del self.x_label[0]
                self.x_label=tuple(self.x_label)
                #print(self.x_label)


    def add_y(self):
        for index in self.view.selectedIndexes():
            if index.column() == 0:
                n = index.row()
                self.y_axis_word.setText((self.model.items[n])[0])
                self.y_axis_label=(self.model.items[n])[0]
                self.y_label=self.model.items[n]
                self.y_label=list(self.y_label)
                #print(self.y_label)
                del self.y_label[0]
                del self.y_label[0]
                self.y_label=tuple(self.y_label)
                #print(self.y_label)


#    def test(self):
#        path = os.getcwd() + "/fasttext/" + project + ".bin"
#        model = FastText(path)

#        cos = model.similarity('ディズニーシー', '並ぶ')
#        print(cos)


    def all_cosine_simirality(self):


        all_word=[]

        labels_in_all_word=[]
        labels_in_all_word.append("")
        for n in self.wordA:
            labels_in_all_word.append(n)    #"表の頭にラベルをつける"
        self.label_name=tuple(labels_in_all_word)

        for wordb in self.wordB:
            #print(wordb)
            each_word=[]
            each_word.append(wordb)
            all_cos=[]
            for worda in self.wordA:
############################################################
################windows用:gensim
#                path = os.getcwd() + "/fasttext/" + self.project + ".vec"
#                model = gensim.models.KeyedVectors.load_word2vec_format(path, binary=False)

#                v1a=model[wordb]

#                v1a=np.asarray(v1a)
#                v2a=model[worda]
                #print("gensim", worda,v2a)
#                v2a=np.asarray(v2a)
#                vss=v1a+v2a
#                cos=float(np.dot(v1a,v2a) / (np.linalg.norm(v1a) * np.linalg.norm(v2a)))
############################################################
################windows用:my calcuration
                if os.name == "nt":
                    path = os.getcwd() + "/fastText/" + self.project + ".vec"
                    f = codecs.open(path, 'r', 'utf-8')
                    reader=f.readlines()
                    f.close()

                    cfg=configparser.ConfigParser()
                    file_path = self.selected_project + ".ini"
                    cfg.read(file_path)
                    dimensions=int(cfg['project']["dimensions"])

                    word_array = {}
                    for i, n in enumerate(reader):
                        if i == 0:
                            pass
                        else:
                            n = n.split(" ")
                            vec=n[1:dimensions + 1]

                            vector=[]
                            label=n[0]
                            for j in vec:
                                j=float(j)
                                vector.append(j)

                            vector=tuple(vector)
                            vector=np.asarray(vector)
                            a={label:vector}
                            word_array.update(a)

                    if (worda in word_array.keys()) == False or (wordb in word_array.keys()) == False:  #vecファイルに存在しない単語は０を表示
                        cos=int(0)
                    else:
                        v1a=word_array[worda]
                        v2a=word_array[wordb]
                        cos=float(np.dot(v1a,v2a) / (np.linalg.norm(v1a) * np.linalg.norm(v2a)))
                        #print("A",worda,"B",wordb,"C",v1a,"D",v2a,"E",cos)
                        #print(self.result)

                else:
                    #pass #windows版で使用
############################################################
################pyfasttext用
                    path = os.getcwd() + "/fastText/" + self.project + ".bin"
                    model = FastText(path)
                    #print(worda,model[worda])

                    cos = model.similarity(wordb, worda)
############################################################
                all_cos.append(cos)

            data=np.array(all_cos)
            #print(data)
            var=np.var(data)
            #print(var)
            #var=var.set_printoptions(precision=5, suppress=True)
            #print(round(float(var), 6))
            #data=list(data)
            #print(type(all_cos))
            #print(all_cos)
            #var=variance(data)
            #print(var)
            if var < 0.0001:
                var = "0 or ≒ 0"
            else:
                pass
            each_word.append(str(var))
            each_word.extend(all_cos)
            all_word.append(tuple(each_word))

        all_word.sort(key=itemgetter(1), reverse=True)

        for n in all_word:
            self.model.addRow(n)

    def show(self):
        self.w.exec_()


class MyModel(QAbstractItemModel):

    #headers = "","",""#head_word
    #items = []

    def __init__(self, project, word_a, word_b):#, parent=None):
        super().__init__()


        a=["","分散"]
        head_word=word_a
        a.extend(head_word)
        self.headers= a
        self.items = []

    def index(self, row, column, parent=QModelIndex()):
        return self.createIndex(row, column, None)

    def parent(self, child):
        return QModelIndex()

    def rowCount(self, parent=QModelIndex()):
        return len(self.items)

    def columnCount(self, parent=QModelIndex()):
        return len(self.headers)

    def data(self, index, role=Qt.DisplayRole):
        if role == Qt.DisplayRole:
            try:
                return self.items[index.row()][index.column()]
            except:
                return
        return

    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if role != Qt.DisplayRole:
            return
        if orientation == Qt.Horizontal:
            return self.headers[section]

    def addRow(self, n):
        #print(n)
        self.beginInsertRows(QModelIndex(), len(self.items), 1)
        #self.items.insert(0,n)
        self.items.append(n)
        self.endInsertRows()

    def remove_all(self):
        self.items.clear()

class View(QTreeView):
    def __init__(self, parent=None):
        super(View, self).__init__(parent)
        self.setItemsExpandable(False)
        self.setIndentation(0)
        #self.setSelectionMode(QAbstractItemView.ExtendedSelection)

    def drawBranches(self, painter, rect, index):
        return


if __name__=="__main__":
    app=QApplication(sys.argv)
    project="catelabetest"
    worda=["ある","楽しい","ます","子供","パンダ"]
    wordb=[ '楽しむ',"広い","タニシ"]
    Cognitive_map_result_SubWindow(project, worda, wordb).show()
    sys.exit(app.exec_())
