import sys, configparser, os

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 encode_to_utf8 import main_code
from tyo_on import tyo_on_encode
from delete_symbol import delete_symbols
from zenkaku_hankaku import zen_han
from mysql_text import text_to_mysql
from mysql_to_morpheme_temp import resource_of_morpheme
from mysql_temp_to_mysql import morpheme_to_mysql
from mysql_re_pre_process import re_pre
from mysql_csv import csv_to_mysql
from mysql_category_label_text_count import count_main
from write_project_ini import write_pro_ini

class Pre_Processing_SubWindow(QWidget):

    def __init__(self, project):
        super(Pre_Processing_SubWindow,self).__init__()
        self.project=project

        self.pre_process_subwindow()

    def pre_process_subwindow(self):
        self.w=QDialog()
        pro_name_label=QLabel()
        pro_name=self.project + "プロジェクト"
        pro_name_label.setText(pro_name)
        fontA=QFont()
        fontA.setPointSize(15)
        pro_name_label.setFont(fontA)

        fontB=QFont()
        fontB.setPointSize(8)

        QToolTip.setFont(QFont('SansSerif', 10))

        #han_zen_vbox = QVBoxLayout()
        self.tyo_on_cb = QCheckBox("長音記号を修正する", self)
        self.tyo_on_cb.setToolTip("長音記号を修正します")
        self.tyo_on_cb.toggle()
        self.delete_symbol_cb = QCheckBox("記号を削除する", self)
        self.delete_symbol_cb.setToolTip("分析に不要な記号を削除します")
        #self.delete_symbol_cb.toggle()
        han_h_box=QHBoxLayout()
        zen_h_box=QHBoxLayout()
        sym_han_labe=QLabel("半角記号")
        sym_zen_labe=QLabel("全角記号")
        self.list_of_symbols_han=QLineEdit()
        self.list_of_symbols_zen=QLineEdit()
        self.list_of_symbols_han.setEnabled(False)
        self.list_of_symbols_zen.setEnabled(False)
        han_h_box.addWidget(sym_han_labe)
        han_h_box.addWidget(self.list_of_symbols_han)
        zen_h_box.addWidget(sym_zen_labe)
        zen_h_box.addWidget(self.list_of_symbols_zen)
        self.list_of_symbols_han.setText("!\#$&()*+/:;<=>?@^_`{|}~･｢｣")
        self.list_of_symbols_zen.setText("！”＃＄％＆’（）＊＋／：；＜＝＞？＠￥＾＿｀｛｜｝〜・・「」『』【】〈〉《》")
        self.list_of_symbols_han.setToolTip("削除する記号を選択してください")
        self.list_of_symbols_zen.setToolTip("削除する記号を選択してください")

        self.hankaku_zenkaku_cb = QCheckBox("半角・全角変換処理をする", self)
        self.hankaku_zenkaku_cb.setToolTip("カタカナを全角に英数字を半角に変換します")
        self.hankaku_zenkaku_cb.toggle()
        #self.stop_word_cb = QCheckBox("ストップワードを削除する", self)
        #self.stop_word_cb.setToolTip("ストップワードを削除します")
        #han_zen_vbox.addWidget(self.tyo_on_cb)
        #han_zen_vbox.addStretch(3)
        #han_zen_vbox.addWidget(self.delete_symbol_cb)
        #han_zen_vbox.addLayout(han_h_box)
        #han_zen_vbox.addLayout(zen_h_box)
        #han_zen_vbox.addStretch(3)
        #han_zen_vbox.addWidget(self.hankaku_zenkaku_cb)
        ##################han_zen_vbox.addWidget(stop_word_cb)

        self.delete_symbol_cb.stateChanged.connect(self.dele_sym)

        radio_v_box = QVBoxLayout()
        self.basis_word = QRadioButton("基本形") #基本形を使用
        self.original_word = QRadioButton("表層形")  #表層形を使用
        self.original_word.toggle()
        self.button_group = QButtonGroup()
        self.button_group.addButton(self.original_word)
        self.button_group.addButton(self.basis_word)

        self.content_cb = QCheckBox("内容語のみ使用する", self)
        self.content_cb.setToolTip("助詞や接続詞を分析対象から外し、名詞、動詞、形容詞など意味を持つ単語のみを使用します")

        radio_v_box.addWidget(self.original_word)
        radio_v_box.addWidget(self.basis_word)

        #radio_v_box.addStretch(2)
        #radio_v_box.addWidget(self.content_cb)


        button_h_box=QHBoxLayout()
        process_button=QPushButton("実行")
        process_button.clicked.connect(self.process)
        cancelB=QPushButton("キャンセル")
        cancelB.clicked.connect(self.w.close)
        button_h_box.addStretch(2)
        button_h_box.addWidget(process_button)
        button_h_box.addWidget(cancelB)

        main_v_layout=QVBoxLayout()
        main_v_layout.addWidget(pro_name_label)
        main_v_layout.addStretch(1)
        main_v_layout.addWidget(self.tyo_on_cb)
        main_v_layout.addStretch(1)
        main_v_layout.addWidget(self.delete_symbol_cb)
        main_v_layout.addLayout(han_h_box)
        main_v_layout.addLayout(zen_h_box)
        main_v_layout.addStretch(1)
        main_v_layout.addWidget(self.hankaku_zenkaku_cb)
        main_v_layout.addStretch(1)
        main_v_layout.addLayout(radio_v_box)
        main_v_layout.addStretch(1)
        main_v_layout.addWidget(self.content_cb)
        main_v_layout.addStretch(1)
        main_v_layout.addLayout(button_h_box)

        self.w.setGeometry(300, 300, 350, 400)
        self.w.setWindowTitle('前処理')
        self.w.setLayout(main_v_layout)

    def dele_sym(self):
        if self.delete_symbol_cb.checkState() > 0:
            self.list_of_symbols_han.setEnabled(True)
            self.list_of_symbols_zen.setEnabled(True)
        else:
            self.list_of_symbols_han.setEnabled(False)
            self.list_of_symbols_zen.setEnabled(False)

    def process(self):
        reply = QMessageBox.question(self, '前処理の開始',
            "この処理はたいへん時間がかかります<br>前処理を開始しますか?<br>終了すると前処理ウィンドウは自動的に閉じられます", QMessageBox.No |
            QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:

            file_path=self.ini_check(self.project)
            if file_path == 0:
                #print("iniファイルが存在しません")
                message=QMessageBox.information(self,"お知らせ",  "iniファイルが存在しません", QMessageBox.Ok)
            else:
                config = configparser.ConfigParser()
                config.read(file_path)
                project_name=config['project']["project_name"]
                text_column_no=config['project']["text_column_no"]
                category_column_no=config['project']["category_column_no"]
                label_column_no=config['project']["label_column_no"]
                files=config['project']["files"]
                original_data_type=config['project']["original_data_type"]
                csv_path=config['project']["csv_path"]

                if original_data_type == "1":
                    #print("前処理するデータがありません")
                    message=QMessageBox.information(self,"お知らせ",  "前処理するデータがありません", QMessageBox.Ok)

                elif original_data_type == "2" or original_data_type == "3":
                    ###################################################
                    #mysqlのtext_tableの初期化
                    ###################################################
                    re_pre(self.project)    #from mysql_re_pre_process

                    ###################################################
                    #テキスト形式のデータをmysqlに投入
                    ###################################################
                    if original_data_type == "2":

                        ###################################################
                        #iniファイルのfilesの文字列型をタプルのリストに変換
                        ###################################################
                        #files=files.replace("), (",")")
                        #files=files.split(")")
                        files=files[1:]
                        files=files[:-1]
                        files=files.replace("), (","!!")
                        files=files.split("!!")

                        regist_files=[]

                        for n in files:

                            #n = n.replace("(","").replace(", ",",").replace("'","")
                            n = n.replace(", ",",").replace("'","")
                            n = n.split(",")
                            n=tuple(n)

                            if len(n) > 1:
                                    regist_files.append(n)
                            else:
                                pass

                        self.text_encode(regist_files)   #テキストファイルの修正とデータベースへの登録処理

                    ###################################################
                    #CSV形式のデータをmysqlに投入
                    ###################################################
                    elif original_data_type == "3":
                        self.csv_encode(text_column_no, category_column_no, label_column_no, csv_path)    #csvファイルの修正とデータベースへの登録処理

                else:
                    #print("プロジェクトファイルの登録に失敗しているようです")
                    message=QMessageBox.information(self,"お知らせ",  "プロジェクトファイルの登録に失敗しているようです", QMessageBox.Ok)

                if original_data_type == "1":
                    pass
                else:
                    ###################################################
                    #データベースからテキストを取り出して設定に応じて前処理し、その結果を保存
                    ###################################################
                    resource_of_morpheme(self.project)  #from mysql_to_morpheme_temp

                    ####################################
                    #mecabを使って形態素解析
                    ####################################
                    basis_word_check = 0
                    if self.basis_word.isChecked() == True:
                        basis_word_check=0
                    else:
                        basis_word_check=1

                    ####################################
                    #内容語のみを分析対象にする
                    ####################################
                    content_check = 0
                    if self.content_cb.checkState() > 0:
                        content_check=1
                    else:
                        content_check=0

                    res = morpheme_to_mysql(self.project, basis_word_check, content_check)    # from mysql_temp_to_mysql

                    original = res[0]
                    morpheme = res[1]

                    message = "----オリジナルファイルの最終行----<br>" + original + "<br>----と形態素解析済みの最終行----<br>" + morpheme + "<br>----は一致していますか？----"

                    message=QMessageBox.information(self,"お知らせ",  message, QMessageBox.Ok)
                    #print("形態素解析終了")

                    count_main(self.project)    # from mysql_category_label_text_count
                    #print("iniファイルの更新終了")

                    path= os.getcwd() + "/encode_temp.txt"
                    os.remove(path)



                    ####################################
                    #iniファイルに形態素解析時の設定を登録
                    ####################################
                    #print(type(self.han))
                    write_pro_ini(self.project).main(
                    tyo_on = self.tyo_on_ini,
                    han = self.han,
                    zen = self.zen,
                    zen_han = self.zen_han,
                    basis_word = str(basis_word_check),
                    discrimination="0"

                    )



                self.w.close()

        else:
            pass

    def csv_encode(self, text_column_no, category_column_no, label_column_no, csv_path):

        main_code(csv_path)#読み込んだファイルの文字コードをutf-8に変換し、encode_temp.txtに保存    from encode_to_utf8

        ###################################################################################
        #チェックボックスにチェックが入っていれば長音記号を修正する
        ###################################################################################
        if self.tyo_on_cb.checkState() > 0:
            self.tyo_on_ini="1"
            tyo_on_encode()    #聴音機号の表記ゆれの修正
        else:
            self.tyo_on_ini="0"
            pass

        ###################################################################################
        #チェックボックスにチェックが入っていれば半角記号と全角記号を取り除く
        ###################################################################################
        if self.delete_symbol_cb.checkState() > 0:
            han=self.list_of_symbols_han.text()
            self.han='[' + han + ']'
            zen=self.list_of_symbols_zen.text()
            self.zen='[' + zen + ']'
            delete_symbols(self.han,self.zen)
        else:
            self.han="0"
            self.zen="0"
            pass

        ###################################################################################
        #チェックボックスにチェックが入っていればカタカナを全角に、英数字を半角に変換する
        ###################################################################################
        if self.hankaku_zenkaku_cb.checkState()> 0 :
            zen_han()
            self.zen_han = "1"
        else:
            self.zen_han = "0"
            pass

        csv_to_mysql(self.project, text_column_no, category_column_no, label_column_no) #from mysql_csv


    def text_encode(self,files):
        for n in files:
            category=n[0]
            label=n[1]
            text=n[2]

            main_code(text) #読み込んだファイルの文字コードをutf-8に変換し、encode_temp.txtに保存   from encode_to_utf8


            ###################################################################################
            #チェックボックスにチェックが入っていれば長音記号を修正する
            ###################################################################################
            if self.tyo_on_cb.checkState() > 0:
                self.tyo_on_ini="1"
                tyo_on_encode()    #聴音機号の表記ゆれの修正
            else:
                self.tyo_on_ini="0"
                pass

            ###################################################################################
            #チェックボックスにチェックが入っていれば半角記号と全角記号を取り除く
            ###################################################################################
            if self.delete_symbol_cb.checkState() > 0:
                han=self.list_of_symbols_han.text()
                self.han='[' + han + ']'
                zen=self.list_of_symbols_zen.text()
                self.zen='[' + zen + ']'
                delete_symbols(self.han,self.zen)
            else:
                self.han="0"
                self.zen="0"
                pass

            ###################################################################################
            #チェックボックスにチェックが入っていればカタカナを全角に、英数字を半角に変換する
            ###################################################################################
            if self.hankaku_zenkaku_cb.checkState()> 0 :
                zen_han()
                self.zen_han = "1"
            else:
                self.zen_han = "0"
                pass

            text_to_mysql(self.project, category, label)



    def ini_check(self,project):
        current_directory=os.getcwd()
        file_check=current_directory + ("/") + project + (".ini")

        if os.path.exists(file_check):
            return file_check
        else:
            return 0

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

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

    pro_name="only_text"

    ex=Pre_Processing_SubWindow(pro_name)
    Pre_Processing_SubWindow(pro_name).show()
    sys.exit(app.exec_())
