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

#******************************************************************************
#
# Freewat
# ---------------------------------------------------------
#
#
# Copyright (C) 2018 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
import processing
from PyQt4 import QtGui, uic
from freewat.freewat_utils import getVectorLayerByName, getVectorLayerNames, getModelsInfoLists, getModelInfoByName
from freewat.createGrid_utils import get_rgrid_nrow_ncol, get_rgrid_delr_delc
#
#
FORM_CLASS, _ = uic.loadUiType(os.path.join( os.path.dirname(__file__), 'ui/ui_settingTMR.ui') )
#
class CreateTMRFileDialog(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.createTMR)
        self.manageGui()

##
##
    def manageGui(self):
        self.cmbModelName.clear()
        self.cmbGridLayer.clear()
        layerNameList = getVectorLayerNames()
        layerNameList.sort()

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

        self.cmbModelName.addItems(modelNameList)

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

        self.cmbGridLayer.addItems(grid_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 createTMR(self):

        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(0)
        self.progressBar.setValue(0)

        QApplication.processEvents()

        # ------------ Load input data  ------------
        modelName = self.cmbModelName.currentText()
        gridLayer = getVectorLayerByName(self.cmbGridLayer.currentText())

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

        # --- Input from GUI
        # info on original grid
        features = processing.features(gridLayer)
        if len(features) > 1:
            QMessageBox.warning(self, self.tr('Warning!'), self.tr('You selected more than 1 cell!!\nPlease, try again!'))
            self.reject()
        else:
            ft = [f for f in features][0]
            thisCol = ft['COL']
            thisRow = ft['ROW']
            (x_this,y_this) = ft.geometry().centroid().asPoint()

        # deselect cell to retrieve delr, delc
        gridLayer.removeSelection() #'gridLayer'
        (nrow, ncol) = get_rgrid_nrow_ncol(gridLayer)
        (dr, dc) = get_rgrid_delr_delc(gridLayer)

        totLC = ncol*dr
        totLR = nrow*dc
        # Retrieve the name of the new file from Text Box
        name = self.txtFile.text()
        fileName = os.path.join(pathfile, name + '.txt')

        # refinement parameters from GUI
        if self.radioRefRatio.isChecked():
            N = int(self.spinRefRatio.value())
        else:
            dim = float(self.spinRefDiamension.value())
            N = None

        # multiplier
        m = float(self.spinMultiplier.value())
        #
        # tollerance to calculate the border compared to original grid
        toll = float(self.spinToll.value())

        # corner x,y, of former grid (lower left corner)
        expSelect = QgsExpression( '"ROW" = %i and "COL"= %i '%(nrow,1))
        cornerGeom = [i.geometry() for i in gridLayer.getFeatures(QgsFeatureRequest(expSelect))][0]
        (x_ll_cent,y_ll_cent) = cornerGeom.centroid().asPoint()
        #
        x1_corner = x_ll_cent - dc/2
        y1_corner = y_ll_cent - dr/2

        # --
        # Along x axis  - Colums
        # --
        # distance from left border
        L_targetLeft = dc*(thisCol - 1) + dc/2
        #L_targetLeft = x1_corner + totLC

        if N is None :
            newdc_left = [dim]
        else:
            newdc_left = [dc/N]

        thisCol_new = 1
        totL_new_left = L_targetLeft + newdc_left[0]
        while totL_new_left < totLC:
            newvalue = newdc_left[-1]*m
            totL_new_left += newvalue
            # the IF check is for the latest cell (on right side):
            if totL_new_left < (totLC + toll):
                newdc_left.append(newvalue)
                thisCol_new += 1

        # go towards left side
        totL_new_right = L_targetLeft
        if N is None :
            newdc_right = [dim]
        else:
            newdc_right = [(dc/N)*m]

        while totL_new_right > 0:
            newvalue = newdc_right[-1]*m
            totL_new_right = totL_new_right - newvalue
            # the IF check is for the latest cell (on right side):
            if totL_new_right > - toll: newdc_right.append(newvalue)

        newdc_right.reverse()
        newdc = newdc_right + newdc_left
        #
        Ncol_new = len(newdc)
        thisCol_new = Ncol_new - thisCol_new + 1
        # --
        # Along y axis  - Rows
        # --
        # to the bottom
        L_targetTop = dr*(thisRow - 1) + dr/2
        if N is None :
            newdr_down = [dim]
        else:
            newdr_down = [(dr/N)*m]

        thisRow_new = 1
        totL_new_down = L_targetTop + newdr_down[0]
        while totL_new_down < totLR:
            newvalue = newdr_down[-1]*m
            totL_new_down += newvalue
            # the IF check is for the latest cell (on bottom side):
            if totL_new_down < totLR + toll:
                newdr_down.append(newvalue)
                thisRow_new += 1

        # to the top
        totL_new_up = L_targetTop

        if N is None :
            newdr_up = [dim]
        else:
            newdr_up = [(dr/N)*m]

        while totL_new_up > 0:
            newvalue = newdr_up[-1]*m
            totL_new_up = totL_new_up - newvalue
            # the IF check is for the latest cell (on top side):
            if totL_new_up > - toll: newdr_up.append(newvalue)

        newdr_up.reverse()
        newdr = newdr_up + newdr_down
        #
        Nrow_new = len(newdr)
        thisRow_new = Nrow_new - thisRow_new + 1


        # New coord. of the corner
        x1_new = x_this - newdc[thisCol_new - 1]/2
        for i in range(thisCol_new-1):
            x1_new -= newdc[i]
        x1_corner_new = x1_new
        x1_new -= newdc[-1]/2
        #
        y1_new = y_this #- newdr[thisRow_new - 1]/2

        for i in range(thisRow_new-1, Nrow_new):
            y1_new -= newdr[i]
        y1_corner_new = y1_new
        y1_new -= newdr[-1]/2
        #


        # col for text file
        totNEW_col = [0.0]
        for v in newdc:
            totNEW_col.append(totNEW_col[-1] + v)
        # row for text file
        totNEW_row = [0.0]
        # in refinement Text File, origin refers to LowerLeft corner. So... reverse this:
        newdr.reverse()
        for v in newdr:
            totNEW_row.append(totNEW_row[-1] + v)

        #print totNEW_col, totNEW_row

        # write file

        f = open(fileName, 'w')
        # -write header
        f.write('World_Origin_X, World_Origin_Y, Model_Origin_X, Model_Origin_Y, Angle \n')
        f.write('{}, {}, 0, 0, 0 \n'.format(x1_corner_new,y1_corner_new))
        # Cols
        f.write('{} \n'.format(Ncol_new))
        for i in range(len(totNEW_col)):
            f.write('{} \n'.format(totNEW_col[i]))
        # Rows
        f.write('{} \n'.format(Nrow_new))
        for i in range(len(totNEW_row)):
            f.write('{} \n'.format(totNEW_row[i]))
        f.close()

        self.progressBar.setMaximum(100)

        # Message and closing
        msg = 'File input \n %s.txt \n for Telescopic Refinement saved in Model Working Directory\n\n'%name
        msg += 'Open the tool \n \nFREEWAT > Model Setup > Create Grid \n \nand use this file as Input TXT file '

        QMessageBox.information(self, self.tr('Input file for TMR created!'), self.tr(msg))

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