import select, time

class message:
	pass

RemoveStream = message()

class ircmultiplexer:
	def __init__(self):
		self.streams = {}
		self.w_streams = {}
		self.pending_actions = []
	def register(self, stream, handler):
		self.streams[stream] = handler
	def w_register(self, stream, handler):
		self.w_streams[stream] = handler
	def p_register(self, action):
		self.pending_actions.append(action)
	def remove(self, stream):
		del self.streams[stream]
	def w_remove(self, stream):
		del self.w_streams[stream]
	def mainloop(self):
		while 1:
			w_items = self.w_streams.items()
			w_streams = []
			for stream, handler in w_items:
				if handler.queuelen():
					w_streams.append(stream)
			if self.pending_actions:
				readystreams = select.select(self.streams.keys(),
					w_streams, [], .5)
			else:
				readystreams = select.select(self.streams.keys(),
					w_streams, [])

			for stream in readystreams[0]:
				result = self.streams[stream]()
				if result == RemoveStream:
					self.remove(stream)
					if stream in self.w_streams.keys():
						self.w_remove(stream)
			for stream in readystreams[1]:
				result = self.w_streams[stream]()
				if result == RemoveStream:
					self.w_remove(stream)
					if stream in self.streams.keys():
						self.remove(stream)

			now = time.time()
			removeactions = [] # Has to make activating new
			                   # actions while looping vaguely sane
			for action in self.pending_actions[:]:
				if now >= action.time:
					newtimeout = action()
					if newtimeout:
						action.time = newtimeout
						self.p_register(action)
					removeactions.append(action)
			for action in removeactions:
				# Note: This allows for actions to reinsert themselves
				# when being called above.
				self.pending_actions.remove(action)
