"""Action diagram item."""

from gaphor import UML
from gaphor.diagram.presentation import ElementPresentation, Named, Valued
from gaphor.diagram.shapes import Box, Text, draw_border, stroke
from gaphor.diagram.support import represents
from gaphor.UML.recipes import stereotypes_str
from gaphor.UML.umlfmt import format_call_behavior_action_name


@represents(UML.Action)
class ActionItem(Named, ElementPresentation):
    def __init__(self, diagram, id=None):
        super().__init__(diagram, id, width=50, height=30)

        self.width = 100
        self.shape = Box(
            Text(
                text=lambda: stereotypes_str(self.subject),
            ),
            Text(
                text=lambda: self.subject.name or "",
            ),
            style={
                "padding": (4, 12, 4, 12),
                "border-radius": 15,
            },
            draw=draw_border,
        )

        self.watch("subject[NamedElement].name")
        self.watch("subject.appliedStereotype.classifier.name")


@represents(UML.ValueSpecificationAction)
class ValueSpecificationActionItem(Valued, ElementPresentation):
    def __init__(self, diagram, id=None):
        super().__init__(diagram, id, width=50, height=30)

        self.width = 100
        self.shape = Box(
            Text(
                text=lambda: "«valueSpecification»",
            ),
            Text(
                text=lambda: self.subject.value or "",
            ),
            style={
                "padding": (4, 12, 4, 12),
                "border-radius": 15,
            },
            draw=draw_border,
        )

        self.watch("subject[ValueSpecificationAction].value")


@represents(UML.CallBehaviorAction)
class CallBehaviorActionItem(ActionItem):
    def __init__(self, diagram, id=None):
        super().__init__(diagram, id)

        self.shape = Box(
            Text(
                text=lambda: stereotypes_str(self.subject),
            ),
            Text(
                text=lambda: format_call_behavior_action_name(self.subject),
            ),
            style={
                "padding": (4, 24, 4, 12),
                "border-radius": 15,
            },
            draw=self.draw_border_with_fork,
        )

        self.watch("subject[CallBehaviorAction].behavior.name")

    def draw_border_with_fork(self, box, context, bounding_box):
        draw_border(box, context, bounding_box)

        cr = context.cairo
        x, y, width, height = bounding_box

        x_offset = width - 15
        y_offset = height - 15
        half_width = 5
        half_height = 5

        cr.move_to(x_offset, y_offset - half_height)
        cr.line_to(x_offset, y_offset + half_height)
        cr.close_path()

        cr.move_to(x_offset - half_width, y_offset)
        cr.line_to(x_offset + half_width, y_offset)
        cr.close_path()

        cr.move_to(x_offset - half_width, y_offset)
        cr.line_to(x_offset - half_width, y_offset + half_height)
        cr.close_path()

        cr.move_to(x_offset + half_width, y_offset)
        cr.line_to(x_offset + half_width, y_offset + half_height)
        cr.close_path()

        stroke(context, fill=True)


@represents(UML.SendSignalAction)
class SendSignalActionItem(Named, ElementPresentation):
    def __init__(self, diagram, id=None):
        super().__init__(diagram, id, width=50, height=30)

        self.shape = Box(
            Text(
                text=lambda: stereotypes_str(self.subject),
            ),
            Text(text=lambda: self.subject.name or ""),
            style={"padding": (4, 24, 4, 12)},
            draw=self.draw_border,
        )

        self.watch("subject[NamedElement].name")
        self.watch("subject.appliedStereotype.classifier.name")

    def draw_border(self, box, context, bounding_box):
        cr = context.cairo
        d = 15
        x, y, width, height = bounding_box
        cr.move_to(0, 0)
        cr.line_to(width - d, 0)
        cr.line_to(width, height / 2)
        cr.line_to(width - d, height)
        cr.line_to(0, height)
        cr.close_path()

        stroke(context, fill=True)


@represents(UML.AcceptEventAction)
class AcceptEventActionItem(Named, ElementPresentation):
    def __init__(self, diagram, id=None):
        super().__init__(diagram, id, width=50, height=30)

        self.shape = Box(
            Text(
                text=lambda: stereotypes_str(self.subject),
            ),
            Text(text=lambda: self.subject.name or ""),
            style={"padding": (4, 12, 4, 24)},
            draw=self.draw_border,
        )

        self.watch("subject[NamedElement].name")
        self.watch("subject.appliedStereotype.classifier.name")

    def draw_border(self, box, context, bounding_box):
        cr = context.cairo
        d = 15
        x, y, width, height = bounding_box
        cr.move_to(0, 0)
        cr.line_to(width, 0)
        cr.line_to(width, height)
        cr.line_to(0, height)
        cr.line_to(d, height / 2)
        cr.close_path()

        stroke(context, fill=True)
