Index: code/branches/output/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- code/branches/output/src/orxonox/OrxonoxPrereqs.h	(revision 8828)
+++ code/branches/output/src/orxonox/OrxonoxPrereqs.h	(revision 8829)
@@ -77,4 +77,10 @@
     class Radar;
     class Scene;
+
+    // chat
+    class ChatHistory;
+    class ChatInputHandler;
+    class ChatListener;
+    class ChatManager;
 
     // collisionshapes
Index: code/branches/output/src/orxonox/chat/CMakeLists.txt
===================================================================
--- code/branches/output/src/orxonox/chat/CMakeLists.txt	(revision 8828)
+++ code/branches/output/src/orxonox/chat/CMakeLists.txt	(revision 8829)
@@ -2,3 +2,4 @@
   ChatHistory.cc
   ChatInputHandler.cc
+  ChatManager.cc
 )
Index: code/branches/output/src/orxonox/chat/ChatHistory.cc
===================================================================
--- code/branches/output/src/orxonox/chat/ChatHistory.cc	(revision 8828)
+++ code/branches/output/src/orxonox/chat/ChatHistory.cc	(revision 8829)
@@ -74,25 +74,11 @@
 
   /* react to incoming chat */
-  void ChatHistory::incomingChat(const std::string& message,
-    unsigned int senderID)
+  void ChatHistory::incomingChat(const std::string& message, const std::string& /*name*/)
   {
-    /* --> a) look up the actual name of the sender */
-    std::string text = message;
-
-#ifndef CHATTEST
-    /* get sender ID and prepend it to the message */
-    if (senderID != NETWORK_PEER_ID_UNKNOWN)
-    {
-      PlayerInfo* player = PlayerManager::getInstance().getClient(senderID);
-      if (player)
-        text = player->getName() + ": " + message;
-    }
-#endif
-
     /* add the line to the history */
-    this->chat_hist_addline( text );
+    this->chat_hist_addline( message );
 
     /* add the line to the log */
-    this->chat_hist_logline( text );
+    this->chat_hist_logline( message );
   }
 
Index: code/branches/output/src/orxonox/chat/ChatHistory.h
===================================================================
--- code/branches/output/src/orxonox/chat/ChatHistory.h	(revision 8828)
+++ code/branches/output/src/orxonox/chat/ChatHistory.h	(revision 8829)
@@ -37,11 +37,12 @@
 
 #ifndef CHATTEST
-#include <OrxonoxPrereqs.h>
-#include <PlayerManager.h>
-#include <infos/PlayerInfo.h>
-#include <core/BaseObject.h>
-#include <network/ChatListener.h>
-#include <core/PathConfig.h>
-#include <util/Singleton.h>
+#include "OrxonoxPrereqs.h"
+
+#include "util/Singleton.h"
+#include "core/BaseObject.h"
+#include "core/PathConfig.h"
+#include "chat/ChatListener.h"
+#include "infos/PlayerInfo.h"
+#include "PlayerManager.h"
 #endif
 
@@ -82,6 +83,5 @@
        * \param senderID Identification number of the sender
        */
-      virtual void incomingChat(const std::string& message,
-        unsigned int senderID);
+      virtual void incomingChat(const std::string& message, const std::string& name);
 
       /** Synchronize logfile onto the hard drive
Index: code/branches/output/src/orxonox/chat/ChatInputHandler.cc
===================================================================
--- code/branches/output/src/orxonox/chat/ChatInputHandler.cc	(revision 8828)
+++ code/branches/output/src/orxonox/chat/ChatInputHandler.cc	(revision 8829)
@@ -44,6 +44,6 @@
 #include "core/input/InputManager.h"
 #include "core/input/InputState.h"
-#include "network/Host.h"
-
+
+#include "chat/ChatManager.h"
 #include "PlayerManager.h"
 #include "infos/PlayerInfo.h"
@@ -213,24 +213,8 @@
 
   /* handle incoming chat */
