try:
    from opengltk.OpenGL.GL import *
    from opengltk.OpenGL.GLUT import *
    from opengltk.OpenGL.GLU import *
except:
    print "Error: Could not import opengltk "

import sys

from UTpackages.UTimposter import utimposterrend


class TestImposterRenderer:
    def __init__(self):
        self.initialized = False
        self.windowCreated = False
        self.imposterRenderer = None
        self.state = "ROTATE"
        self.mousex =0
        self.mousey =0
        self.cdx = 0
        self.cdy = 0
        self.whichbutton=0
        self.rotMatrix = [1.,0.,0.,0.,
                          0.,1.,0.,0.,
                          0.,0.,1.,0.,
                          0.,0.,0.,1.]
        self.transMatrix = [1.,0.,0.,0.,
                            0.,1.,0.,0.,
                            0.,0.,1.,0.,
                            0.,0.,0.,1.]

        
    def display(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
	glMatrixMode(GL_MODELVIEW)
        #
        glLoadIdentity()
        #glTranslated(0.0, 0.0, -4.0)
        glMultMatrixd(self.transMatrix)
        glMultMatrixd(self.rotMatrix)
        #
	#glPushMatrix()

        if self.imposterRenderer:
            self.imposterRenderer.renderBuffer(True, False, None, None, 0, False, 1.0)
	#glPopMatrix()
	glutSwapBuffers()
        
    def mouseCallbackFunction(self, button, state, x, y):
        if (state == GLUT_DOWN):
            self.mousex = x
            self.mousey = y
            self.whichbutton = button
            self.cdx = 0
            self.cdy = 0
        pass
        
    def mouseMotionCallbackFunction(self, x, y):
        #return
        dx = x-self.mousex
        dy = y-self.mousey
        if self.state == 'ROTATE':
            self.Rotate(dx, dy)

        elif self.state ==  'TRANSLATE':
            if (self.whichbutton == GLUT_LEFT_BUTTON):
                self.Translate(dx, -dy,0)
            else:
                self.Translate(0,0,-dy)
        else:
            pass
        self.mousex = x
        self.mousey = y
        glutPostRedisplay()

    
    def reshapeCallbackFunction(self, w, h):
        if w < 6: w = 6
        if h < 6: h = 6

	glMatrixMode(GL_PROJECTION)
	glLoadIdentity()
	glViewport(0, 0, w, h)

	windowSize = None
        if w>h: 
            windowSize = w/15.0
	else:
            windowSize = h/15.0
	glOrtho(-windowSize/2.0, windowSize/2.0, -windowSize/2.0, windowSize/2.0, -200, 200)

	glMatrixMode(GL_MODELVIEW)
	glLoadIdentity()
	gluLookAt(0.0,0.0,5.0, 
                  0.0,0.0,-1.0,
                  0.0, 1.0, 0.0)
        
    def setCallbacks(self):
	glutDisplayFunc(self.display)
        #glutIdleFunc(self.Idle)
	glutMouseFunc(self.mouseCallbackFunction)
	glutMotionFunc(self.mouseMotionCallbackFunction)
	glutReshapeFunc(self.reshapeCallbackFunction)
        glutKeyboardFunc(self.Keyboard)

    def Idle(self):
        self.Rotate(self.cdx, self.cdy)
        glutPostRedisplay()

    def BeginGraphics(self):
        glutInit('foo')
	glutInitDisplayMode( GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE )
	self.initialized = True
        windowHandle = glutCreateWindow("ImposterRenderer")
	self.windowCreated = True
        self.initModelMatrix()
        self.setCallbacks()
        numBalls = 4
        x = [1,1,4,1]
        y = [2,3,2,8]
        z = [3,5,3,1]
        r = [1,1,1,1]
        red =   [1,1,0,0]
        green = [1,0,1,0]
        blue =  [0,0,0,1]
        if not self.initializeImposterRenderer(numBalls, x, y, z, r, red, green, blue):
        
            print "Could not initialize the imposter renderer\n"
            return 

        if not self.startLoop():
            print "Could not start the glut loop\n"


    def initializeImposterRenderer(self, numBalls, x, y, z, r, red, green, blue):
        self.imposterRenderer = utimposterrend.ImposterRenderer()
        status = self.imposterRenderer.initRenderer()
        #print "status:", status
        if not status:
            print "Could not initialize the imposter renderer\n"
            return False
        self.imposterRenderer.initSubRenderers(0)
        self.imposterRenderer.clear()
        brp = utimposterrend.BallRendererPtr(self.imposterRenderer.m_BallRenderer)
        self.imposterRenderer.setLightVector([0,1,1,0])
        for i in range(numBalls):
            brp.addBall(x[i], y[i], z[i], r[i], red[i], green[i], blue[i])
        return True


    def startLoop(self):
        if self.initialized and self.windowCreated:
            glutMainLoop()
        else:
            return False


    def Keyboard(self,key, x, y):

        print '--> keyboard( %s <%c>, %i, %i)' % (key, chr( key), x, y)
	chkey = chr(key)
        if (chkey == 'R') or (chkey=='r'):
            self.state = 'ROTATE'

        elif (chkey == 't') or (chkey=='T'):
            self.state = 'TRANSLATE'

        elif (chkey == 'q') or (chkey == 'Q'):
            sys.exit()
        else:
            pass


    def Rotate(self,dx, dy):
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        glRotated((float(dy)), 1.0, 0.0, 0.0)
        glRotated((float(dx)), 0.0, 1.0, 0.0)
        glMultMatrixd(self.rotMatrix)
        self.rotMatrix=glGetDoublev(GL_MODELVIEW_MATRIX)
        #self.rotMatrix.shape = (16,)
        glPopMatrix()

    def Translate(self,dx,dy, dz):
        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadIdentity()
        glTranslated((float(dx))/100.0, (float(dy))/100.0, (float(dz))/10.0)
        glMultMatrixd(self.transMatrix)
        self.transMatrix = glGetDoublev(GL_MODELVIEW_MATRIX)
        self.transMatrix.shape = (16,)
        glPopMatrix()

    def initModelMatrix(self):
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        self.rotMatrix=glGetDoublev(GL_MODELVIEW_MATRIX)
        self.transMatrix=glGetDoublev(GL_MODELVIEW_MATRIX)


## imposterRenderer = ImposterRenderer()
## imposterRenderer.initRenderer()
## imposterRenderer.initSubRenderers(0)
## imposterRenderer.clear()
## brp = BallRendererPtr(imposterRenderer.m_BallRenderer)
## brp.addBall(1 ,2, 3, 1, 1, 1, 0)


#import _utimposterrend
#_utimposterrend.BallRenderer_addBall(imposterRenderer.m_BallRenderer, 1, 2, 3, 1, 1, 1, 0)

## imposterRenderer.renderBuffer(True, False, None, None, 0, False, 1.0)


#print "Use the mouse buttons to control."
#print " Hit 't' or 'T' to do translation."
#print " Hit 'r' or 'R' to do rotation."
print "Hit q  key to quit."

t = TestImposterRenderer()
t.BeginGraphics()
