__author__ = 'bailey'

import tkinter as gwaphics

class Blob(object):
    def __init__(self, canvas, deltaX = 5, deltaY = 0, *args, **kwargs):
        self.canvas = canvas
        self.id = canvas.create_oval(*args, **kwargs)
        self.vx = deltaX
        self.vy = deltaY
    def move(self):
        x1, y1, x2, y2 = self.canvas.bbox(self.id) ## unpacking the list defining the current bounding box of the object
        if x2 > App.WIDTH or x1 < 0: ## reflecting horizontally
            self.vx *= -1
        if y2 > App.HEIGHT or y1 < 0: ## reflecting vertically
            self.vy *= -1
        self.canvas.move(self.id, self.vx, self.vy)

class Silly(object):
    def __init__(self, canvas, deltaX = 5, deltaY = 0, *args, **kwargs):
        self.canvas = canvas
        self.id = canvas.create_text(*args, **kwargs)
        self.vx = deltaX
        self.vy = deltaY
    def move(self):
        x1, y1, x2, y2 = self.canvas.bbox(self.id) ## unpacking the list defining the current bounding box of the object
        if x2 > App.WIDTH or x1 < 0: ## reflecting horizontally
            self.vx *= -1
        if y2 > App.HEIGHT or y1 < 0: ## reflecting vertically
            self.vy *= -1
        self.canvas.move(self.id, self.vx, self.vy)

class Bouncy(object):
    def __init__(self, canvas, other, deltaX = 5, deltaY = 0, *args, **kwargs):
        self.canvas = canvas
        self.other = other ## the other thing we'll bounce off from
        self.id = canvas.create_oval(*args, **kwargs)
        self.vx = deltaX
        self.vy = deltaY
        self.other_X_bounce = False ## to handle bouncing off the other object wihtout getting trapped !!
    def move(self):
        x1, y1, x2, y2 = self.canvas.bbox(self.id) ## unpacking the list defining the current bounding box of the object
        X1, Y1, X2, Y2 = self.other.canvas.bbox(self.other.id) ## unpacking the details of the other object
        if x2 > App.WIDTH or x1 < 0: ## reflecting horizontally
            self.vx *= -1
        elif y2 > App.HEIGHT or y1 < 0: ## reflecting vertically
            self.vy *= -1
        if (x2 > X1 and x2 < X2) or (x1 > X1 and x1 < X2): ## if pink is inside blue horizontally
            print("\tINSIDE the blue ball ....")
            if self.other_X_bounce == False:
                self.vx = -self.vx  ## reflect
                print("pink's (x1, x2) = (" + str(x1) + ", " + str(x2) + ") and blue's (X1, X2) = (" + str(X1) + ", " + str(X2)
                      + ") ... and within blue ball .. reflecting and setting bounce = TRUE")
                self.other_X_bounce = True ## ensure don't enter this again until after leaving blue ball
            else:
                print("\tbounce is TRUE and STILL within blue ball .... not re-reflecting")
                print("pink's (x1, x2) = (" + str(x1) + ", " + str(x2) + ") and blue's (X1, X2) = (" + str(X1) + ", " + str(X2)
                      + ") ... and so STILL within blue ball ..")
        else:
            print("\tOUTSIDE blue ball")
            if self.other_X_bounce == True:
                print("\t\tSUDDENLY OUTSIDE blue ball so resetting bounce to be FALSE")
                self.other_X_bounce = False
            else:
                print("\t\tOUTSIDE blue ball and bounce was FALSE ... so keeping bounce to be FALSE")
                self.other_X_bounce = False
        ##if y2 > Y1 or y1 < Y2: ## reflecting vertically
        ##    self.vy *= -1
        self.canvas.move(self.id, self.vx, self.vy)


class App(object):
    WIDTH = 1000
    HEIGHT = 600
    def __init__(self, master, **kwargs):
        self.master = master
        self.delay = 10
        self.canvas = gwaphics.Canvas(self.master, width = App.WIDTH, height = App.HEIGHT)
        self.canvas.pack()
        shift = Blob(self.canvas, 5, 0, 20, 260, 120, 360, outline = 'white', fill = 'blue')
        self.blobs = [
            shift,
            Blob(self.canvas, 5, 0, 2, 2, 40, 40, outline = 'white', fill = 'red'),
            Blob(self.canvas, 5, 2, 2, 2, 60, 60, outline = 'white', fill = 'green'),
            Silly(self.canvas, 5, 1, 200, 200, fill = 'black', text = "Bonjour mes amis", font = ("Purisa", 36)),
            Bouncy(self.canvas, shift, 6, 2, 300, 460, 400, 560, outline = 'white', fill = 'pink')
            ]
        self.canvas.pack()
        self.master.after(0, self.animate) ## this makes the first call to the animate function

    def animate(self):
         for blob in self.blobs: ## this will move each blob exactly once
             blob.move()
         self.master.after(self.delay, self.animate) ## this is NOT recursion -- it schedules a later call to the animate function

root = gwaphics.Tk()
app = App(root)
root.mainloop()