-  void ChatInputHandler::incomingChat(const std::string& message,
-    unsigned int senderID)
-  {
-    /* look up the actual name of the sender */
-    std::string text = message;
-    std::string name = "";
-
-    /* setup player name info */
-    if (senderID != NETWORK_PEER_ID_UNKNOWN)
-    {
-       PlayerInfo* player = PlayerManager::getInstance().getClient(senderID);
-       if (player)
-       {
-         name = player->getName();
-         text = name + ": " + message;
-       }
-    }
-
+  void ChatInputHandler::incomingChat(const std::string& message, const std::string& name)
+  {
     /* create item */
-    CEGUI::ListboxTextItem *toadd = new CEGUI::ListboxTextItem( text );
+    CEGUI::ListboxTextItem *toadd = new CEGUI::ListboxTextItem( message );
 
     /* setup colors */
@@ -320,5 +304,5 @@
 
     /* c) send the chat via some call */
-    Host::Chat( msgtosend );
+    ChatManager::chat( msgtosend );
 
     /* d) stop listening to input - only if this is not fullchat */
Index: code/branches/output/src/orxonox/chat/ChatInputHandler.h
===================================================================
--- code/branches/output/src/orxonox/chat/ChatInputHandler.h	(revision 8828)
+++ code/branches/output/src/orxonox/chat/ChatInputHandler.h	(revision 8829)
@@ -30,5 +30,5 @@
 #define _ChatInputHandler_H__
 
-#include <OrxonoxPrereqs.h>
+#include "OrxonoxPrereqs.h"
 
 #include <string>
@@ -37,5 +37,5 @@
 
 #include "util/Singleton.h"
-#include "network/ChatListener.h"
+#include "chat/ChatListener.h"
 
 namespace orxonox // tolua_export
@@ -112,6 +112,5 @@
        * history window of the full chat window)
        */
-      void incomingChat( const std::string& message,
-        unsigned int senderID );
+      void incomingChat(const std::string& message, const std::string& name);
 
       /** \param full true means show full chat window with history,
Index: code/branches/output/src/orxonox/chat/ChatListener.h
===================================================================
--- code/branches/output/src/orxonox/chat/ChatListener.h	(revision 8829)
+++ code/branches/output/src/orxonox/chat/ChatListener.h	(revision 8829)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ChatListener_H__
+#define _ChatListener_H__
+
+#include "OrxonoxPrereqs.h"
+
+namespace orxonox
+{
+    /**
+        @brief Classes inheriting from this interface get a notification whenever a chat
+        message was sent through ChatManager.
+    */
+    class _OrxonoxExport ChatListener : virtual public OrxonoxClass
+    {
+        friend class ChatManager;
+
+        public:
+            ChatListener(); // implemented in ChatManager.cc
+            virtual ~ChatListener() {}
+
+        protected:
+            /**
+                @brief Gets called whenever a chat message was sent through ChatManager.
+                @param message The whole message (including name of the sender if available)
+                @param name The name of the sender (if available, otherwise "")
+            */
+            virtual void incomingChat(const std::string& message, const std::string& name) = 0;
+    };
+}
+
+#endif /* _ChatListener_H__ */
Index: code/branches/output/src/orxonox/chat/ChatManager.cc
===================================================================
--- code/branches/output/src/orxonox/chat/ChatManager.cc	(revision 8829)
+++ code/branches/output/src/orxonox/chat/ChatManager.cc	(revision 8829)
@@ -0,0 +1,120 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ChatManager.h"
+#include "ChatListener.h"
+
+#include "util/ScopedSingletonManager.h"
+#include "core/CoreIncludes.h"
+#include "core/command/ConsoleCommand.h"
+#include "network/Host.h"
+
+#include "PlayerManager.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    ManageScopedSingleton(ChatManager, ScopeID::Root, false);
+
+    SetConsoleCommand("chat", &ChatManager::chat).defaultValue(1, NETWORK_PEER_ID_BROADCAST);
+
+    ChatManager::ChatManager()
+    {
+        RegisterObject(ChatManager);
+    }
+
+    /**
+        @brief Sends a message (usually gameplay related) without explicit sender to the chat.
+        @param message The message
+        @param targetID The client ID (network) of the receiver. Usually the broadcast ID
+    */
+    /*static*/ void ChatManager::message(const std::string& message, unsigned int targetID)
+    {
+        unsigned int sourceID = NETWORK_PEER_ID_UNKNOWN;
+
+        // only the server should send gameplay messages through the network. otherwise display the message locally
+        if (GameMode::isServer())
+            Host::sendChat(message, sourceID, targetID);
+        else
+            ChatManager::getInstance().incomingChat(message, sourceID);
+    }
+
+    /**
+        @brief Sends a chat message with the client as its sender to the chat.
+        @param message The message
+        @param targetID The client ID (network) of the receiver. Usually the broadcast ID
+    */
+    /*static*/ void ChatManager::chat(const std::string& message, unsigned int targetID)
+    {
+        unsigned int sourceID = Host::getPlayerID();
+
+        // if connected to the network, send chat messages online. otherwise display chat locally
+        if (GameMode::isServer() || GameMode::isClient())
+            Host::sendChat(message, sourceID, targetID);
+        else
+            ChatManager::getInstance().incomingChat(message, sourceID);
+    }
+
+    /**
+        @brief Inherited callback from NetworkChatListener, but gets also called directly
+        by ChatManager itself if the client is offline. Distributes an incoming chat message
+        to all ChatListeners.
+        @param message The message
+        @param sourceID The client ID (network) of the sender
+    */
+    void ChatManager::incomingChat(const std::string& message, unsigned int sourceID)
+    {
+        std::string text = message;
+        std::string name;
+
+        // get the name of the sender and prepend it to the text message
+        if (sourceID != NETWORK_PEER_ID_UNKNOWN)
+        {
+            PlayerInfo* player = PlayerManager::getInstance().getClient(sourceID);
+            if (player)
+            {
+                name = player->getName();
+                text = name + ": " + message;
+            }
+        }
+
+        // notify all listeners
+        for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
+            it->incomingChat(text, name);
+    }
+
+
+    //////////////////////////////////////////////////////////////////////////
+    // ChatListener                                                         //
+    //////////////////////////////////////////////////////////////////////////
+
+    ChatListener::ChatListener()
+    {
+        RegisterRootObject(ChatListener);
+    }
+}
Index: code/branches/output/src/orxonox/chat/ChatManager.h
===================================================================
--- code/branches/output/src/orxonox/chat/ChatManager.h	(revision 8829)
+++ code/branches/output/src/orxonox/chat/ChatManager.h	(revision 8829)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ChatManager_H__
+#define _ChatManager_H__
+
+#include "OrxonoxPrereqs.h"
+#include "util/Singleton.h"
+#include "network/NetworkChatListener.h"
+
+namespace orxonox
+{
+    /**
+        @brief This class collects and distributes chat messages. If the client is online,
+        all chat messages are sent and received through the network. Otherwise chat is handled
+        directly by this class.
+    */
+    class _OrxonoxExport ChatManager : public Singleton<ChatManager>, public NetworkChatListener
+    {
+        friend class Singleton<ChatManager>;
+
+        public:
+            ChatManager();
+            virtual ~ChatManager() {}
+
+            static void message(const std::string& message, unsigned int targetID = NETWORK_PEER_ID_BROADCAST);
+            static void chat(const std::string& message, unsigned int targetID = NETWORK_PEER_ID_BROADCAST);
+
+        protected:
+            ChatManager(const ChatManager&);
+
+            virtual void incomingChat(const std::string& message, unsigned int sourceID);
+
+            static ChatManager* singletonPtr_s;
+    };
+}
+
+#endif /* _ChatManager_H__ */
Index: code/branches/output/src/orxonox/gametypes/Asteroids.cc
===================================================================
--- code/branches/output/src/orxonox/gametypes/Asteroids.cc	(revision 8828)
+++ code/branches/output/src/orxonox/gametypes/Asteroids.cc	(revision 8829)
@@ -30,5 +30,5 @@
 
 #include "core/CoreIncludes.h"
