import cairo

from gi.repository import Gtk, GObject, Gdk

from .OverlayWindow import OverlayWindow

from .__init__ import NORTH, EAST, SOUTH, WEST


class ArrowButton(OverlayWindow):
    """Leafs will connect to the drag-drop signal"""

    __gsignals__ = {
        "dropped": (GObject.SignalFlags.RUN_FIRST, None, (object,)),
        "hovered": (GObject.SignalFlags.RUN_FIRST, None, (object,)),
        "left": (GObject.SignalFlags.RUN_FIRST, None, ()),
    }

    def __init__(self, parent, svgPath, position):
        OverlayWindow.__init__(self, parent)
        self.myposition = position
        self.svgPath = svgPath

        # targets = [("GTK_NOTEBOOK_TAB", Gtk.TargetFlags.SAME_APP, 0xbadbeef)]
        targets = [
            Gtk.TargetEntry.new("GTK_NOTEBOOK_TAB", Gtk.TargetFlags.SAME_APP, 0xBADBEEF)
        ]
        self.drag_dest_set(
            Gtk.DestDefaults.DROP | Gtk.DestDefaults.MOTION,
            targets,
            Gdk.DragAction.MOVE,
        )
        self.drag_dest_set_track_motion(True)
        self.myparent.button_cids[self] += [
            self.connect("drag-motion", self.__onDragMotion),
            self.connect("drag-leave", self.__onDragLeave),
            self.connect("drag-drop", self.__onDragDrop),
            self.connect_after("draw", self.__onExposeEvent),
        ]
        self.hovered = False

        self.myparentAlloc = None
        self.myparentPos = None
        self.hasHole = False

    def _calcSize(self):
        parentAlloc = self.myparent.get_allocation()
        width, height = self.getSizeOfSvg(self.svgPath)

        if self.myparentAlloc is None:
            self.resize(width, height)

        if self.get_window() and not self.hasHole:
            self.hasHole = True
            self.digAHole(self.svgPath, width, height)

        if self.myposition == NORTH:
            x_loc, y_loc = parentAlloc.width / 2.0 - width / 2.0, 0
        elif self.myposition == EAST:
            x_loc, y_loc = (
                parentAlloc.width - width,
                parentAlloc.height / 2.0 - height / 2.0,
            )
        elif self.myposition == SOUTH:
            x_loc, y_loc = (
                parentAlloc.width / 2.0 - width / 2.0,
                parentAlloc.height - height,
            )
        elif self.myposition == WEST:
            x_loc, y_loc = 0, parentAlloc.height / 2.0 - height / 2.0

        x_loc, y_loc = self.translateCoords(int(x_loc), int(y_loc))
        if (x_loc, y_loc) != self.get_position():
            self.move(x_loc, y_loc)

        self.myparentAlloc = parentAlloc
        window = self.myparent.get_window()
        if window is None:
            print("   !!! get_window() returned None for", self.myparent)
        else:
            self.myparentPos = window.get_position()

    def __onExposeEvent(self, self_, ctx):
        self._calcSize()
        context = self.get_window().cairo_create()
        width, height = self.getSizeOfSvg(self.svgPath)
        surface = self.getSurfaceFromSvg(self.svgPath, width, height)

        if self.is_composited():
            context.set_operator(cairo.OPERATOR_CLEAR)
            context.set_source_rgba(0.0, 0.0, 0.0, 0.0)
            context.paint()
            context.set_operator(cairo.OPERATOR_OVER)

        # FIXME
        # mask = Gdk.Pixmap(None, width, height, 1)
        # mcontext = mask.cairo_create()
        # mcontext.set_source_surface(surface, 0, 0)
        # mcontext.paint()
        # self.window.shape_combine_mask(mask, 0, 0)

        context.set_source_surface(surface, 0, 0)
        context.paint()

    def __containsPoint(self, x, y):
        alloc = self.get_allocation()
        return 0 <= x < alloc.width and 0 <= y < alloc.height

    def __onDragMotion(self, arrow, context, x, y, timestamp):
        if not self.hovered and self.__containsPoint(x, y):
            self.hovered = True
            self.emit("hovered", Gtk.drag_get_source_widget(context))
        elif self.hovered and not self.__containsPoint(x, y):
            self.hovered = False
            self.emit("left")

    def __onDragLeave(self, arrow, context, timestamp):
        if self.hovered:
            self.hovered = False
            self.emit("left")

    def __onDragDrop(self, arrow, context, x, y, timestamp):
        if self.__containsPoint(x, y):
            self.emit("dropped", Gtk.drag_get_source_widget(context))
            context.finish(True, True, timestamp)
            return True
