'''
Created on Jan 16, 2011

@author: clifton
'''
from zellegraphics import GraphWin, Circle, Point
import time
from random import randrange, random

WIDTH = 240
HEIGHT = 180
MAX_INIT_VELOCITY = 5.0
PAUSE_DURATION = 0.02 # seconds
RADIUS = 15
GRAV_ACCEL = 0.5

def getNewBall():
    '''Return a random location (x,y) and velocity (vx, vy) for the ball in pixels.'''
    x = randrange(WIDTH)
    y = randrange(HEIGHT/2)
    vx = random() * MAX_INIT_VELOCITY
    vy = random() * MAX_INIT_VELOCITY
    ball = Circle(Point(x, y), RADIUS)
    return x, y, vx, vy, ball

def moveBall(x, y, ball):
    '''Moves the given ball (Circle) to the given location.'''
    oldCtr = ball.getCenter()
    dx = x - oldCtr.getX()
    dy = y - oldCtr.getY()
    ball.move(dx, dy)
    
def applyPhysicsToBall(x, y, vx, vy):
    '''Simulates physics applied to a ball with the given properties, 
    returning new value for the properties.'''
    # Update x and y based on velocity
    newX = x + vx
    newY = y + vy
    # Update velocity based on hitting the edges
    newVY = vy
    if newY > HEIGHT:
        newVY = -1 * newVY
        if newY > HEIGHT:
            newY = HEIGHT - (newY - HEIGHT)
    newVX = vx
    if newX > WIDTH or newX < 0:
        newVX = -1 * newVX
    # Update velocity based on gravity
    newVY = newVY + GRAV_ACCEL
    return newX, newY, newVX, newVY
    
def main():
    '''That's the way the ball bounces'''
    # Create window
    win = GraphWin("Bounce!", WIDTH, HEIGHT)
    # Get location and velocity for a ball
    x, y, vx, vy, ball = getNewBall()
    ball.draw(win)
    # Repeat:
    while win.checkMouse() == None:
        #   draw the ball
        moveBall(x, y, ball)
        #   apply physics to the ball
        x, y, vx, vy = applyPhysicsToBall(x, y, vx, vy)
        #   pause to let display catch up
        time.sleep(PAUSE_DURATION)
    win.close()

if __name__ == '__main__':
    main()
    
    
    
    
    
    