# Bryan Schumaker (8/7/2010)

events  = dict()
threads = None

start_thread = None


def invite(key, func, bg=False):
	global events
	if key not in events:
		events[key] = set()
	events[key].add((func,bg))


def uninvite(key, func):
	global events
	if key not in events:
		return
	events[key].discard(func)


def start_thread_once(func, *args):
	global threads
	global start_thread
	import threads
	start_thread = threads.background
	return threads.background(func, *args)
start_thread = start_thread_once


def start(key, *args):
	global events
	if key not in events:
		return
	for func, bg in events[key]:
		try:
			if bg == False:
				func(*args)
			else:
				start_thread(func, *args)
		except Exception,e:
			uninvite(key, func)
			print
			print "===== EVENT ERROR ====="
			print "Event:", key
			print "Function:", func
			print "Args:", args
			print "Error: ", e
			print "The function has been uninvited from this event"
			print "======================="


def call(action, func=None, *args):
	start("PRE%s" % action, *args)
	if func == None:
		return None

	res = func(*args)
	start("POST%s" % action, res)
	return res




