#
# originally from tk_demo.py by Torbert, 10.8.2008
#
# Tkinter Demo, Version 1.0
#
#   Input: none
# Process: a square with a message tries to run off the screen
#  Output: graphical display updated every 10 milliseconds
#
# Updated now for Schelling neighborhood problem. The data structure is
# a grid of patches, and each patch can hold 0 or more agents in a list.
# Although for this problem, only 0 or 1 agents will be used at a time.

from Tkinter import *
from sys import exit
from random import *

w,h=800,600
gridw=200
gridh=200
centerx=(w-gridw)/2
centery=(h-gridh)/2
x,y,dx,dy=100,50,25,25
density=.8

agentList=[]
patchList=[]

#myColor="#"+decToHex(randint(0,255))+decToHex(randint(0,255))+decToHex(randint(0,255))

class Agent:
    def __init__(self, x, y, row, col):
        self.myX=x
        self.myY=y
        self.myRow=row
        self.myCol=col
        self.myColor=getColor()

class Patch:
    def __init__(self, x, y, row, col):
        self.myX=x
        self.myY=y
        self.myRow=row
        self.myCol=col
        self.myColor=getPatchColor()
        self.occupants=[]

def tick():
	global x
	x+=1
#	x1,y1,x2,y2=canvas.coords(rect)
#	print x1,y1,x2,y2
	canvas.coords(rect,x,y,x+dx,y+dy) # move the objects
	canvas.coords(objt,x+dx/2,y+dy/2)
	canvas.after(10,tick) # animation

def decToHex(val):
    s = "%x" % val
    if len(s) < 2:
        s="0"+s
    return s

def getColor():
    s="#"+decToHex(randint(0,255))+decToHex(randint(0,255))+decToHex(randint(0,255))
    return s

#see rgbchart.com
def getPatchColor():
    s="#"+decToHex(255)+decToHex(255)+decToHex(85) # "#ffff55"
    return s


def click(evnt):
    global x,y
    x,y=evnt.x,evnt.y
    myColor=getColor()
    canvas.itemconfigure(rect,fill=myColor)
    canvas.itemconfigure(objt,text='Hey!')
    
def quit(evnt):
	exit(0)

def getPatchAtRowCol(patchList,row,col):
    for patch in patchList:
        if patch.myRow==row and patch.myCol==col:
            return patch
    return None

x=randint(0,255)
print "%d = %s" % (x, decToHex(x))
r=randint(0,255)
g=randint(0,255)
b=randint(0,255)
print "r=%d g=%d b=%d" % (r,g,b)
color="#"+decToHex(r)+decToHex(g)+decToHex(b)
print "color=%s" % color

print "rand color=%s" % getColor()

cols=gridw/dx
rows=gridh/dy
numTotalPatches=cols*rows
numAgents=density*numTotalPatches

#UPDATED CODE
alreadyusedindexes=[]
for i in range(0,int(numAgents)):
    found=False
    while not found:
        randindex=randint(0,numTotalPatches-1)
        if not randindex in alreadyusedindexes:
            found=True
            alreadyusedindexes.append(randindex)
    row=randindex/cols
    col=randindex%cols
    x=col*dx+centerx
    y=row*dy+centery
    agent=Agent(x,y,row,col)
    if random() < .5:
        agent.myColor="#0022DD"  #see www.rgbchart.com  000 034 221, blue
    else:
        agent.myColor="#FF2233"  #see www.rgbchart.com  255 034 051, red
    agentList.append(agent)

for index in range(0,numTotalPatches):
    row=index/cols
    col=index%cols
    x=col*dx+centerx
    y=row*dy+centery
    patch=Patch(x,y,row,col)
    patchList.append(patch)

for agent in agentList:
    row = agent.myRow
    col = agent.myCol
    patch=getPatchAtRowCol(patchList,row,col)
    if patch != None:
        patch.occupants.append(agent)
        print "agent added to patch at row %d, col %d" % (row,col)
    else:
        print "No patch at row %d, col %d" % (row,col)
    
#
# Initialize.
#
root=Tk()
canvas=Canvas(root,width=w,height=h,bg='white')
canvas.pack()
#
# Graphics objects. 
#
#rect=canvas.create_oval(x,y,x+dx,y+dy,fill='yellow',outline='black')
#rect=canvas.create_oval(x,y,x+dx,y+dy,fill='#00ffff',outline='black')
agentpatches=[]
patches=[]
for patch in patchList:
    myx=patch.myX
    myy=patch.myY
    color=patch.myColor
    patches.append(canvas.create_rectangle(myx,myy,myx+dx,myy+dy,fill=color,outline='black'))

rect=canvas.create_oval(x,y,x+dx,y+dy,fill=getColor(),outline='black')
objt=canvas.create_text(x+dx/2,y+dy/2,text='Bye!',fill='white')

for agent in agentList:
    myx=agent.myX
    myy=agent.myY
    color=agent.myColor
    agentpatches.append(canvas.create_oval(myx,myy,myx+dx,myy+dy,fill=color,outline='black'))

#
# Callbacks.
#
root.bind('<Button-1>',click)
root.bind('<q>',quit)
canvas.after(10,tick) # animation
#
# Start the continuous graphics display loop.
#
root.mainloop()

