import sys, configparser, time, os, configparser, codecs

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)
from PyQt5.QtGui import (QIcon, QFont, QColor, QPixmap, QDrag, QPainter,
 QBrush, QPen,QStandardItem,QStandardItemModel)
from PyQt5.QtCore import (QCoreApplication, Qt, QObject, pyqtSignal,
 QMimeData, )

from open_project import open_project_SubWindow
from new_project import new_project_SubWindow
from new_project_pre import new_project_pre_SubWindow
from new_project_csv import new_project_csv_SubWindow
from pre_process_window import Pre_Processing_SubWindow
from delete_project import delete_project_SubWindow
from distributed_repre_window import distirbuted_SubWindow
from sampling_window import sampling_SubWindow
from similarity_window import Similarity_SubWindow
from similar_word import Similar_word_SubWindow
from distributed_learn_window import distirbuted_learn_SubWindow
from divi_class import Classify_SubWindow
from cognitive_map import Cognitive_map_SubWindow
from cross_category import Cross_Category_SubWindow
from word_addition import Word_Addition_SubWindow
from mysql_start_stop import mysql_Start, mysql_Stop, else_Start, else_Stop
from main_config import main_Config
from startup import setup
from about_vector_to import about_vectot_to_SubWindow


#######################################
#メインウィンドウ
#######################################

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

        #######################################
        #設定ファイルの読み込み
        #######################################
#        con=configparser.ConfigParser()
#        con.read('main.ini')
#        self.mysql_id=con['settings']["id"]
#        self.mysql_pass=config['settings']["pass"]
#        self.projects=config['settings']["projects"].split(",")
#        self.root_path=config['settings']["root_path"]
#        self.using_os=config['settings']["os"]

        open_main_config = codecs.open("main_config","r","utf-8")
        h=open_main_config.read()
        if h == "":
            setup()
        else:
            pass


        self.mysql_id, self.mysql_pass, self.no_use_projects, self.root_path, self.using_os = main_Config()
        self.selected_project=""

        path="./projects_config"
        if os.path.exists(path):
            g = codecs.open("projects_config","r","utf-8")
            h=g.read()
            h=h.replace("\n","").replace("\\","")
            self.projects=h.split(",")
            #print(self.projects)
        else:
            g = codecs.open("projects_config","w","utf-8")
            g.write("")
            g.close()
            self.projects=[]

        time.sleep(0.1)

        g = codecs.open("select_project_temp.txt","w","utf-8")
        g.write("")
        g.close()


        if self.using_os == "nt":   #macとwinはmysqlをプログラムで起動
            mysql_Start()
        else:
            else_Start()

        self.initUI()



############################################################
#GUI
############################################################
    def initUI(self):

        menubar=self.menuBar()
        menubar.setNativeMenuBar(False) #システムメニューバーに表示させないようにする

####################
        fileMenu=menubar.addMenu('プロジェクト')

        openProject=QAction("プロジェクトを開く", self)
        openProject.setStatusTip("プロジェクトを開く")
        openProject.triggered.connect(self.make_open_project)

        newProject=QMenu("新規プロジェクトの作成",self)

        self.pre_learned=QAction("学習済みデータを使用",self)    ############windowsでは使用できない
        self.pre_learned.triggered.connect(self.make_new_project_pre)  ############windowsでは使用できない

        self.learning=QAction("テキストデータを登録",self)
        self.learning.triggered.connect(self.make_new_project)

        self.learning_csv=QAction("ラベル付きCSVデータを登録",self)
        self.learning_csv.triggered.connect(self.make_new_project_csv)

        if self.using_os == "nt":
            pass
        else:
            newProject.addAction(self.pre_learned) ############windowsでは使用できない
        newProject.addAction(self.learning)
        newProject.addAction(self.learning_csv)

        deleteAct=QAction("プロジェクトの削除",self)
        deleteAct.setStatusTip("登録済みのプロジェクトを削除する")
        deleteAct.triggered.connect(self.make_delete_project)

        exitAct=QAction("終了",self)
        exitAct.setStatusTip("アプリケーションを終了する")
        exitAct.triggered.connect(self.button_close)
        exitAct.triggered.connect(qApp.quit)

        fileMenu.addAction(openProject)
        ####fileMenu.addAction(newProject)
        fileMenu.addAction(newProject.menuAction())
        fileMenu.addAction(deleteAct)
        fileMenu.addAction(exitAct)
