# -*- 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.freewat_utils import getModelNlayByName, getModelNspecByName, getTransportModelsByName, ComboStyledItemDelegate

from freewat.mdoCreate_utils  import createSSM_PointSourceLayer, createSSM_RchEvtLayer
#
#
FORM_CLASS, _ = uic.loadUiType(os.path.join( os.path.dirname(__file__), 'ui/ui_createSSMLayer.ui') )
#


class CreateSSMLayerDialog(QDialog, FORM_CLASS):
    def __init__(self, iface):
        QDialog.__init__(self)
        self.iface = iface
        self.setupUi(self)
        # link the flow model with related transport model(s):
        self.cmbFlowName.currentIndexChanged.connect(self.reloadFields)
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.button(QDialogButtonBox.Ok).setText("Run")
        self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.createSSM)
        self.manageGui()
##
##
    def manageGui(self):
        self.cmbFlowName.clear()
        layerNameList = getVectorLayerNames()
        layerNameList.sort()

        # Retrieve modelname and pathfile List
        (modelNameList, pathList) =  getModelsInfoLists(layerNameList)

        self.cmbFlowName.addItems(modelNameList)
#
    def defineListModel(self, splist):
        nsp = len(splist)
        model = QtGui.QStandardItemModel(nsp, 1)# nsp rows, 1 col
        it0 = QtGui.QStandardItem('Select Sress Period(s)')
        for i, sp  in enumerate(splist):
            item = QtGui.QStandardItem(str(sp))
            item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            item.setData(Qt.Checked, Qt.CheckStateRole)
            model.setItem(i+1, 0, item)
        model.setItem(0,it0)
        return model
#
    def reloadFields(self):
        # Insert list of transport model(s) according with selected flow model:
        self.cmbTransportName.clear()
        layerNameList = getVectorLayerNames()

        list_of_models = getTransportModelsByName(self.cmbFlowName.currentText())
        self.cmbTransportName.addItems(list_of_models)

        # Retrieve numebr of stress periods from FlowModel
        (pathfile, nsp ) = getModelInfoByName(self.cmbFlowName.currentText())
        splist = []
        for i in range(1, nsp + 1):
            splist.append(i)

        # Insert Stress Periods in combos
        # rch
        self.modelSPrch = self.defineListModel(splist)
        self.cmbSPrch.setModel(self.modelSPrch)
        self.cmbSPrch.setItemDelegate(ComboStyledItemDelegate())
        # evt
        #self.modelSPevt = model
        self.modelSPevt = self.defineListModel(splist)
        self.cmbSPevt.setModel(self.modelSPevt)
        self.cmbSPevt.setItemDelegate(ComboStyledItemDelegate())
        # chd
        self.modelSPchd = self.defineListModel(splist)
        self.cmbSPchd.setModel(self.modelSPchd)
        self.cmbSPchd.setItemDelegate(ComboStyledItemDelegate())
        # wel
        self.modelSPwel = self.defineListModel(splist)
        self.cmbSPwel.setModel(self.modelSPwel)
        self.cmbSPwel.setItemDelegate(ComboStyledItemDelegate())
        # riv
        self.modelSPriv = self.defineListModel(splist)
        self.cmbSPriv.setModel(self.modelSPriv)
        self.cmbSPriv.setItemDelegate(ComboStyledItemDelegate())
        # ghb
        self.modelSPghb = self.defineListModel(splist)
        self.cmbSPghb.setModel(self.modelSPghb)
        self.cmbSPghb.setItemDelegate(ComboStyledItemDelegate())
        # mass
        self.modelSPmass = self.defineListModel(splist)
        self.cmbSPmass.setModel(self.modelSPmass)
        self.cmbSPmass.setItemDelegate(ComboStyledItemDelegate())
        # const
        self.modelSPconst = self.defineListModel(splist)
        self.cmbSPconst.setModel(self.modelSPconst)
        self.cmbSPconst.setItemDelegate(ComboStyledItemDelegate())

        # Insert list in packages combos
        # distributed (rch and evt)

        # fill the Grid combobox with only the _grid layer
        grid_layers = []
        for nametemp in layerNameList:
            if '_grid' in nametemp:
                grid_layers.append(nametemp)

        self.cmbGrid.addItems(grid_layers)

        # chd
        chd_layers = []
        for nametemp in layerNameList:
            if '_chd' in nametemp:
                chd_layers.append(nametemp)
        self.cmbCHD.addItems(chd_layers)
        # wel
        wel_layers = []
        for nametemp in layerNameList:
            if '_wel' in nametemp:
                wel_layers.append(nametemp)
        self.cmbWEL.addItems(wel_layers)
        # riv
        riv_layers = []
        for nametemp in layerNameList:
            if '_riv' in nametemp:
                riv_layers.append(nametemp)
        self.cmbRIV.addItems(riv_layers)
        # ghb
        ghb_layers = []
        for nametemp in layerNameList:
            if '_ghb' in nametemp:
                ghb_layers.append(nametemp)
        self.cmbGHB.addItems(ghb_layers)
        # mass loading
        mass_layers = []
        self.cmbMass.addItems(layerNameList)
        # mass loading
        const_layers = []
        self.cmbConstant.addItems(layerNameList)

##
##
    def reject(self):
        QDialog.reject(self)

