# -*- coding: utf-8 -*-
"""
/***************************************************************************
 dzetsakaGUI
                                 A QGIS plugin
 desc
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2018-02-24
        git sha              : $Format:%H$
        copyright            : (C) 2018 by Nicolas Karasiak
        email                : karasiak.nicolas@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 basics
from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QAction, QMessageBox, QDialog, QFileDialog, QApplication
from qgis.core import QgsMessageLog, QgsProcessingAlgorithm, QgsApplication


# import outside libraries
#import configparser
import tempfile
import os.path
import gdal
import ogr
import osr

# import local libraries
from . import resources
from . import ui
from .scripts import function_dataraster as dataraster
from .scripts import mainfunction

from .dzetsaka_provider import dzetsakaProvider


class dzetsakaGUI (QDialog):
    """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

        # add Processing loadAlgorithms

        # init dialog and dzetsaka dock
        QDialog.__init__(self)
        #sender = self.sender()
        self.settings = QSettings()
        self.loadConfig()

        self.provider = dzetsakaProvider(self.providerType)
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        if self.firstInstallation is True:
            self.showWelcomeWidget()

        # initialize locale
        """
        locale = self.settings.value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'dzetsaka_{}.qm'.format(locale))

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

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)
        """
        
        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&dzetsaka')
#        # TODO: We are going to let the user set this up in a future iteration
#        self.toolbar = self.iface.addToolBar(u'dzetsaka')
#        self.toolbar.setObjectName(u'dzetsaka')
        self.pluginIsActive = False
        self.dockwidget = None
#        



        # param
        self.lastSaveDir = ''

        # run dock
        # self.run()

    def rememberLastSaveDir(self, fileName):
        """!@brief Remember last sd dir when saving or loading file"""
        if fileName != '':
            self.lastSaveDir = fileName
            self.settings.setValue('/dzetsaka/lastSaveDir', self.lastSaveDir)

    # noinspection PyMethodMayBeStatic
    def showWelcomeWidget(self):
        self.welcomeWidget = ui.welcomeWidget()
        self.welcomeWidget.show()

        self.settings.setValue('/dzetsaka/firstInstallation', False)

    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('dzetsaka', message)

    def add_action(
            self,
            icon_path,
            text,
            callback,
            enabled_flag=True,
            add_to_menu=True,
            add_to_toolbar=True,
            status_tip=None,
            whats_this=None,
            parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

#        if add_to_toolbar:
#            self.toolbar.addAction(action)
#
        if add_to_menu:
            self.iface.addPluginToMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action


    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        QgsApplication.processingRegistry().addProvider(self.provider)

        icon_path = ':/plugins/dzetsaka/img/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'welcome message'),
            callback=self.showWelcomeWidget,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())

        icon_path = ':/plugins/dzetsaka/img/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'classification dock'),
            callback=self.run,
            parent=self.iface.mainWindow())

        icon_settings_path = ':/plugins/dzetsaka/img/dzetsaka_settings.png'
        self.add_action(
            icon_settings_path,
            text=self.tr(u'settings'),
            callback=self.loadSettings,
            add_to_toolbar=True,
            parent=self.iface.mainWindow())
        
        self.dockIcon = QAction(QIcon(':/plugins/dzetsaka/img/icon.png'), 'dzetsaka classification dock', self.iface.mainWindow())
        self.dockIcon.triggered.connect(self.run)
        self.iface.addToolBarIcon(self.dockIcon)
        self.actions.append(self.dockIcon)
        
        self.settingsIcon = QAction(QIcon(':/plugins/dzetsaka/img/dzetsaka_settings.png'), 'dzetsaka settings', self.iface.mainWindow())
        self.settingsIcon.triggered.connect(self.loadSettings)
        self.iface.addToolBarIcon(self.settingsIcon)
        self.actions.append(self.settingsIcon)
        
    # --------------------------------------------------------------------------

    def onClosePlugin(self):
        """Cleanup necessary items here when plugin dockwidget is closed"""

        #print "** CLOSING dzetsakaGUI"
        # disconnects
        self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)

        # remove this statement if dockwidget is to remain
        # for reuse if plugin is reopened
        # Commented next statement since it causes QGIS crashe
        # when closing the docked window:
        # self.dockwidget = None

        self.pluginIsActive = False

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""

        # close dock
        self.pluginIsActive = False
        if self.dockwidget is not None:
            self.dockwidget.close()

        # Remove processing algorithms
        QgsApplication.processingRegistry().removeProvider(self.provider)
        
        