####################
        pre_process=menubar.addMenu('前処理')#形態素解析、ランダム処理

        morpheme_analysis=QAction("形態素解析",self)
        morpheme_analysis.setStatusTip("形態素解析を行う")
        morpheme_analysis.triggered.connect(self.make_morpheme_analysis)

        randomize=QAction("テキストのサンプリング",self)
        randomize.setStatusTip("使用するデータを無作為抽出しラベルごとの件数を揃える")
        randomize.triggered.connect(self.make_randomize)

        distributed_representation=QMenu("分散表現の取得",self)

        distributed=QAction("分散表現の取得(skip-gram)", self)
        distributed.setToolTip("分散表現の取得(skip-gram")
        distributed.triggered.connect(self.make_distributed)

        with_verify=QAction("分散表現の取得(supervised)", self)
        with_verify.setToolTip("分散表現の取得(supervised)")
        with_verify.triggered.connect(self.make_with_verify)

        distributed_representation.addAction(distributed)
        distributed_representation.addAction(with_verify)

        pre_process.addAction(morpheme_analysis)
        pre_process.addAction(randomize)
        pre_process.addAction(distributed_representation.menuAction())

####################
        analyze=menubar.addMenu("分析")   #各種分析

        similarity_variation=QMenu("類似度に基づく分析", self)

        similarity=QAction("類似度", self)
        similarity.setStatusTip("類似度を計算します")
        similarity.triggered.connect(self.make_similarity)

        similar_word=QAction("類似語検索", self)
        similar_word.setToolTip("類似語を検索します")
        similar_word.triggered.connect(self.make_similar_word)

        word_addition=QAction("単語の加減算", self)
        word_addition.setToolTip("加法構成性を利用した分析")
        word_addition.triggered.connect(self.make_word_addition)

        similarity_variation.addAction(similarity)
        similarity_variation.addAction(similar_word)
        similarity_variation.addAction(word_addition)

        texts_classify=QMenu("テキストの分類", self)

        sentence_classify=QAction("テキストの分類", self)
        sentence_classify.setToolTip("テキストを分類します")
        sentence_classify.triggered.connect(self.make_classify)

        cross_category=QAction("カテゴリー横断文章分析", self)
        cross_category.setToolTip("再ラベリングのうまく行かなかった単語を利用して、カテゴリー横断的な特徴を分析します")
        cross_category.triggered.connect(self.make_cross_category)

        texts_classify.addAction(sentence_classify)
        texts_classify.addAction(cross_category)

        cognitive_map=QAction("知覚マップの作成", self)
        cognitive_map.setToolTip("知覚マップを作成します")
        cognitive_map.triggered.connect(self.make_cognitive_map)

        analyze.addAction(similarity_variation.menuAction())
        analyze.addAction(texts_classify.menuAction())
        analyze.addAction(cognitive_map)

####################
        about=menubar.addMenu("about")

        about_vector_to=QAction("Vector_toについて",self)
        about_vector_to.triggered.connect(self.make_about_vector_to)

        about.addAction(about_vector_to)
####################
        self.statusBar()

        self.main_list=QListWidget()

        self.setCentralWidget(self.main_list)

        self.setGeometry(300, 300, 350, 350)
        #self.move(300,150)
        self.setWindowTitle('Vector to')
        self.setWindowIcon(QIcon("icon.png"))
        self.show()


############################################################
#各ボタン処理
############################################################
####vector toについて
    def make_about_vector_to(self):
        subwindow=about_vectot_to_SubWindow()
        subwindow.show()
####単語の加減算
    def make_word_addition(self):
        if self.selected_project == "":
            message=QMessageBox.information(self, "お知らせ","プロジェクトを選択してください", QMessageBox.Ok)
            #print("プロジェクトを選択してください")
        elif os.path.exists(os.getcwd() + "/fastText/" + self.selected_project + ".bin") == False:
            message=QMessageBox.information(self, "お知らせ","分散表現の取得ができていません", QMessageBox.Ok)
        else:
            subwindow=Word_Addition_SubWindow(self.selected_project)
            subwindow.show()

####カテゴリー横断分析
    def make_cross_category(self):
        if self.selected_project == "":
            message=QMessageBox.information(self, "お知らせ","プロジェクトを選択してください", QMessageBox.Ok)
            #print("プロジェクトを選択してください")
        elif os.path.exists(os.getcwd() + "/fastText/" + self.selected_project + ".bin") == False:
            message=QMessageBox.information(self, "お知らせ","分散表現の取得ができていません", QMessageBox.Ok)
        else:
            cfg_type=configparser.ConfigParser()
            file_path = self.selected_project + ".ini"
            cfg_type.read(file_path)
            data_type=cfg_type['project']["original_data_type"]

            if data_type == "1":
                message=QMessageBox.information(self, "お知らせ","このプロジェクトではご使用いただけません", QMessageBox.Ok)
            else:
                subwindow=Cross_Category_SubWindow(self.selected_project)   #from cross_category
                subwindow.show()

