From 1d7b76386202c7df168c088c6acde96718b05975 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Fri, 1 Oct 2010 10:27:01 +0100
Subject: Include contact's status when you start a chat with them.

Resolves: #580

diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index bb4bacd..7fbf677 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -37,11 +37,19 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ
 	String nick = nickResolver_->jidToNick(toJID_);
 	chatWindow_->setName(nick);
 	String startMessage("Starting chat with " + nick);
+	Presence::ref theirPresence;
 	if (isInMUC) {
-		startMessage += " in chatroom " + contact.toBare().toString() + ".";
+		startMessage += " in chatroom " + contact.toBare().toString();
+		theirPresence = presenceOracle->getLastPresence(contact);
 	} else {
-		startMessage += " (" + contact.toBare().toString() + ").";
+		startMessage += " - " + contact.toBare().toString();
+		theirPresence = contact.isBare() ? presenceOracle->getHighestPriorityPresence(contact.toBare()) : presenceOracle->getLastPresence(contact);
 	}
+	startMessage += ": " + StatusShow::typeToFriendlyName(theirPresence ? theirPresence->getShow() : StatusShow::None);
+	if (theirPresence && !theirPresence->getStatus().isEmpty()) {
+		startMessage += " (" + theirPresence->getStatus() + ")";
+	}
+	startMessage += ".";
 	chatWindow_->addSystemMessage(startMessage);
 	chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
 	chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
diff --git a/Swiften/Elements/StatusShow.h b/Swiften/Elements/StatusShow.h
index 747ddf1..1bdae96 100644
--- a/Swiften/Elements/StatusShow.h
+++ b/Swiften/Elements/StatusShow.h
@@ -38,6 +38,22 @@ namespace Swift {
 				return "Unknown";
 			}
 
+			/**
+			 * Can be used for rough ordering of Types.
+			 * Greater magnitude = more available.
+			 */
+			static int typeToAvailabilityOrdering(Type type) {
+				switch (type) {
+				case Online: return 4;
+				case FFC: return 5;
+				case Away: return 2;
+				case XA: return 1;
+				case DND: return 3;
+				case None: return 0;
+				}
+				return -1;
+			}
+
 		private:
 			Type type_;
 	};
diff --git a/Swiften/Presence/PresenceOracle.cpp b/Swiften/Presence/PresenceOracle.cpp
index 758ae7c..439a84d 100644
--- a/Swiften/Presence/PresenceOracle.cpp
+++ b/Swiften/Presence/PresenceOracle.cpp
@@ -59,5 +59,25 @@ Presence::ref PresenceOracle::getLastPresence(const JID& jid) const {
 	}
 }
 
+Presence::ref PresenceOracle::getHighestPriorityPresence(const JID& bareJID) const {
+	PresencesMap::const_iterator i = entries_.find(bareJID);
+	if (i == entries_.end()) {
+		return Presence::ref();
+	}
+	PresenceMap presenceMap = i->second;
+	PresenceMap::const_iterator j = presenceMap.begin();
+	Presence::ref highest;
+	for (; j != presenceMap.end(); j++) {
+		Presence::ref current = j->second;
+		if (!highest
+				|| current->getPriority() > highest->getPriority()
+				|| (current->getPriority() == highest->getPriority()
+						&& StatusShow::typeToAvailabilityOrdering(current->getShow()) > StatusShow::typeToAvailabilityOrdering(highest->getShow()))) {
+			highest = current;
+		}
+
+	}
+	return highest;
+}
 
 }
diff --git a/Swiften/Presence/PresenceOracle.h b/Swiften/Presence/PresenceOracle.h
index e5f0372..8c4fce4 100644
--- a/Swiften/Presence/PresenceOracle.h
+++ b/Swiften/Presence/PresenceOracle.h
@@ -21,6 +21,7 @@ class StanzaChannel;
 			~PresenceOracle();
 
 			Presence::ref getLastPresence(const JID&) const;
+			Presence::ref getHighestPriorityPresence(const JID& bareJID) const;
 
 		public:
 			boost::signal<void (boost::shared_ptr<Presence>)> onPresenceChange;
-- 
cgit v0.10.2-6-g49f6