
import Queue
import threading
import string

class Event:
	def __init__(s, type,
					cmd='',
					game=None,
					player=None,
					planet=None,
					name='',
					year=None,
					x=None,
					y=None,
					quant=None,
					src=None,
					dst=None,
					flag=None,
					ships=None,
					extra=None):
		s.type = type
		s.cmd = cmd
		s.game = s.conv(game)
		s.player = s.conv(player)
		s.planet = s.conv(planet)
		s.name = name
		s.year = year
		s.x = s.conv(x)
		s.y = s.conv(y)
		s.quant = s.conv(quant)
		s.src = s.conv(src)
		s.dst = s.conv(dst)
		s.flag = s.conv(flag)
		s.ships = ships			# FIXME type?
		s.extra = extra

	def conv(s, val):
		try:
			val = string.atoi(val)
		except TypeError:
			pass
		return val
	
class SimpleEventReceiver:
	def __init__(s, evq=None):
		s.evq = evq
		s.init()
	
	def init(s):
		s.eventhandlers = {}

	def recv_event(s, ev):
		try:
			handler = s.eventhandlers[ev.type]
		except KeyError:
			print "No handler for event type %s in %s" % (ev.type, s)
			return
		handler(ev)
	
	def send_event(s, ev):
		"Send an event into the main event queue."
		s.evq.recv_event(ev)


class EventReceiver:
	"""A base class for all objects that wish to receive events.
	   EventReceivers have a Queue for incoming events, and run in
	   a separate thread."""
	
	def __init__(s, evq=None):
		s.thread = threading.Thread(target=s.run)
		s.thread.setDaemon(1)
		s.queue = Queue.Queue(0)
		s.evq = evq
		s.init()
		s.reg_self()

	def init(s):
		s.eventhandlers = {}

	def reg_self(s):
		"Register myself as an event receiver"
		for type in s.eventhandlers.keys():
			s.evq.reg_receiver(type, s)
	
	def start(s):
		"Start the new thread, ready to listen for events"
		s.thread.start()

	def run(s):
		"The method that Keeps On Going(tm)"
		while 1:
 			s.once()
	
	def once(s):
		"This is run repeatedly. Default action is to handle events, no more."
		ev = s.queue.get()
		try:
			handler = s.eventhandlers[ev.type]
		except KeyError:
			print "No handler for event type %s in %s" % (ev.type, s)
			return
		handler(ev)

	def recv_event(s, ev):
		"Receive an event and put it in the queue for the thread to pick up."
		s.queue.put(ev)
	
	def send_event(s, ev):
		"Send an event into the main event queue."
		s.evq.recv_event(ev)

class SimpleInterfaceElement (SimpleEventReceiver):
	def __init__(s, master, arg=None, evq=None):
		SimpleEventReceiver.__init__(s, evq)
		s.master = master
		s.arg = arg
		s.init_vars()
		s.clear()
		s.draw(master)

	def init_vars(s):
		pass
	
	def clear(s):
		pass
	
	def draw(s, master):
		pass		

class InterfaceElement (SimpleEventReceiver):
	def __init__(s, master, evq):
		SimpleEventReceiver.__init__(s, evq)
		s.master = master
		s.init_vars()
		s.clear()
		s.draw(master)
		s.init()
		s.reg_self()
	
	def init(s):
		s.eventhandlers = {}

	def reg_self(s):
		"Register myself as an event receiver"
		for type in s.eventhandlers.keys():
			s.evq.reg_receiver(type, s)
	
	def init_vars(s):
		pass

	def clear(s):
		pass

	def draw(s, master):
		pass


class ClientEventQueue (EventReceiver):
	"""ClientEventQueue is used to collect events, keep track of which objects
	   want to receive them and send incoming events to the receivers."""

	def __init__(s):
		EventReceiver.__init__(s)
		s.queue = Queue.Queue(0)
		s.receivers = {}

	def reg_self(s):
		pass	# No need to register, I'm smart enough myself
		
	def reg_receiver(s, type, obj):
		"Register a receiver for an event type"
		
		try:
			if obj not in s.receivers[type]:
				s.receivers[type].append(obj)
		except KeyError:
			s.receivers[type] = [obj]
	
	def once(s):
		ev = s.queue.get()
		try:
			handlers = s.receivers[ev.type]
		except KeyError:
			print "Nobody wants event type %s" % ev.type
			return
		for h in handlers:
			h.recv_event(ev)
		