import time, sys, os, configparser, re, codecs
from pyfasttext import FastText #windows版ではコメントアウト
import numpy as np
#import gensim
from operator import itemgetter

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)

from word_count_window import Word_Count
from word_count_window import count

class MyModel(QAbstractItemModel):
    headers = '類似語', '類似度'
    items = []

    def __init__(self, parent=None):
        super().__init__()

    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, res):
        self.beginInsertRows(QModelIndex(), len(self.items), 1)
        #self.items.insert(0,(labe, prediction, text))
        self.items.append((res))
        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

class Word_Addition_SubWindow(QWidget):
    def __init__(self, project, model):
        super(Word_Addition_SubWindow, self).__init__()

        g = open("window_temp.txt","w")
        g.write("0")
        g.close()

        self.project = project
        self.model2 = model
        self.word_addition_subwindow()

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

        radio_h_box=QHBoxLayout()

        radio_v_box = QVBoxLayout()
        self.content_word = QRadioButton("内容語") #基本形を使用
        self.all_word = QRadioButton("全出現語")  #表層形を使用
        self.content_word.toggle()
        self.button_group = QButtonGroup()
        self.button_group.addButton(self.content_word)
        self.button_group.addButton(self.all_word)
        radio_v_box.addWidget(self.content_word)
        radio_v_box.addWidget(self.all_word)

        count_v_box = QVBoxLayout()
        count_h_box = QHBoxLayout()
        text_label = QLabel("出現回数")
        self.min = QLineEdit()
        self.min.setToolTip("参照する単語の最低出現回数を設定してください")
        self.min.setText("5")
        count_label = QLabel("回以上")
        count_h_box.addWidget(text_label)
        count_h_box.addStretch(2)
        count_h_box.addWidget(self.min)
        count_h_box.addWidget(count_label)

        button=QPushButton("頻出語の参照")
        button.setFocusPolicy(Qt.NoFocus)
        button.clicked.connect(lambda: self.showD(self.w, self.project))

        count_v_box.addLayout(count_h_box)
        count_v_box.addWidget(button)

        radio_h_box.addLayout(radio_v_box)
        radio_h_box.addStretch(1)
        radio_h_box.addLayout(count_v_box)

        cal_h_box=QHBoxLayout()
        self.res_label=QLabel("計算式")
        self.formula=QLineEdit()  #修了後調整
        self.formula.setToolTip("単語や記号の間はスペースで区切ってください")
        self.cal_button=QPushButton("計算")
        cal_h_box.addWidget(self.res_label)
        cal_h_box.addWidget(self.formula)
        cal_h_box.addWidget(self.cal_button)
        self.cal_button.clicked.connect(self.calcuration)

        cal_v_box=QVBoxLayout()
        caution=QLabel("※　計算式を入力する際には、単語や「＋」「−」の間をスペースで区切ってください<br>例）　wordA + wordB - wordC")
        cal_v_box.addLayout(cal_h_box)
        cal_v_box.addWidget(caution)

        self.model=MyModel(self)
        self.view=View()
        self.view.setModel(self.model)
        self.view.setUniformRowHeights(True)
        self.view.setColumnWidth(0, 170)
        self.view.setColumnWidth(1, 170)

        main_v_layout=QVBoxLayout()

        close_h_box=QHBoxLayout()
        close_button = QPushButton("閉じる", self)
        close_button.clicked.connect(self.exit)
        close_h_box.addStretch(1)
        close_h_box.addWidget(close_button)

        self.formula_pos=QLabel()
        self.formula_neg=QLabel()

        main_v_layout.addLayout(radio_h_box)
        #main_v_layout.addLayout(cal_h_box)
        main_v_layout.addLayout(cal_v_box)
        main_v_layout.addWidget(self.view)
        main_v_layout.addWidget(self.formula_pos)
        main_v_layout.addWidget(self.formula_neg)
        main_v_layout.addLayout(close_h_box)


        self.w.setGeometry(300, 300, 500, 550)
        self.w.setWindowTitle("単語の加減算")

        self.w.setLayout(main_v_layout)

    def calcuration(self):
        try:
            self.model.remove_all()

            if self.formula.text() == "":
                pass
            else:
                formula = "+" + self.formula.text()
                formula = formula.replace("　"," ").replace("＋","+")#.replace("ー","-")
                formula = formula.replace(" + "," +")
                formula = formula.replace(" - "," -").replace(" ー "," -")

                #formula = re.sub('[˗֊‐‑‒–⁃⁻₋−﹣－ｰ—―─━ーー]+', '-', formula)

                #formula = formula.replace("+"," +").replace("-", " -")
                formula = formula.split(" ")

                pos=[]
                neg=[]

                #print(formula)

                for n in formula:
                    if n == "":
                        pass
                    else:
                        n = n.replace("+", "+ ").replace("-", "- ")
                        n = n.split(" ")

                        if n[0] == "+":
                            pos.append(n[1])
                        else:
                            neg.append(n[1])

                #print(pos)BGM　ー　amp　＋　BBQ
                #print(neg)