##
    def createSSM(self):

        # ------------ Load input data  ------------
        #
        modelName = self.cmbFlowName.currentText()
        transportName = self.cmbTransportName.currentText()

        # Remark: pathfile from model table and number of stress periods (nsp) from time table
        (pathfile, nsp ) = getModelInfoByName(modelName)
        nlay = getModelNlayByName(modelName)
        (nspec, mob, mass) = getModelNspecByName(modelName, transportName)

        # dbName
        dbName = os.path.join(pathfile, modelName + '.sqlite')

        # run for selected distributed packages
        gridlayer = getVectorLayerByName(self.cmbGrid.currentText())
        newName  = self.txtName.text()
        # initialize inrch and inevt
        inrch = ['F' for i in range(1,nsp + 1)]
        inevt = inrch
        flagDist = 0
        # rch
        if self.chkRch.isChecked() :
            flagDist = 1
            # Retrieve list of selected StressPeriods from SP combo
            i = 1
            # Set 'True" only selected stress periods
            while self.modelSPrch.item(i):
                if self.modelSPrch.item(i).checkState() == 2:
                    inrch[i-1] = 'T'
                i += 1
        # evt
        if self.chkEvt.isChecked() :
            flagDist = 1
            # Retrieve list of selected StressPeriods from SP combo
            i = 1
            # Set 'True" only selected stress periods
            while self.modelSPevt.item(i):
                if self.modelSPevt.item(i).checkState() == 2:
                    inevt[i-1] = 'T'
                i += 1
        #
        if flagDist == 1:
            createSSM_RchEvtLayer(gridlayer, newName, pathfile, modelName, nsp, nlay, nspec, inrch, inevt)


        # run for selected point packages
        # chd
        if self.chkChd.isChecked() :
            chdlayer = getVectorLayerByName(self.cmbCHD.currentText())
            newName  = self.txtChd.text()
            # Retrieve list of selected StressPeriods from SP combo
            splist = []
            i = 1
            while self.modelSPchd.item(i):
                if self.modelSPchd.item(i).checkState() == 2:
                    valore = self.modelSPchd.item(i).data(0)
                    splist.append( int(valore) )
                i += 1
            whichtype = 'chd'
            createSSM_PointSourceLayer(chdlayer, newName, whichtype, pathfile, modelName, splist, nsp, nlay, nspec)
        # wel
        if self.chkWel.isChecked() :
            wellayer = getVectorLayerByName(self.cmbWEL.currentText())
            newName  = self.txtWel.text()
            # Retrieve list of selected StressPeriods from SP combo
            splist = []
            i = 1
            while self.modelSPwel.item(i):
                if self.modelSPwel.item(i).checkState() == 2:
                    valore = self.modelSPwel.item(i).data(0)
                    splist.append( int(valore) )
                i += 1
            whichtype = 'wel'
            createSSM_PointSourceLayer(wellayer, newName, whichtype, pathfile, modelName, splist, nsp, nlay, nspec)

        # ghb
        if self.chkGhb.isChecked() :
            ghblayer = getVectorLayerByName(self.cmbGHB.currentText())
            newName  = self.txtGhb.text()
            # Retrieve list of selected StressPeriods from SP combo
            splist = []
            i = 1
            while self.modelSPghb.item(i):
                if self.modelSPghb.item(i).checkState() == 2:
                    valore = self.modelSPghb.item(i).data(0)
                    splist.append( int(valore) )
                i += 1
            whichtype = 'ghb'
            createSSM_PointSourceLayer(ghblayer, newName, whichtype, pathfile, modelName, splist, nsp, nlay, nspec)

        # riv
        if self.chkRiv.isChecked() :
            rivlayer = getVectorLayerByName(self.cmbRIV.currentText())
            newName  = self.txtRiv.text()
            # Retrieve list of selected StressPeriods from SP combo
            splist = []
            i = 1
            while self.modelSPriv.item(i):
                if self.modelSPriv.item(i).checkState() == 2:
                    valore = self.modelSPriv.item(i).data(0)
                    splist.append( int(valore) )
                i += 1
            whichtype = 'riv'
            createSSM_PointSourceLayer(rivlayer, newName, whichtype, pathfile, modelName, splist, nsp, nlay, nspec)

        # mass
        if self.chkMass.isChecked() :
            masslayer = getVectorLayerByName(self.cmbMass.currentText())
            newName  = self.txtMass.text()
            # Retrieve list of selected StressPeriods from SP combo
            splist = []
            i = 1
            while self.modelSPmass.item(i):
                if self.modelSPmass.item(i).checkState() == 2:
                    valore = self.modelSPmass.item(i).data(0)
                    splist.append( int(valore) )
                i += 1
            whichtype = 'mass'
            createSSM_PointSourceLayer(masslayer, newName, whichtype, pathfile, modelName, splist, nsp, nlay, nspec)

        # constant loading
        if self.chkConst.isChecked() :
            constlayer = getVectorLayerByName(self.cmbConstant.currentText())
            newName  = self.txtConst.text()
            # Retrieve list of selected StressPeriods from SP combo
            splist = []
            i = 1
            while self.modelSPconst.item(i):
                if self.modelSPconst.item(i).checkState() == 2:
                    valore = self.modelSPconst.item(i).data(0)
                    splist.append( int(valore) )
                i += 1
            whichtype = 'const'
            createSSM_PointSourceLayer(constlayer, newName, whichtype, pathfile, modelName, splist, nsp, nlay, nspec)

        QDialog.reject(self)
