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

"""
/***************************************************************************
 QProto
                                 A QGIS plugin
 QProto algorithm
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2018-04-19
        copyright            : (C) 2018 by Matteo Ghetta (Faunalia)
        email                : matteo.ghetta@faunalia.eu
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
"""

__author__ = 'Matteo Ghetta (Faunalia)'
__date__ = '2018-04-19'
__copyright__ = '(C) 2018 by Matteo Ghetta (Faunalia)'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'


import math
from osgeo import gdal
import numpy as np
import os
from qgis.core import (QgsPointXY,
                       QgsFeature,
                       QgsGeometry,
                       QgsRaster,
                       QgsRasterBandStats,
                       QgsContrastEnhancement,
                       QgsRasterShader,
                       QgsColorRampShader,
                       QgsSingleBandPseudoColorRenderer)

from PyQt5.QtGui import QColor

def map2pixel(geoTransform, extent):
    '''
    this function converts the map coordinates in the pixel's position
    '''
    (xmin, xmax, ymin, ymax) = (extent.xMinimum(), extent.xMaximum(), extent.yMinimum(), extent.yMaximum())
    (Xmin, Ymax) = gdal.ApplyGeoTransform(gdal.InvGeoTransform(geoTransform), xmin, ymax)
    (Xmax, Ymin) = gdal.ApplyGeoTransform(gdal.InvGeoTransform(geoTransform), xmax, ymin)
    return (int(Xmin), int(Ymax), int(Xmax), int(Ymin))

def pixel2map(geoTransform, X, Y):
    '''
    this function converts the pixel's position in the map coordinates
    '''
    (x, y) = gdal.ApplyGeoTransform(geoTransform, X + 0.5, Y + 0.5)
    return (x, y)


def triangolo(point1, f, name, dist, alfa):
    '''
    this function creates the triangle that limits the lateral dispersion of
    the phenomenon
    '''
    points = [point1]
    angle1 = math.radians(90-(f[name] + alfa))
    dist_x, dist_y = (dist * math.cos(angle1), dist * math.sin(angle1))
    point2 = QgsPointXY(point1[0] + dist_x, point1[1] + dist_y) # point 2 (aspect + lateral dispersion)
    points.append(point2)
    angle2 = math.radians(90-((f[name]) - alfa))
    dist_x, dist_y = (dist * math.cos(angle2), dist * math.sin(angle2))
    point3 = QgsPointXY(point1[0] + dist_x, point1[1] + dist_y) # point 3 (aspect - lateral dispersion)
    points.append(point3)
    poly = QgsFeature()
    trGeom = QgsGeometry()
    poly.setGeometry(trGeom.fromPolygonXY([points]))
    return poly


def OutStyle(inRaster, Results, visualName):
    '''
    this function defines the color style of the final outputs
    '''

    completePath = os.path.join(Results, visualName)
    fileName = os.path.splitext(completePath)[0]
    styleName = fileName + '.qml'
    endString = os.path.join(Results, styleName)
    inRaster_extent = inRaster.extent()
    provider = inRaster.dataProvider()
    ver = provider.hasStatistics(1, QgsRasterBandStats.All)
    stats = provider.bandStatistics(1, QgsRasterBandStats.All, inRaster_extent, 0)
    min= stats.minimumValue
    max = stats.maximumValue
    if visualName.startswith('count'): # the legend of the "count.tif" output will show integer numbers
        val1 = int(min)
        val2 = int(max/4)
        val3 = int(val2 + max/4)
        val4 = int(val3 + max/4)
        val5 = int(max)
    else: # the legend of the other outputs will show numbers with two decimal places
        val1 = round(min, 2)
        val2 = round((max/4), 2)
        val3 = round((val2 + max/4), 2)
        val4 = round((val3 + max/4), 2)
        val5 = round(max, 2)
    algorithm = QgsContrastEnhancement.StretchToMinimumMaximum
    # limits = QgsRaster.ContrastEnhancementMinMax
    inRaster.setContrastEnhancement(algorithm, 1)
    Shader = QgsRasterShader()
    ColorRamp = QgsColorRampShader()
    ColorRamp.setColorRampType(QgsColorRampShader.Interpolated)
    lst = []
    if visualName.startswith('susceptibility') or visualName.startswith('w_en') or visualName.startswith('w_tot_en'): # the legend of these outputs will show values from 'very limited' to 'very high'
        lst.append(QgsColorRampShader.ColorRampItem(val1, QColor('#2b83ba'), 'very low'))
        lst.append(QgsColorRampShader.ColorRampItem(val2, QColor('#abdda4'), 'limited'))
        lst.append(QgsColorRampShader.ColorRampItem(val3, QColor('#ffffbf'), 'medium'))
        lst.append(QgsColorRampShader.ColorRampItem(val4, QColor('#fdae61'), 'high'))
        lst.append(QgsColorRampShader.ColorRampItem(val5, QColor('#d7191c'), 'very high'))
    else:
        lst.append(QgsColorRampShader.ColorRampItem(val1, QColor('#2b83ba'), str(val1)))
        lst.append(QgsColorRampShader.ColorRampItem(val2, QColor('#abdda4'), str(val2)))
        lst.append(QgsColorRampShader.ColorRampItem(val3, QColor('#ffffbf'), str(val3)))
        lst.append(QgsColorRampShader.ColorRampItem(val4, QColor('#fdae61'), str(val4)))
        lst.append(QgsColorRampShader.ColorRampItem(val5, QColor('#d7191c'), str(val5)))
    ColorRamp.setColorRampItemList(lst)
    Shader.setRasterShaderFunction(ColorRamp)
    ps = QgsSingleBandPseudoColorRenderer(provider, 1, Shader)
    inRaster.setRenderer(ps)
    #inRaster.renderer().setOpacity(0.69) # raster transparency is set to 30%
    inRaster.saveNamedStyle(endString)

    return endString