-#include "network/Host.h"
+#include "chat/ChatManager.h"
 #include "worldentities/pawns/Pawn.h"
 
@@ -74,5 +74,5 @@
 
         std::string message("The match has started! Reach the first chekpoint within 15 seconds! But be aware, there may be pirates around...");
-        Host::Broadcast(message);
+        ChatManager::message(message);
 
     }
@@ -83,5 +83,5 @@
 
         std::string message("The match has ended.");
-        Host::Broadcast(message);
+        ChatManager::message(message);
     }
 }
Index: code/branches/output/src/orxonox/gametypes/Deathmatch.cc
===================================================================
--- code/branches/output/src/orxonox/gametypes/Deathmatch.cc	(revision 8828)
+++ code/branches/output/src/orxonox/gametypes/Deathmatch.cc	(revision 8829)
@@ -30,5 +30,5 @@
 
 #include "core/CoreIncludes.h"
-#include "network/Host.h"
+#include "chat/ChatManager.h"
 #include "infos/PlayerInfo.h"
 #include "worldentities/pawns/Pawn.h"
@@ -48,5 +48,5 @@
 
         std::string message("The match has started!");
-        Host::Broadcast(message);
+        ChatManager::message(message);
     }
 
@@ -56,5 +56,5 @@
 
         std::string message("The match has ended.");
