# -*- coding: utf-8 -*-
"""A minimal polygon drawing map tool.

Left-click adds vertices, right-click (or double-click) finishes the
polygon and emits `finished(QgsGeometry)` in the canvas CRS.
"""

from qgis.PyQt.QtCore import Qt, pyqtSignal
from qgis.PyQt.QtGui import QColor
from qgis.gui import QgsMapTool, QgsRubberBand
from qgis.core import QgsWkbTypes, QgsGeometry, QgsPointXY


class PolygonDrawTool(QgsMapTool):
    finished = pyqtSignal(object)      # QgsGeometry (polygon, canvas CRS)

    def __init__(self, canvas):
        super().__init__(canvas)
        self.canvas = canvas
        self.points = []
        self.rb = QgsRubberBand(canvas, QgsWkbTypes.GeometryType.PolygonGeometry)
        self.rb.setColor(QColor(255, 80, 40, 90))
        self.rb.setStrokeColor(QColor(255, 80, 40))
        self.rb.setWidth(2)
        self.temp = QgsRubberBand(canvas, QgsWkbTypes.GeometryType.LineGeometry)
        self.temp.setColor(QColor(255, 80, 40, 160))
        self.temp.setWidth(1)

    def _map_pt(self, e):
        return self.toMapCoordinates(e.pos())

    def canvasPressEvent(self, e):
        if e.button() == Qt.MouseButton.LeftButton:
            p = self._map_pt(e)
            self.points.append(p)
            self.rb.addPoint(p, True)
        elif e.button() == Qt.MouseButton.RightButton:
            self._finish()

    def canvasMoveEvent(self, e):
        if not self.points:
            return
        self.temp.reset(QgsWkbTypes.GeometryType.LineGeometry)
        last = self.points[-1]
        cur = self._map_pt(e)
        self.temp.addPoint(last, False)
        self.temp.addPoint(cur, True)

    def canvasDoubleClickEvent(self, e):
        self._finish()

    def _finish(self):
        self.temp.reset(QgsWkbTypes.GeometryType.LineGeometry)
        if len(self.points) < 3:
            self.reset()
            return
        geom = QgsGeometry.fromPolygonXY([[QgsPointXY(p) for p in self.points]])
        self.reset()
        self.finished.emit(geom)

    def reset(self):
        self.points = []
        self.rb.reset(QgsWkbTypes.GeometryType.PolygonGeometry)
        self.temp.reset(QgsWkbTypes.GeometryType.LineGeometry)

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