# Source code for draugr.drawers.mpl_drawers.mpldrawer

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-

    __author__ = "Christian Heider Nielsen"
    __doc__ = r"""

               Created on 21/09/2019
               """

    __all__ = ["MplDrawer", "MockDrawer"]

    from abc import abstractmethod
    from typing import Any, Sequence, Tuple

    import matplotlib
    from matplotlib import pyplot

    from draugr.drawers.drawer import Drawer

    # TODO: implement a key for closing the plot
    # close figure with spacebar
    # fig.canvas.mpl_connect('key_press_event', lambda evt: if evt.key == ' ': plt.close())
    # global solution
    # fig.canvas.mpl_connect('key_press_event', lambda evt: print(repr(evt.key))) # print key pressed
    # plt.rcParams['keymap.quit'].append(' ')

    class MplDrawer(
        # metaclass=PostInit
        Drawer
    ):
        """
        Real time plotting base class

        for Matplotlib"""

        # @drop_unused_kws
        def __init__(
            self,
            *,
            default_delta: float = 1 / 120,
            render: bool = True,
            placement: Tuple[int, int] = None,
            **kwargs,
        ):
            """

            :param default_delta:
            :param render:
            :param placement:
            :param kwargs:"""
            super().__init__(**kwargs)
            self.fig = None

            if not render:
                return

            if default_delta is None:  # Zero still passes
                default_delta = 1 / 120

            self._default_delta = default_delta
            self.n = 0

            """
    fig_manager = pyplot.get_current_fig_manager()
    geom = fig_manager.window.geometry()
    x, y, dx, dy = geom.getRect()
    fig_manager.window.setGeometry(*placement, dx, dy)
    fig_manager.window.SetPosition((500, 0))
    """
            self.placement = placement

        """
    @drop_unused_kws
    def __post_init__(self,*, figure_size: Tuple[int, int] = None):
    if self.fig is None:
    if figure_size is None:
    figure_size = (4, 4)
    self.fig = pyplot.figure(figsize=figure_size)
    """

        def draw(self, data: Any, delta: float = None):
            """description"""
            if not self.fig:
                raise NotImplementedError(
                    "Figure was not instantiated check specialisation of MplDrawer"
                )

            self._draw(data)

            pyplot.draw()

            if self.n <= 1 and self.placement:
                self.move_figure(self.fig, *self.placement)
            self.n += 1

            if delta:  # TODO: ALLOW FOR ASYNC DRAWING
                pyplot.pause(delta)
            elif self._default_delta:
                pyplot.pause(self._default_delta)

        @staticmethod
        def move_figure(figure: pyplot.Figure, x: int = 0, y: int = 0):
            r"""
            Move figure's upper left corner to pixel (x, y)"""
            backend = matplotlib.get_backend()
            if hasattr(figure.canvas.manager, "window"):
                window = figure.canvas.manager.window
                if backend == "TkAgg":
                    window.wm_geometry(f"+{x:d}+{y:d}")
                elif backend == "WXAgg":
                    window.SetPosition((x, y))
                else:
                    # This works for QT and GTK
                    # You can also use window.setGeometry
                    window.move(x, y)

        def __enter__(self):
            return self

        def close(self):
            """description"""
            if self._verbose:
                print("mlpdrawer close was called")
            if self.fig:
                pyplot.close(self.fig)

        def __exit__(self, exc_type, exc_val, exc_tb):
            self.close()

        def __del__(self):
            self.close()

        @abstractmethod
        def _draw(self, data: Any) -> None:
            """

            :param data:
            :type data:"""
            raise NotImplementedError

    class MockDrawer(MplDrawer):
        """
        Mock for drawer, accepts data but draws nothing"""

        def _draw(self, data: Sequence) -> None:
            """

            :param data:
            :type data:"""
            pass