# DRILL: adapt Ball class to bounce off walls

# Ball class
class Ball:
    def __init__(self, start_x, start_y, start_v_x, start_v_y, color='blue'):
        # Ball location and velocity
        self.x = start_x
        self.y = start_y
        self.v_x = start_v_x
        self.v_y = start_v_y

        # Ball color, for drawing purposes
        self.color = color

    def update_position(self, timestep):
        self.x = self.x + timestep * self.v_x
        self.y = self.y + timestep * self.v_y
        if( self.y <= -CANVAS_HEIGHT/2+BALL_RADIUS ):
            self.v_y = -self.v_y
            self.y = self.y + timestep * self.v_y

    def update_velocity(self, timestep):
        self.v_y = self.v_y + timestep * EARTH_GRAVITY_ACCELERATION

    def animate_step(self, timestep):
        self.update_position(timestep)
        self.update_velocity(timestep)

    def draw_ball(self):
        D.append(draw.Circle(self.x, self.y, BALL_RADIUS, fill=self.color)) 


# List of Ball objects (with gravity)
CANVAS_WIDTH = 200
CANVAS_HEIGHT = 200
EARTH_GRAVITY_ACCELERATION = -9.8   # acceleration due to gravity, m/sec^2
BALL_RADIUS = 10  # radius of the ball in pixels

D = draw.Drawing(CANVAS_WIDTH, CANVAS_HEIGHT, origin='center') # define drawing canvas

def draw_frame():
    for b in ball_list:
        b.draw_ball();
    for b in ball_list:
        b.animate_step(0.2) # with gravity

    return D    

ball_list = []; # initialize empty list
colors = ['red', 'orange', 'yellow','green', 'blue', 'indigo', 'violet']
for i in range(1,100):
    x  = randint(-90,90)
    y  = randint(-90,90)
    vx = 20*random() - 10
    vy = 20*random() - 10
    c  = randint(0,len(colors)-1)
    ball_list.append( Ball(x, y, vx, vy, colors[c]) )

for i in range(0,1000):
    D = draw.Drawing(200, 200, origin='center' ) # erase canvas
    with draw.animate_jupyter(draw_frame, delay=0.05) as anim:
        anim.draw_frame()



# DRILL: BankAccount
class BankAccount:
    def __init__(self, initial):
        self.balance = initial
        
    def deposit(self, amount):
        self.balance = self.balance + amount
        
    def withdraw(self, amount):
        self.balance = self.balance - amount
        
    def overdrawn(self):
        return self.balance < 0
    
    def __str__(self):
        return "balance: " + str(self.balance)
    
# Driver code to test BankAccount
my_account = BankAccount(150)
print( my_account )
my_account.deposit(200)
print( my_account )
my_account.withdraw(50)
print( my_account )
print( my_account.overdrawn() )
my_account.withdraw(500)
print( my_account )
print( my_account.overdrawn() )



# DRILL: Kangaroo
class Kangaroo:
    def __init__(self):
        self.pouch_contents = []

    def put_in_pouch(self,x):
        for i in range(len(self.pouch_contents)):
            if( self.pouch_contents[i] == x ):
                print("already in pouch")
                return
        self.pouch_contents.append(x)

    def __str__(self):
        if( len(self.pouch_contents) == 0 ):
            return "The kangaroo's pouch is empty."
        else:
            return "The kangaroo's pouch contains: " + str(self.pouch_contents)

# Driver code to test Kangaroo
K = Kangaroo()
print(K)
K.put_in_pouch( "ball" )
print(K)
K.put_in_pouch( "hammer")
print(K)
K.put_in_pouch( "ball" )
print(K)



