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

#******************************************************************************
#
# Freewat
# ---------------------------------------------------------
#
#
# Copyright (C) 2014 - 2015 Iacopo Borsi (iacopo.borsi@tea-group.com)
#
# This source 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.
#
# This code is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# A copy of the GNU General Public License is available on the World Wide Web
# at <http://www.gnu.org/licenses/>. You can also obtain it by writing
# to the Free Software Foundation, 51 Franklin Street, Suite 500 Boston,
# MA 02110-1335 USA.
#
#******************************************************************************


from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
import os
from PyQt4 import QtGui, uic
from freewat.freewat_utils import getVectorLayerByName, getVectorLayerNames, getModelsInfoLists, getModelInfoByName
from freewat.mdoCreate_utils import createWellLayer, createModelLayer
from freewat.sqlite_utils import getTableNamesList
from pyspatialite import dbapi2 as sqlite3
#
#
FORM_CLASS, _ = uic.loadUiType(os.path.join( os.path.dirname(__file__), 'ui/ui_mergeTool.ui') )
#
class MergeToolDialog(QDialog, FORM_CLASS):
    def __init__(self, iface):
        QDialog.__init__(self)
        self.iface = iface
        self.setupUi(self)
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.MergeTool)
        self.manageGui()
        #set up the QListWidget with the signal emitted when the selection is changes and connect to the function
        # QObject.connect(self.listWidget, SIGNAL("itemSelectionChanged()"), self.get_selected_layers)
##
    def manageGui(self):
        self.cmbModelName.clear()
        layerNameList = getVectorLayerNames()
        layerNameList.sort()
        # Retrieve modelname and pathfile List
        (self.modelNameList, pathList) =  getModelsInfoLists(layerNameList)
        # Populate the modelComboBox with the model names
        self.cmbModelName.addItems(self.modelNameList)

        #empty list that will be populated with the names of the selected layers
        self.selectedLayers = []

        # Trying to set up the listWidgetView
        self.listWidget.setEditTriggers(QtGui.QAbstractItemView.DoubleClicked|QtGui.QAbstractItemView.EditKeyPressed)
        self.listWidget.setSelectionMode(QtGui.QAbstractItemView.MultiSelection)
        self.listWidget.setViewMode(QtGui.QListView.ListMode)


        # Load the layers in the listWidget
        self.layers = []
        for i in QgsMapLayerRegistry.instance().mapLayers().values():
            #load only POLYGON layers, to filer out useless layers
            # if i.type() == QgsMapLayer.VectorLayer and i.geometryType() == QGis.Polygon:
            self.layers.append(i.name())

        # Populate the listWidget with all the polygon layer present in the TOC
        self.listWidget.addItems(self.layers)

##
    def reject(self):
        QDialog.reject(self)
##
    def restoreGui(self):
        self.progressBar.setFormat("%p%")
        self.progressBar.setRange(0, 1)
        self.progressBar.setValue(0)
        self.cancelButton.clicked.disconnect(self.stopProcessing)
        self.okButton.setEnabled(True)
##
    def MergeTool(self):

        #Load model name
        modelName = self.cmbModelName.currentText()

        #Remark: pathfile from model table and number of stress periods (nsp) from time table
        (pathfile, nsp ) = getModelInfoByName(modelName)

        #Retrieve the name of the NEW layer from Text Box
        layerName = self.textEdit.text()

        #Retrieve the information of the model
        dbName = pathfile + '/' + modelName + ".sqlite"
        tableList = getTableNamesList(dbName)

        #populate the list with the name of only the SELECTED layers!
        for ll in self.listWidget.selectedItems():
            self.selectedLayers.append(ll.text())

        #Connect to the DB and set up the query
        con = sqlite3.connect(dbName)
        # con = sqlite3.connect(":memory:") if you want write it in RAM
        con.enable_load_extension(True)
        cur = con.cursor()

        #String with the first SQL statement
        sql_init = "CREATE TABLE %s AS " %layerName

        #Populate list with all the layer names (should be populated with only the SELECTED layers)
        sl = []
        for index, lay in enumerate(self.selectedLayers):
            sl.append("SELECT * FROM %s UNION ALL " %lay)
            sql_trunk = ''.join(sl)
            #delete the last characters from the string to make the query executable
            sql_query = sql_trunk[:-11] + "; "


        #match the exact model trough the list of all models
        db = [os.path.basename(dbName).replace('.sqlite', '')]
        for i in db:
            if i in self.modelNameList:
                modelName = 'modeltable_' + str(i)


        #Build all the sql strings together and run the query
        sql_final = sql_init + sql_query
        cur.execute(sql_final)


        #Retrieve the number of the EPSG code to pass in the next SQL string
        model = getVectorLayerByName(modelName)
        for ft in model.getFeatures():
            crs = ft['crs']
            #get just the number of the crs and get rid of EPSG:
            crs = int(crs[5:])


        #Recover the geometry column so the table becomes a geometry layer (crs is retireved from the modeltable)
        cur.execute("SELECT RecoverGeometryColumn('%s', 'Geometry', %s, 'MULTIPOLYGON', 'XY');" %(layerName, crs))

        #Discard and re-create the geometry column (useful if you wanted the the geometry column will be of MULTIPOGON type
        #cur.execute("SELECT DiscardGeometryColumn('%s', 'Geometry');" %layerName)
        #cur.execute("SELECT AddGeometryColumn('%s', 'the_geom', %s, 'MULTIPOLYGON', 'XY');" %(layerName, crs))

        # Close SpatiaLiteDB
        cur.close()
        # Save the changes
        con.commit()
        # Close connection
        con.close()


        ##Retrieve the SL layer and add it to the map
        uri = QgsDataSourceURI()
        uri.setDatabase(dbName)
        schema = ''
        table = layerName
        geom_column = "Geometry"
        uri.setDataSource(schema, table, geom_column)
        display_name = table

        wlayer = QgsVectorLayer(uri.uri(), display_name, 'spatialite')

        QgsMapLayerRegistry.instance().addMapLayer(wlayer)

        #Close the dialog window after the execution of the algorithm
        self.reject()
