#coding=utf-8
#Copyright (C) 2015 IDAEA-CSIC
#
#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. This program is distributed in the hope that it will be useful, but 
#ITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
#PURPOSE. See the GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License along with this program; if not, write to 
#the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
:copyright: Copyright (C) 2015 IDAEA-CSIC
:authors: V. Velasco Mansilla, L.M. de Vries, A. Nardi, R. Criollo, E. Vázquez Suñé
:contact: enric.vazquez@idaea.csic.es
:license: GPL General Public License, version 2 or any later version (http://opensource.org/licenses/GPL-2.0)
'''
from PyQt4.Qt import QSqlQueryModel, Qt, QModelIndex, QAbstractTableModel, QBrush, QColor
from qgis.core import QgsGeometry, QgsFeatureRequest
from PyQt4 import QtCore

class MEASUREMENT_RESULTS:
    Active = 0
    PointId = 1
    Point = 2
    Sample = 3 #for chem
    Observation = 3 #for hydro
    SampleDate = 4
    Campaign = 5 
    MeasurementDate = 6
    ParamId = 7
    BaseParamId = 8
    Parameter = 9
    MeasurementValue = 10
    LimitValue = 11 #for chem
    MeasurementId = 11 #for hydro
    Value = 12
    Unit = 13
    UnitId = 14
    UnitCode = 15
    IsCalculated = 16
    XCoord = 17
    YCoord = 18
    
    count = 19

class SavedQueryMeasurementsModel(QAbstractTableModel): 
    def __init__(self, parent=None):
        super(SavedQueryMeasurementsModel, self).__init__(parent)
        self.queryModel = QSqlQueryModel() 
        self.activeArray = []
        self.newValue = []
        self.valueIsCalulated = []
        self.xCoord = []
        self.yCoord = []

    def headerData(self, section, orientation, role = Qt.DisplayRole):
        if (role != Qt.DisplayRole):
            return None
        headerName = None
        if(role == Qt.DisplayRole and orientation == Qt.Horizontal):
            if(section == MEASUREMENT_RESULTS.Active):
                headerName = "Active"
            elif(section > MEASUREMENT_RESULTS.Active and section < MEASUREMENT_RESULTS.Value):
                headerName = self.queryModel.headerData(section - 1, orientation, Qt.DisplayRole) # -1 for active column
            elif(section == MEASUREMENT_RESULTS.Value):
                headerName = "Value"
            elif(section > MEASUREMENT_RESULTS.Value and section < MEASUREMENT_RESULTS.IsCalculated): 
                headerName = self.queryModel.headerData(section - 2, orientation, Qt.DisplayRole) # -1 for active&value columns
            elif(section == MEASUREMENT_RESULTS.IsCalculated):
                headerName = "Is Calculated"
            elif(section == MEASUREMENT_RESULTS.XCoord):
                headerName = "Coordinate X"
            elif(section == MEASUREMENT_RESULTS.YCoord):
                headerName = "Coordinate Y"
            elif(section > MEASUREMENT_RESULTS.YCoord):
                numOfCustomColumns = MEASUREMENT_RESULTS.count - self.queryModel.columnCount() - 1 # -1 for geometry column
                headerName = self.queryModel.headerData(section - numOfCustomColumns, orientation, Qt.DisplayRole)
            else:
                return None
        return headerName
 
    def setDB(self, db):
        self.curDB = db

    def setOutOfRangeParams(self, params):
        self.outOfRangeParams = params

    def rowCount(self, parent=QModelIndex()):
        return self.queryModel.rowCount(parent)

    def columnCount(self, parent=QModelIndex()):
        return MEASUREMENT_RESULTS.count

    def data(self, index, role=Qt.DisplayRole):
        if(not index or not index.isValid()):
            return None

        curRow = index.row()
        if(role == Qt.BackgroundRole and self.valueIsCalulated[curRow] ):
            return QBrush(QColor(240,240,240))#Qt.lightGray))

        if(role == Qt.DisplayRole):
            curColumn = index.column() 
            if(curColumn == MEASUREMENT_RESULTS.Active):
                return self.activeArray[curRow]
            elif(curColumn > MEASUREMENT_RESULTS.Active and curColumn < MEASUREMENT_RESULTS.Value):
                return self.queryModel.index(curRow,curColumn-1).data(role)
            elif(curColumn == MEASUREMENT_RESULTS.Value):
                return self.newValue[curRow]
            elif(curColumn > MEASUREMENT_RESULTS.Value and curColumn < MEASUREMENT_RESULTS.IsCalculated):
                return self.queryModel.index(curRow,curColumn-2).data(role)
            elif(curColumn == MEASUREMENT_RESULTS.IsCalculated):
                return self.valueIsCalulated[curRow]
            elif(curColumn == MEASUREMENT_RESULTS.XCoord):
                return self.xCoord[curRow]
            elif(curColumn == MEASUREMENT_RESULTS.YCoord):
                return self.yCoord[curRow]
            elif(curColumn > MEASUREMENT_RESULTS.YCoord):
                numOfCustomColumns = MEASUREMENT_RESULTS.count - self.queryModel.columnCount() - 1
                return self.queryModel.index(curRow,curColumn-numOfCustomColumns).data(role)
            else:
                return None
        return None

    def setData(self, index, value, role=Qt.EditRole):
        if(not index or not index.isValid()):
            return False
        if (index.column() == 0):
            self.activeArray[index.row()] = value
            self.dataChanged.emit(index,index)
            return True
        return False

    def parseCompValue(self, fullString, paramProps):
        limitValue = 0.0
        firstLetter = fullString[0]

        #compValue = float(fullString[1:].replace(',', '.')) # AN Hey, problem with comma and points conversion due to incorrect data in database
        compValue = float(fullString[1:])
            
        if(firstLetter == '<'):
            limitValue = paramProps["min"]
        elif(firstLetter == '>'):
            limitValue = paramProps["max"]
        newValue = compValue * limitValue
        return newValue

    def setQuery(self, query, pointsTableInfo):
        self.queryModel.setQuery(query)
        
        pointsLayer = pointsTableInfo["layerObject"]
        
        while self.queryModel.canFetchMore():
            self.queryModel.fetchMore()
        
        self.activeArray  = [1] * self.queryModel.rowCount()
        
        for rowId in range(self.queryModel.rowCount()):
            curRow = self.queryModel.record(rowId)
            value = curRow.value("value")
            compValue = curRow.value("limitValue")
            paramId = curRow.value("baseParamId")
            curParamProps = self.outOfRangeParams[paramId]
            newValue = value
            valueCalculated = False
            if(compValue != None and value == None):
                newValue = self.parseCompValue(compValue, curParamProps)
                valueCalculated = True
            self.newValue.append(newValue)
            self.valueIsCalulated.append(valueCalculated)
            pointId = curRow.value("PointId")
            pointFeature = pointsLayer.getFeatures(QgsFeatureRequest().setFilterFid( pointId ) ) 
            nextFeat = pointFeature.next()
            curPoint = nextFeat.geometry().asPoint()
            myType = nextFeat.geometry().type()
            self.xCoord.append(curPoint[0])
            self.yCoord.append(curPoint[1])

    def reset(self):
        self.query().exec_()
        
    def flags(self, index):        
        if not index.isValid():
            return QtCore.Qt.NoItemFlags
        if (index.column() == 0):
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable |  QtCore.Qt.ItemIsEditable
        
        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable            