### Simulation Code Writing ###
from tkinter import *
import random
import math
def makeModel(data):
    # Initialize the box dimensions and position
    data["bx"] = 150
    data["by"] = 150
    data["bwidth"] = 200
    data["bheight"] = 200
    
    # Initialize the circle
    data["cx"] = 250
    data["cy"] = 250
    data["radius"] = 30
    data["color"] = "purple"

def makeView(data, canvas):
    # Draw the box
    canvas.create_rectangle(data["bx"], data["by"], 
                            data["bx"] + data["bwidth"], 
                            data["by"] + data["bheight"], outline="black")

    # Draw the circle
    canvas.create_oval(data["cx"] - data["radius"], 
                       data["cy"] - data["radius"], 
                       data["cx"] + data["radius"], 
                       data["cy"] + data["radius"], 
                       fill=data["color"])

def runRules(data, call):
    # Update circle position
    
    # Determine if circle's center is within the box
    pass


### Debugging ###
"""
obtainOdds takes in a 2d list, L, and returns a list of every element in L that is odd
"""
def obtainOdds(L):
    odds = []
    for row in range(len(L)):
        for col in range(len(L[0])):
            if L[row][col] % 2 == 1:
                odds.append(L[col][row])
    return odds

"""
createDiagMatrix takes in a matrix M (i.e. another 2d list)
    and returns a square matrix that has every odd element of
    matrix M on the diagonal. All non-diagonal elements are
    equal to the sum of the odds.

For example:
    createDiagMatrix([[1,3]])
    => [[1, 4],
        [4, 3]],
    where 1 and 3 are on the diagonal,
    and 1+3=4 on the off diagonals. 

"""

def createDiagMatrix(M):
    newMat = []
    odds = obtainOdds(M)
    oddSum = sum(odds)
    for i in range(len(odds)):
        tempLst = [oddSum] * len(odds)
        tempLst[0] = odds[i] 
        newMat.append(tempLst)
    return newMat

# Test Cases #
tst =   [
            [1,2,3],
            [4,5,6],
            [7,8,9]
        ]

assert(createDiagMatrix(tst) == 
    [
        [1,25,25,25,25], 
        [25,3,25,25,25],
        [25,25,5,25,25],
        [25,25,25,7,25],
        [25,25,25,25,9]
    ])
    
assert(createDiagMatrix([]) == [])
assert(createDiagMatrix([[1,2,3]]) == [[1,4],[4,3]])
print("Tests passed!")


### Working with Data ###

import csv 

def readCSVFile(path):
    pass

"""
Write a function departmentNameDict that stores the information
in an input list as a dictionary. The input list is a 2D list
where each inner list contains 4 elements: department_id,
department_name, location_id, and department_expenses.
For each inner list, the output dictionary should contain
a key-value pair that maps department_name to a two-element
list [location_id, department_expenses].
"""

def departmentNameDict(data):
    pass

"""
Write a function departmentInfo that takes in a dictionary
like the one outputted above, as well as a list of departments,
and finds the mean expenses across the departments, as well as
the most common location among the departments. The function
should also print this information. You may want to import
a package to help you with this function!
"""

def departmentInfo(d, departments):
    pass


# Write a line of code below to call readCSVFile and store the result in 
# a variable called data! Then uncomment the following lines of code to run the test cases!


'''
departmentDictionary = departmentNameDict(data[1:])
departments1 = ["Purchasing", "Recruiting", "Payroll", "Marketing", "IT", "Construction"]
departments2 = ["Control And Credit", "Government Sales", "Shareholder Services", "Executive", "NOC"]
departmentInfo(departmentDictionary, departments1)
departmentInfo(departmentDictionary, departments2)
'''

########################### DO NOT ALTER: SIMULATION FRAMEWORK CODE ##########################

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 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.mainloop()


runSimulation(500,500, 0.3)