####知覚マップを作成
    def make_cognitive_map(self):
        if self.selected_project == "":
            message=QMessageBox.information(self, "お知らせ","プロジェクトを選択してください", QMessageBox.Ok)
#            print("プロジェクトを選択してください")
        elif os.path.exists(os.getcwd() + "/fastText/" + self.selected_project + ".bin") == False:
            message=QMessageBox.information(self, "お知らせ","分散表現の取得ができていません", QMessageBox.Ok)
        else:
            subwindow=Cognitive_map_SubWindow(self.selected_project)    # from cognitive_map
            subwindow.show()

####テキストを分類
    def make_classify(self):
        if self.selected_project == "":
            message=QMessageBox.information(self, "お知らせ","プロジェクトを選択してください", QMessageBox.Ok)
#            print("プロジェクトを選択してください")
        elif os.path.exists(os.getcwd() + "/fastText/" + self.selected_project + ".bin") == False:
            message=QMessageBox.information(self, "お知らせ","分散表現の取得ができていません", QMessageBox.Ok)
        else:
            cfg_type=configparser.ConfigParser()
            file_path = self.selected_project + ".ini"
            cfg_type.read(file_path)
            data_type=cfg_type['project']["original_data_type"]

            if data_type == "1":
                message=QMessageBox.information(self, "お知らせ","このプロジェクトではご使用いただけません", QMessageBox.Ok)
            else:
                subwindow=Classify_SubWindow(self.selected_project) # from divi_class
                subwindow.show()

####単語間のコサイン類似度の計算
    def make_similar_word(self):
        if self.selected_project == "":
            message=QMessageBox.information(self, "お知らせ","プロジェクトを選択してください", QMessageBox.Ok)
#            print("プロジェクトを選択してください")
        elif os.path.exists(os.getcwd() + "/fastText/" + self.selected_project + ".bin") == False:
            message=QMessageBox.information(self, "お知らせ","分散表現の取得ができていません", QMessageBox.Ok)
        else:
            subwindow=Similar_word_SubWindow(self.selected_project) # from similar_word
            subwindow.show()



####単語間のコサイン類似度の計算
    def make_similarity(self):
        if self.selected_project == "":
            message=QMessageBox.information(self, "お知らせ","プロジェクトを選択してください", QMessageBox.Ok)
#            print("プロジェクトを選択してください")
        elif os.path.exists(os.getcwd() + "/fastText/" + self.selected_project + ".bin") == False:
            message=QMessageBox.information(self, "お知らせ","分散表現の取得ができていません", QMessageBox.Ok)
        else:
            subwindow=Similarity_SubWindow(self.selected_project)
            subwindow.show()


####分散表現の取得とテキスト分類の精度も確認する
    def make_with_verify(self):
        if self.selected_project == "":
            message=QMessageBox.information(self, "お知らせ","プロジェクトを選択してください", QMessageBox.Ok)
#            print("プロジェクトを選択してください")
        else:
            cfg_type=configparser.ConfigParser()
            file_path = self.selected_project + ".ini"
            cfg_type.read(file_path)
            data_type=cfg_type['project']["original_data_type"]
            labels=cfg_type['project']["nums_of_label"]
            tyo_on_ck=cfg_type['project']["tyo_on"]

            if data_type == "1":
                message=QMessageBox.information(self, "お知らせ","このプロジェクトでは必要ありません", QMessageBox.Ok)
            elif labels == "0":
                message=QMessageBox.information(self, "お知らせ","このプロジェクトでは実行できません", QMessageBox.Ok)
            elif tyo_on_ck == "":
                message=QMessageBox.information(self, "お知らせ", "先に形態素解析を行ってください", QMessageBox.Ok)
            else:
                subwindow=distirbuted_learn_SubWindow(self.selected_project)    # from distributed_learn_window
                subwindow.show()
                self.import_project_ini()

####分散表現の取得
    def make_distributed(self):
        if self.selected_project == "":
            message=QMessageBox.information(self, "お知らせ","プロジェクトを選択してください", QMessageBox.Ok)