###############################################################################
#windows用:gensim
#                dec = pos + neg

#                path = os.getcwd() + "/fasttext/" + self.project + ".vec"
#                model = gensim.models.KeyedVectors.load_word2vec_format(path, binary=False)

#                pos_vec=np.asarray(model[pos[0]])
#                pos_vec.flags.writeable = True
#                pos.pop(0)
#                for n in pos:
#                    array_n=np.asarray(model[n])
#                    pos_vec += array_n

#                for n in neg:
#                    array_n = np.asarray(model[n])
#                    pos_vec -= array_n

#                a = model.most_similar([pos_vec],[],15)

#                res=[]
#                for n in a:
#                    for i in dec:
#                        if n[0] == i:
#                            res.append(n)
#                        else:
#                            pass

#                for n in res:
#                    a.remove(n)

#                del a[10:]

#                for n in a:
#                    if n[0] =="</s>":
#                        pass
#                    else:
#                        self.model.addRow(n)

###############################################################################
################windows用:my calcuration

                if os.name == "nt":
                    dec = pos + neg

                    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)

                    pos_vec = word_array[pos[0]]

                    pos_vec.flags.writeable = True
                    pos.pop(0)
                    for n in pos:
                        array_n=word_array[n]
                        pos_vec += array_n

                    for n in neg:
                        array_n=word_array[n]
                        pos_vec -= array_n

                    content_check = 0
                    min_word = 1
                    all_words = count(self.project, content_check, min_word).word_list

                    all_word=[]
                    for n in all_words:
                        all_word.append(n[0])

                    for n in dec:
                        all_word.remove(n)

                    v1a=pos_vec

                    res=[]
                    for n in all_word:
                        try:
                            v2a=word_array[n]
                            result=(np.dot(v1a,v2a) / (np.linalg.norm(v1a) * np.linalg.norm(v2a)))
                            a=(n, result)
                            res.append(a)
                        except:
                            pass

                    res.sort(key=itemgetter(1), reverse=True)
                    res=res[0:15]

                    for n in res:
                        if n[0] =="</s>":
                            pass
                        else:
                            wo=n[0]
                            num=float(n[1])
                            a=(wo,num)
                            self.model.addRow(a)
        #                        print(a)

                else:
                    #pass   #Windows版で使用
###############################################################################
#pyfasttext
#                    path2 = os.getcwd() + "/fastText/" + self.project + ".bin"
#                    model2 = FastText(path2)
                    model2 = self.model2

                    res=model2.most_similar(positive=pos, negative=neg, k=10)
                    for n in res:
                        self.model.addRow(n)

###############################################################################

            self.formula_pos.setText("Positive word: " + str(pos))
            self.formula_neg.setText("Negative word: " + str(neg))

        except:
            #print("登録されている単語を使用してください")
            message=QMessageBox.information(self,"お知らせ", "登録されている単語を使用してください", QMessageBox.Ok)

    def showD(self, w, project):

        cfg=configparser.ConfigParser()
        file_path = project + ".ini"
        cfg.read(file_path)
        original_data_type=cfg['project']["original_data_type"]

        if int(original_data_type) == 1:
            #print("このプロジェクトでは使用できません")
            message=QMessageBox.information(self,"お知らせ", "このプロジェクトでは使用できません", QMessageBox.Ok)
        else:
            g = open("window_temp.txt","r")
            p=g.readline()
            g.close()

            if p == "0":
                content_word_check = 0
                if self.content_word.isChecked() == True:
                    content_word_check=0
                else:
                    content_word_check=1

                Word_Count(w, project, content_word_check, self.min.text())

            elif p == "1":
                #print("すでにウィンドウが開かれています")
                message=QMessageBox.information(self,"お知らせ", "すでにウィンドウが開かれています", QMessageBox.Ok)
            else:
                #print("error")
                message=QMessageBox.information(self,"お知らせ", "error", QMessageBox.Ok)

    def closeEvent(self, event):
        os.remove("./window_temp.txt")
        time.sleep(0.1)
        self.model.remove_all()
        self.w.close()

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

    def exit(self):
        os.remove("./window_temp.txt")
        time.sleep(0.1)
        self.model.remove_all()
        self.w.close()




if __name__=="__main__":
    app=QApplication(sys.argv)
    project="allsentence"
    Word_Addition_SubWindow(project).show()
    sys.exit(app.exec_())
