Index: code/branches/presentation/src/modules/notifications/NotificationQueue.cc
===================================================================
--- code/branches/presentation/src/modules/notifications/NotificationQueue.cc	(revision 8499)
+++ code/branches/presentation/src/modules/notifications/NotificationQueue.cc	(revision 8637)
@@ -38,18 +38,31 @@
 
 #include "core/CoreIncludes.h"
-#include "core/GameMode.h"
-#include "core/GUIManager.h"
-#include "core/LuaState.h"
-#include "util/Convert.h"
+#include "core/XMLPort.h"
 #include "util/SubString.h"
-
-#include "Notification.h"
 
 namespace orxonox
 {
 
-    /**
-    @brief
-        Constructor. Creates and initializes the object.
+    CreateFactory(NotificationQueue);
+    
+    /**
+    @brief
+        Default constructor. Registers and initializes the object.
+    @param creator
+        The creator of the NotificationQueue.
+    */
+    NotificationQueue::NotificationQueue(BaseObject* creator) : BaseObject(creator), registered_(false)
+    {
+        RegisterObject(NotificationQueue);
+
+        this->initialize();
+    }
+
+    // TODO move to docu.
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    @param creator
+        The creator of the NotificationQueue
     @param name
         The name of the new NotificationQueue. It needs to be unique
@@ -62,20 +75,42 @@
         The time during which a Notification is (at most) displayed.
     */
-    NotificationQueue::NotificationQueue(const std::string& name, const std::string& senders, unsigned int size, unsigned int displayTime)
-    {
-        this->registered_ = false;
-
-        RegisterRootObject(NotificationQueue);
-
-        // Initialize.
+
+    /**
+    @brief
+        Destructor.
+    */
+    NotificationQueue::~NotificationQueue()
+    {
+        this->targets_.clear();
+
+        if(this->isRegistered()) // If the NotificationQueue is registered.
+        {
+            this->clear(true);
+
+            // Unregister with the NotificationManager.
+            NotificationManager::getInstance().unregisterQueue(this);
+        }
+    }
+
+    /**
+    @brief
+        Initializes the NotificationQueue.
+    */
+    void NotificationQueue::initialize(void)
+    {
         this->size_ = 0;
         this->tickTime_ = 0.0f;
-
-        // Sets the input values.
-        this->setTargets(senders);
-        this->name_ = name;
-        this->maxSize_ = size;
-        this->setDisplayTime(displayTime);
-
+        this->maxSize_ = NotificationQueue::DEFAULT_SIZE;
+        this->displayTime_ = NotificationQueue::DEFAULT_DISPLAY_TIME;
+
+        this->creationTime_ = std::time(0);
+    }
+
+    /**
+    @brief
+        Creates the NotificationQueue.
+    */
+    void NotificationQueue::create(void)
+    {
         // Register the NotificationQueue with the NotificationManager.
         bool queueRegistered = NotificationManager::getInstance().registerQueue(this);
@@ -88,66 +123,5 @@
         }
 
-        this->create(); // Creates the NotificationQueue in lua.
-
-        // Register the NotificationQueue as NotificationListener with the NotificationManager.
-        bool listenerRegistered = NotificationManager::getInstance().registerListener(this);
-        if(!listenerRegistered) // If the registration has failed.
-        {
-            this->registered_ = false;
-            // Remove the NotificationQueue in lua.
-            if(GameMode::showsGraphics())
-                GUIManager::getInstance().getLuaState()->doString("NotificationLayer.removeQueue(\"" + this->getName() +  "\")");
-            NotificationManager::getInstance().unregisterQueue(this);
-            COUT(1) << "Error: NotificationQueue '" << this->getName() << "' could not be registered." << std::endl;
-            return;
-        }
-
         COUT(3) << "NotificationQueue '" << this->getName() << "' created." << std::endl;
-    }
-
-    /**
-    @brief
-        Destructor.
-    */
-    NotificationQueue::~NotificationQueue()
-    {
-        this->targets_.clear();
-
-        if(this->registered_) // If the NotificationQueue is registered.
-        {
-            this->clear(true);
-
-            // Unregister with the NotificationManager.
-            NotificationManager::getInstance().unregisterListener(this);
-            NotificationManager::getInstance().unregisterQueue(this);
-        }
-    }
-
-    /**
-    @brief
-        Destroys the NotificationQueue.
-        Used in lua and NotificationManager.
-    @param noGraphics
-        If this is set to true (false is default), then the queue is not removed in lua. This is used to destroy the queue, after the GUIManager has been destroyed.
-    */
-    void NotificationQueue::destroy(bool noGraphics)
-    {
-        // Remove the NotificationQueue in lua.
-        if(GameMode::showsGraphics() && !noGraphics)
-            GUIManager::getInstance().getLuaState()->doString("NotificationLayer.removeQueue(\"" + this->getName() +  "\")");
-
-        COUT(3) << "NotificationQueue '" << this->getName() << "' destroyed." << std::endl;
-
-        this->OrxonoxClass::destroy();
-    }
-
-    /**
-    @brief
-        Creates the NotificationQueue in lua.
-    */
-    void NotificationQueue::create(void)
-    {
-        if(GameMode::showsGraphics())
-            GUIManager::getInstance().getLuaState()->doString("NotificationLayer.createQueue(\"" + this->getName() +  "\", " + multi_cast<std::string>(this->getMaxSize()) + ")");
     }
 
@@ -161,7 +135,7 @@
     {
         this->tickTime_ += dt; // Add the time interval that has passed to the time counter.
-        if(this->tickTime_ >= 1.0) // If the time counter is greater than 1s all Notifications that have expired are removed, if it is smaller we wait to the next tick.
-        {
-            this->timeLimit_.time = std::time(0)-this->displayTime_; // Container containig the current time.
+        if(this->displayTime_ != INF && this->tickTime_ >= 1.0) // If the time counter is greater than 1s all Notifications that have expired are removed, if it is smaller we wait to the next tick.
+        {
+            this->timeLimit_.time = std::time(0)-this->displayTime_; // Container containing the current time.
 
             std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator it = this->ordering_.begin();
@@ -177,8 +151,20 @@
     }
 
+    void NotificationQueue::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(NotificationQueue, XMLPort, xmlelement, mode);
+
+        XMLPortParam(NotificationQueue, "targets", setTargets, getTargets, xmlelement, mode).defaultValues(NotificationListener::ALL);
+        XMLPortParam(NotificationQueue, "size", setMaxSize, getMaxSize, xmlelement, mode);
+        XMLPortParam(NotificationQueue, "displayTime", setDisplayTime, getDisplayTime, xmlelement, mode);
+
+        this->create();
+    }
+
     /**
     @brief
         Updates the NotificationQueue.
         Updates by clearing the queue and requesting all relevant Notifications from the NotificationManager and inserting them into the queue.
+        This is called by the NotificationManager when the Notifications have changed so much, that the NotificationQueue may have to re-initialize his operations.
     */
     void NotificationQueue::update(void)
@@ -188,11 +174,17 @@
         std::multimap<std::time_t, Notification*>* notifications = new std::multimap<std::time_t, Notification*>;
         // Get the Notifications sent in the interval from now to now minus the display time.
-        NotificationManager::getInstance().getNotifications(this, notifications, this->displayTime_);
+        if(this->displayTime_ == INF)
+            NotificationManager::getInstance().getNewestNotifications(this, notifications, this->getMaxSize());
+        else
+            NotificationManager::getInstance().getNotifications(this, notifications, this->displayTime_);
 
         if(!notifications->empty())
         {
-            // Add all Notifications.
+            // Add all Notifications that have been created after this NotificationQueue was created.
             for(std::multimap<std::time_t, Notification*>::iterator it = notifications->begin(); it != notifications->end(); it++)
-                this->push(it->second, it->first);
+            {
+                if(it->first >= this->creationTime_)
+                    this->push(it->second, it->first);
+            }
         }
 
@@ -246,9 +238,9 @@
         this->notifications_.insert(this->notifications_.begin(), container);
 
-        // Push the Notification to the GUI.
-        if(GameMode::showsGraphics())
-            GUIManager::getInstance().getLuaState()->doString("NotificationLayer.pushNotification(\"" + this->getName() + "\", \"" + notification->getMessage() + "\")");
+        // Inform that a Notification was pushed.
+        this->notificationPushed(notification);
 
         COUT(5) << "Notification \"" << notification->getMessage() << "\" pushed to NotificationQueue '" << this->getName() << "'" << endl;
+        COUT(3) << "NotificationQueue \"" << this->getName() << "\": " << notification->getMessage() << endl;
     }
 
@@ -279,7 +271,6 @@
         delete container;
 
-        // Pops the Notification from the GUI.
-        if(GameMode::showsGraphics())
-            GUIManager::getInstance().getLuaState()->doString("NotificationLayer.popNotification(\"" + this->getName() + "\")");
+        // Inform that a Notification was popped.
+        this->notificationPopped();
     }
 