-        Host::Broadcast(message);
+        ChatManager::message(message);
     }
 
@@ -64,5 +64,5 @@
 
         const std::string& message = player->getName() + " entered the game";
-        Host::Broadcast(message);
+        ChatManager::message(message);
     }
 
@@ -74,5 +74,5 @@
         {
             const std::string& message = player->getName() + " left the game";
-            Host::Broadcast(message);
+            ChatManager::message(message);
         }
 
@@ -87,5 +87,5 @@
         {
             const std::string& message = player->getOldName() + " changed name to " + player->getName();
-            Host::Broadcast(message);
+            ChatManager::message(message);
         }
 
@@ -108,5 +108,5 @@
                 message = victim->getPlayer()->getName() + " died";
 
-            Host::Broadcast(message);
+            ChatManager::message(message);
         }
 
@@ -121,5 +121,5 @@
         {
             const std::string& message = player->getName() + " scores!";
-            Host::Broadcast(message);
+            ChatManager::message(message);
         }
     }
Index: code/branches/output/src/orxonox/gametypes/Dynamicmatch.cc
===================================================================
--- code/branches/output/src/orxonox/gametypes/Dynamicmatch.cc	(revision 8828)
+++ code/branches/output/src/orxonox/gametypes/Dynamicmatch.cc	(revision 8829)
@@ -49,5 +49,5 @@
 #include "core/CoreIncludes.h"
 #include "core/command/Executor.h"
-#include "network/Host.h"
+#include "chat/ChatManager.h"
 #include "infos/PlayerInfo.h"
 #include "worldentities/pawns/Pawn.h"
@@ -343,5 +343,5 @@
         Gametype::playerEntered(player);
         const std::string& message = player->getName() + " entered the game";
-        Host::Broadcast(message);
+        ChatManager::message(message);
     }
 
@@ -358,5 +358,5 @@
             }
             const std::string& message = player->getName() + " left the game";
-            Host::Broadcast(message);
+            ChatManager::message(message);
             //remove player from map
             playerParty_.erase (player);
@@ -615,5 +615,5 @@
         {
             const std::string& message = player->getOldName() + " changed name to " + player->getName();
-            Host::Broadcast(message);
+            ChatManager::message(message);
         }
 
@@ -627,5 +627,5 @@
         {
             std::string message("Dynamicmatch started!");
-            Host::Broadcast(message);
+            ChatManager::message(message);
         }
         else if(tutorial) // Announce selectionphase
