from twisted.words.xish.domish import Element
from twisted.words.protocols.jabber.jid import internJID
from twisted.internet.defer import Deferred
from twisted.internet import reactor

import qi.xmpp.client.ns as ns
from qi.xmpp.client.errorCodes import errorCodeMap

def sendMessage(client, to, fro, body, mtype=None, delay=None):
	""" Sends a Jabber message """
	el = Element((None, "message"))
	el.attributes["to"] = to
	el.attributes["from"] = fro
	el.attributes["id"] = client.makeMessageID()
	if(mtype):
		el.attributes["type"] = mtype
	
	if(delay):
		x = el.addElement("x")
		x.attributes["xmlns"] = disco.XDELAY
		x.attributes["from"] = fro
		x.attributes["stamp"] = delay
	
	b = el.addElement("body")
	b.addContent(body)
	client.xmlstream.send(el)

def sendPresence(client, fro=None, to=None, show=None, status=None, priority=None, ptype=None, avatarHash=None, nickname=None, payload=[]):
	"""
	""" 
	# Strip the resource off any presence subscribes (as per XMPP RFC 3921 Section 5.1.6)
	if ptype in ("subscribe", "subscribed", "unsubscribe", "unsubscribed"):
		to = internJID(to).userhost()
		if fro:
			fro = internJID(fro).userhost()
	
	el = Element(("", "presence"))
	if fro:
		el.attributes["from"] = fro
	if to:
		el.attributes["to"] = to
	
	if(ptype):
		el.attributes["type"] = ptype
	if(show):
		s = el.addElement("show")
		s.addContent(show)
	if(status):
		s = el.addElement("status")
		s.addContent(status)
	if(priority):
		s = el.addElement("priority")
		s.addContent(priority)
	
	if(not ptype and avatarHash):
		if(avatarHash):
			x = el.addElement("x")
			x.attributes["xmlns"] = ns.NS_XVCARDUPDATE
			h = x.addElement("photo")
			h.addContent(avatarHash)
	
	if(payload):
		for p in payload:
			el.addChild(p)

	client.xmlstream.send(el)

def sendIq(client, el, timeout=15):
	""" Used for sending IQ packets.
	The id attribute for the IQ will be autogenerated if it is not there yet.
	Returns a deferred which will fire with the matching IQ response as it's sole argument. """
	
	def checkDeferred():
		if(not d.called):
			d.errback(Exception("Timeout"))
			del client.deferredIqs[ID]
	ID = el.getAttribute("id")
	if(not ID):
		ID = client.makeMessageID()
		el.attributes["id"] = ID
	
	client.xmlstream.send(el)

	d = Deferred()	
	client.deferredIqs[ID] = d
	reactor.callLater(timeout, checkDeferred)

	return d
	
def sendIqResult(client,el):
	"""
	"""
	client.xmlstream.send(el)
	
def sendIqError(xmlstream, to, fro, ID, etype, condition):
	""" Sends an IQ error response. See the XMPP RFC for details on the fields. """
	el = Element((None, "iq"))
	el.attributes["to"] = to
	el.attributes["from"] = fro
	if(ID):
		el.attributes["id"] = ID
	el.attributes["type"] = "error"
	error = el.addElement("error")
	error.attributes["type"] = etype
	error.attributes["code"] = str(errorCodeMap[condition])
	cond = error.addElement(condition)
	cond.attributes["xmlns"] = ns.NS_XMPP_STANZAS
	xmlstream.send(el)
