# -*- coding: utf-8 -*-
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from qgis.core import *
from qgis.gui import *
import traceback, os
from MagicWand.mapHelpers.MapGraph import MapGraph


class Vectorize2Tool(QgsMapToolEmitPoint):
    def __init__(self,
                 canvas,
                 iface,
                ):

        QgsMapToolEmitPoint.__init__(self, canvas)
        self.canvas = canvas
        self.iface = iface
        name = "VectorizeTool"
        self.setObjectName(name)

        self.mapGraph = MapGraph()

        pencilIcon = QImage(":/VectorizeTools/icons/pencil.png").scaled(QSize(32,32))
        self.pencilCursor = QCursor(QPixmap.fromImage(pencilIcon))
        self.setCursor(self.pencilCursor)

        self.rubberBand = QgsRubberBand(self.canvas, QGis.Polygon)
        self.rubberBand.setColor(Qt.blue)
        self.rubberBand.setWidth(5)

        self.rubberBandVisibile = QgsRubberBand(self.canvas, QGis.Point)
        self.rubberBandVisibile.setColor(QColor(255, 255, 255, 200))
        self.rubberBandVisibile.setWidth(3)

        self.rubberBandAngoli = QgsRubberBand(self.canvas, QGis.Point)
        self.rubberBandAngoli.setColor(Qt.red)
        self.rubberBandAngoli.setWidth(1)

        self.rubberBandSnapping = QgsRubberBand(self.canvas, False)
        self.rubberBandSnapping.setColor(Qt.red)
        self.rubberBandSnapping.setWidth(2)

        self.viewSteps = False

        self.canvasClicked.connect(self.canvasPointClicked)

    # ========================================= Temp layer ========================================= #

    def createTempLayer(self):
        tempVectorLayer = QgsVectorLayer("Polygon", "temp", "memory")
        stylePath = os.path.dirname(os.path.abspath(__file__))
        stylePath = stylePath[0: stylePath.rfind(os.path.sep)+1]+"styles"+os.path.sep+"vectorStyle.qml"
        tempVectorLayer.loadNamedStyle(stylePath)

        #QMessageBox.information(None, "", str(stylePath))
        results = QgsMapLayerRegistry.instance().addMapLayers([tempVectorLayer])
        cond = tempVectorLayer.isValid() and tempVectorLayer in results
        if cond:
            self.tempVectorLayer = tempVectorLayer
        else:
            QMessageBox.information(None, "", "Vector layer invalid")
        return cond


    # ========================================= Setters ============================================ #
    def setTolerance(self, v):
        self.mapGraph.tolerance = v

    def setApproximation(self, a):
        self.mapGraph.approximation = a

    # ========================================= Basic ============================================= #
    def activate(self):
        QgsMapToolEmitPoint.activate(self)
        self.canvas.setFocus()
        self.canvas.refresh()
        self.canvas.repaint()

    def deactivate(self):
        QgsMapToolEmitPoint.deactivate(self)
        self.reset()

    def toolName(self):
        return "VectorizeTool"

    def reset(self):
        self.rubberBand.reset(QGis.Polygon)
        self.rubberBandAngoli.reset(False)
        self.rubberBandVisibile.reset(QGis.Line)

    def removeLastPointPersonal(self):
        self.rubberBand.removeLastPoint()
        self.rubberBandAngoli.removeLastPoint()
        self.rubberBandVisibile.removeLastPoint()

    # ========================================= OnClick ============================================= #


    def canvasMoveEvent(self, event):

        lyr = self.iface.activeLayer()
        if lyr and lyr.type() == QgsMapLayer.RasterLayer:
            point = self.canvas.getCoordinateTransform().toMapPoint(event.x(), event.y())
            self.rasterLayer = lyr
            rgbColor = self.mapGraph.getPixelValue(point, self.rasterLayer)
            #QMessageBox.information(None, "", str(rgbColor))
            if rgbColor == (-1,-1,-1): rgbColor = (255,255,255)
            self.pixelOver.emit(rgbColor)

    # ========================================= OnClick ============================================= #


    def canvasPointClicked(self, point, button):

        lyr = self.iface.activeLayer()

        if lyr and lyr.type() == QgsMapLayer.RasterLayer:
            self.rasterLayer = lyr
            try:
                if button == Qt.LeftButton:
                    if self.createTempLayer():
                        self.iface.setActiveLayer(self.rasterLayer)

                        featDaAggiungere = []

                        N = self.mapGraph.approximation

                        rect = self.mapGraph.getPixelRectangleNxN(point, self.rasterLayer, N)

                        labColorFirst = self.mapGraph.getRectValue(rect, self.rasterLayer, N)
                        geom = QgsGeometry.fromRect(rect)

                        extent = self.canvas.extent()
                        try:
                            geom = self.visita(geom, point, rect, self.rasterLayer, labColorFirst, N, extent)
                            #self.rubberBand.setToGeometry(geom, None)
                        except RuntimeError as re:
                            QMessageBox.information(None, "", "Recursion error")

                        feat = QgsFeature()
                        #geom = geom.smooth(N, 0.25)
                        #geom.simplify(pow(N, N))
                        feat.setGeometry(geom)
                        featDaAggiungere.append(feat)

                        """
                        toRemove = []
                        iterF = self.tempVectorLayer.getFeatures()
                        for feat in iterF:
                            toRemove.append(feat.id())
                        iterF.close()
                        self.tempVectorLayer.dataProvider().deleteFeatures(toRemove)
                        """

                        self.tempVectorLayer.dataProvider().addFeatures(featDaAggiungere)
                        self.tempVectorLayer.triggerRepaint()


                elif button == Qt.RightButton:
                    pass
            except:
                tb = traceback.format_exc()
                QMessageBox.information(None, "Attenzione", "Error in canvasPointClicked:\n"+str(tb))
        else:
            QMessageBox.information(None, "Attenzione", "The active layer must be raster")

    def visita(self, geom, center, rect, raster, colorFirst,N, extent):
        geomNuova = QgsGeometry.fromRect(rect)
        geom = geom.combine(geomNuova)

        if self.viewSteps:
            self.rubberBand.setToGeometry(geom, None)
            QMessageBox.information(None, "", "")

        adjacentPoints = self.mapGraph.getAllAdjacentPixelPositionsNxN(center, raster, N)

        trovati = []
        directionTrovate = []
        for adjPoint, direction in adjacentPoints:

            adjRect = self.mapGraph.getPixelRectangleNxN(adjPoint, self.rasterLayer, N)
            labColorAdj = self.mapGraph.getRectValue(adjRect, raster, N)

            if extent.contains(adjPoint):
                if self.mapGraph.pixelSimili(colorFirst, labColorAdj):
                    trovati.append((adjPoint,adjRect))
                    directionTrovate.append(direction)

        toIgnore = []
        #for ind, direction in enumerate(directionTrovate):
        #    indVero = self.directions.index(direction)

        #    dirPrecVera = self.directions[(indVero-1)%len(self.directions)]
        #    dirSuccVera = self.directions[(indVero+1)%len(self.directions)]

        #    dirPrecTrovata = directionTrovate[(ind-1)%len(directionTrovate)]
        #    dirSuccTrovata = directionTrovate[(ind+1)%len(directionTrovate)]

        #    if dirPrecVera != dirPrecTrovata and dirSuccVera != dirSuccTrovata:
        #        toIgnore.append(ind)

        for ind,(pointT,rectT) in enumerate(trovati):
            if ind not in toIgnore:
                if not geom.contains(pointT):
                    geom = self.visita(geom, pointT, rectT, raster, colorFirst, N, extent)

        return geom


    # ========================================= Signals ============================================= #
    pixelOver = pyqtSignal(object)