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

"""
/***************************************************************************
Name                 : DB Manager
Description          : Database manager plugin for QGIS
Date                 : Oct 13, 2011
copyright            : (C) 2011 by Giuseppe Sucameli
email                : brush.tyler@gmail.com

The content of this file is based on
- PG_Manager by Martin Dobias (GPLv2 license)
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
"""
from builtins import str

from qgis.PyQt.QtCore import Qt, QSettings, QFileInfo
from qgis.PyQt.QtWidgets import QDialog, QFileDialog, QMessageBox, QApplication
from qgis.PyQt.QtGui import QCursor

from qgis.core import QgsVectorFileWriter, QgsVectorDataProvider, QgsCoordinateReferenceSystem, QgsVectorLayerImport

from .ui.ui_DlgExportVector import Ui_DbManagerDlgExportVector as Ui_Dialog


class DlgExportVector(QDialog, Ui_Dialog):

    def __init__(self, inLayer, inDb, parent=None):
        QDialog.__init__(self, parent)
        self.inLayer = inLayer
        self.db = inDb
        self.setupUi(self)

        vectorFilterName = "lastVectorFileFilter"  # "lastRasterFileFilter"
        self.lastUsedVectorFilterSettingsKey = u"/UI/{0}".format(vectorFilterName)
        self.lastUsedVectorDirSettingsKey = u"/UI/{0}Dir".format(vectorFilterName)

        # update UI
        self.setupWorkingMode()
        self.populateFileFilters()
        self.populateEncodings()

    def setupWorkingMode(self):
        # set default values
        inCrs = self.inLayer.crs()
        srid = inCrs.postgisSrid() if inCrs.isValid() else 4236
        self.editSourceSrid.setText("%s" % srid)
        self.editTargetSrid.setText("%s" % srid)

        self.btnChooseOutputFile.clicked.connect(self.chooseOutputFile)
        self.checkSupports()

    def checkSupports(self):
        """ update options available for the current input layer """
        allowSpatial = self.db.connector.hasSpatialSupport()
        hasGeomType = self.inLayer and self.inLayer.hasGeometryType()
        self.chkSourceSrid.setEnabled(allowSpatial and hasGeomType)
        self.chkTargetSrid.setEnabled(allowSpatial and hasGeomType)
        # self.chkSpatialIndex.setEnabled(allowSpatial and hasGeomType)

    def chooseOutputFile(self):
        # get last used dir
        settings = QSettings()
        lastUsedDir = settings.value(self.lastUsedVectorDirSettingsKey, ".")

        # get selected filter
        selectedFilter = self.cboFileFormat.currentData()

        # ask for a filename
        filename, filter = QFileDialog.getSaveFileName(self, self.tr("Choose where to save the file"), lastUsedDir,
                                                       selectedFilter)
        if filename == "":
            return

        filterString = QgsVectorFileWriter.filterForDriver(selectedFilter)
        ext = filterString[filterString.find('.'):]
        ext = ext[:ext.find(' ')]

        if not filename.lower().endswith(ext):
            filename += ext

        # store the last used dir
        settings.setValue(self.lastUsedVectorDirSettingsKey, QFileInfo(filename).filePath())

        self.editOutputFile.setText(filename)

    def populateEncodings(self):
        # populate the combo with supported encodings
        self.cboEncoding.addItems(QgsVectorDataProvider.availableEncodings())

        # set the last used encoding
        enc = self.inLayer.dataProvider().encoding()
        idx = self.cboEncoding.findText(enc)
        if idx < 0:
            self.cboEncoding.insertItem(0, enc)
            idx = 0
        self.cboEncoding.setCurrentIndex(idx)

    def populateFileFilters(self):
        # populate the combo with supported vector file formats
        for name, filt in list(QgsVectorFileWriter.ogrDriverList().items()):
            self.cboFileFormat.addItem(name, filt)

        # set the last used filter
        settings = QSettings()
        filt = settings.value(self.lastUsedVectorFilterSettingsKey, "ESRI Shapefile")

        idx = self.cboFileFormat.findText(filt)
        if idx < 0:
            idx = 0
        self.cboFileFormat.setCurrentIndex(idx)

    def accept(self):
        # sanity checks
        if self.editOutputFile.text() == "":
            QMessageBox.information(self, self.tr("Export to file"), self.tr("Output file name is required"))
            return

        if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked():
            try:
                sourceSrid = int(self.editSourceSrid.text())
            except ValueError:
                QMessageBox.information(self, self.tr("Export to file"),
                                        self.tr("Invalid source srid: must be an integer"))
                return

        if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked():
            try:
                targetSrid = int(self.editTargetSrid.text())
            except ValueError:
                QMessageBox.information(self, self.tr("Export to file"),
                                        self.tr("Invalid target srid: must be an integer"))
                return

        # override cursor
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        # store current input layer crs, so I can restore it later
        prevInCrs = self.inLayer.crs()
        try:
            uri = self.editOutputFile.text()
            providerName = "ogr"

            options = {}

            # set the OGR driver will be used
            driverName = self.cboFileFormat.currentData()
            options['driverName'] = driverName

            # set the output file encoding
            if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked():
                enc = self.cboEncoding.currentText()
                options['fileEncoding'] = enc

            if self.chkDropTable.isChecked():
                options['overwrite'] = True

            outCrs = QgsCoordinateReferenceSystem()
            if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked():
                targetSrid = int(self.editTargetSrid.text())
                outCrs = QgsCoordinateReferenceSystem(targetSrid)

            # update input layer crs
            if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked():
                sourceSrid = int(self.editSourceSrid.text())
                inCrs = QgsCoordinateReferenceSystem(sourceSrid)
                self.inLayer.setCrs(inCrs)

            # do the export!
            ret, errMsg = QgsVectorLayerImport.importLayer(self.inLayer, uri, providerName, outCrs, False,
                                                           False, options)
        except Exception as e:
            ret = -1
            errMsg = str(e)

        finally:
            # restore input layer crs and encoding
            self.inLayer.setCrs(prevInCrs)
            # restore cursor
            QApplication.restoreOverrideCursor()

        if ret != 0:
            QMessageBox.warning(self, self.tr("Export to file"), self.tr("Error %d\n%s") % (ret, errMsg))
            return

        # create spatial index
        # if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked():
        #       self.db.connector.createSpatialIndex( (schema, table), geom )

        QMessageBox.information(self, self.tr("Export to file"), self.tr("Export finished."))
        return QDialog.accept(self)


if __name__ == '__main__':
    import sys

    a = QApplication(sys.argv)
    dlg = DlgExportVector()
    dlg.show()
    sys.exit(a.exec_())