'''
/***************************************************************************
Name       :  geowrsi_settings_controller.py
Description:  Controller for GeoWRSI Tool
copyright  :  (C) 2022-2023 by FEWS
email      :  dhackman@contractor.usgs.gov
Author     :  Derek Hackman
Modified   :  mm/dd/yyyy - descripton - Description


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

/***************************************************************************
 *                                                                         *
 *   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

from PyQt5.QtWidgets import QDialog, QFileDialog, QMessageBox

from fews_tools.forms.Ui_GeoWRSISettings import Ui_GeoWRSISettings
from fews_tools.controllers.import_vector_to_raster_controller import ImportVectorToRasterController
from fews_tools.controllers.import_vector_to_raster_sos_controller import ImportVectorToRasterControllerSOS
from fews_tools.controllers.import_vector_to_raster_lgp_controller import ImportVectorToRasterControllerLGP
from fews_tools.controllers.import_vector_to_raster_whc_controller import ImportVectorToRasterControllerWHC
from fews_tools.controllers.sos_controller import SOSController
from fews_tools.models.datasets_model import DatasetsModel
from fews_tools.models.region_model import RegionModel
from fews_tools.models.workspace_setup_model import WorkspaceSetupModel

from fews_tools import fews_tools_config as config
from fews_tools.utilities import geoclim_qgs_utilities as qgs_util
from fews_tools.utilities import geoclim_utilities as util
from fews_tools.utilities import geowrsi_utilities as geo_util


class GeoWRSISettings(QDialog):
    '''
    Class to set up the GeoWrsi settings
    '''

    def __init__(self):
        QDialog.__init__(self)
        self.ui = Ui_GeoWRSISettings()
        self.ui.setupUi(self)
        self.wrksp_setup = WorkspaceSetupModel()
        self.reg_info = RegionModel()
        self.reg_dic = {}
        self.ds_dic_ppt = {}
        self.ds_dic_pet = {}
        self.browse_path = self.wrksp_setup.get_static_data_path()
        self.output_path =\
            os.path.join(self.wrksp_setup.get_workspace(),
                         config.PROGRAM_SETTINGS,
                         config.GEOWRSI_SETTINGS_FILE)
        self.set_dic = geo_util.get_default_settings_dic()
        self.reset_bool = False

        self.sos_default_settings = {
            'type_of_sos_calculation': "3-Period Rain Threshold",
            'period_1_rainfall': 25,
            'period_2_3_rainfall': 20,
            'ignore_sos_clim': False,
            'max_periods_early': 2,
            'max_periods_late': 9,
            'recalculate_sos_after_crop_failure': False,
            'crop_failure_definition_for_restart': None,
            'crop_failure_definition_for_restart_percent': 30,
            'dont_restart_after': 40,
            'max_growing_periods_after_eos': 6,
            'exclude_areas_less_than': False,
            'exclude_areas_less_than_percent': 90}

        self.__initial_form_load__()
        self.ui.saveButton.clicked.connect(self.save_settings)
        self.ui.calculatedSOSRadioButton.toggled.connect(
            self.set_sos_functionality)
        self.ui.selectedSOSRadioButton.toggled.connect(
            self.set_sos_functionality)
        self.ui.specifySOSPeriodRadioButton.toggled.connect(
            self.set_sos_functionality)
        self.ui.climatologicalSOSRadioButton.toggled.connect(
            self.set_sos_functionality)
        self.ui.SOSFileBrowseButton.clicked.connect(self.get_browsed_file)
        self.ui.SOSPeriodSpinBox.valueChanged.connect(
            self.set_sos_functionality)
        self.ui.adjustSOSCalculationParametersButton.clicked.connect(
            self.adjust_sos_calculation_parameters)
        self.ui.defaultLGPRadioButton.toggled.connect(
            self.set_lgp_functionality)
        self.ui.selectedLGPRadioButton.toggled.connect(
            self.set_lgp_functionality)
        self.ui.specifyGrowingPeriodLGPRadioButton.toggled.connect(
            self.set_lgp_functionality)
        self.ui.LGPFileBrowseButton.clicked.connect(self.get_browsed_file)
        self.ui.specifyGrowingPeriodLGPSpinBox.valueChanged.connect(
            self.set_lgp_functionality)
        self.ui.defaultWHCRadioButton.toggled.connect(
            self.set_whc_functionality)
        self.ui.selectedWHCRadioButton.toggled.connect(
            self.set_whc_functionality)
        self.ui.specifyWHCRadioButton.toggled.connect(
            self.set_whc_functionality)
        self.ui.WHCFileBrowseButton.clicked.connect(self.get_browsed_file)
        self.ui.specifyWHCSpinBox.valueChanged.connect(
            self.set_whc_functionality)
        self.ui.defaultMaskRadioButton.toggled.connect(
            self.set_mask_functionality)
        self.ui.maskFileBrowseButton.clicked.connect(self.get_browsed_file)
        self.ui.importMaskFromVectorButton.clicked.connect(
            self.import_mask_from_shape)
        self.ui.importSOSFromVectorButton.clicked.connect(
            self.import_sos_from_shape)
        self.ui.importLGPFromVectorButton.clicked.connect(
            self.import_lgp_from_shape)
        self.ui.importWHCFromVectorButton.clicked.connect(
            self.import_whc_from_shape)
        self.ui.resetButton.clicked.connect(self.reset_to_defaults)
        # On a change of region, need to call the set functionality for each
        # tab so that any defaults get reset for the regions
        self.ui.regionComboBox.currentIndexChanged.connect(
            self.set_all_tabs_functionality)
        

    def __initial_form_load__(self):
        '''
        Load the setings GUI with the default region, crop and overall setup
        '''
        self.set_dic = geo_util.set_settings_dic_from_file(self.output_path,
                                                           self.set_dic)
        # Setup Ui based on the set_dic
        self.set_gui_from_dic()

    def set_gui_from_dic(self):
        # Setup Region ComboBox
        if not self.reset_bool:
            util.fill_misc_widget(self.ui.regionComboBox,
                                self.get_geowrsi_regions())
        else:
            self.ui.regionComboBox.setCurrentIndex(0)
        if self.set_dic['analysis_region'] != '':
            self.ui.regionComboBox.setCurrentText(self.set_dic['analysis_region'])

        # Setup Crop ComboBox
        util.fill_crop_combo(self.ui.cropComboBox)
        if self.set_dic['crop_type'] != '':
            self.ui.cropComboBox.setCurrentText(self.set_dic['crop_type'])

        # Setup SOS Tab
        if self.set_dic['sos_type'] == 'Calculated':
            self.ui.SOSPeriodSpinBox.setEnabled(False)
            self.ui.SOSFileBrowseButton.setEnabled(False)
            self.ui.calculatedSOSRadioButton.setChecked(True)
        elif self.set_dic['sos_type'] == 'Selected':
            self.ui.SOSPeriodSpinBox.setEnabled(False)
            self.ui.SOSFileBrowseButton.setEnabled(True)
            self.ui.SOSFileLineEdit.setText(self.set_dic['sos_file'])
            self.ui.selectedSOSRadioButton.setChecked(True)
        elif self.set_dic['sos_type'] == 'Specified':
            self.ui.SOSPeriodSpinBox.setEnabled(True)
            self.ui.SOSFileBrowseButton.setEnabled(False)
            self.ui.SOSPeriodSpinBox.setValue(int(self.set_dic['sos_period']))
            self.ui.specifySOSPeriodRadioButton.setChecked(True)
        elif self.set_dic['sos_type'] == 'Climatological':
            self.ui.SOSPeriodSpinBox.setEnabled(False)
            self.ui.SOSFileBrowseButton.setEnabled(False)
            self.ui.climatologicalSOSRadioButton.setChecked(True)
        # Disabled SOS Features as we are not sure what they do
        self.ui.SOSOffsetSpinBox.setEnabled(False)
        self.ui.specifyClimatologicalSOSButton.setEnabled(False)

        # Setup LGP Tab
        if self.set_dic['lgp_type'] == 'Default':
            self.ui.specifyGrowingPeriodLGPSpinBox.setEnabled(False)
            self.ui.LGPFileBrowseButton.setEnabled(False)
            self.ui.defaultLGPRadioButton.setChecked(True)
        elif self.set_dic['lgp_type'] == 'Selected':
            self.ui.specifyGrowingPeriodLGPSpinBox.setEnabled(False)
            self.ui.LGPFileBrowseButton.setEnabled(True)
            self.ui.LGPFileLineEdit.setText(self.set_dic['lgp_file'])
            self.ui.selectedLGPRadioButton.setChecked(True)
        elif self.set_dic['lgp_type'] == 'Specified':
            self.ui.specifyGrowingPeriodLGPSpinBox.setEnabled(True)
            self.ui.LGPFileBrowseButton.setEnabled(False)
            self.ui.specifyGrowingPeriodLGPSpinBox.setValue(
                int(self.set_dic['lgp_period']))
            self.ui.specifyGrowingPeriodLGPRadioButton.setChecked(True)
        
        # Setup WHC Tab
        if self.set_dic['whc_type'] == 'Default':
            self.ui.specifyWHCSpinBox.setEnabled(False)
            self.ui.WHCFileBrowseButton.setEnabled(False)
            self.ui.defaultWHCRadioButton.setChecked(True)
        elif self.set_dic['whc_type'] == 'Selected':
            self.ui.specifyWHCSpinBox.setEnabled(False)
            self.ui.WHCFileBrowseButton.setEnabled(True)
            self.ui.WHCFileLineEdit.setText(self.set_dic['whc_file'])
            self.ui.selectedWHCRadioButton.setChecked(True)
        elif self.set_dic['whc_type'] == 'Specified':
            self.ui.specifyWHCSpinBox.setEnabled(True)
            self.ui.WHCFileBrowseButton.setEnabled(False)
            self.ui.specifyWHCSpinBox.setValue(float(self.set_dic['whc_mm']))
            self.ui.specifyWHCRadioButton.setChecked(True)

        # Setup Mask Tab
        if self.set_dic['mask_type'] == 'Default':
            self.ui.maskFileBrowseButton.setEnabled(False)
            self.ui.defaultMaskRadioButton.setChecked(True)
        elif self.set_dic['mask_type'] == 'Selected':
            self.ui.maskFileBrowseButton.setEnabled(True)
            self.ui.maskFileLineEdit.setText(self.set_dic['mask_file'])
            self.ui.selectedMaskRadioButton.setChecked(True)

        util.fill_dataset_combo_by_type(self.ui.pptComboBox,
                                        config.DATA_TYPES[0][1])
        if self.set_dic['ppt_dataset'] != '':
            self.ui.pptComboBox.setCurrentText(self.set_dic['ppt_dataset'])
        util.fill_dataset_combo_by_type(self.ui.petComboBox,
                                        config.DATA_TYPES[4][1])
        if self.set_dic['pet_dataset'] != '':
            self.ui.petComboBox.setCurrentText(self.set_dic['pet_dataset'])

        # Disable some of the features that are not yet implemented    
        self.ui.precipitationSettingsGroupBox.setEnabled(False)
        self.ui.precipitationSettingsGroupBox.setTitle("Precipitation Settings"
                                                       " (Not Implemented Yet)"
                                                       )
        self.ui.evapotranspirationGroupBox.setEnabled(False)
        self.ui.evapotranspirationGroupBox.setTitle("Evapotranspiration "
                                                    "(Not Implemented Yet)")
        self.ui.simulatedDataCheckBox.setEnabled(False)
        # Initialize each tabs functionality here
        self.set_all_tabs_functionality()

    def reset_to_defaults(self):
        '''
        When the reset button is clicked this will reset form to
        default settings
        '''
        self.set_dic = geo_util.get_default_settings_dic()
        self.reset_bool = True
        # Setup Ui based on the set_dic
        self.set_gui_from_dic()
        self.reset_bool = False

    def set_all_tabs_functionality(self):
        '''
        Set the functionality for all tabs, used to initialize form
        and when the region is changed
        '''
        self.get_region()
        # Set spin boxes based on region PeriodType
        self.set_gui_periodicity()
        self.set_sos_functionality()
        self.set_lgp_functionality()
        self.set_whc_functionality()
        self.set_mask_functionality()

    def adjust_sos_calculation_parameters(self):
        '''
        This will allow the user to adjust the sos calculation parameters,
        it will also set the set_dic for the related fields.
        '''
        dlgsos = SOSController(self.sos_default_settings)
        dlgsos.exec_()

    def set_sos_functionality(self):
        '''
        This function is called when any of the SOS radio buttons
        are toggled, and it will enable or disable buttons based off
        which button is toggled. This will also set the SOS file,
        call the SOS Calculation function, get the specified SOS dekad,
        or the Climatological SOS.
        '''
        # Add in call to SOS Calculation button here
        self.ui.SOSPeriodSpinBox.setEnabled(False)
        self.ui.SOSFileBrowseButton.setEnabled(False)
        self.set_dic['sos_file'] = ''
        self.set_dic['sos_period'] = 0
        if self.ui.selectedSOSRadioButton.isChecked():
            self.ui.SOSFileBrowseButton.setEnabled(True)
            self.ui.SOSPeriodSpinBox.setEnabled(False)
            self.set_dic['sos_file'] = self.ui.SOSFileLineEdit.text()
            self.set_dic['sos_period'] = 0
        elif self.ui.specifySOSPeriodRadioButton.isChecked():
            self.ui.SOSFileBrowseButton.setEnabled(False)
            self.ui.SOSPeriodSpinBox.setEnabled(True)
            self.set_dic['sos_file'] = ''
            self.set_dic['sos_period'] = self.ui.SOSPeriodSpinBox.value()
        elif self.ui.climatologicalSOSRadioButton.isChecked():
            self.ui.SOSPeriodSpinBox.setEnabled(False)
            self.ui.SOSFileBrowseButton.setEnabled(False)
            self.set_dic['sos_file'] = ''
            self.set_dic['sos_period'] = 0

    def set_lgp_functionality(self):
        '''
        This function is called when any of the LGP radio buttons
        is toggled, and it will enable or disable buttons based off
        which button is toggled. This will also set the LGP file,
        either default, selected, or specified
        '''
        self.ui.specifyGrowingPeriodLGPSpinBox.setEnabled(False)
        self.ui.LGPFileBrowseButton.setEnabled(False)
        self.set_dic['lgp_file'] = self.reg_dic['LGP']
        self.set_dic['lgp_period'] = 0
        if self.ui.selectedLGPRadioButton.isChecked():
            self.ui.specifyGrowingPeriodLGPSpinBox.setEnabled(False)
            self.ui.LGPFileBrowseButton.setEnabled(True)
            self.set_dic['lgp_file'] = self.ui.LGPFileLineEdit.text()
            self.set_dic['lgp_period'] = 0
        elif self.ui.specifyGrowingPeriodLGPRadioButton.isChecked():
            self.ui.specifyGrowingPeriodLGPSpinBox.setEnabled(True)
            self.ui.LGPFileBrowseButton.setEnabled(False)
            self.set_dic['lgp_file'] = ''
            self.set_dic['lgp_period'] = \
                self.ui.specifyGrowingPeriodLGPSpinBox.value()

    def set_whc_functionality(self):
        '''
        This function is called when any of the WHC radio buttons
        is toggled, and it will enable or disable buttons based off
        which button is toggled. This will also set the WHC file,
        either default, selected, or specified
        '''
        self.ui.specifyWHCSpinBox.setEnabled(False)
        self.ui.WHCFileBrowseButton.setEnabled(False)
        self.set_dic['whc_file'] = self.reg_dic['WHC']
        self.set_dic['whc_mm'] = 0.0
        if self.ui.selectedWHCRadioButton.isChecked():
            self.ui.specifyWHCSpinBox.setEnabled(False)
            self.ui.WHCFileBrowseButton.setEnabled(True)
            self.set_dic['whc_file'] = self.ui.WHCFileLineEdit.text()
            self.set_dic['whc_mm'] = 0.0
        elif self.ui.specifyWHCRadioButton.isChecked():
            self.ui.specifyWHCSpinBox.setEnabled(True)
            self.ui.WHCFileBrowseButton.setEnabled(False)
            self.set_dic['whc_file'] = ''
            self.set_dic['whc_mm'] = self.ui.specifyWHCSpinBox.value()

    def set_mask_functionality(self):
        '''
        This function is called when any of the Mask radio buttons
        is toggled, and it will enable or disable buttons based off
        which button is toggled. This will also set the Mask file,
        either default, selected
        '''
        self.ui.maskFileBrowseButton.setEnabled(False)
        self.set_dic['mask_file'] = self.reg_dic['Mask']
        if self.ui.selectedMaskRadioButton.isChecked():
            self.ui.maskFileBrowseButton.setEnabled(True)
            self.set_dic['mask_file'] = self.ui.maskFileLineEdit.text()

    def get_browsed_file(self):
        '''
        Depending on the current tab of the settingsTabWidget, when
        the browse button is clicked it will allow the user to browse
        and select the file for that tab
        '''
        if self.get_current_tab() == 1:
            self.browse_file_for_key('sos_file')
            self.ui.SOSFileLineEdit.setText(self.set_dic['sos_file'])
        elif self.get_current_tab() == 2:
            self.browse_file_for_key('lgp_file')
            self.ui.LGPFileLineEdit.setText(self.set_dic['lgp_file'])
        elif self.get_current_tab() == 3:
            self.browse_file_for_key('whc_file')
            self.ui.WHCFileLineEdit.setText(self.set_dic['whc_file'])
        elif self.get_current_tab() == 4:
            self.browse_file_for_key('mask_file')
            self.ui.maskFileLineEdit.setText(self.set_dic['mask_file'])

    def browse_file_for_key(self, key):
        '''
        Allow user to select a file and fill in settings dic key value
        '''
        self.set_dic[key] =\
            QFileDialog.getOpenFileName(
                self,
                u'Select Filename',
                self.browse_path,
                config.RST_FILE_TYPES)[0]

    def import_mask_from_shape(self):
        '''
        Initiates the dialog to rasterize a vector into a mask file
        '''
        if self.reg_info.query_named_region(
                self.ui.regionComboBox.currentText()):
            return  # error
        self.reg_dic = self.reg_info.get_region_dictionary()
        region_fields_dic = {
            'RegionName': self.reg_dic['RegionName'],
            'MinimumLatitude': self.reg_dic['MinimumLatitude'],
            'MaximumLatitude': self.reg_dic['MaximumLatitude'],
            'MinimumLongitude': self.reg_dic['MinimumLongitude'],
            'MaximumLongitude': self.reg_dic['MaximumLongitude'],
            'Height': self.reg_dic['Height'],
            'Width': self.reg_dic['Width']}
        import_mask_dlg = ImportVectorToRasterController(region_fields_dic)
        import_mask_dlg.exec_()
        # need to assign the result to the mask control
        mask_file_name = import_mask_dlg.get_mask_filename()
        self.ui.maskFileLineEdit.setText(
            self.wrksp_setup.fix_os_sep_in_path(mask_file_name))
        self.ui.selectedMaskRadioButton.setChecked(True)
        self.set_mask_functionality()
    
    def import_sos_from_shape(self):
        '''
        Initiates the dialog to rasterize a sos vector file into a raster file
        '''
        if self.reg_info.query_named_region(
                self.ui.regionComboBox.currentText()):
            return  # error
        self.reg_dic = self.reg_info.get_region_dictionary()
        region_fields_dic = {
            'RegionName': self.reg_dic['RegionName'],
            'MinimumLatitude': self.reg_dic['MinimumLatitude'],
            'MaximumLatitude': self.reg_dic['MaximumLatitude'],
            'MinimumLongitude': self.reg_dic['MinimumLongitude'],
            'MaximumLongitude': self.reg_dic['MaximumLongitude'],
            'Height': self.reg_dic['Height'],
            'Width': self.reg_dic['Width']}
        import_raster_dlg = ImportVectorToRasterControllerSOS(region_fields_dic)
        import_raster_dlg.exec_()
        # need to assign the result to the sos control
        raster_file_name = import_raster_dlg.get_raster_filename()
        self.ui.SOSFileLineEdit.setText(
            self.wrksp_setup.fix_os_sep_in_path(raster_file_name))
        self.ui.selectedSOSRadioButton.setChecked(True)
        self.set_sos_functionality()

    def import_lgp_from_shape(self):
        '''
        Initiates the dialog to rasterize a lgp vector file into a raster file
        '''
        if self.reg_info.query_named_region(
                self.ui.regionComboBox.currentText()):
            return  # error
        self.reg_dic = self.reg_info.get_region_dictionary()
        region_fields_dic = {
            'RegionName': self.reg_dic['RegionName'],
            'MinimumLatitude': self.reg_dic['MinimumLatitude'],
            'MaximumLatitude': self.reg_dic['MaximumLatitude'],
            'MinimumLongitude': self.reg_dic['MinimumLongitude'],
            'MaximumLongitude': self.reg_dic['MaximumLongitude'],
            'Height': self.reg_dic['Height'],
            'Width': self.reg_dic['Width']}
        import_raster_dlg = ImportVectorToRasterControllerLGP(region_fields_dic)
        import_raster_dlg.exec_()
        # need to assign the result to the sos control
        raster_file_name = import_raster_dlg.get_raster_filename()
        self.ui.LGPFileLineEdit.setText(
            self.wrksp_setup.fix_os_sep_in_path(raster_file_name))
        self.ui.selectedLGPRadioButton.setChecked(True)
        self.set_lgp_functionality()

    def import_whc_from_shape(self):
        '''
        Initiates the dialog to rasterize a whc vector file into a raster file
        '''
        if self.reg_info.query_named_region(
                self.ui.regionComboBox.currentText()):
            return  # error
        self.reg_dic = self.reg_info.get_region_dictionary()
        region_fields_dic = {
            'RegionName': self.reg_dic['RegionName'],
            'MinimumLatitude': self.reg_dic['MinimumLatitude'],
            'MaximumLatitude': self.reg_dic['MaximumLatitude'],
            'MinimumLongitude': self.reg_dic['MinimumLongitude'],
            'MaximumLongitude': self.reg_dic['MaximumLongitude'],
            'Height': self.reg_dic['Height'],
            'Width': self.reg_dic['Width']}
        import_raster_dlg = ImportVectorToRasterControllerWHC(region_fields_dic)
        import_raster_dlg.exec_()
        # need to assign the result to the sos control
        raster_file_name = import_raster_dlg.get_raster_filename()
        self.ui.WHCFileLineEdit.setText(
            self.wrksp_setup.fix_os_sep_in_path(raster_file_name))
        self.ui.selectedWHCRadioButton.setChecked(True)
        self.set_whc_functionality()

    def get_current_tab(self):
        '''
        Get the current tab in the settings tab
        '''
        return self.ui.settingsTabWidget.currentIndex()

    def get_geowrsi_regions(self):
        '''
        Function to get the regions that are WRSI regions
        Get only the regions that have the data for the GeoWRSI tool
        returns(list) - wrsi_region_list - list of the wrsi regions
        '''
        region_name_list = self.reg_info.get_all_region_names()
        region_name_list = sorted(region_name_list)
        wrsi_region_list = []
        for name in region_name_list:
            if not self.reg_info.query_named_region(name):
                self.reg_dic = self.reg_info.get_region_dictionary()
                if self.check_wrsi_region():
                    wrsi_region_list.append(self.reg_dic['RegionName'])
        return wrsi_region_list

    def check_wrsi_region(self):
        '''
        Check to make sure regions have needed WRSI columns
        Regions need to have Comments, InitialPeriod, FinalPeriod, PeriodType
        SOS, WRSI, LGP, WHC, SOSColor, DataDirectory
        '''
        for key, value in self.reg_dic.items():
            if not value and key != 'Comments':
                return False
        return True

    def get_type_sos(self):
        '''
        Function to get type as a string from the radio button for SOS
        Calculated, Selected, Specified, Clim
        '''
        # decide based on which button is selected
        if self.ui.calculatedSOSRadioButton.isChecked():
            sos_type = 'Calculated'
        elif self.ui.selectedSOSRadioButton.isChecked():
            sos_type = 'Selected'
        elif self.ui.specifySOSPeriodRadioButton.isChecked():
            sos_type = 'Specified'
        else:
            sos_type = 'Climatological'
        return sos_type

    def get_type_lgp(self):
        '''
        Function to get type as a string from the radio button for LGP
        Default, Selected, Specified
        '''
        # decide based on which button is selected
        if self.ui.defaultLGPRadioButton.isChecked():
            lgp_type = 'Default'
        elif self.ui.selectedLGPRadioButton.isChecked():
            lgp_type = 'Selected'
        else:
            lgp_type = 'Specified'
        return lgp_type

    def get_type_whc(self):
        '''
        Function to get type as a string from the radio button for WHC
        Default, Selected, Specified
        '''
        # decide based on which button is selected
        if self.ui.defaultWHCRadioButton.isChecked():
            whc_type = 'Default'
        elif self.ui.selectedWHCRadioButton.isChecked():
            whc_type = 'Selected'
        else:
            whc_type = 'Specified'
        return whc_type

    def get_type_mask(self):
        '''
        Function to get type as a string from the radio button for Mask
        Default, Selected
        '''
        # decide based on which button is selected
        if self.ui.defaultMaskRadioButton.isChecked():
            mask_type = 'Default'
        else:
            mask_type = 'Selected'
        return mask_type

    def get_region(self):
        '''
        Gets the named region from the combobox and sets it in the set_dic
        and queries it into the reg_dic
        '''
        if not self.reg_info.query_named_region(
                self.ui.regionComboBox.currentText()):
            self.reg_dic = self.reg_info.get_region_dictionary()
            self.set_dic['analysis_region'] = self.reg_dic['RegionName']
        else:
            QMessageBox.information(
                self, 'Region Not Found',
                'The selected region cannot be found in database!',
                QMessageBox.Ok)

    def set_gui_periodicity(self):
        '''
        Set the GUI periodicity where needed based on the PeriodType from the
        selected region (labels, spin box min/max values)
        '''
        if self.reg_dic['PeriodType'] == 'Dekadal':
            self.ui.specifySOSPeriodRadioButton.setText('Specify SOS Dekad')
            self.ui.SOSPeriodSpinBox.setMaximum(36)
            self.ui.specifyGrowingPeriodLGPRadioButton.setText(
                'Specify Growing Period (in dekads)')
            self.ui.specifyGrowingPeriodLGPSpinBox.setMaximum(36)
            self.ui.SOSOffsetSpinBox.setMaximum(4)
            self.ui.SOSOffsetSpinBox.setMinimum(-4)
        elif self.reg_dic['PeriodType'] == 'Pentadal':
            self.ui.specifySOSPeriodRadioButton.setText('Specify SOS Pentad')
            self.ui.SOSPeriodSpinBox.setMaximum(72)
            self.ui.specifyGrowingPeriodLGPRadioButton.setText(
                'Specify Growing Period (in pentads)')
            self.ui.specifyGrowingPeriodLGPSpinBox.setMaximum(72)
            self.ui.SOSOffsetSpinBox.setMaximum(8)
            self.ui.SOSOffsetSpinBox.setMinimum(-8)

    def save_settings(self):
        '''
        This function is called when ok is clicked on the GUI
        This  will assign any values that are not already set
        in the set_dic file and then print the set_dic to the
        ProgramSettings folder as config.WSRI_SETTINGS_FILE
        '''
        self.set_dic['crop_type'] = self.ui.cropComboBox.currentText()
        self.set_dic['sos_type'] = self.get_type_sos()
        self.set_dic['sos_offset'] = self.ui.SOSOffsetSpinBox.value()
        self.set_dic['lgp_type'] = self.get_type_lgp()
        self.set_dic['whc_type'] = self.get_type_whc()
        self.set_dic['mask_type'] = self.get_type_mask()
        self.set_dic['precip_type'] =\
            geo_util.get_wrsi_input_type(self.ui.actualPrecipRadioButton)
        self.set_dic['pet_type'] =\
            geo_util.get_wrsi_input_type(self.ui.actualPETRadioButton)
        self.set_dic['use_simulated_data'] =\
            self.ui.simulatedDataCheckBox.isChecked()
        self.set_dic['ppt_dataset'] = self.ui.pptComboBox.currentText()
        self.set_dic['pet_dataset'] = self.ui.petComboBox.currentText()
        if self.check_files():
            return
        if self.check_dataset_selection():
            return

        # Read in the existing geowrsi settings file
        geowrsi_dic = {}

        if os.path.exists(self.output_path):
            with open(self.output_path) as f_obj:
                for line in f_obj:
                    (key, value) = line.split(" ", 1)
                    geowrsi_dic[key] = value[:-1]

        # For each dictionary pair in sos_dic either replace or append on
        # the existing geowrsi dictionary to not overwrite the sos settings
        for key, value in self.set_dic.items():
            geowrsi_dic[key] = value

        for key, value in self.sos_default_settings.items():
            if key not in geowrsi_dic.keys():
                geowrsi_dic[key] = value

        with open(self.output_path, "w") as f_obj:
            for key, value in geowrsi_dic.items():
                f_obj.write('%s %s\n' % (key, value))
        self.close()

    def check_dataset_selection(self):
        '''
        This is used to check that the PPT and PET datasets have the same
        periodicity, when the ok button is clicked otherwise it will give
        the user a message and make sure they match to save settings
        returns(bool) - flag - true of false based if the selections are valid
        '''
        ds_info_ppt = DatasetsModel()
        ds_info_ppt.query_named_dataset(self.set_dic['ppt_dataset'])
        self.ds_dic_ppt = ds_info_ppt.get_ds_dictionary()
        ds_info_pet = DatasetsModel()
        ds_info_pet.query_named_dataset(self.set_dic['pet_dataset'])
        self.ds_dic_pet = ds_info_pet.get_ds_dictionary()
        # Check datasets have same PERIODICITY
        flag = False
        if self.ds_dic_ppt['PERIODICITY'] != self.ds_dic_pet['PERIODICITY']:
            QMessageBox.information(self,
                                    u'Dataset Periodicity mismatch!!',
                                    'PPT and PET datasets do not '
                                    'use same periodicity',
                                    QMessageBox.Ok)
            flag = True
        if self.reg_dic['PeriodType'] != self.ds_dic_ppt['PERIODICITY']:
            QMessageBox.information(self,
                                    u'Dataset vs Region '
                                    'Periodicity mismatch!!',
                                    'PPT and PET datasets do not use same '
                                    'periodicity as the region',
                                    QMessageBox.Ok)
            flag = True
        return flag

    def check_files(self):
        '''
        This function is used to make sure that the selected and default file
        paths actually exists.
        '''
        flag = False
        if self.get_type_sos() == 'Selected':
            # Check that file path is not empty and that it exists
            if self.set_dic['sos_file'] == '':
                # Error - SOS type is Selected but no file has been chosen
                QMessageBox.information(
                    self, 'Missing selected sos file',
                    'Selected sos type: No file selected!', QMessageBox.Ok)
                flag = True
            elif not os.path.exists(self.set_dic['sos_file']):
                # Error - Path to selected file does not exist
                QMessageBox.information(
                    self, 'Selected SOS File: Path Not Found',
                    'The selected path to the SOS file cannot be found!',
                    QMessageBox.Ok)
                flag = True
            else:
                sos_params = qgs_util.extract_raster_file_params(
                    self.set_dic['sos_file'])
                sos_ok = \
                    qgs_util.check_dataset_vs_region_extents(
                        self, sos_params[0],
                        qgs_util.get_region_extent(self.reg_dic))
                if not sos_ok:
                    QMessageBox.information(
                        self, 'Selected SOS File: Error',
                        'This file has a region mismatch error',
                        QMessageBox.Ok)
                    flag = True
        if self.get_type_lgp() == 'Selected' or\
                self.get_type_lgp() == 'Default':
            # Check that file path is not empty and that it exists
            if self.set_dic['lgp_file'] == '':
                # Error - SOS type is Selected but no file has been chosen
                QMessageBox.information(
                    self, 'Missing LGP File',
                    'LGP: No file selected!', QMessageBox.Ok)
                flag = True
            elif not os.path.exists(self.set_dic['lgp_file']):
                # Error - Path to selected file does not exist
                QMessageBox.information(
                    self, 'LGP File: Path Not Found',
                    'The path to the LGP file cannot be found!',
                    QMessageBox.Ok)
                flag = True
            else:  # Check file extents
                lgp_params = qgs_util.extract_raster_file_params(
                    self.set_dic['lgp_file'])
                lgp_ok = \
                    qgs_util.check_dataset_vs_region_extents(
                        self, lgp_params[0],
                        qgs_util.get_region_extent(self.reg_dic))
                if not lgp_ok:
                    QMessageBox.information(
                        self, 'LGP File: Error',
                        'This file has a region mismatch error',
                        QMessageBox.Ok)
                    flag = True
        if self.get_type_whc() == 'Selected' or\
                self.get_type_whc() == 'Default':
            # Check that file path is not empty and that it exists
            if self.set_dic['whc_file'] == '':
                # Error - SOS type is Selected but no file has been chosen
                QMessageBox.information(
                    self, 'Missing WHC File',
                    'WHC: No file selected!', QMessageBox.Ok)
                flag = True
            elif not os.path.exists(self.set_dic['whc_file']):
                # Error - Path to selected file does not exist
                QMessageBox.information(
                    self, 'WHC File: Path Not Found',
                    'The path to the WHC file cannot be found!',
                    QMessageBox.Ok)
                flag = True
            else:
                whc_params = qgs_util.extract_raster_file_params(
                    self.set_dic['whc_file'])
                whc_ok = \
                    qgs_util.check_dataset_vs_region_extents(
                        self, whc_params[0],
                        qgs_util.get_region_extent(self.reg_dic))
                if not whc_ok:
                    QMessageBox.information(
                        self, 'WHC File: Error',
                        'This file has a region mismatch error',
                        QMessageBox.Ok)
                    flag = True
        if self.get_type_mask() == 'Selected' or\
                self.get_type_mask() == 'Default':
            # Check that file path is not empty and that it exists
            if self.set_dic['mask_file'] == '':
                # Error - SOS type is Selected but no file has been chosen
                QMessageBox.information(
                    self, 'Missing Mask File',
                    'Mask: No file selected!', QMessageBox.Ok)
                flag = True
            elif not os.path.exists(self.set_dic['mask_file']):
                # Error - Path to selected file does not exist
                QMessageBox.information(
                    self, 'Mask File: Path Not Found',
                    'The path to the Mask file cannot be found!',
                    QMessageBox.Ok)
                flag = True
            else:
                mask_params = qgs_util.extract_raster_file_params(
                    self.set_dic['mask_file'])
                mask_ok = \
                    qgs_util.check_dataset_vs_region_extents(
                        self, mask_params[0],
                        qgs_util.get_region_extent(self.reg_dic))
                if not mask_ok:
                    QMessageBox.information(
                        self, 'Mask File: Error',
                        'This file has a region mismatch error',
                        QMessageBox.Ok)
                    flag = True
        return flag
