"""
/***************************************************************************
 FEWSTools
                                 A QGIS plugin
 FEWS Tools for GeoProcessing
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
    begin                : 2019-09-15
    git sha              : $Format:%H$
    copyright            : (C) 2019-2023 by FEWS
    email                : minxuansun@contractor.usgs.gov
    Modified:  04/14/2020 cholen - Updated order of toolbar
               05/19/2020 msun - Adjusted default workspace creation
               08/14/2020 cholen - Removed dead code, adjust tool tip
               08/29/2020 cholen - Remove set defaults tool
               10/22/2020 cholen - Change setup var name to match other files
               01/07/2021 msun - Add default output directory controller
               02/01/2021 cholen - Comment NetCDF until external tool works
               05/26/2022 jhowton - Added GeoWRSI toolbar
               07/13/2022 cholen - Added GeoWRSI help
               07/25/2022 cholen - Database migration for GeoWRSI
               07/29/2022 cholen - Refactor
               10/07/2022 dhackman - Added define_wrsi_output_settings

 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""
import os.path
import shutil

from PyQt5.QtCore import QCoreApplication, QSettings, QTranslator, qVersion
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QAction, QMenu, QMessageBox, QToolBar


from fews_tools import fews_tools_config as config
from fews_tools.controllers.basiics_controller import BasiicsController
from fews_tools.controllers.changes_in_averages_controller import ChangesInAveragesController
from fews_tools.controllers.climate_data_download_controller import ClimateDataDownloadController
from fews_tools.controllers.climatological_analysis_controller import ClimatologicalAnalysisController
from fews_tools.controllers.composites_controller import CompositesController
from fews_tools.controllers.contour_controller import ContourController
from fews_tools.controllers.crops_controller import CropsController
from fews_tools.controllers.datasets_controller import DatasetsController
from fews_tools.controllers.extract_stats_controller import ExtractStatsController
from fews_tools.controllers.geowrsi_climatological_analysis_controller import GeoWRSIClimatologicalAnalysisController
from fews_tools.controllers.geowrsi_controller import GeoWRSIController
from fews_tools.controllers.geowrsi_output_settings_controller import GeoWRSIOutputSettings
from fews_tools.controllers.geowrsi_settings_controller import GeoWRSISettings
from fews_tools.controllers.help_controller import HelpController
from fews_tools.controllers.import_archive_controller import ImportArchiveController
# from .netCDF_controller import NetCDFController
from fews_tools.controllers.output_controller import OutputController
from fews_tools.controllers.rainfall_summary_controller import RainfallSummariesController
from fews_tools.controllers.reclassify_grids_controller import ReclassifyGridsController
from fews_tools.controllers.region_controller import RegionController
from fews_tools.controllers.view_available_data_controller import ViewAvailableDataController
from fews_tools.controllers.workspace_setup_controller import WorkspaceSetupController
from fews_tools.controllers.wrsi_help_controller import WRSIHelpController
from fews_tools.models.workspace_setup_model import WorkspaceSetupModel


def basiics_tool():
    """    Open BASIICS tool    """
    BasiicsController().exec_()


def changes_in_averages_tool():
    """    Open Changes in averages tool    """
    ChangesInAveragesController().exec_()


def climatological_analysis_tool():
    """    Open Climatological analysis tool    """
    ClimatologicalAnalysisController().exec_()


def composites_tool():
    """    Open Composites tool    """
    CompositesController().exec_()


def contours_tool():
    """     Open Contours tool    """
    ContourController().exec_()


def define_crops():
    """    Open Crops definition tool    """
    CropsController().exec_()


def define_datasets():
    """    Open Datasets definition tool    """
    DatasetsController().exec_()


def define_output_settings():
    """    Open Output directory definition tool    """
    OutputController().exec_()


def define_regions():
    """    Open Regions definition tool    """
    RegionController().exec_()


def define_workspace_settings():
    """    Open Workspace settings definition tool    """
    WorkspaceSetupController().exec_()


def define_wrsi_settings():
    """    Open WRSI Settings definition tool    """
    GeoWRSISettings().exec_()


def define_wrsi_output_settings():
    """    Open WRSI Output Settings tool    """
    GeoWRSIOutputSettings().exec()


def download_data_tool():
    """    Open Data Download tool    """
    ClimateDataDownloadController().exec_()


def extract_stats_tool():
    """    Open Extract stats tool    """
    ExtractStatsController().exec_()


def import_archive_tool():
    """    Open Import archives tool    """
    ImportArchiveController().exec_()


def rainfall_summary_tool():
    """    Open Rainfall summary tool    """
    RainfallSummariesController().exec_()


def reclass_grids_tool():
    """    Open Reclassify Grids tool    """
    ReclassifyGridsController().exec_()


def view_data_tool():
    """    Open View data tool    """
    ViewAvailableDataController().exec_()


def wrsi_clim_tool():
    """    Open Climatological WRSI/SOS Analysis tool    """
    GeoWRSIClimatologicalAnalysisController().exec_()


def wrsi_tool():
    """    Open WRSI tool    """
    GeoWRSIController().exec_()


def translate_text(message):
    """Get the translation for a string using Qt translation API.
    We implement this ourselves since we do not inherit QObject.

    :param(string) message: String for translation.
    :returns(QString): Translated version of message.
    """
    return QCoreApplication.translate('FEWSTools', message)


class FEWSTools:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            plugin_dir,
            'i18n',
            'FEWSTools_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            translator = QTranslator()
            translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(translator)

        # Declare instance attributes
        self.menu = translate_text(u'&FEWS Tools')

        # define actions for Main menu drop down
        plugin_dir = os.path.dirname(__file__)
        self.icon_dir = os.path.join(plugin_dir, 'icons')

        # enable and fill in the GeoCLIM toolbar
        self.geoclim_toolbar = self.iface.addToolBar('GeoCLIM')
        self.geoclim_actions = []

        # enable and fill in the GeoWRSI toolbar
        self.geowrsi_toolbar = self.iface.addToolBar('GeoWRSI')
        self.geowrsi_actions = []

    def initGui(self):
        """          Intialize the QGIS GUI for the plugin        """
        # define actions and triggers for actions for Main menu drop down
        action_geoclim = QMenu(u'GeoCLIM', self.iface.mainWindow())
        action_geoclim_sub = QAction(
            u'GeoCLIM Tools', self.iface.mainWindow())

        action_geowrsi = QAction(u'GeoWRSI', self.iface.mainWindow())
        action_reclass = QAction(
            u'Reclassify Grids', self.iface.mainWindow())

        action_geoclim.pyqtConfigure(triggered=self.geoclim)
        action_geowrsi.pyqtConfigure(triggered=self.geowrsi)
        action_reclass.pyqtConfigure(triggered=reclass_grids_tool)

        # add a 'FEWS Tools' item to the main menu
        self.menu = QMenu('FEWS Tools')
        self.menu.addMenu(action_geoclim)
        self.menu.addAction(action_geowrsi)
        action_geoclim.addAction(action_geoclim_sub)
        action_geoclim.addAction(action_reclass)
        self.iface.mainWindow().menuBar().insertMenu(
            self.iface.firstRightStandardMenu().menuAction(),
            self.menu)

        # users have the option to move the workspace from the default
        # so before deploying the workspace to the default location,
        # c:\Users\<user>\Documents, check if there is a workspace setting
        # in the database and if there is a GeoCLIM folder at that location
        # If so, do nothing

        # Note that if the workspace setting is 'c:\Workspace' (default value
        # in the db for a fresh deployment), and there is a GeoCLIM folder
        # at that location, do nothing.  The user may have actually
        # selected that location, so if it's there, leave it alone.

        # Else if the workspace setting is 'c:\Workspace' (default value in
        # the db for a fresh deployment), and there is NOT a GeoCLIM folder
        # at that location, deploy a copy of the workspace template to the
        # default location.
        # check if database file exist, create one from example if not
        if not os.path.exists(config.DB_FILE):
            first_run = True
            shutil.copy(config.EXAMPLE_DB_FILE, config.DB_FILE)
        else:
            first_run = False
        wrksp_setup = WorkspaceSetupModel()
        settings = WorkspaceSetupController()
        workspace = wrksp_setup.get_workspace()
        folder_list = workspace.split(os.sep)
        # if folder_list has a last element that is empty, drop it...
        if folder_list[-1] == '':
            folder_list = folder_list[0:-1]
        # Check for the 'GeoCLIM' folder, because the 'Output' sub-folder
        # can also be moved to another location using the output options.
        if not (os.path.isdir(workspace) and folder_list[-1] == 'GeoCLIM'):
            if first_run is True:
                if os.path.exists(config.OLD_DB_FILE):
                    settings.migrate_database()
                    wrksp_setup.__init__()
                    workspace = wrksp_setup.get_workspace()
                    settings.build_default_workspace(workspace)
                else:
                    settings.build_default_workspace('')
        
        self.hide_qgis_toolbars()

    def hide_qgis_toolbars(self):
        """
          Hide all QGIS default toolbars (user can reselect, if desired)
        """
        self.iface.digitizeToolBar().setVisible(False)
        self.iface.mapNavToolToolBar().setVisible(False)
        self.iface.advancedDigitizeToolBar().setVisible(False)
        self.iface.pluginToolBar().setVisible(False)
        self.iface.layerToolBar().setVisible(False)
        self.iface.databaseToolBar().setVisible(False)
        self.iface.fileToolBar().setVisible(False)
        self.iface.helpToolBar().setVisible(False)
        self.iface.vectorToolBar().setVisible(False)
        self.iface.rasterToolBar().setVisible(False)
        self.iface.webToolBar().setVisible(False)
        self.iface.attributesToolBar().setVisible(False)
        self.iface.mainWindow().findChild(
            QToolBar, 'mLabelToolBar').setVisible(False)
        self.iface.mainWindow().findChild(
            QToolBar, 'mLayerToolBar').setVisible(False)

    def geoclim(self):
        """        Enable GeoCLIM functionality        """
        if self.geoclim_actions:
            return  # keep from duplicating

        # If neither toolbar has been added yet show workspace path
        if not self.geoclim_actions and not self.geowrsi_actions:
            self.show_workspace_path()

        geoclim_tool_dic = {
            "workspace.png": {"text": "Workspace Settings",
                              "function":  define_workspace_settings},
            "output.png": {"text": "Output Settings",
                           "function": define_output_settings},
            "database.png": {"text": "Add/Edit Datasets",
                             "function": define_datasets},
            "region.png": {"text": "Add/Edit Regions",
                           "function": define_regions},
            "import.png": {"text": "Import Climate Data Archives",
                           "function": import_archive_tool},
            "download.png": {"text": "Download Data",
                             "function":  download_data_tool},
            "view.png": {"text": "View Available Data",
                         "function": view_data_tool},
            "climAnalysis.png": {"text": "Climatological Analysis",
                                 "function": climatological_analysis_tool},
            "summary.png": {"text": "Rainfall Summaries",
                            "function": rainfall_summary_tool},
            "composites.png": {"text": "Composites",
                               "function": composites_tool},
            "contours.png": {"text": "Contours",
                             "function": contours_tool},
            "averages.png": {"text": "Changes in Averages",
                             "function": changes_in_averages_tool},
            "basiics.png": {"text": "BASIICS",
                            "function": basiics_tool},
            "statistics.png": {"text": "Extract Statistics",
                               "function": extract_stats_tool}
        }

        for key in geoclim_tool_dic:
            icon_l = os.path.join(self.icon_dir, key)
            text_l = geoclim_tool_dic[key]["text"]
            func_l = geoclim_tool_dic[key]["function"]
            action_l = QAction(
                QIcon(icon_l), text_l, None)
            action_l.triggered.connect(func_l)
            self.geoclim_actions.append(action_l)
        for action in self.geoclim_actions:
            self.geoclim_toolbar.addAction(action)

        icon_help = os.path.join(self.icon_dir, 'help.png')
        action_help = QAction(
            QIcon(icon_help), 'Help', self.iface.mainWindow())

        help_controller = HelpController(self.iface)
        action_help.setMenu(help_controller.get_menu())
        self.geoclim_actions.append(action_help)
        self.geoclim_toolbar.addAction(action_help)
#        netCDF_controller = NetCDFController(self.iface)
#        self.action_NetCDF.setMenu(netCDF_controller.get_menu())
        # # self.geoclim_toolbar.addAction(self.action_NetCDF)

    def geowrsi(self):
        """        Enable GeoWRSI functionality        """
        if self.geowrsi_actions:
            return  # keep from duplicating

        # If neither toolbar has been added yet show workspace path
        if not self.geoclim_actions and not self.geowrsi_actions:
            self.show_workspace_path()

        geowrsi_tool_dic = {
            "crops.png": {"text": "Add/Edit Crops",
                          "function": define_crops},
            "setup.png": {"text": "WRSI Settings",
                          "function":  define_wrsi_settings},
            "runWRSI.png": {"text": "Run WRSI",
                            "function":  wrsi_tool},
            "climWRSISOSAnalysis.png": {"text": "Climatological WRSI/SOS Analysis",
                                        "function":  wrsi_clim_tool},
            "output.png": {"text": "WRSI Output Settings",
                           "function": define_wrsi_output_settings}
        }

        for key in geowrsi_tool_dic:
            icon_l = os.path.join(self.icon_dir, key)
            text_l = geowrsi_tool_dic[key]["text"]
            func_l = geowrsi_tool_dic[key]["function"]
            action_l = QAction(
                QIcon(icon_l), text_l, None)
            action_l.triggered.connect(func_l)
            self.geowrsi_actions.append(action_l)
        for action in self.geowrsi_actions:
            self.geowrsi_toolbar.addAction(action)

        icon_help = os.path.join(self.icon_dir, 'help.png')
        action_wrsi_help = QAction(
            QIcon(icon_help), 'WRSI Help', self.iface.mainWindow())
        help_controller = WRSIHelpController(self.iface)
        action_wrsi_help.setMenu(help_controller.get_menu())
        self.geowrsi_actions.append(action_wrsi_help)
        self.geowrsi_toolbar.addAction(action_wrsi_help)

    def unload(self):
        '''
        Removes the plugin menu item and icon from QGIS GUI.  This method is
        needed to use the reload during development.  Don't delete it.
        '''
        for action in (self.geoclim_actions + self.geoclim_actions):
            self.iface.removePluginMenu(
                translate_text(u'&FEWS Tools'),
                action)
            self.iface.removeToolBarIcon(action)

    def show_workspace_path(self):
        '''
        Display a popup showing the workspace location
        '''
        wrksp_setup = WorkspaceSetupModel()
        workspace = wrksp_setup.get_workspace()
        folder_list = workspace.split(os.sep)
        # if folder_list has a last element that is empty, drop it...
        if folder_list[-1] == '':
            folder_list = folder_list[0:-1]
        # Check for the 'GeoCLIM' folder, because the 'Output' sub-folder
        # can also be moved to another location using the output options.
        if os.path.isdir(workspace) and folder_list[-1] == 'GeoCLIM':
            QMessageBox.information(
                self.iface.mainWindow(),
                'Existing workspace detected here:',
                workspace, QMessageBox.Ok)
