"""
Learning Goals
 - Represent the state of a system in a model by identifying components and rules
 - Visualize a model using graphics
 - Update a model over time based on rules
 - Update a model after events (mouse-based and keyboard-based) based on rules
"""
"""
mode = "JSON"

# Data Analysis Recap
f = open("icecream.json", "r") # f is a file object

if mode == "TEXT":
    # Can interpret text in f directly by reading the file
    text = f.read()
    print(text)
elif mode == "CSV":
    # Can parse text in f as a spreadsheet (2D list) using the csv library
    # But only if the text is in a CSV format!
    import csv
    reader = csv.reader(f)
    data = list(reader)
    print(data)
elif mode == "JSON":
    # Can parse text in f as a generic data structure using the json library
    # But only if the text is in a JSON format!
    import json
    data = json.load(f)
    print(data)
"""

####








import random


def makeModel(data):
    data["color"] = "red"
    data["text"] = ""

def makeView(data, canvas):
    canvas.create_oval(100, 100, 200, 200, fill=data["color"])

def runRules(data, call):
    colors = [ "red", "orange", "yellow", "green", "blue", "purple" ]
    #data["color"] = random.choice(colors)

def keyPressed(data, event):
    if event.keysym == "Return":
        data["color"] = data["text"]
        data["text"] = ""
    else:
        data["text"] = data["text"] + event.char
    print(data["text"])

def mousePressed(data, event):
    print("X:", event.x)
    print("Y:", event.y)
    colors = [ "red", "orange", "yellow", "green", "blue", "purple" ]
    if ((150 - event.x)**2 + (150 - event.y)**2) ** 0.5 <= 50:
        data["color"] = random.choice(colors)


# You do not need to be able to write the following functions;
# just modify the five functions above.

from tkinter import *

def timeLoop(data, canvas, call):
    runRules(data, call)

    canvas.delete(ALL)
    makeView(data, canvas)
    canvas.update()

    canvas.after(data["timeRate"], timeLoop, data, canvas, call + 1)

def keyEventHandler(data, canvas, event):
    keyPressed(data, event)

    canvas.delete(ALL)
    makeView(data, canvas)
    canvas.update()

def mouseEventHandler(data, canvas, event):
    mousePressed(data, event)

    canvas.delete(ALL)
    makeView(data, canvas)
    canvas.update()

def runSimulation(w, h, timeRate):
    data = { }
    data["timeRate"] = int(timeRate * 1000) # call will be in ms
    makeModel(data)

    root = Tk()
    canvas = Canvas(root, width=w, height=h)
    canvas.configure(bd=0, highlightthickness=0)
    canvas.pack()
    makeView(data, canvas)

    canvas.after(data["timeRate"], timeLoop, data, canvas, 1)

    root.bind("<Key>", lambda event : keyEventHandler(data, canvas, event))
    root.bind("<Button-1>", lambda event : mouseEventHandler(data, canvas, event))

    root.mainloop()

runSimulation(400, 400, 1)