from Tkinter import *

JUMP = 40
MAX_WIDTH = 20 * JUMP
MAX_HEIGHT = 20 * JUMP

root = Tk()

canvas = Canvas(root, width=MAX_WIDTH, height=MAX_HEIGHT, bg="white")
canvas.pack()

name = 0

def lower(value):
    return value / JUMP * JUMP

def upper(value):
    return (value / JUMP + 1) * JUMP

def avg(a, b):
    return float(a + b) / 2

class InterfaceCore():
    mode = ""
    drawn = set()
    refs = dict()

    def set_mode(self, mode):
        self.mode = mode

    def clicked(self, event):
        if self.mode == "":
            print("Please select a block first")
        else:
            x = event.x
            y = event.y
            r = canvas.create_rectangle(lower(x), lower(y), upper(x), upper(y), fill="white")
            t = canvas.create_text(avg(lower(x), upper(x)), avg(lower(y), upper(y)), text=self.mode, fill="black")
            global name
            b = (lower(x), lower(y), upper(x), upper(y), str(name))
            self.drawn.add(b)
            self.refs[str(name)] = [r, t]
            name += 1

    def find(self, location):
        x, y = location
        for e in self.drawn:
            if (e[0] <= x and
                e[1] <= y and
                e[2] >= x and
                e[3] >= y):
                    return e[4]

        print("Found nothing at that location!")
        return []

    def draw(self, start, end):
        source = self.find(start)
        target = self.find(end)

        print("Connect from %s to %s" % (source, target))

        if source and target:
            canvas.create_line(start[0], start[1], end[0], end[1], fill="black", arrow=LAST)

core = InterfaceCore()

def addition():
    core.set_mode("+")

def negation():
    core.set_mode("-")

def clicked(event):
    core.clicked(event)

def draw(event):
    global start_location
    start_location = (event.x, event.y)

def release(event):
    core.draw(start_location, (event.x, event.y))

Button(root, text="+", command=addition).pack()
Button(root, text="-", command=negation).pack()

core.canvas = canvas

for i in range(JUMP, MAX_HEIGHT, JUMP):
    canvas.create_line(0, i, MAX_HEIGHT, i, fill="grey")
for i in range(JUMP, MAX_WIDTH, JUMP):
    canvas.create_line(i, 0, i, MAX_WIDTH, fill="grey")

canvas.bind("<Button-1>", clicked)
canvas.bind("<Button-3>", draw)
canvas.bind("<ButtonRelease-3>", release)

root.mainloop()
