"""
wx OGL (2d graphics library) utility functions for Epics and wxPython
interaction

OGL is a (somewhat old-fashioned) 2D drawing library included with wxPython.
There are probably newer/better drawing libraries, but OGL works quite well
for drawing simple shapes or bitmaps.

"""
import wx.lib.ogl as ogl
from .wxlib import PVMixin

class PVShapeMixin(PVMixin):
    """
    Mixin for any Shape that has PV callback support

    """
    def __init__(self, pv=None, pvname=None):
        PVMixin.__init__(self, pv, pvname)
        self.brushTranslations = {}
        self.penTranslations = {}
        self.shownTranslations = {}

    def SetBrushTranslations(self, translations):
        """
        Set a dictionary of value->brush translations that will be set automatically
        when the PV value changes. The brush is used to paint the shape foreground

        The argument should be a dictionary with keys as PV values (string if available), and values
        as wx.Brush instances.

        """
        self.brushTranslations = translations

    def SetPenTranslations(self, translations):
        """
        Set a dictionary of value->bpen translations that will be set automatically
        when the PV value changes. The pen is used to paint the shape outline.

        The argument should be a dictionary with keys as PV values (string if available), and values
        as wx.Brush instances.

        """
        self.penTranslations = translations


    def SetShownTranslations(self, translations):
        """
        Set a dictionary of value->boolean 'Shown' translations that will be set automatically
        when the PV value changes. The value is used to show/hide the shape.

        """
        self.shownTranslations = translations


    def OnPVChange(self, raw_value):
        """
        Do not override this method, override PVChanged if you would like to do any
        custom callback behaviour

        """
        if raw_value in self.brushTranslations:
            self.SetBrush(self.brushTranslations[raw_value])
        if raw_value in self.penTranslations:
            self.SetPen(self.penTranslations[raw_value])
        if raw_value in self.shownTranslations:
            self.Show(self.shownTranslations[raw_value])
        self.PVChanged(raw_value)
        self.Invalidate()

    def PVChanged(self, raw_value):
        """
        Override this method if you want your shape to do any special processing when the
        PV changes

        Note that the shape will be automatically invalidated (redrawn) after this method is called.

        """
        pass


    def Invalidate(self):
        """
        Invalidate the shape's area on the parent shape canvas to cause a redraw
        (convenience method)

        """
        (w, h) = self.GetBoundingBoxMax()
        x = self.GetX()
        y = self.GetY()
        self.GetCanvas().RefreshRect((x-w/2, y-h/2, w, h))


class PVRectangle(ogl.RectangleShape, PVShapeMixin):
    """
    A RectangleShape which is associated with a particular PV value

    """
    def __init__(self, w, h, pv=None, pvname=None):
        ogl.RectangleShape.__init__(self, w, h)
        PVShapeMixin.__init__(self, pv, pvname)

class PVCircle(ogl.CircleShape, PVShapeMixin):
    """
    A CircleShape which is associated with a particular PV value

    """
    def __init__(self, diameter, pv=None, pvname=None):
        ogl.CircleShape.__init__(self, diameter)
        PVShapeMixin.__init__(self, pv, pvname)

"""
wx OGL (2d graphics library) utility functions for Epics and wxPython
interaction

OGL is a (somewhat old-fashioned) 2D drawing library included with wxPython.
There are probably newer/better drawing libraries, but OGL works quite well
for drawing simple shapes or bitmaps.

"""
import wx.lib.ogl as ogl
from .wxlib import PVMixin

class PVShapeMixin(PVMixin):
    """
    Mixin for any Shape that has PV callback support

    """
    def __init__(self, pv=None, pvname=None):
        PVMixin.__init__(self, pv, pvname)
        self.brushTranslations = {}
        self.penTranslations = {}
        self.shownTranslations = {}

    def SetBrushTranslations(self, translations):
        """
        Set a dictionary of value->brush translations that will be set automatically
        when the PV value changes. The brush is used to paint the shape foreground

        The argument should be a dictionary with keys as PV values (string if available), and values
        as wx.Brush instances.

        """
        self.brushTranslations = translations

    def SetPenTranslations(self, translations):
        """
        Set a dictionary of value->bpen translations that will be set automatically
        when the PV value changes. The pen is used to paint the shape outline.

        The argument should be a dictionary with keys as PV values (string if available), and values
        as wx.Brush instances.

        """
        self.penTranslations = translations


    def SetShownTranslations(self, translations):
        """
        Set a dictionary of value->boolean 'Shown' translations that will be set automatically
        when the PV value changes. The value is used to show/hide the shape.

        """
        self.shownTranslations = translations


    def OnPVChange(self, raw_value):
        """
        Do not override this method, override PVChanged if you would like to do any
        custom callback behaviour

        """
        if raw_value in self.brushTranslations:
            self.SetBrush(self.brushTranslations[raw_value])
        if raw_value in self.penTranslations:
            self.SetPen(self.penTranslations[raw_value])
        if raw_value in self.shownTranslations:
            self.Show(self.shownTranslations[raw_value])
        self.PVChanged(raw_value)
        self.Invalidate()

    def PVChanged(self, raw_value):
        """
        Override this method if you want your shape to do any special processing when the
        PV changes

        Note that the shape will be automatically invalidated (redrawn) after this method is called.

        """
        pass


    def Invalidate(self):
        """
        Invalidate the shape's area on the parent shape canvas to cause a redraw
        (convenience method)

        """
        (w, h) = self.GetBoundingBoxMax()
        x = self.GetX()
        y = self.GetY()
        self.GetCanvas().RefreshRect((x-w/2, y-h/2, w, h))


class PVRectangle(ogl.RectangleShape, PVShapeMixin):
    """
    A RectangleShape which is associated with a particular PV value

    """
    def __init__(self, w, h, pv=None, pvname=None):
        ogl.RectangleShape.__init__(self, w, h)
        PVShapeMixin.__init__(self, pv, pvname)

class PVCircle(ogl.CircleShape, PVShapeMixin):
    """
    A CircleShape which is associated with a particular PV value

    """
    def __init__(self, diameter, pv=None, pvname=None):
        ogl.CircleShape.__init__(self, diameter)
        PVShapeMixin.__init__(self, pv, pvname)

wx OGL (2d graphics library) utility functions for Epics and wxPython interaction  OGL is a (somewhat old-fashioned) 2D drawing library included with wxPython. There are probably newer/better drawing libraries, but OGL works quite well for drawing simple shapes or bitmaps. Mixin for any Shape that has PV callback support Set a dictionary of value->brush translations that will be set automatically         when the PV value changes. The brush is used to paint the shape foreground          The argument should be a dictionary with keys as PV values (string if available), and values         as wx.Brush instances. Set a dictionary of value->bpen translations that will be set automatically         when the PV value changes. The pen is used to paint the shape outline.          The argument should be a dictionary with keys as PV values (string if available), and values         as wx.Brush instances. Set a dictionary of value->boolean 'Shown' translations that will be set automatically         when the PV value changes. The value is used to show/hide the shape. Do not override this method, override PVChanged if you would like to do any         custom callback behaviour Override this method if you want your shape to do any special processing when the         PV changes          Note that the shape will be automatically invalidated (redrawn) after this method is called. Invalidate the shape's area on the parent shape canvas to cause a redraw         (convenience method) A RectangleShape which is associated with a particular PV value A CircleShape which is associated with a particular PV value