from Tkinter import *
from random import *
from sys import *
from time import *
from ballAll_MDL_Compiled import ballAll_MDL

gap = 8

class Control:
    def __init__(self, wid, hei, r, bc):
        self.root = Tk()
        self.canvas = Canvas(self.root, width = wid, height = hei, bg = bc)
        self.width = wid
        self.height = hei
        self.radius = r
        self.g = 500
        self.balls = {}
        self.leftTime = 0
        self.rightTime = 0
        self.upTime = 0
        self.count = 0
        seed()
	self.colors = [ '#110000', '#220000', '#330000', '#440000', '#550000', \
			'#660000', '#770000', '#880000', '#990000', '#aa0000', \
                        '#bb0000', '#cc0000', '#dd0000', '#ee0000', \
			'#ff0000', '#ee0000', '#dd0000', '#cc0000', '#bb0000', \
			'#aa0000', '#990000', '#880000', '#770000', '#660000', \
			'#550000', '#440000', '#330000', '#220000', '#110000', \
			'#001100', '#002200', '#003300', '#004400', '#005500', \
			'#006600', '#007700', '#008800', '#009900', '#00aa00', \
			'#00bb00', '#00cc00', '#00dd00', '#00ee00', '#00ff00', \
			'#00ee00', '#00dd00', '#00cc00', '#00bb00', '#00aa00', \
			'#009900', '#008800', '#007700', '#006600', '#005500', \
			'#004400', '#003300', '#002200', '#001100', '#000011', \
			'#000022', '#000033', '#000044', '#000055', '#000066', \
			'#000077', '#000088', '#000099', '#0000aa', '#0000bb', \
			'#0000cc', '#0000dd', '#0000ee', '#0000ff', '#0000ee', \
			'#0000dd', '#0000cc', '#0000bb', '#0000aa', '#000099', \
			'#000088', '#000077', '#000066', '#000055', '#000044', \
			'#000033', '#000022', '#000011']
        #self.colors = ['red', 'blue', 'green', 'yellow', 'purple']
        self.curColor = 0        
        self.ctl = ballAll_MDL()
        self.ctl.initModel()
        self.ctl.event('start', self)


    def getWidth(self):
        return self.width

    def getHeight(self):
        return self.height

    def init(self, bid):
        xPos = randint(0, self.width)
        yPos = 0
        xSpeed = randint(-2000, 2000)
        ySpeed = randint(0, 500)

        choice = randint(0, 1)
        dir = 'x'
        if choice == 1:
            dir = 'y'
        newx = xPos + xSpeed * 0.01
        newy = yPos + ySpeed * 0.01 + 0.5 * (self.g) * 0.0001
        ySpeed += 10 * 0.1
        gid = self.canvas.create_oval(newx - self.radius, \
                                      newy - self.radius, \
                                      newx + self.radius, \
                                      newy + self.radius, \
                                      fill = self.colors[self.curColor])
        
        self.balls[bid] = {'pos':[newx, newy], 'prev':[xPos, yPos], \
                           'speed':[xSpeed, ySpeed], 'a':[0, self.g], \
                           'gid':gid, 'dir':dir, 'radius':self.radius, 'rate':-0.1, \
                           'curColor':self.curColor}
        self.root.protocol('WM_DELETE_WINDOW', self.onQuit)
        self.canvas.pack()
        return [gid, self.balls[bid]['pos'], self.balls[bid]['speed']]

    def onQuit(self):
        exit(0)
        
    def bounce(self, bid, dt):
        ball = self.balls[bid]

        ball['speed'][0] += ball['a'][0] * dt
        newx = 2 * ball['pos'][0] - ball['prev'][0] + ball['a'][0] * dt
        if ball['a'][0] != 0:
            ball['a'][0] = 0

        #newy = ball['pos'][1] + ball['speed'][1] * dt + 0.5 * ball['a'][1] * dt * dt            
        ball['speed'][1] += ball['a'][1] * dt
        newy = 2 * ball['pos'][1] - ball['prev'][1] + ball['a'][1] * dt
        if ball['a'][1] != self.g:
            ball['a'][1] = self.g
            
        ball['prev'][0] = ball['pos'][0]
        ball['prev'][1] = ball['pos'][1]
        
        if newx >= self.width:
	    newx = self.width + (ball['prev'][0] - newx) * 0.3
	    ball['prev'][0] = self.width
	    ball['speed'][0] *= -1
            #newx = self.width
            #ball['a'][0] += -1.1 * ball['speed'][0] / float(dt)
        if newx <= 0:
            #newx = 0
	    newx = (ball['prev'][0] - newx) * 0.5
	    ball['prev'][0] = 0
	    ball['speed'][0] *= -1
            #ball['a'][0] += -1.1 * ball['speed'][0] / float(dt)
        if newy <= 0:
	    newy = (ball['prev'][1] - newy) * 0.5
            ball['prev'][1] = 0.2
            ball['speed'][1] *= -1
            #newy = 0 + ball['speed'][1] * 0.8 + 0.5 * ball['a'][1] * 0.8 * 0.8
	    #newy *= -1
            #ball['speed'][1] += ball['a'][1] * 0.8
        if newy >= self.height:
	    prevy = newy
	    #ratio = (newy - self.height) / (newy - ball['prev'][1])
	    #if bid == 1:
            #    print 'ratio = ' + str(ratio)
            newy = self.height + (self.height - newy) * 0.3
	    #newy = self.height + (ball['prev'][1] - newy) * 0.5
            ball['prev'][1] = self.height + (self.height - ball['prev'][1])
	    #ball['prev'][1] = self.height
            ball['speed'][1] *= -1
            #ball['a'][1] += -2 * ball['speed'][1] / float(dt)
	    #newy = self.height - (self.height - newy)
            #newy = self.height + ball['speed'][1] + 0.5 * ball['a'][1]
            #ball['speed'][1] += ball['a'][1]
            #ball['speed'][1] *= -1
            #ball['speed'][1] = 0
            
        ball['pos'][0] = newx
        ball['pos'][1] = newy

        gid = ball['gid']
        self.canvas.coords(gid, \
                           newx - ball['radius'], \
                           newy - ball['radius'], \
                           newx + ball['radius'], \
                           newy + ball['radius'])

    def changeColor(self, bid):
        ball = self.balls[bid]
        #self.curColor = (self.curColor + 1) % len(self.colors)
        ball['curColor'] = (ball['curColor'] + 1) % len(self.colors)
        #ball['curColor'] += 1
        #self.count = (self.count + 1) % len(self.balls)
        #if self.count == 0:
        #    self.curColor = (self.curColor + 1) % len(self.colors)
        gid = ball['gid']
        self.canvas.itemconfig(gid, fill = self.colors[ball['curColor']])
        #self.canvas.itemconfig(gid, fill = self.colors[self.curColor])

    def changeShape(self, bid):
        b = self.balls[bid]
        b['radius'] = float(b['radius']) + float(b['rate']) * float(self.radius)
        if b['radius'] < 0.1 * self.radius:
            b['radius'] = 0.1 * self.radius
            b['rate'] *= -1
        elif b['radius'] > self.radius:
            b['radius'] = self.radius
            b['rate'] *= -1
        #if b['dir'] == 'x':
	#if bid == 1:
	#	print 'radius: ' + str(b['radius'])
        #self.canvas.coords(b['gid'], \
	#		       float(b['pos'][0]) - float(b['radius']), \
        #                       float(b['pos'][1]) - float(b['radius']), \
        #                       float(b['pos'][0]) + float(b['radius']), \
        #                       float(b['pos'][1]) + float(b['radius']))
        #else:
        #    self.canvas.coords(b['gid'], \
        #                       b['pos'][0] - self.radius, \
        #                       b['pos'][1] - b['radius'], \
        #                       b['pos'][0] + self.radius, \
        #                       b['pos'][1] + b['radius'])

    def setNewForce(self):
        self.cx = 0.5 * self.width
        self.cy = 0.5 * self.height
        
    def blowUp(self, bid):
        if time() - self.rightTime < gap or time() - self.leftTime < gap:
            return
        ball = self.balls[bid]
        a = randint(-8800, -4200)
        ball['a'][1] += a
        self.upTime = time()

    def blowRight(self, bid):
        if time() - self.leftTime < gap or time() - self.upTime < gap:
            return
	ball = self.balls[bid]
	ax = randint(3200, 7200)
 
	#ay = randint(-1800, -1200)
	#print 'push right!'
	ball['a'][0] += ax
        ay = randint(-8800, -4200)
        ball['a'][1] += ay
	#ball['a'][1] += ay
	self.rightTime = time()

    def blowLeft(self, bid):
        if time() - self.rightTime < gap or time() - self.upTime < gap:
            return
	ball = self.balls[bid]
	ax = randint(-7200, -3200)
	#ay = randint(-1800, -1200)
	#print 'push left!'
	ball['a'][0] += ax
        ay = randint(-8800, -4200)
        ball['a'][1] += ay
	#ball['a'][1] += ay
	self.leftTime = time()

        
 

# MAIN
c = Control(1400, 800, 50, "black") 
c.root.mainloop()
