# ============================================================================== #
    # mainwindow.py - AcouSed                                   #
    # Copyright (C) 2024  INRAE                                              #
    #                                                                        #
    # This program is free software: you can redistribute it and/or modify   #
    # it under the terms of the GNU General Public License as published by   #
    # the Free Software Foundation, either version 3 of the License, or      #
    # (at your option) any later version.                                    #
    #                                                                        #
    # This program is distributed in the hope that it will be useful,        #
    # but WITHOUT ANY WARRANTY; without even the implied warranty of         #
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          #
    # GNU General Public License for more details.                           #
    #                                                                        #
    # You should have received a copy of the GNU General Public License      #
    # along with this program.  If not, see <https://www.gnu.org/licenses/>. #

    #                                                      by Brahim MOUDJED #
# ============================================================================== #

# -*- coding: utf-8 -*-

import os

# Form implementation generated from reading ui file 'mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets
from Model.create_table_for_save_as import CreateTableForSaveAs
from Model.update_table_for_save import UpdateTableForSave
from Model.read_table_for_open import ReadTableForOpen
from Model.calibration_constant_kt import CalibrationConstantKt
from View.about_window import AboutWindow
import settings as stg

import numpy as np
from subprocess import Popen

import time


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        self.mainwindow = MainWindow
        self.mainwindow.setObjectName("MainWindow")
        self.mainwindow.resize(898, 498)
        self.mainwindow.setLocale(QtCore.QLocale(QtCore.QLocale.French, QtCore.QLocale.France))
        self.mainwindow.setDocumentMode(False)
        self.mainwindow.setDockNestingEnabled(False)
        self.mainwindow.setUnifiedTitleAndToolBarOnMac(False)

        self.centralwidget = QtWidgets.QWidget(self.mainwindow)
        self.centralwidget.setObjectName("centralwidget")

        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")

        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setAutoFillBackground(False)
        self.tabWidget.setLocale(QtCore.QLocale(QtCore.QLocale.French, QtCore.QLocale.France))
        self.tabWidget.setDocumentMode(True)
        self.tabWidget.setTabsClosable(False)
        self.tabWidget.setTabBarAutoHide(False)
        self.tabWidget.setObjectName("tabWidget")

        self.tab1 = QtWidgets.QWidget()
        self.tab1.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
        self.tab1.setObjectName("tab1")
        self.tabWidget.addTab(self.tab1, "")

        self.tab2 = QtWidgets.QWidget()
        self.tab2.setObjectName("tab2")
        self.tabWidget.addTab(self.tab2, "")

        self.tab3 = QtWidgets.QWidget()
        self.tab3.setObjectName("tab3")
        self.tabWidget.addTab(self.tab3, "")

        self.tab4 = QtWidgets.QWidget()
        self.tab4.setObjectName("tab4")
        self.tabWidget.addTab(self.tab4, "")

        self.tab5 = QtWidgets.QWidget()
        self.tab5.setObjectName("tab5")
        self.tabWidget.addTab(self.tab5, "")

        self.tab6 = QtWidgets.QWidget()
        self.tab6.setObjectName("tab6")
        self.tabWidget.addTab(self.tab6, "")

        self.verticalLayout.addWidget(self.tabWidget)
        self.mainwindow.setCentralWidget(self.centralwidget)

        self.menubar = QtWidgets.QMenuBar(self.mainwindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 898, 22))
        self.menubar.setObjectName("menubar")

        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setLocale(QtCore.QLocale(QtCore.QLocale.French, QtCore.QLocale.France))
        self.menuFile.setObjectName("menuFile")

        self.menuSettings = QtWidgets.QMenu(self.menuFile)
        self.menuSettings.setObjectName("menuSettings")

        self.menuLanguage = QtWidgets.QMenu(self.menuSettings)
        self.menuLanguage.setObjectName("menuLanguage")

        self.menuExport = QtWidgets.QMenu(self.menuFile)
        self.menuExport.setObjectName("menuExport")

        self.menuTools = QtWidgets.QMenu(self.menubar)
        self.menuTools.setLocale(QtCore.QLocale(QtCore.QLocale.French, QtCore.QLocale.France))
        self.menuTools.setObjectName("menuTools")

        self.menuHelp = QtWidgets.QMenu(self.menubar)
        self.menuHelp.setObjectName("menuHelp")

        self.mainwindow.setMenuBar(self.menubar)

        self.statusbar = QtWidgets.QStatusBar(self.mainwindow)
        self.statusbar.setObjectName("statusbar")
        self.mainwindow.setStatusBar(self.statusbar)

        self.toolBar = QtWidgets.QToolBar(self.mainwindow)
        self.toolBar.setObjectName("toolBar")
        self.mainwindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)

        self.actionOpen = QtWidgets.QAction(self.mainwindow)
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap("icons/icon_folder.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionOpen.setIcon(icon1)
        self.actionOpen.setObjectName("actionOpen")

        self.actionSave = QtWidgets.QAction(self.mainwindow)
        icon2 = QtGui.QIcon()
        icon2.addPixmap(QtGui.QPixmap("icons/save.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionSave.setIcon(icon2)
        self.actionSave.setObjectName("actionSave")

        self.actionEnglish = QtWidgets.QAction(self.mainwindow)
        icon6 = QtGui.QIcon()
        icon6.addPixmap(QtGui.QPixmap("icons/en.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionEnglish.setIcon(icon6)
        self.actionEnglish.setObjectName("actionEnglish")

        self.actionFrench = QtWidgets.QAction(self.mainwindow)
        icon7 = QtGui.QIcon()
        icon7.addPixmap(QtGui.QPixmap("icons/fr.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionFrench.setIcon(icon7)
        self.actionFrench.setObjectName("actionFrench")

        self.action_ABSCalibrationConstant = QtWidgets.QAction(self.mainwindow)
        self.action_ABSCalibrationConstant.setText("ABS constant calibration kt")

        self.actionTable_of_Backscatter_values = QtWidgets.QAction(self.mainwindow)
        self.actionTable_of_Backscatter_values.setObjectName("actionTable_of_Backscatter_values")

        self.actionSave_As = QtWidgets.QAction(self.mainwindow)
        self.actionSave_As.setObjectName("actionSave_As")

        self.actionAbout = QtWidgets.QAction(self.mainwindow)
        self.actionAbout.setObjectName("actionAbout")

        self.actionUserManual = QtWidgets.QAction(self.mainwindow)
        self.actionUserManual.setText("User Manual")

        self.action_AcousticInversionTheory = QtWidgets.QAction(self.mainwindow)
        self.action_AcousticInversionTheory.setText("Acoustic inversion theory")

        self.action_AQUAscatUserManual = QtWidgets.QAction(self.mainwindow)
        self.action_AQUAscatUserManual.setText("Tutorial AQUAscat software")

        self.actionDB_Browser_for_SQLite = QtWidgets.QAction(self.mainwindow)
        self.actionDB_Browser_for_SQLite.setObjectName("actionDB_Browser_for_SQLite")

        self.menuLanguage.addAction(self.actionEnglish)
        self.menuLanguage.addAction(self.actionFrench)

        self.menuSettings.addAction(self.menuLanguage.menuAction())
        self.menuSettings.addAction(self.action_ABSCalibrationConstant)

        self.menuExport.addAction(self.actionTable_of_Backscatter_values)

        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addAction(self.actionSave)
        self.menuFile.addAction(self.actionSave_As)
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.menuSettings.menuAction())
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.menuExport.menuAction())

        self.menuTools.addAction(self.actionDB_Browser_for_SQLite)

        self.menuHelp.addAction(self.actionAbout)
        self.menuHelp.addAction(self.actionUserManual)
        self.menuHelp.addAction(self.action_AcousticInversionTheory)
        self.menuHelp.addAction(self.action_AQUAscatUserManual)

        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuTools.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())

        self.toolBar.addAction(self.actionOpen)
        self.toolBar.addAction(self.actionSave)
        self.toolBar.addSeparator()
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.actionEnglish)
        self.toolBar.addAction(self.actionFrench)

        self.retranslateUi()
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(self.mainwindow)

        # --- Create Context Menu ---
        self.createContextMenu()

        # --- Connect Action Save As ---
        self.actionSave_As.triggered.connect(self.save_as)

        # --- Connect Action save ---
        self.actionSave.triggered.connect(self.save)

        # --- Connect Action Open ---
        self.actionOpen.triggered.connect(self.open)
        # self.actionOpen.triggered.connect(lambda: print('tott'))

        # --- Connect Action ABS calibration constant kt ---
        self.action_ABSCalibrationConstant.triggered.connect(self.load_calibration_constant_values)

        # --- Connect Action export acoustic backscatter values ---
        self.actionTable_of_Backscatter_values.triggered.connect(
            self.export_table_of_acoustic_BS_values_to_excel_or_libreOfficeCalc_file)

        # --- Connect Action DB_Browser_for_SQLite ---
        self.actionDB_Browser_for_SQLite.triggered.connect(self.db_browser_for_sqlite)

        # --- Connect Action About ---
        self.actionAbout.triggered.connect(self.about_window)

        # --- Connect Action User Manual ---
        self.actionUserManual.triggered.connect(self.user_manual)
        self.action_AcousticInversionTheory.triggered.connect(self.inversion_acoustic_theory)
        self.action_AQUAscatUserManual.triggered.connect(self.tutorial_AQUAscat_software)


    def createContextMenu(self):
        # Setting contextMenuPolicy
        self.centralwidget.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
        # Populating the widget with actions
        self.centralwidget.addAction(self.actionSave_As)
        self.centralwidget.addAction(self.actionSave)
        self.centralwidget.addAction(self.actionOpen)
        self.centralwidget.addAction(self.actionTable_of_Backscatter_values)
        self.centralwidget.addAction(self.actionEnglish)
        self.centralwidget.addAction(self.actionFrench)
        self.centralwidget.addAction(self.actionDB_Browser_for_SQLite)

    def save_as(self):
        CreateTableForSaveAs()
        self.mainwindow.setWindowTitle(
            "AcouSed - " +
            stg.filename_save_as
        )

    def save(self):
        UpdateTableForSave()

    def open(self):
        reader = ReadTableForOpen()
        if reader.opened:
            self.mainwindow.open_study_update_tabs()

    def load_calibration_constant_values(self):
        cc_kt = CalibrationConstantKt()
        cc_kt.exec()

    def db_browser_for_sqlite(self):
        try:
            Popen("sqlitebrowser")
        except OSError as e:
            msg_box = QtWidgets.QMessageBox()
            msg_box.setWindowTitle("DB Browser for SQLite Error")
            msg_box.setIcon(QtWidgets.QMessageBox.Critical)
            msg_box.setText(f"DB Browser for SQLite Error:\n  {str(e)}")
            msg_box.setStandardButtons(QtWidgets.QMessageBox.Ok)
            msg_box.exec()

    def about_window(self):
        print("about")
        aw = AboutWindow()
        aw.exec()

    def current_file_path(self, filename):
        return os.path.abspath(
            os.path.join(
                os.path.dirname(__file__),
                "..", filename
            )
        )

    def open_doc_file(self, filename):
        QtGui.QDesktopServices.openUrl(
            QtCore.QUrl(
                f"file://{self.current_file_path(filename)}"
            )
        )

    def user_manual(self):
        self.open_doc_file('AcouSed_UserManual.pdf')

    def inversion_acoustic_theory(self):
        self.open_doc_file('Acoustic_Inversion_theory.pdf')

    def tutorial_AQUAscat_software(self):
        self.open_doc_file('Tutorial_AQUAscat_software.pdf')

    def export_table_of_acoustic_BS_values_to_excel_or_libreOfficeCalc_file(self):

        if len(stg.BS_raw_data_reshape) != 0:

            # --- Open file dialog to select the directory ---

            name = QtWidgets.QFileDialog.getExistingDirectory(caption="Select Directory - Acoustic BS raw data Table")
            print("name table to save ", name)

            # --- Save the raw acoustic backscatter data from a Dataframe to csv file ---

            t0 = time.time()
            print("len(stg.BS_raw_data_reshape) ", len(stg.BS_raw_data_reshape))

            if name:

                for i in range(len(stg.BS_raw_data_reshape)):

                    header_list = []
                    header_list.clear()
                    table_data = np.array([[]])
                    for freq_ind, freq_value in enumerate(stg.freq_text[0]):
                        header_list.append("Time - " + freq_value)
                        header_list.append("Depth - " + freq_value)
                        header_list.append("BS - " + freq_value)

                        if freq_ind == 0:
                            table_data = np.vstack((np.vstack((stg.time_reshape[i][:, freq_ind],
                                                               stg.depth_reshape[i][:, freq_ind])),
                                                               stg.BS_raw_data_reshape[i][:, freq_ind]))

                        else:
                            table_data = np.vstack((table_data,
                                                    np.vstack((np.vstack(
                                                        (stg.time_reshape[i][:, freq_ind],
                                                         stg.depth_reshape[i][:, freq_ind])),
                                                         stg.BS_raw_data_reshape[i][:, freq_ind]))
                                                    ))

                    exec("DataFrame_acoustic_" + str(i) + "= pd.DataFrame(None)")
                    exec("DataFrame_acoustic_" + str(i) + "= pd.DataFrame(data=table_data.transpose(), columns=header_list)")

                    exec("DataFrame_acoustic_" + str(i) + ".to_csv(" +
                         "path_or_buf=" +
                         "'" + name + "/" + "Table_" +
                         str(stg.filename_BS_raw_data[i][:-4]) + ".csv'" + ", " +
                         "sep=" + "',' " + ", " +
                         "header=DataFrame_acoustic_" + str(i) + ".columns" + ")")

            t1 = time.time() - t0
            print("time duration export BS ", t1)
            print("table of BS value Export finished")

    def retranslateUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.mainwindow.setWindowTitle(_translate("MainWindow", "AcouSed - unsaved file"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab1), _translate("MainWindow", "Acoustic data"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab2), _translate("MainWindow", "Signal preprocessing"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab3), _translate("MainWindow", "Sample data"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab4), _translate("MainWindow", "Sediment Calibration"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab5), _translate("MainWindow", "Acoustic inversion"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab6), _translate("MainWindow", "Note"))
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.menuSettings.setTitle(_translate("MainWindow", "Settings"))
        self.menuLanguage.setTitle(_translate("MainWindow", "Language"))
        self.menuExport.setTitle(_translate("MainWindow", "Export"))
        self.menuTools.setTitle(_translate("MainWindow", "Tools"))
        self.menuHelp.setTitle(_translate("MainWindow", "Help"))
        self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
        self.actionOpen.setText(_translate("MainWindow", "Open ..."))
        self.actionSave.setText(_translate("MainWindow", "Save"))
        self.actionEnglish.setText(_translate("MainWindow", "English"))
        self.actionFrench.setText(_translate("MainWindow", "French"))
        self.actionTable_of_Backscatter_values.setText(_translate("MainWindow", "Table of Backscatter values"))
        self.actionSave_As.setText(_translate("MainWindow", "Save As ..."))
        self.actionAbout.setText(_translate("MainWindow", "About"))
        self.actionDB_Browser_for_SQLite.setText(_translate("MainWindow", "DB Browser for SQLite"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