#        self.iface.removePluginMenu(self.pluginName, self.settingsIcon)
#        self.iface.removePluginMenu(self.tr(u'&dzetsaka'),self.actions[0])
        
        for action in self.actions:
            self.iface.removeToolBarIcon(action)
            self.iface.removePluginMenu(
                self.tr(u'&dzetsaka'),
                action)
#
#        # remove the toolbar
#       qg del self.toolbar
    # --------------------------------------------------------------------------

    def run(self):
        """Run method that loads and starts the plugin"""

        if not self.pluginIsActive or self.dockwidget is None:
            self.pluginIsActive = True

            #print "** STARTING dzetsakaGUI"

            # dockwidget may not exist if:
            #    first run of plugin
            #    removed on close (see self.onClosePlugin method)
            if self.dockwidget is None:
                # Create the dockwidget (after translation) and keep reference
                self.dockwidget = ui.dzetsakaDockWidget()

            # connect to provide cleanup on closing of dockwidget
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)

            from qgis.core import QgsProviderRegistry
            exceptRaster = QgsProviderRegistry.instance().providerList()
            exceptRaster.remove('gdal')
            self.dockwidget.inRaster.setExcludedProviders(exceptRaster)

            exceptVector = QgsProviderRegistry.instance().providerList()
            exceptVector.remove('ogr')
            self.dockwidget.inShape.setExcludedProviders(exceptVector)

            self.dockwidget.outRaster.clear()
            self.dockwidget.outRasterButton.clicked.connect(
                self.select_output_file)

            self.dockwidget.outModel.clear()
            self.dockwidget.checkOutModel.clicked.connect(self.checkbox_state)

            self.dockwidget.inModel.clear()
            self.dockwidget.checkInModel.clicked.connect(self.checkbox_state)

            self.dockwidget.inMask.clear()
            self.dockwidget.checkInMask.clicked.connect(self.checkbox_state)

            self.dockwidget.outMatrix.clear()
            self.dockwidget.checkOutMatrix.clicked.connect(self.checkbox_state)

            self.dockwidget.outConfidenceMap.clear()
            self.dockwidget.checkInConfidence.clicked.connect(
                self.checkbox_state)

            self.dockwidget.inField.clear()

            # show the dockwidget
            # TODO: fix to allow choice of dock location
            self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockwidget)
            self.dockwidget.show()

            def onChangedLayer():
                """!@brief Update columns if vector changes"""
                # We clear combobox
                self.dockwidget.inField.clear()
                # Then we fill it with new selected Layer
                if self.dockwidget.inField.currentText() == '' and self.dockwidget.inShape.currentLayer(
                ) and self.dockwidget.inShape.currentLayer() != 'NoneType':
                    try:
                        activeLayer = self.dockwidget.inShape.currentLayer()
                        provider = activeLayer.dataProvider()
                        fields = provider.fields()
                        listFieldNames = [field.name() for field in fields]
                        self.dockwidget.inField.addItems(listFieldNames)
                    except BaseException:
                        QgsMessageLog.logMessage(
                            'dzetsaka cannot change active layer. Maybe you opened an OSM/Online background ?')

            onChangedLayer()
            self.dockwidget.inShape.currentIndexChanged[int].connect(
                onChangedLayer)

            self.dockwidget.settingsButton.clicked.connect(self.loadSettings)

            # let's run the classification !
            self.dockwidget.performMagic.clicked.connect(self.runMagic)

            # self.dockwidget.mGroupBox.toggled.connect(self.resizeDock)
            self.dockwidget.mGroupBox.collapsedStateChanged.connect(
                self.resizeDock)

    def resizeDock(self):

        if self.dockwidget.mGroupBox.isCollapsed():

            self.dockwidget.mGroupBox.setFixedHeight(20)
            self.dockwidget.setFixedHeight(350)

        else:
            self.dockwidget.setMinimumHeight(470)
            self.dockwidget.mGroupBox.setMinimumHeight(160)

    def select_output_file(self):
        """!@brief Select file to save, and gives the right extension if the user don't put it"""
        sender = self.sender()

        fileName, _filter = QFileDialog.getSaveFileName(
            self.dockwidget, "Select output file", self.lastSaveDir, "TIF (*.tif)")
        self.rememberLastSaveDir(fileName)

        if not fileName:
            return
            # If user give right file extension, we don't add it

        fileName, fileExtension = os.path.splitext(fileName)

        if sender == self.dockwidget.outRasterButton:
            if fileExtension != '.tif':
                self.dockwidget.outRaster.setText(fileName + '.tif')
            else:
                self.dockwidget.outRaster.setText(fileName + fileExtension)

        # check if historical map run
        if 'self.historicalmap' in locals():
            if sender == self.historicalmap.outRasterButton:
                if fileExtension != '.tif':
                    self.historicalmap.outRaster.setText(fileName + '.tif')
                else:
                    self.historicalmap.outRaster.setText(
                        fileName + fileExtension)
            if sender == self.historicalmap.outShpButton:
                if fileExtension != '.shp':
                    self.historicalmap.outShp.setText(fileName + '.shp')
                else:
                    self.historicalmap.outShp.setText(fileName + fileExtension)
        # check if filters_dock run
        if 'self.filters_dock' in locals():
            if sender == self.filters_dock.outRasterButton:
                if fileExtension != '.tif':
                    self.filters_dock.outRaster.setText(fileName + '.tif')
            else:
                self.filters_dock.outRaster.setText(fileName + fileExtension)

    def loadConfig(self):
        """!@brief Class that loads all saved settings from config.txt"""

        try:
            """
            dzetsakaRoot = os.path.dirname(os.path.realpath(__file__))
            self.Config = configparser.ConfigParser()
            self.configFile = os.path.join(dzetsakaRoot,'config.txt')
            self.Config.read(self.configFile)


            self.classifier = self.Config.get('Classification','classifier')


            self.classSuffix = self.Config.get('Classification','suffix')
            self.classPrefix = self.Config.get('Classification','prefix')

            self.maskSuffix = self.Config.get('Classification','maskSuffix')

            self.providerType = self.Config.get('Providers','provider')
            """
            self.classifiers = [
                'Gaussian Mixture Model',
                'Random Forest',
                'Support Vector Machines',
                'K-Nearest Neighbors']
            self.providers = ['Standard', 'Experimental']

            self.classifier = self.settings.value(
                '/dzetsaka/classifier', '', str)
            if not self.classifier:
                self.classifier = self.classifiers[0]
                self.settings.setValue('/dzetsaka/classifier', self.classifier)

            self.classSuffix = self.settings.value(
                '/dzetsaka/classSuffix', '', str)
            if not self.classSuffix:
                self.classSuffix = '_class'
                self.settings.setValue(
                    '/dzetsaka/classSuffix', self.classSuffix)

            self.classPrefix = self.settings.value(
                '/dzetsaka/classPrefix', '', str)
            if not self.classPrefix:
                self.classPrefix = ''
                self.settings.setValue(
                    '/dzetsaka/classPrefix', self.classPrefix)

            self.maskSuffix = self.settings.value(
                '/dzetsaka/maskSuffix', '', str)
            if not self.maskSuffix:
                self.maskSuffix = '_mask'
                self.settings.setValue('/dzetsaka/maskSuffix', self.maskSuffix)

            self.providerType = self.settings.value(
                '/dzetsaka/providerType', '', str)
            if not self.providerType:
                self.providerType = self.providers[0]
                self.providerType = self.settings.setValue(
                    '/dzetsaka/providerType', self.providerType)

            self.firstInstallation = self.settings.value(
                '/dzetsaka/firstInstallation', 'None', bool)
            if self.firstInstallation is None:
                self.firstInstallation = True
                self.settings.setValue('/dzetsaka/firstInstallation', True)

        except BaseException:
            QgsMessageLog.logMessage(
                'failed to open config file ' + self.configFile)

    def loadSettings(self):
        """!@brief load settings dock"""
        self.settingsdock = ui.settings_dock()
        self.settingsdock.show()

        try:
            # Reload config
            self.loadConfig()
            # Classification settings

            # classifier

            for i, cls in enumerate(self.classifiers):
                if self.classifier == cls:
                    self.settingsdock.selectClassifier.setCurrentIndex(i)

            self.settingsdock.selectClassifier.currentIndexChanged[int].connect(
                self.saveSettings)

            self.settings.setValue('/dzetsaka/classifier', self.classifier)

            # suffix
            self.settingsdock.classSuffix.setText(self.classSuffix)
            self.settingsdock.classSuffix.textChanged.connect(
                self.saveSettings)
            self.settings.setValue('/dzetsaka/classSuffix', self.classSuffix)
            # prefix
            self.settingsdock.classPrefix.setText(self.classPrefix)
            self.settingsdock.classPrefix.textChanged.connect(
                self.saveSettings)
            self.settings.setValue('/dzetsaka/classPrefix', self.classPrefix)
            # mask suffix
            self.settingsdock.maskSuffix.setText(self.maskSuffix)
            self.settingsdock.maskSuffix.textChanged.connect(self.saveSettings)
            self.settings.setValue('/dzetsaka/maskSuffix', self.maskSuffix)
            ##

            for i, prvd in enumerate(self.providers):
                if self.providerType == prvd:
                    self.settingsdock.selectProviders.setCurrentIndex(i)

            self.settingsdock.selectProviders.currentIndexChanged[int].connect(
                self.saveSettings)
            self.settings.setValue('/dzetsaka/providerType', self.providerType)
            # Reload config for further use
            self.loadConfig()

        except BaseException:
            QgsMessageLog.logMessage('Failed to load settings...')

    def runMagic(self):
        """!@brief Perform training and classification for dzetsaka"""

        """
        VERIFICATION STEP
        """
        # verif before doing the job
        message = ' '

        if self.dockwidget.inModel.text() == '':
            try:
                self.dockwidget.inShape.currentLayer().dataProvider().dataSourceUri()
            except BaseException:
                message = "\n - If you don't use a model, please specify a vector"
        try:
            self.dockwidget.inRaster.currentLayer().dataProvider().dataSourceUri()
        except BaseException:
            message = message + \
                str("\n - You need a raster to make a classification.")

        try:

            # get raster
            inRaster = self.dockwidget.inRaster.currentLayer()
            inRaster = inRaster.dataProvider().dataSourceUri()

            # get raster proj
            inRasterOp = gdal.Open(inRaster)
            inRasterProj = inRasterOp.GetProjection()
            inRasterProj = osr.SpatialReference(inRasterProj)

            if self.dockwidget.inModel.text() == '':
                # verif srs
                # get vector
                inShape = self.dockwidget.inShape.currentLayer()
                inShape = inShape.dataProvider().dataSourceUri().split('|')[
                    0]  # Remove layerid=0 from SHP Path
                # get shp proj
                inShapeOp = ogr.Open(inShape)
                inShapeLyr = inShapeOp.GetLayer()
                inShapeProj = inShapeLyr.GetSpatialRef()

                # chekc IsSame Projection
                if inShapeProj.IsSameGeogCS(inRasterProj) == 0:
                    message = message + \
                        str("\n - Raster and ROI do not have the same projection.")
        except BaseException:
            QgsMessageLog.logMessage('inShape is : ' + inShape)
            QgsMessageLog.logMessage('inRaster is : ' + inRaster)
            QgsMessageLog.logMessage(
                'inShapeProj.IsSameGeogCS(inRasterProj) : ' +
                inShapeProj.IsSameGeogCS(inRasterProj))
            message = message + \
                str('\n - Can\'t compare projection between raster and vector.')

        try:
            inMask = self.dockwidget.inMask.text()

            if inMask == '':
                inMask = None
            # check if mask with _mask.extension
            autoMask = os.path.splitext(inRaster)
            autoMask = autoMask[0] + self.maskSuffix + autoMask[1]

            if os.path.exists(autoMask):
                inMask = autoMask
                QgsMessageLog.logMessage('Mask found : ' + str(autoMask))

            if inMask is not None:
                mask = gdal.Open(inMask, gdal.GA_ReadOnly)
            # Check size
                if (inRasterOp.RasterXSize != mask.RasterXSize) or (
                        inRasterOp.RasterYSize != mask.RasterYSize):
                    message = message + \
                        str('\n - Raster image and mask do not have the same size.')

        except BaseException:
            message = message + \
                str('\n - Can\'t compare mask and raster size.')
        """ END OF VERIFICATION STEP """

        if message != ' ':

            reply = QMessageBox.question(self.iface.mainWindow(), 'Informations missing or invalid',
                                         message + '\n Would you like to continue anyway ?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

            if reply == QMessageBox.Yes:
                message = ' '

        # all is ok, so do the job !
        if message == ' ':
            # get config
            self.loadConfig()
            # Get model if given
            model = self.dockwidget.inModel.text()

# ==============================================================================
#             # if model not given, perform training
#             inRaster=self.dockwidget.inRaster.currentLayer()
#             inRaster=inRaster.dataProvider().dataSourceUri()
# ==============================================================================

            # create temp if not output raster
            if self.dockwidget.outRaster.text() == '':
                tempFolder = tempfile.mkdtemp()
                outRaster = os.path.join(
                    tempFolder,
                    self.classPrefix +
                    os.path.splitext(
                        os.path.basename(inRaster))[0] +
                    self.classSuffix +
                    '.tif')

            else:
                outRaster = self.dockwidget.outRaster.text()

            # Confidence map

            if self.dockwidget.checkInConfidence.isChecked():
                confidenceMap = self.dockwidget.outConfidenceMap.text()
            else:
                confidenceMap = None

            # Get Classifier
            # retrieve shortname classifier
            classifierShortName = ['GMM', 'RF', 'SVM', 'KNN']
            for i, cls in enumerate(self.classifiers):
                if self.classifier == cls:
                    inClassifier = classifierShortName[i]

            # Check if model, else perform training
            NODATA = -9999

            if model != '':
                model = self.dockwidget.inModel.text()
                QgsMessageLog.logMessage('Model is ' + str(model))
            else:
                if self.dockwidget.outModel.text() == '':
                    model = tempfile.mktemp('.' + str(inClassifier))
                else:
                    model = self.dockwidget.outModel.text()
                QgsMessageLog.logMessage('No model loaded')

            inField = self.dockwidget.inField.currentText()
            inSeed = 0
            # Perform training & classification
            if self.dockwidget.checkOutMatrix.isChecked():
                outMatrix = self.dockwidget.outMatrix.text()
                inSplit = self.dockwidget.inSplit.value()
            else:
                inSplit = 100
                outMatrix = None

            try:

                if not self.dockwidget.checkInModel.isChecked():
                    QgsMessageLog.logMessage(
                        'Begin training with ' + inClassifier + ' classifier')

                    temp = mainfunction.learnModel(
                        inRaster,
                        inShape,
                        inField,
                        model,
                        inSplit,
                        inSeed=inSeed,
                        outMatrix=outMatrix,
                        inClassifier=inClassifier,
                        extraParam=None,
                        feedback='gui')

                    # perform learning

                stop = False
            except BaseException:
                QgsMessageLog.logMessage('Raster is' + str(inRaster))
                QgsMessageLog.logMessage('Vector is' + str(inShape))
                QgsMessageLog.logMessage('Column field is ' + str(inField))
                QgsMessageLog.logMessage('Split is' + str(inSplit))
                QgsMessageLog.logMessage('Model is ' + str(model))

                message = (
                    'Something went wrong during the training. Please make sure you respect these conditions : <br> - Are you sure to have only integer values in your ' +
                    str(inField) +
                    ' column ? <br> - Do your shapefile and raster have the same projection ?')
                QMessageBox.warning(
                    self,
                    'dzetsaka has encountered a problem',
                    message,
                    QMessageBox.Ok)
                stop = True
                QApplication.restoreOverrideCursor()
                

            if not stop:
                # Begin classification
                QgsMessageLog.logMessage(
                    'Begin classification with ' + str(inClassifier))
                temp = mainfunction.classifyImage()

                temp.initPredict(
                    inRaster,
                    model,
                    outRaster,
                    inMask=inMask,
                    confidenceMap=confidenceMap,
                    confidenceMapPerClass=None,
                    NODATA=NODATA,
                    feedback='gui')
                QgsMessageLog.logMessage('Dzetsaka classification done.')
                self.iface.addRasterLayer(outRaster)

                if confidenceMap:
                    self.iface.addRasterLayer(confidenceMap)

    def checkbox_state(self):
        """!@brief Manage checkbox in main dock"""

        sender = self.sender()

        # If load model
        if sender == self.dockwidget.checkInModel and self.dockwidget.checkInModel.isChecked():
            fileName, _filter = QFileDialog.getOpenFileName(
                self.dockwidget, "Select your file", self.lastSaveDir)
            self.rememberLastSaveDir(fileName)
            if fileName != '':
                self.dockwidget.inModel.setText(fileName)
                self.dockwidget.inModel.setEnabled(True)
                # Disable training, so disable vector choise
                self.dockwidget.inShape.setEnabled(False)
                self.dockwidget.inField.setEnabled(False)

            else:
                self.dockwidget.checkInModel.setChecked(False)
                self.dockwidget.inModel.setEnabled(False)
                self.dockwidget.inShape.setEnabled(True)
                self.dockwidget.inField.setEnabled(True)

        elif sender == self.dockwidget.checkInModel:
            self.dockwidget.inModel.clear()
            self.dockwidget.inModel.setEnabled(False)
            self.dockwidget.inShape.setEnabled(True)
            self.dockwidget.inField.setEnabled(True)

        # If save model
        if sender == self.dockwidget.checkOutModel and self.dockwidget.checkOutModel.isChecked():
            fileName, _filter = QFileDialog.getSaveFileName(
                self.dockwidget, "Select output file", self.lastSaveDir)
            self.rememberLastSaveDir(fileName)
            if fileName != '':
                self.dockwidget.outModel.setText(fileName)
                self.dockwidget.outModel.setEnabled(True)

            else:
                self.dockwidget.checkOutModel.setChecked(False)
                self.dockwidget.outModel.setEnabled(False)

        elif sender == self.dockwidget.checkOutModel:
            self.dockwidget.outModel.clear()
            self.dockwidget.outModel.setEnabled(False)

        # If mask
        if sender == self.dockwidget.checkInMask and self.dockwidget.checkInMask.isChecked():
            fileName, _filter = QFileDialog.getOpenFileName(
                self.dockwidget, "Select your mask raster", self.lastSaveDir, "TIF (*.tif)")
            self.rememberLastSaveDir(fileName)
            if fileName != '':

                self.dockwidget.inMask.setText(fileName)
                self.dockwidget.inMask.setEnabled(True)
            else:
                self.dockwidget.checkInMask.setChecked(False)
                self.dockwidget.inMask.setEnabled(False)
        elif sender == self.dockwidget.checkInMask:
            self.dockwidget.inMask.clear()
            self.dockwidget.inMask.setEnabled(False)

        # If save matrix
        if sender == self.dockwidget.checkOutMatrix and self.dockwidget.checkOutMatrix.isChecked():
            fileName, _filter = QFileDialog.getSaveFileName(
                self.dockwidget, "Save to a *.csv file", self.lastSaveDir, "CSV (*.csv)")
            self.rememberLastSaveDir(fileName)
            if fileName != '':
                fileName, fileExtension = os.path.splitext(fileName)
                fileName = fileName + '.csv'
                self.dockwidget.outMatrix.setText(fileName)
                self.dockwidget.outMatrix.setEnabled(True)
                self.dockwidget.inSplit.setEnabled(True)
                self.dockwidget.inSplit.setValue(50)
            else:
                self.dockwidget.checkOutMatrix.setChecked(False)
                self.dockwidget.outMatrix.setEnabled(False)
                self.dockwidget.outMatrix.setEnabled(False)
                self.dockwidget.inSplit.setEnabled(False)
                self.dockwidget.inSplit.setValue(100)

        elif sender == self.dockwidget.checkOutMatrix:
            self.dockwidget.outMatrix.clear()
            self.dockwidget.checkOutMatrix.setChecked(False)
            self.dockwidget.outMatrix.setEnabled(False)
            self.dockwidget.outMatrix.setEnabled(False)
            self.dockwidget.inSplit.setEnabled(False)
            self.dockwidget.inSplit.setValue(100)

      # If save model
        # retrieve shortname classifier
        if sender == self.dockwidget.checkInConfidence and self.dockwidget.checkInConfidence.isChecked():
            fileName, _filter = QFileDialog.getSaveFileName(
                self.dockwidget, "Select output file (*.tif)", self.lastSaveDir, "TIF (*.tif)")
            self.rememberLastSaveDir(fileName)
            if fileName != '':
                fileName, fileExtension = os.path.splitext(fileName)
                fileName = fileName + '.tif'
                self.dockwidget.outConfidenceMap.setText(fileName)
                self.dockwidget.outConfidenceMap.setEnabled(True)

            else:
                self.dockwidget.checkInConfidence.setChecked(False)
                self.dockwidget.outConfidenceMap.setEnabled(False)

        elif sender == self.dockwidget.checkInConfidence:
            self.dockwidget.outConfidenceMap.clear()
            self.dockwidget.checkInConfidence.setChecked(False)
            self.dockwidget.outConfidenceMap.setEnabled(False)

    def saveSettings(self):
        """!@brief save settings if modifications"""
        # Change classifier
        if self.sender() == self.settingsdock.selectClassifier:
            if self.settingsdock.selectClassifier.currentText() != 'Gaussian Mixture Model':
                # try if Sklearn is installed, or force GMM
                try:
                    from sklearn import metrics
                    if self.classifier != self.settingsdock.selectClassifier.currentText():
                        # self.modifyConfig('Classification','classifier',self.settingsdock.selectClassifier.currentText())
                        self.settings.setValue(
                            '/dzetsaka/classifier',
                            self.settingsdock.selectClassifier.currentText())
                except BaseException:
                    QMessageBox.warning(
                        self,
                        'Library missing',
                        'Scikit-learn library is missing on your computer.<br><br> You must use Gaussian Mixture Model, or <a href=\'https://github.com/lennepkade/dzetsaka/#installation-of-scikit-learn\'>consult dzetsaka homepage to learn on to install the missing library</a>.',
                        QMessageBox.Ok)
                    # reset to GMM
                    self.settingsdock.selectClassifier.setCurrentIndex(0)
                    #self.modifyConfig('Classification','classifier','Gaussian Mixture Model')
                    self.settings.setValue(
                        '/dzetsaka/classifier', 'Gaussian Mixture Model')
            else:
                #self.modifyConfig('Classification','classifier','Gaussian Mixture Model')
                self.settings.setValue(
                    '/dzetsaka/classifier',
                    'Gaussian Mixture Model')

        if self.sender() == self.settingsdock.classSuffix:
            if self.classSuffix != self.settingsdock.classSuffix.text():
                # self.modifyConfig('Classification','suffix',self.settingsdock.classSuffix.text())
                self.settings.setValue(
                    '/dzetsaka/classSuffix',
                    self.settingsdock.classSuffix.text())
        if self.sender() == self.settingsdock.classPrefix:
            if self.classPrefix != self.settingsdock.classPrefix.text():
                # self.modifyConfig('Classification','prefix',self.settingsdock.classPrefix.text())
                self.settings.setValue(
                    '/dzetsaka/classPrefix',
                    self.settingsdock.classPrefix.text())
        if self.sender() == self.settingsdock.maskSuffix:
            if self.maskSuffix != self.settingsdock.maskSuffix.text():
                # self.modifyConfig('Classification','maskSuffix',self.settingsdock.maskSuffix.text())
                self.settings.setValue(
                    '/dzetsaka/maskSuffix',
                    self.settingsdock.maskSuffix.text())
        if self.sender() == self.settingsdock.selectProviders:
            self.providerType = self.settingsdock.selectProviders.currentText()

            # self.modifyConfig('Providers','provider',self.settingsdock.selectProviders.currentText())
            self.settings.setValue(
                '/dzetsaka/providerType',
                self.settingsdock.selectProviders.currentText())
            QgsApplication.processingRegistry().removeProvider(self.provider)

            from .dzetsaka_provider import dzetsakaProvider
            self.provider = dzetsakaProvider(self.providerType)
            QgsApplication.processingRegistry().addProvider(self.provider)

    def modifyConfig(self, section, option, value):
        configFile = open(self.configFile, 'w')
        self.Config.set(section, option, value)
        self.Config.write(configFile)
        configFile.close()