#!/cygdrive/c/Python26/python.exe

import wx
from wx.glcanvas import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *

class MyGLCanvas(GLCanvas):
    def __init__(self, parent):
        # Explicit attribute list to disable double buffering
        attribList = [WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 16]
        GLCanvas.__init__(self, parent, -1, attribList=attribList)
        # glutInit()
        self.gl_is_initialized = False
        wx.EVT_PAINT(self, self.on_paint)
        # Prevent flicker by overriding erase background event
        wx.EVT_ERASE_BACKGROUND(self, lambda event: None)
        
    def init_gl(self):
        glClearColor(1.0, 1.0, 1.0, 0.0)
        glShadeModel(GL_SMOOTH)
        glEnable(GL_DEPTH_TEST)
        self.init_materials()
        
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        # glFrustum(-50.0, 50.0, -50.0, 50.0, 5.0, 100.0)
        gluPerspective(60.0, 1.0, 5.0, 100.0)
        
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        glTranslatef(0.0, 0.0, -100.0)
        # gluLookAt(0,0,0.0, 0,0,-100.0, 0,0,1)
        
    def init_materials(self):
        pass

    def on_paint(self, event):
        dc = wx.PaintDC(self)
        self.SetCurrent()
        if not self.gl_is_initialized:
            self.init_gl()
            self.gl_is_initialized = True
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        self.render()
        self.SwapBuffers()
        
    def render(self):
        """
        Derived classes should override render() to draw their stuff.
        """
        pass
        

class TeapotCanvas(MyGLCanvas):
    def __init__(self, parent):
        MyGLCanvas.__init__(self, parent)
        self.spin = 0.0 # for animation
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.spin_display, self.timer)
        self.timer.Start(50)
        
    def render(self):
        glPushMatrix()
        glRotatef(self.spin, 0.0, 0.0, 1.0)
        glColor3f(0.5, 0.5, 0.5)
        glutSolidTeapot(25)
        glPopMatrix()        

    def spin_display(self, event):
        self.spin = self.spin + 2.0
        if (self.spin > 360.0):
            self.spin = self.spin - 360.0
        # Trigger repaint
        self.Refresh()
        

class SphereApp(wx.PySimpleApp):
    def __init__(self):
        wx.PySimpleApp.__init__(self)
        frame = wx.Frame(None, -1, 'Sphere', size=wx.Size(250,250))
        self.canvas = TeapotCanvas(frame)
        frame.Show()

        wx.EVT_MOTION(self.canvas, self.on_mouse_move)
        self.old_mouse = None
        wx.EVT_LEFT_UP(self.canvas, self.on_mouse_release)
        wx.EVT_RIGHT_UP(self.canvas, self.on_mouse_release)
        wx.EVT_MIDDLE_UP(self.canvas, self.on_mouse_release)
        wx.EVT_MOUSEWHEEL(self.canvas, self.on_mouse_scroll)
        
        self.MainLoop()

    def on_mouse_release(self, event):
        if self.canvas.HasCapture():
            self.canvas.ReleaseMouse()

    def on_mouse_move(self, event):
        if event.Dragging():
            # Hold onto mouse events while dragging
            if not self.canvas.HasCapture():
                self.canvas.CaptureMouse()
            x, y = event.GetPosition()
            print x, y
            if self.old_mouse:
                old_x = self.old_mouse[0]
                old_y = self.old_mouse[1]
                print x - old_x, y - old_y
            self.old_mouse = (x, y)
            
    def on_mouse_scroll(self, event):
        pos = event.GetWheelRotation()
        print pos

if __name__ == '__main__':
    SphereApp()