@@ -305,7 +296,7 @@
         delete *containerIterator;
 
-        // Removes the Notification from the GUI.
-        if(GameMode::showsGraphics())
-            GUIManager::getInstance().getLuaState()->doString("NotificationLayer.removeNotification(\"" + this->getName() + "\", " + multi_cast<std::string>(index) + ")");
+        // TODO: index automatically cast?
+        // Inform that a Notification was removed.
+        this->notificationRemoved(index);
     }
 
@@ -314,5 +305,5 @@
         Clears the NotificationQueue by removing all NotificationContainers.
     @param noGraphics
-        If this is eset to true the GUI is not informed of the clearing of the NotificationQueue. This is needed only internally.
+        If this is set to true the GUI is not informed of the clearing of the NotificationQueue. This is needed only internally.
     */
     void NotificationQueue::clear(bool noGraphics)
@@ -326,8 +317,4 @@
         this->notifications_.clear();
         this->size_ = 0;
-
-        // Clear the NotificationQueue in the GUI.
-        if(GameMode::showsGraphics() && !noGraphics)
-            GUIManager::getInstance().getLuaState()->doString("NotificationLayer.clearQueue(\"" + this->getName() + "\")");
     }
 
@@ -354,7 +341,13 @@
             return;
 
+        if(size == 0)
+        {
+            COUT(2) << "Trying to set maximal size of NotificationQueue '" << this->getName() << "' to 0. Ignoring..." << endl;
+            return;
+        }
+        
         this->maxSize_ = size;
 
