#!/usr/bin/env python
#
# Aufgabe 5: Simulationsfrontend
# Python-Kurs SS 2003: http://www.inf.tu-dresden.de/python-kurs/
# Josef Spillner <js177634@inf.tu-dresden.de>

# Implementierungshinweise:
# - bei einem Crash der Simulationsobjekte wird die Simulation gestoppt
# - die Grafikobjekte werden bei jedem Schritt neu erzeugt (suboptimal)

# Module
import Tkinter
from Tkconstants import *
import backend

# Globale Variablen
world = None
is_activated = -1
is_running = 0
zoom = 20
itemlist = []
speed = 1

# Eine Simulation auswählen (force: Wechsel erzwingen)
def activate(force):
	global is_activated
	global is_running
	global world

	key = lb.curselection()
	if key:
		preset = int(key[0])
		if preset != is_activated or force:
			world = backend.World()
			backend.init_world(world, preset)
			is_activated = preset
		return 1
	return 0

# Simulationsschritt darstellen
def display():
	for i in itemlist:
		c.delete(i)

	w = int(c['width'])
	h = int(c['height'])
	white = "#%02x%02x%02x"%(255,255,255)
	n = 4

	vbar = c.create_line(w / 2, 0, w / 2, h, width=2, fill=white)
	hbar = c.create_line(0, h / 2, w, h / 2, width=2, fill=white)
	unit1 = c.create_line(w / 2 - zoom, h / 2 - n, w / 2 - zoom, h / 2 + n, width=2, fill=white)
	unit2 = c.create_line(w / 2 + zoom, h / 2 - n, w / 2 + zoom, h / 2 + n, width=2, fill=white)
	unit3 = c.create_line(w / 2 - n, h / 2 - zoom, w / 2 + n, h / 2 - zoom, width=2, fill=white)
	unit4 = c.create_line(w / 2 - n, h / 2 + zoom, w / 2 + n, h / 2 + zoom, width=2, fill=white)
	itemlist.append(vbar)
	itemlist.append(hbar)
	itemlist.append(unit1)
	itemlist.append(unit2)
	itemlist.append(unit3)
	itemlist.append(unit4)

	for o in world.objects:
		x = o.pos.x * zoom + w / 2
		y = -o.pos.y * zoom + h / 2
		point = c.create_oval(x, y, x + zoom, y + zoom, fill="#%02x%02x%02x"%(255, o.mass * 50 + 100, 0))
		itemlist.append(point)

	lprogress.set("Steps: " + str(world.steps))

# Simulation starten (falls noch nicht getan) und laufen lassen
def cmd_run():
	global is_running
	global is_activated

	if activate(0):
		is_running = 1
		bstep.config(state=DISABLED)
		brun.config(state=DISABLED)
		bstop.config(state=NORMAL)
		while(is_running):
			try:
				tk.update()
				for i in range(speed):
					world.step()
				display()
			except:
				is_activated = -1
				cmd_stop()

# Einen Schritt weitergehen
def cmd_step():
	global is_activated

	if activate(0):
		try:
			world.step()
			display()
		except:
			is_activated = -1
			cmd_stop()

# Simulation anhalten
def cmd_stop():
	global is_running

	is_running = 0
	try:
		bstep.config(state=NORMAL)
		brun.config(state=NORMAL)
		bstop.config(state=DISABLED)
	except:
		pass

# Zurücksetzen, eventuell dabei neue Simulation auswählen
def cmd_reset():
	activate(1)

# Geschwindigkeiten
def opt_slow():
	global speed

	speed = 1

def opt_normal():
	global speed

	speed = 2

def opt_fast():
	global speed

	speed = 3

def opt_faster():
	global speed

	speed = 4

def opt_fastest():
	global speed

	speed = 5

# Zoom einstellen
def scroll(val):
	global zoom

	zoom = zoom + int(val)
	if zoom < 1:
		zoom = 1
	if zoom > 40:
		zoom = 40

	lzoom.set("Zoom: " + str(zoom))

# Aufbau der GUI
tk = Tkinter.Tk()
tk.title("Simulation")

opt = Tkinter.StringVar()
lzoom = Tkinter.StringVar()
lprogress = Tkinter.StringVar()

bstep = Tkinter.Button(tk, text="Step", command=cmd_step)
bstep.grid(row=0,column=0)
brun = Tkinter.Button(tk, text="Run", command=cmd_run)
brun.grid(row=0,column=1)
bstop = Tkinter.Button(tk, text="Stop", command=cmd_stop)
bstop.grid(row=0,column=2)
breset = Tkinter.Button(tk, text="Reset", command=cmd_reset)
breset.grid(row=0,column=3)

lb = Tkinter.Listbox(tk)
lb.grid(row=1,column=0,columnspan=3,rowspan=5)

rbslow = Tkinter.Radiobutton(tk, text="Slow", value=1, anchor=W, variable=opt, command=opt_slow)
rbslow.grid(row=1,column=3)
rbnormal = Tkinter.Radiobutton(tk, text="Normal", value=2, anchor=W, variable=opt, command=opt_normal)
rbnormal.grid(row=2,column=3)
rbfast = Tkinter.Radiobutton(tk, text="Fast", value=3, anchor=W, variable=opt, command=opt_fast)
rbfast.grid(row=3,column=3)
rbfaster = Tkinter.Radiobutton(tk, text="Faster", value=4, anchor=W, variable=opt, command=opt_faster)
rbfaster.grid(row=4,column=3)
rbfastest = Tkinter.Radiobutton(tk, text="Fastest", value=5, anchor=W, variable=opt, command=opt_fastest)
rbfastest.grid(row=5,column=3)

sl = Tkinter.Label(tk, textvariable=lzoom)
sl.grid(row=6,column=0)
lzoom.set("Zoom: " + str(zoom))

sb = Tkinter.Scrollbar(tk, command=scroll, orient=HORIZONTAL)
sb.grid(row=6,column=1,columnspan=2)

pl = Tkinter.Label(tk, textvariable=lprogress)
pl.grid(row=6,column=3)
lprogress.set("Steps: 0")

c = Tkinter.Canvas(tk, background="#%02x%02x%02x"%(0,0,255))
c.grid(row=7,column=0,columnspan=4,rowspan=4)

# Initialisierung
presetlist = backend.get_presets()
for p in presetlist:
	lb.insert(END, p)

rbslow.select()
lb.select_set(0)

bstop.config(state=DISABLED)

# Programm starten
tk.mainloop()



syntax highlighted by Code2HTML, v. 0.9.1