'''
/***************************************************************************
Name	   :  import_vector_to_raster_controller.py
Description: Import vector to raster class for FEWSTools plugin,
              updated from QGIS2
copyright  :  (C) 2019-2023 by FEWS
email      :  minxuansun@contractor.usgs.gov
Created    :  11/22/2019 - cholen
Modified   :  02/11/2020 cholen - Changed import to gdal call, added checks
                           for mismatched region and shape or existing mask
              02/20/2019 cholen - add check for shape vs region extents equal
              02/29/2020 cholen - Adjust extents on mask creation.
              04/10/2020 cholen - Updated to not clear map panel.
              04/30/2020 cholen - Fix bug where selecting exclude inside
                           gives wrong results
              05/01/2020 cholen - Hide 'apply changes to program'
              08/29/2020 cholen - Changes to move to the region dlg
              09/15/2020 cholen - Add 'mask' to output filename
              10/08/2020 cholen - Fix os sep in browse
              10/22/2020 cholen - Change wksp_info name to match other files
              02/24/2022 cholen - Add tiff support
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 QMessageBox, QDialog, QFileDialog
from qgis.core import Qgis, QgsMessageLog

from fews_tools import fews_tools_config as config
from fews_tools.utilities import geoclim_gdal_utilities as g_util
from fews_tools.utilities import geoclim_qgs_utilities as qgs_util

from fews_tools.models.region_model import RegionModel
from fews_tools.models.workspace_setup_model import WorkspaceSetupModel
from fews_tools.forms.Ui_ImportVectorToRaster import Ui_ImportVectorToRaster


class ImportVectorToRasterController(QDialog):
    '''
    Class for getting spatial extents from either a file or region definition
    using the Get Spatial Extents dialog
    '''
    RASTER_VALUES = [0, 1]

    def __init__(self, reg_dic):
        QDialog.__init__(self)
        self.ui = Ui_ImportVectorToRaster()
        self.ui.setupUi(self)
        self.ui.closeButton.setFocus()
        self.wrksp_setup = WorkspaceSetupModel()
        self.reg_info = RegionModel()
        self.reg_dic = reg_dic
        self.ui.browseMapButton.clicked.connect(self.browse_map_path)
        self.ui.browseMaskButton.clicked.connect(self.browse_mask_path)
        self.ui.applyChangesToProgramCheckBox.setVisible(False)
        self.ui.insidePolyRadioButton.clicked.connect(
            self.exclude_values_inside_polygons)
        self.ui.outsidePolyRadioButton.clicked.connect(
            self.exclude_values_outside_polygons)
        self.ui.processButton.clicked.connect(self.import_to_mask)
        self.ui.mapInLineEdit.textChanged.connect(self.enable_import_button)
        self.ui.maskOutLineEdit.textChanged.connect(self.enable_import_button)
        self.ui.processButton.setEnabled(False)
        self.burn_value = self.RASTER_VALUES[1]
        self.init_value = self.RASTER_VALUES[0]
        self.mask_filename = ''

    def browse_map_path(self):
        '''
        Browse to map files.
        '''
        map_file =\
            QFileDialog.getOpenFileName(self,
                                        'Please Select the Map File',
                                        self.wrksp_setup.get_map_data_path(),
                                        config.VEC_FILE_TYPES)
        if map_file[0]:
            self.ui.mapInLineEdit.setText(
                self.wrksp_setup.fix_os_sep_in_path(map_file[0]))

    def browse_mask_path(self):
        '''
        Browse to mask files, the name that is filled in will
        be the basename of the map file selected as a .tif extension.  If no
        map file has been selected the filename will default to
        "map_rasterize_mask.bil"
        '''
        if self.ui.mapInLineEdit.text() != '':
            map_file_basename = os.path.basename(
                self.ui.mapInLineEdit.text()).split('.')[0] + "_mask"
        else:
            map_file_basename = 'map_rasterize_mask'
        mask_file =\
            QFileDialog.getSaveFileName(
                self,
                u'Mask file location',
                os.path.join(self.wrksp_setup.get_static_data_path(), map_file_basename),
                config.RST_FILE_TYPES)
        self.ui.maskOutLineEdit.setText(mask_file[0])

    def exclude_values_inside_polygons(self):
        '''
        Choose inside polygons to be the excluded values
        '''
        self.burn_value = self.RASTER_VALUES[0]
        self.init_value = self.RASTER_VALUES[1]

    def exclude_values_outside_polygons(self):
        '''
        Choose outside polygons to be the excluded values.
        '''
        self.burn_value = self.RASTER_VALUES[1]
        self.init_value = self.RASTER_VALUES[0]

    def enable_import_button(self):
        '''
        Enables the import button if widgets are ready
        '''
        if self.ui.mapInLineEdit.text() and self.ui.maskOutLineEdit.text():
            self.ui.processButton.setEnabled(True)

    def get_mask_filename(self):
        '''
        Getter for mask file name
        '''
        return self.mask_filename

    def set_mask_filename(self):
        '''
        Setter for mask file name
        '''
        self.mask_filename = self.ui.maskOutLineEdit.text()

    def import_to_mask(self):
        '''
        Import the vector to the raster, using the default region extents
        and cell size.
        https://docs.qgis.org/2.8/en/docs/user_manual/
            processing_algs/gdalogr/gdal_conversion/rasterize.html
        This will not overwrite an existing mask file.
        '''
        map_file = self.ui.mapInLineEdit.text()
        self.set_mask_filename()
        reg_extent = qgs_util.get_region_extent(self.reg_dic)
        shp_extent = qgs_util.extract_shapefile_extents_rectangle(map_file)
        # this mask extent must be made slightly larger or the mask
        # will flag an error.  Mask must be slightly larger than it's region
        fudge = self.reg_dic['Height'] / 2
        match_rect = qgs_util.rectangle_equals(reg_extent, shp_extent)
        # test if region and shapefile are the same or if shp is within region
        if reg_extent.contains(shp_extent) or match_rect:
            if not os.path.exists(self.mask_filename):
                if map_file and self.mask_filename and\
                        os.path.exists(map_file):
                    g_util.rasterize_vector(
                        map_file, self.mask_filename, self.reg_dic['Height'],
                        reg_extent, self.init_value, self.burn_value,
                        fudge, d_type="UInt16")

                    qgs_util.display_raster_layer(self.mask_filename, 'mask')
                    QgsMessageLog.logMessage(
                        'Import Mask from Vector succeeded', level=Qgis.Info)
                else:
                    QMessageBox.critical(
                        self,
                        'ERROR: Import Mask from Vector did not succeed',
                        'ERROR: Import Mask from Vector did not succeed',
                        QMessageBox.Ok)
                    QgsMessageLog.logMessage('Import Mask from Vector failed',
                                             level=Qgis.Critical)
            else:
                QMessageBox.information(
                    self, 'Mask file already exists',
                    'Mask file already exists!  Exiting!', QMessageBox.Ok)
        else:
            QMessageBox.information(
                self, 'Region extents do not match with shapefile',
                'Region vs shapefile mismatch!  Exiting!', QMessageBox.Ok)
        self.close()
