from Queue import Queue

from Server import Server

class PdServer(Server):
	def __init__(self, queue_type=Queue, **kwargs):
		Server.__init__(self, **kwargs)
		self.numchans = 0
		self.IDs = {}
		if not self.inQueue:
			self.inQueue = queue_type()
		if not self.outQueue:
			self.outQueue = queue_type()
	
	def Connected(self, channel, addr):
		print "Connection from", addr, channel
		self.outQueue.put(["connected", str(channel.id)])
	
	def MakeNewID(self, what):
		ID = 1
		IDs = self.IDs.keys()
		while ID in IDs:
			ID += 1
		self.IDs[ID] = what
		return ID
	
	def Pump(self):
		Server.Pump(self)
		if self.numchans != len(self.channels):
			#print len(self.channels), "channels"
			self.numchans = len(self.channels)
		# send all queued up messages to all clients
		while not self.inQueue.empty():
			sendparts = self.inQueue.get()
			#print "SENDPARTS:", sendparts
			#print len(self.channels)
			#for c in self.channels:
				#print "trying channel:", c.id
				#print str(sendparts[0]) == "*"
				#print str(c.id) == str(sendparts[0])
			[c.ToClient(sendparts[1:]) for c in self.channels if str(sendparts[0]) == "*" or str(c.id) == str(sendparts[0])]
		# pump the outgoing sockets of channels
		for c in self.channels:
			c.Pump()
	
	# internal callbacks
	
	def FromClient(self, source, data):
		self.outQueue.put([source] + data)
	
	def Remove(self, channel):
		del self.IDs[channel.id]
		Server.Remove(self, channel)
		self.outQueue.put(["disconnected", str(channel.id)])
		del channel
	
	### Public methods ###
	
	def PostMessage(self, data):
		""" Send a Pd message to all connected clients. """
		self.inQueue.put(["*"] + data)
	
	def PostMessageTo(self, id, data):
		self.inQueue.put([id] + data)
	
	# check the queue and return any messages from clients
	def GetMessages(self):
		""" Get any pending Pd messages from connected clients. """
		messages = []
		while not self.outQueue.empty():
			messages.append(self.outQueue.get())
		return messages