-        if(this->registered_)
+        if(this->isRegistered())
             this->update();
     }
@@ -364,16 +357,19 @@
         Sets the maximum number of seconds a Notification is displayed.
     @param time
-        The number of seconds the Notifications is displayed.
-    @return
-        Returns true if successful.
-    */
-    void NotificationQueue::setDisplayTime(unsigned int time)
+        The number of seconds a Notification is displayed.
+    */
+    void NotificationQueue::setDisplayTime(int time)
     {
         if(this->displayTime_ == time)
             return;
 
+        if(time != NotificationQueue::INF && time <= 0)
+        {
+            COUT(2) << "Trying to set display time of NotificationQueue '" << this->getName() << "' to non-positive value. Ignoring..." << endl;
+        }
+            
         this->displayTime_ = time;
 
-        if(this->registered_)
+        if(this->isRegistered())
             this->update();
     }
@@ -381,5 +377,5 @@
     /**
     @brief
-        Produces all targets of the NotificationQueue concatinated as string, with commas (',') as seperators.
+        Produces all targets of the NotificationQueue concatenated as string, with commas (',') as separators.
     @return
         Returns the targets as a string.
@@ -407,5 +403,5 @@
         The targets are the senders whose Notifications are displayed in this queue.
     @param targets
-        Accepts a string of targets, each seperated by commas (','), spaces are ignored.
+        Accepts a string of targets, each separated by commas (','), spaces are ignored.
     */
     void NotificationQueue::setTargets(const std::string & targets)
@@ -417,9 +413,23 @@
             this->targets_.insert(string[i]);
 
-        if(this->registered_)
-        {
-            NotificationManager::getInstance().unregisterListener(this);
-            NotificationManager::getInstance().registerListener(this);
-        }
+        // TODO: Why?
+        if(this->isRegistered())
+        {
+            NotificationManager::getInstance().unregisterQueue(this);
+            NotificationManager::getInstance().registerQueue(this);
+        }
+    }
+
+    /**
+    @brief
+        Pops all Notifications from the NotificationQueue.
+    @return
+        Returns true if successful, false if not.
+    */
+    bool NotificationQueue::tidy(void)
+    {
+        while(this->size_ > 0)
+            this->pop();
+        return true;
     }
 
