SCREEN_SIZE = (800, 600)

from math import radians 

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from OpenGL.GLE import *

import pygame
from pygame.locals import *
from random import *
from numpy import array, add, real, complex,cos,power,e,sin




def resize(width, height):
    
    glViewport(0, 0, width, height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(45.0, float(width)/height, .1, 1000.)
    glMatrixMode(GL_MODELVIEW)
        
    glLoadIdentity()


def init():
    
    glEnable(GL_DEPTH_TEST)
    
    glShadeModel(GL_FLAT)
    glClearColor(1.0, 1.0, 1.0, 0.0)

    glEnable(GL_COLOR_MATERIAL)
    
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)        
    glLight(GL_LIGHT0, GL_POSITION,  (0, 1, 1, 0))    
    
    
class Ball(object):
    
    def __init__(self, position, color):
        
        self.position = array (position)
        self.color = color
        self.vel = array ([random(),0.,random()])
        self.size = 3.
        self.display_list = None
        self.trace = []
        self.colors = []
        
        
    def update(self):
        """one tick of speudo physics"""
        if self.position[1]+self.size/2 < 0:
            self.position[1]=-self.size/2
            #refloction + shock absoption
            self.vel[1] = self.vel[1]*-.90
            #print "bounce"
            
        
        # pseudo gravitiy    
        self.vel= add(self.vel,array([0.,-0.05,0.]))
        # some friction
        self.vel= self.vel*.99
        # acceleration
        self.position = add(self.position,self.vel)
        self.display_list = None
        self.color = .7-self.vel
        self.trace.append(self.position)
        self.colors.append(self.color)
        
        
        
        
        
        
    def render(self):   
        glColor( self.color )
        glPushMatrix()
        glTranslatef(self.position[0],self.position[1],self.position[2])
        glutSolidSphere(self.size,32,32)
        glPopMatrix()
        for elm,color in zip(self.trace,self.colors):
            pass
            """
            glPushMatrix()
            glColor( color )
            glTranslatef(elm[0],elm[1],elm[2])
            glutSolidSphere(0.2,6,6)
            glPopMatrix()
            """
            
    

def spring(time):
    time += 1
    x = time
    result = real((complex(10.000000099497512,9.999750006249842e-9)*cos(0.5*x) - complex(9.949751256218596e-8,9.999750006249842e-9)*power(e,complex(0.5,10.)*x)* power(cos(0.5*x),2) + complex(9.999999899502512,1.999950001249969e-6)*sin(0.5*x) - complex(9.949751256218596e-8,9.999750006249842e-9)*power(e,complex(0.5,10.)*x)*power(sin(0.5*x),2))/power(e,0.5*x))
    print result 
    glPushMatrix()
    glTranslatef(0,result,-20)
    glutSolidSphere(1,32,32)
    glPopMatrix()
    return time  
                   

def run():
    
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE, HWSURFACE|OPENGL|DOUBLEBUF)
    
    resize(*SCREEN_SIZE)
    init()
    
    clock = pygame.time.Clock()      
    glMaterial(GL_FRONT, GL_AMBIENT, (0.1, 0.1, 0.1, 1.0))    
    glMaterial(GL_FRONT, GL_DIFFUSE, (1.0, 1.0, 1.0, 1.0))
    balls = []
    balls.append(Ball([-30,30,-100.],(0.1,0.1,.5,)))
    
    time = -1000.
    
    while True:  
        for event in pygame.event.get():
            if event.type == QUIT:
                return
            if event.type == KEYUP and event.key == K_ESCAPE:
                return
            if event.type == KEYUP and event.key == K_SPACE :
                print"space"
                balls.append(Ball([-30,30,-100.],(0.1,0.1,.5,)))
                         
        #print "running"
        # Clear the screen, and z-buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
        # Light must be transformed as well
        glLight(GL_LIGHT0, GL_POSITION,  (0, 1.5, 1, 0)) 
            
        # Render the map
        for ball in balls:
            ball.update()
            #ball.size += .001
            ball.render()
        
        # Show the screen
        pygame.display.flip()
        pygame.time.wait(10)
        
run()