@@ -643,5 +643,5 @@
     {
         std::string message("Earn points:\n\n\n\tIf you're red: Chase the blue player!\n\n\tIf you're blue shoot at a red player or hide.\n\n\tIf you're green: You've got the licence to kill red players!");
-        Host::Broadcast(message);
+        ChatManager::message(message);
         callInstructions_.setTimer(10, false, createExecutor(createFunctor(&Dynamicmatch::furtherInstructions, this)));
     }
@@ -650,5 +650,5 @@
     {
         std::string message("After 3 Minutes the game is over.");
-        Host::Broadcast(message);
+        ChatManager::message(message);
     }*/
     void Dynamicmatch::end()
@@ -657,5 +657,5 @@
 
         std::string message("Time out. Press F2 to see the points you scored.");
-        Host::Broadcast(message);
+        ChatManager::message(message);
     }
     SpawnPoint* Dynamicmatch::getBestSpawnPoint(PlayerInfo* player) const
Index: code/branches/output/src/orxonox/gametypes/LastManStanding.cc
===================================================================
--- code/branches/output/src/orxonox/gametypes/LastManStanding.cc	(revision 8828)
+++ code/branches/output/src/orxonox/gametypes/LastManStanding.cc	(revision 8829)
@@ -30,5 +30,5 @@
 
 #include "core/CoreIncludes.h"
-#include "network/Host.h"
+#include "chat/ChatManager.h"
 #include "infos/PlayerInfo.h"
 #include "worldentities/pawns/Pawn.h"
@@ -105,5 +105,5 @@
             this->playersAlive--;
             const std::string& message = victim->getPlayer()->getName() + " has lost all lives";
-            Host::Broadcast(message);
+            ChatManager::message(message);
         }
 
Index: code/branches/output/src/orxonox/gametypes/LastTeamStanding.cc
===================================================================
--- code/branches/output/src/orxonox/gametypes/LastTeamStanding.cc	(revision 8828)
+++ code/branches/output/src/orxonox/gametypes/LastTeamStanding.cc	(revision 8829)
@@ -30,6 +30,5 @@
 
 #include "core/CoreIncludes.h"
-#include "network/NetworkPrereqs.h"
-#include "network/Host.h"
+#include "chat/ChatManager.h"
 #include "infos/PlayerInfo.h"
 #include "worldentities/pawns/Pawn.h"
@@ -119,5 +118,5 @@
                 this->teamsAlive--;
             const std::string& message = victim->getPlayer()->getName() + " has lost all lives";
-            Host::Broadcast(message);
+            ChatManager::message(message);
         }
         return allow;
Index: code/branches/output/src/orxonox/gametypes/UnderAttack.cc
===================================================================
--- code/branches/output/src/orxonox/gametypes/UnderAttack.cc	(revision 8828)
+++ code/branches/output/src/orxonox/gametypes/UnderAttack.cc	(revision 8829)
@@ -32,5 +32,5 @@
 #include "core/CoreIncludes.h"
 #include "core/ConfigValueIncludes.h"
-#include "network/Host.h"
+#include "chat/ChatManager.h"
 #include "worldentities/pawns/Destroyer.h"
 #include "infos/PlayerInfo.h"
@@ -70,5 +70,5 @@
         this->end(); //end gametype
         std::string message("Ship destroyed! Team 0 has won!");
-        Host::Broadcast(message);
+        ChatManager::message(message);
         this->gameEnded_ = true;
 
@@ -152,5 +152,5 @@
                 this->end();
                 std::string message("Time is up! Team 1 has won!");
-                Host::Broadcast(message);
+                ChatManager::message(message);
 
                 for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
@@ -171,5 +171,5 @@
                 const std::string& message = multi_cast<std::string>(timesequence_) + " seconds left!";
 /*
-                Host::Broadcast(message);
+                ChatManager::message(message);
 */
                 this->gtinfo_->sendAnnounceMessage(message);
