Index: code/branches/presentation3/src/modules/overlays/hud/HUDNavigation.cc
===================================================================
--- code/branches/presentation3/src/modules/overlays/hud/HUDNavigation.cc	(revision 6947)
+++ code/branches/presentation3/src/modules/overlays/hud/HUDNavigation.cc	(revision 6971)
@@ -47,94 +47,122 @@
 #include "worldentities/WorldEntity.h"
 #include "interfaces/RadarViewable.h"
+// #include <boost/bind/bind_template.hpp>
+
 
 namespace orxonox
 {
-    CreateFactory(HUDNavigation);
-
-    HUDNavigation::HUDNavigation(BaseObject* creator)
-        : OrxonoxOverlay(creator)
-    {
-        RegisterObject(HUDNavigation);
-
-        // Set default values
-        setFont("Monofur");
-        setTextSize(0.05f);
-        setNavMarkerSize(0.05f);
-    }
-
-    HUDNavigation::~HUDNavigation()
-    {
-        if (this->isInitialized())
+bool compareDistance ( std::pair<RadarViewable*, unsigned int > a, std::pair<RadarViewable*, unsigned int > b )
+{
+    return a.second<b.second;
+
+}
+CreateFactory ( HUDNavigation );
+
+HUDNavigation::HUDNavigation ( BaseObject* creator )
+        : OrxonoxOverlay ( creator )
+{
+    RegisterObject ( HUDNavigation );
+
+    // Set default values
+    setFont ( "Monofur" );
+    setTextSize ( 0.05f );
+    setNavMarkerSize ( 0.05f );
+}
+
+HUDNavigation::~HUDNavigation()
+{
+    if ( this->isInitialized() )
+    {
+        for ( ObjectMap::iterator it = activeObjectList_.begin(); it != activeObjectList_.end(); )
+            removeObject ( ( it++ )->first );
+
+    }
+
+    sortedObjectList_.clear();
+}
+
+void HUDNavigation::XMLPort ( Element& xmlElement, XMLPort::Mode mode )
+{
+    SUPER ( HUDNavigation, XMLPort, xmlElement, mode );
+
+    XMLPortParam ( HUDNavigation, "font",          setFont,          getFont,          xmlElement, mode );
+    XMLPortParam ( HUDNavigation, "textSize",      setTextSize,      getTextSize,      xmlElement, mode );
+    XMLPortParam ( HUDNavigation, "navMarkerSize", setNavMarkerSize, getNavMarkerSize, xmlElement, mode );
+}
+
+void HUDNavigation::setFont ( const std::string& font )
+{
+    const Ogre::ResourcePtr& fontPtr = Ogre::FontManager::getSingleton().getByName ( font );
+    if ( fontPtr.isNull() )
+    {
+        COUT ( 2 ) << "Warning: HUDNavigation: Font '" << font << "' not found" << std::endl;
+        return;
+    }
+    fontName_ = font;
+    for ( ObjectMap::iterator it = activeObjectList_.begin(); it != activeObjectList_.end(); ++it )
+    {
+        if ( it->second.text_ != NULL )
+            it->second.text_->setFontName ( fontName_ );
+    }
+}
+
+const std::string& HUDNavigation::getFont() const
+{
+    return fontName_;
+}
+
+void HUDNavigation::setTextSize ( float size )
+{
+    if ( size <= 0.0f )
+    {
+        COUT ( 2 ) << "Warning: HUDNavigation: Negative font size not allowed" << std::endl;
+        return;
+    }
+    textSize_ = size;
+    for ( ObjectMap::iterator it = activeObjectList_.begin(); it!=activeObjectList_.end(); ++it )
+    {
+        if ( it->second.text_ )
+            it->second.text_->setCharHeight ( size );
+    }
+}
+
+float HUDNavigation::getTextSize() const
+{
+    return textSize_;
+}
+
+void HUDNavigation::tick ( float dt )
+{
+    SUPER ( HUDNavigation, tick, dt );
+
+    Camera* cam = CameraManager::getInstance().getActiveCamera();
+    if ( cam == NULL )
+        return;
+    const Matrix4& camTransform = cam->getOgreCamera()->getProjectionMatrix() * cam->getOgreCamera()->getViewMatrix();
+
+
+    //TODO: sort list 'sortedObjectList_' according to distance.$
+    for ( sortedList::iterator listIt = sortedObjectList_.begin(); listIt != sortedObjectList_.end(); ++listIt )
+    {
+        listIt->second = ( int ) ( ( listIt->first->getRVWorldPosition() - HumanController::getLocalControllerSingleton()->getControllableEntity()->getWorldPosition() ).length() + 0.5f );
+    }
+
+    sortedObjectList_.sort ( compareDistance );
+
+    unsigned int markerCount_ = 0;
+
+//         for (ObjectMap::iterator it = activeObjectList_.begin(); it != activeObjectList_.end(); ++it)
+    for ( sortedList::iterator listIt = sortedObjectList_.begin(); listIt != sortedObjectList_.end(); ++markerCount_, ++listIt )
+    {
+        ObjectMap::iterator it = activeObjectList_.find ( listIt->first );
+
+        if ( markerCount_ < markerLimit_ )
         {
-            for (ObjectMap::iterator it = activeObjectList_.begin(); it != activeObjectList_.end();)
-                removeObject((it++)->first);
-        }
-    }
-
-    void HUDNavigation::XMLPort(Element& xmlElement, XMLPort::Mode mode)
-    {
-        SUPER(HUDNavigation, XMLPort, xmlElement, mode);
-
-        XMLPortParam(HUDNavigation, "font",          setFont,          getFont,          xmlElement, mode);
-        XMLPortParam(HUDNavigation, "textSize",      setTextSize,      getTextSize,      xmlElement, mode);
-        XMLPortParam(HUDNavigation, "navMarkerSize", setNavMarkerSize, getNavMarkerSize, xmlElement, mode);
-    }
-
-    void HUDNavigation::setFont(const std::string& font)
-    {
-        const Ogre::ResourcePtr& fontPtr = Ogre::FontManager::getSingleton().getByName(font);
-        if (fontPtr.isNull())
-        {
-            COUT(2) << "Warning: HUDNavigation: Font '" << font << "' not found" << std::endl;
-            return;
-        }
-        fontName_ = font;
-        for (ObjectMap::iterator it = activeObjectList_.begin(); it != activeObjectList_.end(); ++it)
-        {
-            if (it->second.text_ != NULL)
-                it->second.text_->setFontName(fontName_);
-        }
-    }
-
-    const std::string& HUDNavigation::getFont() const
-    {
-        return fontName_;
-    }
-
-    void HUDNavigation::setTextSize(float size)
-    {
-        if (size <= 0.0f)
-        {
-            COUT(2) << "Warning: HUDNavigation: Negative font size not allowed" << std::endl;
-            return;
-        }
-        textSize_ = size;
-        for (ObjectMap::iterator it = activeObjectList_.begin(); it!=activeObjectList_.end(); ++it)
-        {
-            if (it->second.text_)
-                it->second.text_->setCharHeight(size);
-        }
-    }
-
-    float HUDNavigation::getTextSize() const
-    {
-        return textSize_;
-    }
-
-    void HUDNavigation::tick(float dt)
-    {
-        SUPER(HUDNavigation, tick, dt);
-
-        Camera* cam = CameraManager::getInstance().getActiveCamera();
-        if (cam == NULL)
-            return;
-        const Matrix4& camTransform = cam->getOgreCamera()->getProjectionMatrix() * cam->getOgreCamera()->getViewMatrix();
-
-        for (ObjectMap::iterator it = activeObjectList_.begin(); it != activeObjectList_.end(); ++it)
-        {
+
+
             // Get Distance to HumanController and save it in the TextAreaOverlayElement.
-            int dist = (int)((it->first->getRVWorldPosition() - HumanController::getLocalControllerSingleton()->getControllableEntity()->getWorldPosition()).length() + 0.5f);
-            it->second.text_->setCaption(multi_cast<std::string>(dist));
-            float textLength = multi_cast<std::string>(dist).size() * it->second.text_->getCharHeight() * 0.3f;
+            int dist = listIt->second;
+            it->second.text_->setCaption ( multi_cast<std::string> ( dist ) );
+            float textLength = multi_cast<std::string> ( dist ).size() * it->second.text_->getCharHeight() * 0.3f;
 
             // Transform to screen coordinates
@@ -142,5 +170,5 @@
 
             bool outOfView = true;
-            if (pos.z > 1.0)
+            if ( pos.z > 1.0 )
             {
                 // z > 1.0 means that the object is behind the camera
@@ -153,27 +181,29 @@
             else
                 outOfView = pos.x < -1.0 || pos.x > 1.0 || pos.y < -1.0 || pos.y > 1.0;
-
-            if (outOfView)
+            // Get Distance to HumanController and save it in the TextAreaOverlayElement.
+            it->second.text_->setCaption ( multi_cast<std::string> ( dist ) );
+
+            if ( outOfView )
             {
                 // Object is not in view
 
                 // Change material only if outOfView changed
-                if (!it->second.wasOutOfView_)
+                if ( !it->second.wasOutOfView_ )
                 {
-                    it->second.panel_->setMaterialName("Orxonox/NavArrows");
+                    it->second.panel_->setMaterialName ( "Orxonox/NavArrows" );
                     it->second.wasOutOfView_ = true;
                 }
 
                 // Switch between top, bottom, left and right position of the arrow at the screen border
-                if (pos.x < pos.y)
+                if ( pos.x < pos.y )
                 {
-                    if (pos.y > -pos.x)
+                    if ( pos.y > -pos.x )
                     {
                         // Top
                         float position = pos.x / pos.y + 1.0f;
-                        it->second.panel_->setPosition((position - it->second.panel_->getWidth()) * 0.5f, 0.0f);
-                        it->second.panel_->setUV(0.5f, 0.0f, 1.0f, 0.5f);
-                        it->second.text_->setLeft((position - textLength) * 0.5f);
-                        it->second.text_->setTop(it->second.panel_->getHeight());
+                        it->second.panel_->setPosition ( ( position - it->second.panel_->getWidth() ) * 0.5f, 0.0f );
+                        it->second.panel_->setUV ( 0.5f, 0.0f, 1.0f, 0.5f );
+                        it->second.text_->setLeft ( ( position - textLength ) * 0.5f );
+                        it->second.text_->setTop ( it->second.panel_->getHeight() );
                     }
                     else
@@ -181,21 +211,22 @@
                         // Left
                         float position = pos.y / pos.x + 1.0f;
-                        it->second.panel_->setPosition(0.0f, (position - it->second.panel_->getWidth()) * 0.5f);
-                        it->second.panel_->setUV(0.0f, 0.0f, 0.5f, 0.5f);
-                        it->second.text_->setLeft(it->second.panel_->getWidth() + 0.01f);
-                        it->second.text_->setTop((position - it->second.text_->getCharHeight()) * 0.5f);
+                        it->second.panel_->setPosition ( 0.0f, ( position - it->second.panel_->getWidth() ) * 0.5f );
+                        it->second.panel_->setUV ( 0.0f, 0.0f, 0.5f, 0.5f );
+                        it->second.text_->setLeft ( it->second.panel_->getWidth() + 0.01f );
+                        it->second.text_->setTop ( ( position - it->second.text_->getCharHeight() ) * 0.5f );
                     }
                 }
+
                 else
                 {
 
-                    if (pos.y < -pos.x)
+                    if ( pos.y < -pos.x )
                     {
                         // Bottom
                         float position = -pos.x / pos.y + 1.0f;
-                        it->second.panel_->setPosition((position - it->second.panel_->getWidth()) * 0.5f, 1.0f - it->second.panel_->getHeight());
-                        it->second.panel_->setUV(0.0f, 0.5f, 0.5f, 1.0f);
-                        it->second.text_->setLeft((position - textLength) * 0.5f);
-                        it->second.text_->setTop(1.0f - it->second.panel_->getHeight() - it->second.text_->getCharHeight());
+                        it->second.panel_->setPosition ( ( position - it->second.panel_->getWidth() ) * 0.5f, 1.0f - it->second.panel_->getHeight() );
+                        it->second.panel_->setUV ( 0.0f, 0.5f, 0.5f, 1.0f );
+                        it->second.text_->setLeft ( ( position - textLength ) * 0.5f );
+                        it->second.text_->setTop ( 1.0f - it->second.panel_->getHeight() - it->second.text_->getCharHeight() );
                     }
                     else
@@ -203,8 +234,8 @@
                         // Right
                         float position = -pos.y / pos.x + 1.0f;
-                        it->second.panel_->setPosition(1.0f - it->second.panel_->getWidth(), (position - it->second.panel_->getHeight()) * 0.5f);
-                        it->second.panel_->setUV(0.5f, 0.5f, 1.0f, 1.0f);
-                        it->second.text_->setLeft(1.0f - it->second.panel_->getWidth() - textLength - 0.01f);
-                        it->second.text_->setTop((position - it->second.text_->getCharHeight()) * 0.5f);
+                        it->second.panel_->setPosition ( 1.0f - it->second.panel_->getWidth(), ( position - it->second.panel_->getHeight() ) * 0.5f );
+                        it->second.panel_->setUV ( 0.5f, 0.5f, 1.0f, 1.0f );
+                        it->second.text_->setLeft ( 1.0f - it->second.panel_->getWidth() - textLength - 0.01f );
+                        it->second.text_->setTop ( ( position - it->second.text_->getCharHeight() ) * 0.5f );
                     }
                 }
@@ -215,18 +246,18 @@
 
                 // Change material only if outOfView changed
-                if (it->second.wasOutOfView_)
+                if ( it->second.wasOutOfView_ )
                 {
-                    it->second.panel_->setMaterialName("Orxonox/NavTDC");
+                    it->second.panel_->setMaterialName ( "Orxonox/NavTDC" );
                     it->second.wasOutOfView_ = false;
                 }
 
                 // Position marker
-                it->second.panel_->setUV(0.0f, 0.0f, 1.0f, 1.0f);
-                it->second.panel_->setLeft((pos.x + 1.0f - it->second.panel_->getWidth()) * 0.5f);
-                it->second.panel_->setTop((-pos.y + 1.0f - it->second.panel_->getHeight()) * 0.5f);
+                it->second.panel_->setUV ( 0.0f, 0.0f, 1.0f, 1.0f );
+                it->second.panel_->setLeft ( ( pos.x + 1.0f - it->second.panel_->getWidth() ) * 0.5f );
+                it->second.panel_->setTop ( ( -pos.y + 1.0f - it->second.panel_->getHeight() ) * 0.5f );
 
                 // Position text
-                it->second.text_->setLeft((pos.x + 1.0f + it->second.panel_->getWidth()) * 0.5f);
-                it->second.text_->setTop((-pos.y + 1.0f + it->second.panel_->getHeight()) * 0.5f);
+                it->second.text_->setLeft ( ( pos.x + 1.0f + it->second.panel_->getWidth() ) * 0.5f );
+                it->second.text_->setTop ( ( -pos.y + 1.0f + it->second.panel_->getHeight() ) * 0.5f );
             }
 
@@ -235,91 +266,123 @@
             it->second.text_->show();
         }
-    }
-
-
-    /** Overridden method of OrxonoxOverlay.
-    @details
-        Usually the entire overlay scales with scale().
-        Here we obviously have to adjust this.
-    */
-    void HUDNavigation::sizeChanged()
-    {
-        // Use size to compensate for aspect ratio if enabled.
-        float xScale = this->getActualSize().x;
-        float yScale = this->getActualSize().y;
-
-        for (ObjectMap::iterator it = activeObjectList_.begin(); it!=activeObjectList_.end(); ++it)
+        else
         {
-            if (it->second.panel_ != NULL)
-                it->second.panel_->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
-            if (it->second.text_ != NULL)
-                it->second.text_->setCharHeight(it->second.text_->getCharHeight() * yScale);
+            it->second.panel_->hide();
+            it->second.text_->hide();
         }
-    }
-
-    void HUDNavigation::addObject(RadarViewable* object)
-    {
-        if (object == NULL)
+
+    }
+}
+
+
+/** Overridden method of OrxonoxOverlay.
+@details
+    Usually the entire overlay scales with scale().
+    Here we obviously have to adjust this.
+*/
+void HUDNavigation::sizeChanged()
+{
+    // Use size to compensate for aspect ratio if enabled.
+    float xScale = this->getActualSize().x;
+    float yScale = this->getActualSize().y;
+
+    for ( ObjectMap::iterator it = activeObjectList_.begin(); it!=activeObjectList_.end(); ++it )
+    {
+        if ( it->second.panel_ != NULL )
+            it->second.panel_->setDimensions ( navMarkerSize_ * xScale, navMarkerSize_ * yScale );
+        if ( it->second.text_ != NULL )
+            it->second.text_->setCharHeight ( it->second.text_->getCharHeight() * yScale );
+    }
+}
+
+void HUDNavigation::addObject ( RadarViewable* object )
+{
+
+    if ( activeObjectList_.size() >= markerLimit_ )
+        if ( object == NULL )
             return;
 
-        // Don't display our own ship
-        if (object == dynamic_cast<RadarViewable*>(this->getOwner()))
-            return;
-
-        // Object hasn't been added yet (we know that)
-        assert(this->activeObjectList_.find(object) == this->activeObjectList_.end());
-
-        // Scales used for dimensions and text size
-        float xScale = this->getActualSize().x;
-        float yScale = this->getActualSize().y;
-
-        // Create everything needed to display the object on the radar and add it to the map
-
-        // Create arrow/marker
-        Ogre::PanelOverlayElement* panel = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
-            .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberString()));
-        panel->setMaterialName("Orxonox/NavTDC");
-        panel->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
-
-        Ogre::TextAreaOverlayElement* text = static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton()
-            .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberString()));
-        text->setFontName(this->fontName_);
-        text->setCharHeight(text->getCharHeight() * yScale);
-
-        ObjectInfo tempStruct = {panel, text, false};
-        activeObjectList_[object] = tempStruct;
-
-        this->background_->addChild(panel);
-        this->background_->addChild(text);
-    }
-
-    void HUDNavigation::removeObject(RadarViewable* viewable)
-    {
-        ObjectMap::iterator it = activeObjectList_.find(viewable);
-
-        if (activeObjectList_.find(viewable) != activeObjectList_.end())
+    // Don't display our own ship
+    if ( object == dynamic_cast<RadarViewable*> ( this->getOwner() ) )
+        return;
+
+    // Object hasn't been added yet (we know that)
+    assert ( this->activeObjectList_.find ( object ) == this->activeObjectList_.end() );
+
+    // Scales used for dimensions and text size
+    float xScale = this->getActualSize().x;
+    float yScale = this->getActualSize().y;
+
+    // Create everything needed to display the object on the radar and add it to the map
+
+    // Create arrow/marker
+    Ogre::PanelOverlayElement* panel = static_cast<Ogre::PanelOverlayElement*> ( Ogre::OverlayManager::getSingleton()
+                                       .createOverlayElement ( "Panel", "HUDNavigation_navMarker_" + getUniqueNumberString() ) );
+    panel->setMaterialName ( "Orxonox/NavTDC" );
+    panel->setDimensions ( navMarkerSize_ * xScale, navMarkerSize_ * yScale );
+
+    Ogre::TextAreaOverlayElement* text = static_cast<Ogre::TextAreaOverlayElement*> ( Ogre::OverlayManager::getSingleton()
+                                         .createOverlayElement ( "TextArea", "HUDNavigation_navText_" + getUniqueNumberString() ) );
+    text->setFontName ( this->fontName_ );
+    text->setCharHeight ( text->getCharHeight() * yScale );
+
+    panel->hide();
+    text->hide();
+
+    ObjectInfo tempStruct = {panel, text, false};
+    activeObjectList_[object] = tempStruct;
+
+    this->background_->addChild ( panel );
+    this->background_->addChild ( text );
+
+    sortedObjectList_.push_front ( std::make_pair ( object, ( unsigned int ) 0 ) );
+
+    //TODO: hide elements
+}
+
+void HUDNavigation::removeObject ( RadarViewable* viewable )
+{
+
+    ObjectMap::iterator it = activeObjectList_.find ( viewable );
+
+    if ( activeObjectList_.find ( viewable ) != activeObjectList_.end() )
+    {
+        // Detach overlays
+        this->background_->removeChild ( it->second.panel_->getName() );
+        this->background_->removeChild ( it->second.text_->getName() );
+        // Properly destroy the overlay elements (do not use delete!)
+        Ogre::OverlayManager::getSingleton().destroyOverlayElement ( it->second.panel_ );
+        Ogre::OverlayManager::getSingleton().destroyOverlayElement ( it->second.text_ );
+        // Remove from the list
+        activeObjectList_.erase ( viewable );
+
+
+    }
+
+
+    else
+        COUT ( 2 ) << "Warning, HUDNavigation: Attempting to remove non-existent object" << std::endl;
+
+    for ( sortedList::iterator listIt = sortedObjectList_.begin(); listIt != sortedObjectList_.end(); ++listIt )
+    {
+        if ( (listIt->first) == viewable )
         {
-            // Detach overlays
-            this->background_->removeChild(it->second.panel_->getName());
-            this->background_->removeChild(it->second.text_->getName());
-            // Properly destroy the overlay elements (do not use delete!)
-            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.panel_);
-            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.text_);
-            // Remove from the list
-            activeObjectList_.erase(viewable);
+            sortedObjectList_.erase ( listIt );
+            break;
         }
-        else
-            COUT(2) << "Warning, HUDNavigation: Attempting to remove non-existent object" << std::endl;
-    }
-
-    void HUDNavigation::changedOwner()
-    {
-        // TODO: Delete old objects?
-        const std::set<RadarViewable*>& respawnObjects = this->getOwner()->getScene()->getRadar()->getRadarObjects();
-        for (std::set<RadarViewable*>::const_iterator it = respawnObjects.begin(); it != respawnObjects.end(); ++it)
-        {
-            if (!(*it)->isHumanShip_)
-                this->addObject(*it);
-        }
-    }
-}
+
+    }
+
+}
+
+void HUDNavigation::changedOwner()
+{
+    // TODO: Delete old objects?
+    const std::set<RadarViewable*>& respawnObjects = this->getOwner()->getScene()->getRadar()->getRadarObjects();
+    for ( std::set<RadarViewable*>::const_iterator it = respawnObjects.begin(); it != respawnObjects.end(); ++it )
+    {
+        if ( ! ( *it )->isHumanShip_ )
+            this->addObject ( *it );
+    }
+}
+}
