#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 import QtGui
from qgis.core import QgsField, QgsFeature, QgsFeatureRequest, QgsPoint, QgsProject, QgsGeometry
from PyQt4.QtCore import QVariant

from AKSettings import TABLES
from AKFeatureResultsMapChem import AKFeatureResultsMapChem
from form.AKWidgetStiffMapSettings import AKWidgetStiffMapSettings

class AKFeatureResultsMapStiff(AKFeatureResultsMapChem):
    '''
    This feature provides the functionality for the second form to create stiff maps. 
    '''
    def __init__(self, settings, iface, windowTitle = "Stiff Chart Map Results", parent=None):
        super(AKFeatureResultsMapStiff, self).__init__(settings, iface, windowTitle = windowTitle, parent=parent)
        
    def customizeForm(self):        
        super(AKFeatureResultsMapStiff, self).customizeForm()
        self.stiffSettingsForm = AKWidgetStiffMapSettings(self.iface, self.m_form)          
        self.m_form.customResultsGroup.layout().addWidget(self.stiffSettingsForm)
                
    def initialize(self):
        self.showData(hideMeasurements=True)
        super(AKFeatureResultsMapStiff, self).initialize(showTable=False)
    
    def onActionClicked(self):    
        targetField = self.getTargetField()
        distY = self.stiffSettingsForm.spnHeight.value()
        scaleX = self.stiffSettingsForm.spnScaleX.value()
        scaleY = 1.0
        timeSeriesData = self.storeDataInTimeSeries()
        root = QgsProject.instance().layerTreeRoot()
        groupName = self.generateNewName("Generated Maps")
        newGroupNode = root.addGroup(groupName)

        for unitId in timeSeriesData:
            curUnitInfo = timeSeriesData[unitId]
            unitCode = curUnitInfo["unitCode"]
            if unitCode == "MQL":
                mqlUnitId = unitId
                break

        pointsLayer = self.m_settings.m_availableTables[TABLES.POINTS]["layerObject"]
        pointsProjection = self.getProjection(pointsLayer)

        allNewLayers = {} 
        if mqlUnitId != -1:
            curUnitInfo = timeSeriesData[mqlUnitId]
            fieldList = []
            for curParamName in curUnitInfo["parameterNames"]:
                fieldList.append(QgsField(curParamName, QVariant.Double))
            allNewLayers["values"] = self.addVectorLayer("Polygon", "Stiff", pointsProjection, fieldList)

            allValues = {}
            for seriesId in curUnitInfo["series"]:
                curSeries = curUnitInfo["series"][seriesId]
                paramId = curSeries["parameterId"]
                pointId = curSeries["pointId"]
                point = curSeries["point"]
                if pointId not in allValues:
                    allValues[pointId] = {}
                    allValues[pointId]["point"] = point                
                values = curSeries["values"]
                targetFields = self.getStatistics(values)
                allValues[pointId][paramId] = targetFields[targetField]
                
            #calculate local stiff coords
            pointIds,coordinates,pointValues = self.retrieveLocalStiffCoordinates(allValues, distY)
            scaledCoordinates = self.calcScaledCoordinates(coordinates, scaleX, scaleY)
            
            translatedCoordinates = self.calcTranslatedCoordinatesToPoints(pointsLayer, pointIds, scaledCoordinates)

            features = []
            for index in range(len(pointIds)):
                pointId = pointIds[index]
                coordinateSet = translatedCoordinates[index] 
                curPointValues = pointValues[index] 
                attributes = [allValues[pointId]["point"]] + curPointValues
                newFeature = self.createStiffPlot(pointsLayer, pointId, coordinateSet, attributes, distY)
                features.append(newFeature)
            curProvider = allNewLayers["values"].dataProvider()
            curProvider.addFeatures(features)

            self.finalizeLayers(allNewLayers,targetField, newGroupNode, self.paramLimits, addLegend = False)
            self.newLayers.update(allNewLayers)
            
        QtGui.QMessageBox.information(self.iface.mainWindow(),
            "Finished creating requested maps.",
            "The following maps have been generated: \n\n- " + "\n- ".join(["Stiff"]))            

    def createStiffPlot(self, pointLayer, pointId, coordinates, attributes, distY):
        pointFeature = pointLayer.getFeatures(QgsFeatureRequest().setFilterFid( pointId ) ).next()
        centerX = pointFeature.geometry().asPoint()[0]
        centerY = pointFeature.geometry().asPoint()[1]
        newFeature = self.createPolygon(coordinates, attributes)
        newGeom = self.createLine(centerX, centerY, distY)
        newFeature.setGeometry(newFeature.geometry().combine(newGeom))
        return newFeature

    def createPolygon(self, coordinates, attributes):
        pointList = [QgsPoint(x[0],x[1]) for x in coordinates]
        pointList.append(QgsPoint(coordinates[0][0],coordinates[0][1]))
        polygon= QgsGeometry.fromPolygon([pointList])
        feature = QgsFeature()
        feature.setGeometry(polygon)
        feature.setAttributes(attributes)
        return feature

    def createLine(self, centerX, centerY, distY):
        distY *= 1.25
        coordinates = [(centerX,centerY - distY), (centerX+1,centerY - distY), (centerX+1,centerY + distY), (centerX,centerY + distY)]
        pointList = [QgsPoint(x[0],x[1]) for x in coordinates]
        pointList.append(QgsPoint(coordinates[0][0],coordinates[0][1]))
        polyLine= QgsGeometry.fromPolygon([pointList])
        return polyLine

    def postProcessModelData(self, paramInfo, parameterOrder):
        super(AKFeatureResultsMapStiff, self).postProcessModelData(paramInfo, parameterOrder)
        self.addValidColumn(paramInfo, parameterOrder)