#            print("プロジェクトを選択してください")
        else:
            cfg_type=configparser.ConfigParser()
            file_path = self.selected_project + ".ini"
            cfg_type.read(file_path)
            data_type=cfg_type['project']["original_data_type"]
            tyo_on_ck=cfg_type['project']["tyo_on"]


            if data_type == "1":
                message=QMessageBox.information(self, "お知らせ","このプロジェクトでは必要ありません", QMessageBox.Ok)
            elif tyo_on_ck == "":
                message=QMessageBox.information(self, "お知らせ","先に形態素解析を行ってください", QMessageBox.Ok)
            else:
                subwindow=distirbuted_SubWindow(self.selected_project)  # from distributed_repre_window
                subwindow.show()
                self.import_project_ini()

####ランダム処理
    def make_randomize(self):
        if self.selected_project == "":
            message=QMessageBox.information(self, "お知らせ","プロジェクトを選択してください", QMessageBox.Ok)
#            print("プロジェクトを選択してください")
        else:
            cfg_type=configparser.ConfigParser()
            file_path = self.selected_project + ".ini"
            cfg_type.read(file_path)
            data_type=cfg_type['project']["original_data_type"]

            if data_type == "1":
                message=QMessageBox.information(self, "お知らせ","このプロジェクトでは必要ありません", QMessageBox.Ok)
            else:
                subwindow=sampling_SubWindow(self.selected_project) # from sampling_window
                subwindow.show()
                self.import_project_ini()

####プロジェクトの修正と削除
    def make_delete_project(self):

        self.pro=self.projects
        subwindow=delete_project_SubWindow(self.pro)    #from delete_project
        subwindow.show()

        g = codecs.open("select_project_temp.txt","r","utf-8")
        p=g.readline()
        g.close()

        p=p.split(",")
        if p[0]=="":
            pass
        else:
            self.projects=p

        self.selected_project=""
        self.main_list.clear()

####形態素解析を行う
    def make_morpheme_analysis(self):

        if self.selected_project == "":
            message=QMessageBox.information(self, "お知らせ","プロジェクトを選択してください", QMessageBox.Ok)
#            print("プロジェクトを選択してください")
        else:
            cfg_type=configparser.ConfigParser()
            file_path = self.selected_project + ".ini"
            cfg_type.read(file_path)
            data_type=cfg_type['project']["original_data_type"]

            if data_type == "1":
                message=QMessageBox.information(self, "お知らせ","このプロジェクトでは必要ありません", QMessageBox.Ok)
            else:
                subwindow=Pre_Processing_SubWindow(self.selected_project)
                subwindow.show()

                self.import_project_ini()

####登録済みのプロジェクトを開く
    def make_open_project(self):
        subwindow=open_project_SubWindow(self.projects)
        subwindow.show()
        g = codecs.open("select_project_temp.txt","r","utf-8")
        project=g.readline()
        g.close()

        #print(project)
        self.selected_project=project

        g = codecs.open("select_project_temp.txt","w","utf-8")
        g.write("")
        g.close()

        self.import_project_ini()

####学習済みデータをつかったプロジェクトの作成
    def make_new_project_pre(self):

        subwindow=new_project_pre_SubWindow(self.projects)
        subwindow.show()

        g = codecs.open("select_project_temp.txt","r","utf-8")
        project=g.readline()
        g.close()

        if project != "":
            self.projects.append(project)

            self.selected_project=project
            #print(self.selected_project)
            del project
        else:
            pass

        g = codecs.open("select_project_temp.txt","w","utf-8")
        g.write("")
        g.close()

        self.import_project_ini()

####CSVデータをインポートしてプロジェクトを作成
    def make_new_project_csv(self):

        subwindow=new_project_csv_SubWindow(self.projects)
        subwindow.show()

        g = codecs.open("select_project_temp.txt","r","utf-8")
        project=g.readline()
        g.close()

        if project != "":
            self.projects.append(project)
            self.selected_project=project
            #print(self.selected_project)
            del project
        else:
            pass

        g = codecs.open("select_project_temp.txt","w","utf-8")
        g.write("")
        g.close()

        self.import_project_ini()

    def make_new_project(self):
        subwindow=new_project_SubWindow(self.projects)
        subwindow.show()

        g = codecs.open("select_project_temp.txt","r","utf-8")
        project=g.readline()
        g.close()

        path1= os.getcwd() + "/cala_temp.txt"
        if os.path.exists(path1):
            os.remove(path1)
        else:
            pass

        if project != "":
            self.projects.append(project)
            self.selected_project=project
            #print(self.selected_project)
            del project
        else:
            pass

        g = codecs.open("select_project_temp.txt","w","utf-8")
        g.write("")
        g.close()

        self.import_project_ini()

####プロジェクトiniファイルを読み込んでメイン画面に表示
    def import_project_ini(self):

        self.main_list.clear()

        if self.selected_project=="":
            pass
        else:
            cfg=configparser.ConfigParser()
            file_path = self.selected_project + ".ini"
            cfg.read(file_path)
            project_name=cfg['project']["project_name"]
            sample=cfg['project']["sample"]
            count_texts_all=cfg['project']["count_texts_all"]
            count_texts_analysis=cfg['project']["count_texts_analysis"]
            train_test=cfg['project']["train_test"]
            nums_of_category=cfg['project']["nums_of_category"]
            nums_of_label=cfg['project']["nums_of_label"]
            basis_word=cfg['project']["basis_word"]
            dimensions=cfg['project']["dimensions"]

            for_main_list=[]

            a="プロジェクト：　" + project_name
            for_main_list.append(a)

            if count_texts_all=="":
                pass
            else:
                b="投入済みテキスト数：　" + count_texts_all
                for_main_list.append(b)

            if count_texts_analysis=="":
                pass
            else:
                c="分散表現獲得に使用するテキスト数: " + count_texts_analysis
                for_main_list.append(c)

            if sample=="":
                pass
            else:
                if sample == "0" or sample == "10":
                    l_sample="    サンプリング：　なし"
                else:
                    l_sample="    サンプリング：　実行"
                for_main_list.append(l_sample)

            if dimensions == "":
                pass
            else:
                l_dimensions="次元数：　" + dimensions
                for_main_list.append(l_dimensions)

            if train_test == "適合率のテストせず":
                l_train_test="適合率のテストせず"
                for_main_list.append(l_train_test)
            elif train_test == "":
                pass
            else:
                l_train_test="分類適合度：　" + train_test + "%"
                for_main_list.append(l_train_test)

            if nums_of_label=="":
                pass
            else:
                a="使用するラベル数：　" + nums_of_label
                for_main_list.append(a)

            if nums_of_category=="":
                pass
            else:
                a="使用するカテゴリー数：　" + nums_of_category
                for_main_list.append(a)

            if basis_word=="":
                pass
            else:
                if basis_word=="0":
                    a="基本形を使用"
                else:
                    a="表層形を使用"
                for_main_list.append(a)

            for n in for_main_list:
                self.main_list.addItem(n)



############################################################
#終了処理
############################################################
####iniファイルへの保存関数
    def end_processing(self):

        #projects.append("sou")
        projects=str(self.projects)

        if projects=="['']":
            pass
        else:
            #print(projects)
            projects=projects.replace("[","").replace("]","").replace("'","").replace(" ","")

            projects=projects.split(",")

            return_projects=[]
            for n in projects:
                if n =="":
                    pass
                else:
                    return_projects.append(n)

            return_projects=str(return_projects)
            return_projects=return_projects.replace("[","").replace("]","").replace("'","").replace(" ","")

            time.sleep(0.1)

    #        os_name = os.name
            self.selected_project=""

            g = codecs.open("projects_config","w", "utf-8")
            a=return_projects
            g.write(a)
            g.close

            time.sleep(0.1)

        selected_project_temp_path = os.getcwd() + "/select_project_temp.txt"
        if os.path.isfile(selected_project_temp_path) == True:
            os.remove(selected_project_temp_path)
        else:
            pass


#        with open("main.ini", "w") as f:
#            config = configparser.ConfigParser()
#            config.add_section("settings")
#            config.set("settings","id",self.mysql_id)
#            config.set("settings","pass",self.mysql_pass)
#            config.set('settings',"projects",projects)
#            config.set('settings',"root_path",os.getcwd())
#            config.set('settings',"os",os_name)
#            config.write(f)
#            f.close

####ウィンドウ上のバツボタンを押された時の処理
    def button_close(self):
        reply = QMessageBox.question(self, 'Vector_toを終了しますか？',
            "Vector_toを終了しますか?", QMessageBox.No |
            QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.end_processing()
            if self.using_os == "nt":
                mysql_Stop()
            else:
                else_Stop()
        else:
            event.ignore()

    def closeEvent(self, event):

        #メッセージ画面の設定いろいろ
        reply = QMessageBox.question(self, 'Vector_toを終了しますか？',
            "Vector_toを終了しますか?", QMessageBox.No |
            QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:
            event.accept()
            self.end_processing()
            if self.using_os == "nt":
                mysql_Stop()
            else:
                else_Stop()
        else:
            event.ignore()

if __name__=="__main__":
    app=QApplication(sys.argv)

    ex=MainWindow()
    sys.exit(app.exec_())

#登録　削除　登録　キャンセル
