class CommandNotification(object):
    """Displays the command status to the targeted players (source and target)"""
    def __init__(self):
        self._source = None
        self._target = None
        self._notification = RectLabel(
            500, 0, 350, 75, Color.GREY, 0,
            Text(pygame.font.SysFont('Agency FB', 30), f"Commanding: None",
                 Color.GREEN2))
        self._notification.change_bg_image(WOOD)
        self._notification.add_frame(FRAME)
        self._wait_command = RectLabel(
            500, 400, 300, 50, Color.GREY, 0,
            Text(pygame.font.SysFont('Agency FB', 30), f"Commanded by: None",
                 Color.GREEN2))
        self._wait_command.change_bg_image(WOOD)
        self._wait_command.add_frame(FRAME)
        self._init_end_command_btn()
        self._is_source = False
        self._is_target = False

    def _init_end_command_btn(self):
        # End command button
        self._end_command_btn = RectButton(
            1080,
            450,
            200,
            50,
            background=Color.ORANGE,
            txt_obj=Text(pygame.font.SysFont('Agency FB', 23), "END COMMAND",
                         Color.GREEN2))
        self._end_command_btn.change_bg_image(WOOD)
        self._end_command_btn.add_frame(FRAME)
        self._end_command_btn.on_click(self.end_command)

    def end_command(self):
        event = StopCommandEvent(self._source)

        if Networking.get_instance().is_host:
            Networking.get_instance().send_to_all_client(event)
        else:
            Networking.get_instance().send_to_server(event)

    @property
    def command(self) -> Tuple[PlayerModel, PlayerModel]:
        return self._source, self._target

    @command.setter
    def command(self, command: Tuple[PlayerModel, PlayerModel]):
        (self._source, self._target) = command
        source_msg = "Commanding: None"
        target_msg = "Commanded by: None"
        if self._target:
            source_msg = f"Commanding: {self._target.nickname}"
        if self._source:
            target_msg = f"Commanded by: {self._source.nickname}"

        self._notification.change_text(
            Text(pygame.font.SysFont('Agency FB', 30), source_msg,
                 Color.ORANGE))
        self._notification.change_bg_image(WOOD)
        self._notification.add_frame(FRAME)
        self._wait_command.change_text(
            Text(pygame.font.SysFont('Agency FB', 30), target_msg,
                 Color.ORANGE))
        self._wait_command.change_bg_image(WOOD)
        self._wait_command.add_frame(FRAME)

    @property
    def is_source(self) -> bool:
        return self._is_source

    @is_source.setter
    def is_source(self, source: bool):
        self._is_source = source

    @property
    def is_target(self) -> bool:
        return self._is_target

    @is_target.setter
    def is_target(self, target: bool):
        self._is_target = target

    def update(self, event_queue: EventQueue):
        if self.is_source:
            self._notification.update(event_queue)
            self._end_command_btn.update(event_queue)
        elif self.is_target:
            self._wait_command.update(event_queue)

    def draw(self, screen):
        if self.is_source:
            self._notification.draw(screen)
            self._end_command_btn.draw(screen)
        elif self.is_target:
            self._wait_command.draw(screen)
class PermissionPrompt(object):
    """Prompt for the player deciding whether to allow to be commanded or not."""
    def __init__(self):
        self.accept_button = RectButton(
            500 - 75, 310, 75, 50, Color.ORANGE, 0,
            Text(pygame.font.SysFont('Agency FB', 20), "Accept", Color.GREEN2))
        self.accept_button.change_bg_image(WOOD)
        self.accept_button.add_frame(FRAME)
        self.deny_button = RectButton(
            500 + 300, 310, 75, 50, Color.ORANGE, 0,
            Text(pygame.font.SysFont('Agency FB', 20), "Deny", Color.GREEN2))
        self.deny_button.change_bg_image(WOOD)
        self.deny_button.add_frame(FRAME)
        self.accept_button.on_click(self._accept_on_click)
        self.deny_button.on_click(self._deny_on_click)

        self._source = None
        self._target = None
        self.background = RectLabel(
            500, 300, 300, 75, Color.GREY, 0,
            Text(pygame.font.SysFont('Agency FB', 20), "Permission?",
                 Color.GREEN2))
        self.background.change_bg_image(WOOD)
        self.background.add_frame(FRAME)

        self._enabled = False

    def _send_reply_event(self, reply: bool):
        if Networking.get_instance().is_host:
            Networking.get_instance().send_to_all_client(
                PermissionReplyEvent(reply, self._source, self._target))
        else:
            Networking.get_instance().send_to_server(
                PermissionReplyEvent(reply, self._source, self._target))

    def _deny_on_click(self):
        self.enabled = False
        self._send_reply_event(False)

    def _accept_on_click(self):
        self.enabled = False
        self._send_reply_event(True)

    def update(self, event_queue: EventQueue):
        if self._enabled:
            self.background.update(event_queue)
            self.accept_button.update(event_queue)
            self.deny_button.update(event_queue)

    def draw(self, screen):
        if self._enabled:
            self.background.draw(screen)
            self.accept_button.draw(screen)
            self.deny_button.draw(screen)

    @property
    def enabled(self) -> bool:
        return self._enabled

    @enabled.setter
    def enabled(self, enable: bool):
        self._enabled = enable

    @property
    def command(self) -> Tuple[PlayerModel, PlayerModel]:
        return self._source, self._target

    @command.setter
    def command(self, command: Tuple[PlayerModel, PlayerModel]):
        self._source = command[0]
        self._target = command[1]
        self.background.change_text(
            Text(pygame.font.SysFont('Agency FB', 20),
                 f"{self._source.nickname} wants to command you",
                 Color.GREEN2))
        self.background.change_bg_image(WOOD)
        self.background.add_frame(FRAME)