from wxPython.wx import *
from wxPython.ogl import *

wxOGLInitialize()

class ConsElem(wxPolygonShape):
    def __init__(self):
        wxPolygonShape.__init__(self)
        points = [(-40,25),(-40,0),(-60,0),(-40,0),(-40,-25),(40,-25),(40,0),(60,0),(40,0),(40,25),(-40,25),(-20,25),(-20,-25),(5,-25),(5,25),(20,25),(20,-25),(20,0),(5,0),(5,25)]
        self.Create(points)
       
class Texto(wxTextShape):
    def __init__(self):
        wxTextShape.__init__(self)

    def AdicionaTexto(self, st):
        self.AddText(st)

class Composite(wxCompositeShape):
    def __init__(self, canvas, x, y):
        wxCompositeShape.__init__(self)

        self.SetCanvas(canvas)
        self.SetDraggable(true)
        dc = wxClientDC(canvas)
        canvas.PrepareDC(dc)

        rec = wxRectangleShape(120,50)
        rec.SetX(x)
        rec.SetY(y)
        rec.SetPen(wxWHITE_PEN)
        rec.Show(true)
        self.AddChild(rec)
        
        ce = ConsElem()
        ce.SetCanvas(canvas)
        ce.SetDraggable(true)
        ce.SetFixedSize(true, true)
        ce.SetX(x)
        ce.SetY(y)
        ce.Show(true)
        self.AddChild(ce)
 
        self.d = Texto()
        self.d.AdicionaTexto("d")
        self.d.SetX(x-10)
        self.d.SetY(y+5)
        self.d.Show(true)

        self.e = Texto()
        self.e.AdicionaTexto("k")
        self.e.SetX(x+10)
        self.e.SetY(y-18)
        self.e.Show(true)

        self.AddChild(self.d)
        self.AddChild(self.e)

        constraint = wxOGLConstraint(gyCONSTRAINT_CENTRED_BOTH, rec, [ce])
        self.AddConstraint(constraint)

#        constraint = wxOGLConstraint(gyCONSTRAINT_CENTRED_BOTH, ce, [d,e])            
#        constraint = wxOGLConstraint(gyCONSTRAINT_CENTRED_BOTH, ce, [f,f,d,f,f,f])
#        constraint2 = wxOGLConstraint(gyCONSTRAINT_CENTRED_BOTH, ce, [f,e])
#        self.AddConstraint(constraint)
#        self.AddConstraint(constraint2)
##        constraint.SetSpacing(0,0)
##        constraint2.SetSpacing(100,100)

        self.Recompute()
        self.CalculateSize()


class MyEvent(wxShapeEvtHandler):
    def __init__(self):
        wxShapeEvtHandler.__init__(self)

    def OnLeftClick(self, x, y, keys = 0, attachment = 0):
        obj = self.GetShape()
        canvas = obj.GetCanvas()
        dc = wxClientDC(canvas)
        canvas.PrepareDC(dc)

        if not obj.Selected():
            shapeList = canvas.GetDiagram().GetShapeList()
            toUnselect = []
            for s in shapeList:
                if s.Selected():
                    toUnselect.append(s)

            obj.Select(True, dc)

            if toUnselect:
                for s in toUnselect:
                    s.Select(False, dc)
                canvas.Redraw(dc)   

    def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
        shape = self.GetShape()
        self.base_OnEndDragLeft(x, y, keys, attachment)
        Composite().Atualiza()
        
        if not shape.Selected():
            self.OnLeftClick(x, y, keys, attachment)

class MyShape(wxShapeCanvas):
    def __init__(self, parent, ID):
        wxShapeCanvas.__init__(self, parent, ID)

        self.SetBackgroundColour(wxWHITE)
        self.diagram = wxDiagram()
        self.SetDiagram(self.diagram)
        self.diagram.SetCanvas(self)

        self.shapes = []
        self.value = 50
        
        EVT_RIGHT_UP(self, self.Draw)
        
    def Draw(self, event):
        shape = Composite(self, event.GetX(), event.GetY())
        shape.SetX(event.GetX())
        shape.SetY(event.GetY())
        self.diagram.AddShape(shape)
        shape.Select(true)
        shape.Show(true)
        self.shapes.append(shape)
        self.Refresh()

        evthandler = MyEvent()
        evthandler.SetShape(shape)
        evthandler.SetPreviousHandler(shape.GetEventHandler())
        shape.SetEventHandler(evthandler)

            
class MyApp(wxApp):
    def OnInit(self):
        frame = wxFrame(NULL, -1, "Test", wxPoint(30,30), wxSize(300,300))
        mycanvas=MyShape(frame, -1)
        frame.Show(true)
        self.SetTopWindow(frame)
        return True

app=MyApp(0)
app.MainLoop()
