Index: code/branches/presentation2012/data/gui/layouts/ShipSelectionMenu.layout
===================================================================
--- code/branches/presentation2012/data/gui/layouts/ShipSelectionMenu.layout	(revision 9208)
+++ code/branches/presentation2012/data/gui/layouts/ShipSelectionMenu.layout	(revision 9208)
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/ShipSelectionBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+	<!-- --> 
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/ShipSelectionWindow" >
+            <Property Name="Text" Value="ShipSelection" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.2,0},{0.15,0},{0.8,0},{0.7,0}}" /> 
+            <Window Type="MenuWidgets/TabControl" Name="orxonox/ShipSelectionTabControl" >
+                <Property Name="TabHeight" Value="{0,26.4388}" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="TabPanePosition" Value="Top" />
+		<Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.1,0},{0.95,0},{0.925,0}}" />
+		
+            </Window>	
+            
+	    <!-- TODO: Ship Description and Image
+	    <Window Type="MenuWidgets/StaticImage" Name="orxonox/ShipSelectionShipImage" >
+                <Property Name="AlwaysOnTop" Value="True" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.55,0},{0.25,0},{0.9,0},{0.675,0}}" />
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/ShipSelectionLevelDescription" >
+                <Property Name="AlwaysOnTop" Value="True" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertScrollbar" Value="True" />
+                <Property Name="HorzScrollbar" Value="True" />
+                <Property Name="UnifiedAreaRect" Value="{{0.1,0},{0.725,0},{0.9,0},{0.875,0}}" />
+            </Window>--> 
+		 
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/ShipSelectionStartButton" >
+            <Property Name="Text" Value="Start" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.725,0},{0.4,0},{0.775,0}}" />
+            <Event Name="Clicked" Function="ShipSelectionMenu.ShipSelectionStartButton_clicked"/>
+        </Window>
+        <!-- TODO: set ship properties
+	<Window Type="MenuWidgets/Button" Name="orxonox/ShipSelectionConfigButton" >
+            <Property Name="Text" Value="Configure" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.425,0},{0.725,0},{0.575,0},{0.775,0}}" />
+            <Property Name="Disabled" Value="True" />
+            <Event Name="Clicked" Function="ShipSelectionMenu.ShipSelectionConfigButton_clicked"/>
+        </Window> --> 
+        <Window Type="MenuWidgets/Button" Name="orxonox/ShipSelectionBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.6,0},{0.725,0},{0.75,0},{0.775,0}}" />
+            <Event Name="Clicked" Function="ShipSelectionMenu.ShipSelectionBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: code/branches/presentation2012/data/gui/scripts/ShipSelectionMenu.lua
===================================================================
--- code/branches/presentation2012/data/gui/scripts/ShipSelectionMenu.lua	(revision 9208)
+++ code/branches/presentation2012/data/gui/scripts/ShipSelectionMenu.lua	(revision 9208)
@@ -0,0 +1,132 @@
+-- ShipSelectionMenu.lua
+
+local P = createMenuSheet("ShipSelectionMenu")
+P.activeTabIndexes = {}
+P.scrollbarWidth = 13
+P.shipList = {}
+function P.onLoad()
+   local dircmd = "ls ../levels/templates/ -l | awk '{print $9}' | grep \"spaceship\" | sed -e 's/\\.[a-zA-Z]*$//'" -- go to spaceships folder and generate a list of installed shipmodels.
+   os.execute(dircmd .. " > ../levels/templates/.shipmodels") --saves output in a textfile
+   --[[TODO: program a Windows Version / platform independent version here:
+   if string.sub(package.config,1,1) == '\\' then
+           -- Windows
+           dircmd = "dir /b/s"
+   end]]	
+   P.createFilterTab("All Ships")   
+end
+
+function P.createShipList() --generates list with tagged shipmodels
+   P.shipList = {}
+   for line in io.lines("../levels/templates/.shipmodels") do  --checks if shipmodel is included in level file
+	if selectedlevel:hasShip(string.lower(line)) then
+		P.shipList[#P.shipList+1] = string.lower(line)
+	end
+   end  
+end
+
+function P.update() --updates listbox with found models
+    P.createShipList()
+    listbox:resetList()
+    --orxonox.GUIManager:setItemTooltipsEnabledHelper(listbox, true)
+    local tabIndexes = {}
+    for k,v in pairs(P.shipList) do
+        --TODO: only add ship if is in the right filter tab
+        --if tag == nil or v:hasShip(tag) then
+            local item = CEGUI.createListboxTextItem(v)
+            item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+            listbox:addItem(item)
+            table.insert(tabIndexes, k)
+            --orxonox.GUIManager:setTooltipTextHelper(item, v:getDescription())
+        --end
+    end
+    table.insert(P.activeTabIndexes, tabIndexes)
+end
+
+function P.createFilterTab(name) -- generates filter tab and list box, sets handler for selection changes
+    tabName = "orxonox/ShipSelectionLevelTab"
+    -- create new tab window with desired name
+    listbox = CEGUI.toListbox(winMgr:createWindow("MenuWidgets/Listbox", tabName)) 
+    listbox:setText(name)
+    listbox:setProperty("UnifiedMaxSize", "{{1,0},{1,0}}")
+    --[[TODO: smaller list if image and description is implemented. 
+	listbox:setProperty("UnifiedAreaRect", "{{0.05,0},{0.1,0},{0.5,0},{0.675,0}}") --]]	 
+    listbox:setProperty("UnifiedAreaRect", "{{0,0},{0,0},{1,0},{1,0}}")
+    -- fill listbox with items
+    P.update()
+    -- listen to selection changes
+    orxonox.GUIManager:subscribeEventHelper(listbox, "ItemSelectionChanged", P.name..".ShipSelectionSelectionChanged")
+    local tabControl = winMgr:getWindow("orxonox/ShipSelectionTabControl")
+    orxonox.GUIManager:subscribeEventHelper(tabControl, "TabSelectionChanged", P.name..".ShipSelectionSelectionChanged")
+    if listbox:getItemCount() > 0 then
+        tabControl:addChildWindow(tabName)
+    end
+end
+
+function P.ShipSelectionGetSelectedModel() --returns selected model, if available.
+    -- choose the active listbox
+    local tabControl = CEGUI.toTabControl(winMgr:getWindow("orxonox/ShipSelectionTabControl"))
+    local listbox = CEGUI.toListbox(tabControl:getTabContentsAtIndex(tabControl:getSelectedTabIndex()))
+    local choice = listbox:getFirstSelectedItem()
+    if choice ~= nil then
+        -- get the right tab and the right index
+        local tabIndexes = P.activeTabIndexes[tabControl:getSelectedTabIndex()+1]
+        local index = tabIndexes[listbox:getItemIndex(choice)+1]
+        return P.shipList[index]
+    else
+        return nil
+    end
+end
+
+function P.ShipSelectionSelectionChanged(e)
+    --[[ TODO: Get image and description from template file
+    local levelImage = winMgr:getWindow("orxonox/ShipSelectionLevelImage")
+    local levelDescription = winMgr:getWindow("orxonox/ShipSelectionLevelDescription")
+    local configButton = winMgr:getWindow("orxonox/ShipSelectionConfigButton")
+    local level = P.ShipSelectionGetSelectedModel()
+    if level ~= nil then
+        --local levelXMLFilename = selectedlevel:getXMLFilename()
+        --local imageName = selectedlevel:getScreenshot()
+        -- set the screenshot and the description for the selected level
+        --levelImage:setProperty("Image", "set:"..levelXMLFilename..imageName.." image:full_image")
+        --levelDescription:setText(level:getDescription())
+        -- only enable config button for "gametype" levels
+        --if level:hasTag("gametype") then
+         --   configButton:setProperty("Disabled", "False")
+        --else
+        --    configButton:setProperty("Disabled", "True")
+        --end
+    else
+        -- also take care of "no level selected"
+        levelImage:setProperty("Image", nil)
+        levelDescription:setText("")
+    end
+   --]]
+end
+
+function P.ShipSelectionStartButton_clicked(e)
+
+    if (selectedlevel ~= nil and P.ShipSelectionGetSelectedModel() ~= nil)  then
+	selectedlevel:selectShip(P.ShipSelectionGetSelectedModel())
+        orxonox.execute("startGame " .. "_temp.oxw")
+        hideAllMenuSheets()
+    else
+	orxonox.execute("orxout user_warning no ship model selected or no tagged shipmodel installed")
+    end
+end
+
+--[[ TODO: function P.ShipSelectionConfigButton_clicked(e)
+
+    local level = P.ShipSelectionGetSelectedModel()
+    if level ~= nil then
+        local configMenu = showMenuSheet("ShipSelectionConfigMenu")
+        configMenu:loadConfig(level)
+    end
+end
+--]]
+
+
+function P.ShipSelectionBackButton_clicked(e)
+    orxonox.execute("keyESC")
+end 
+
+return P
Index: code/branches/presentation2012/data/gui/scripts/SingleplayerMenu.lua
===================================================================
--- code/branches/presentation2012/data/gui/scripts/SingleplayerMenu.lua	(revision 9203)
+++ code/branches/presentation2012/data/gui/scripts/SingleplayerMenu.lua	(revision 9208)
@@ -2,8 +2,9 @@
 
 local P = createMenuSheet("SingleplayerMenu")
-
+P.loadAlong = {"ShipSelectionMenu"}
 P.levelList = {}
 P.activeTabIndexes = {}
 P.scrollbarWidth = 13
+selectedlevel = {} -- level for ship selection
 
 function P.onLoad()
@@ -46,5 +47,6 @@
     while index < size do
         level = orxonox.LevelManager:getInstance():getAvailableLevelListItem(index)
-        if level ~= nil then
+        if (level ~= nil and level:getXMLFilename() ~= "_temp.oxw") then
+	    --os.execute("echo " .. level:getXMLFilename() .." >> ~/outputorx")
             local levelXMLFilename = level:getXMLFilename()
             -- create an imageset for each screenshot
@@ -141,8 +143,13 @@
 
 function P.SingleplayerStartButton_clicked(e)
-    local level = P.SingleplayerGetSelectedLevel()
-    if level ~= nil then
-        orxonox.execute("startGame " .. level:getXMLFilename())
-        hideAllMenuSheets()
+    selectedlevel = P.SingleplayerGetSelectedLevel()
+    if selectedlevel ~= nil then
+        if selectedlevel:hasTag("shipselection") then
+            local shipSelectionMenu = showMenuSheet("ShipSelectionMenu", true)
+            shipSelectionMenu:update()
+        else
+            orxonox.execute("startGame " .. selectedlevel:getXMLFilename())
+            hideAllMenuSheets()
+	end
     end
 end
Index: code/branches/presentation2012/data/levels/tutorial.oxw
===================================================================
--- code/branches/presentation2012/data/levels/tutorial.oxw	(revision 9203)
+++ code/branches/presentation2012/data/levels/tutorial.oxw	(revision 9208)
@@ -2,6 +2,7 @@
  name = "Coding Tutorial"
  description = "Level for the coding tutorial."
- tags = "tutorial"
+ tags = "tutorial, shipselection"
  screenshot = "codingtutorial.png"
+ startingships = "spaceshipassff, spaceshipghost, spaceshipspacecruiser"
 />
 
@@ -10,4 +11,6 @@
   include("stats.oxo")
   include("templates/spaceshipAssff.oxt")
+  include("templates/spaceshipGhost.oxt")
+  include("templates/spaceshipSpacecruiser.oxt")
   include("templates/lodInformation.oxt")
 ?>
@@ -23,8 +26,4 @@
    skybox       = "Orxonox/skypanoramagen1"
   >
-
-
-
-
 <Drone name="meineDrohne" primarythrust="80" auxilarythrust="10" rotationthrust="10" mass= "50" linearDamping = "0.9" angularDamping = "0.7">
   <attached>
@@ -53,5 +52,5 @@
       for i = 1, 10, 1 do
     ?>
-      <SpawnPoint position="<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+      <SpawnPoint position="<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>" lookat="0,0,0" spawnclass=SpaceShip pawndesign=shipselection />
     <?lua end ?>
 
Index: code/branches/presentation2012/src/libraries/core/Loader.cc
===================================================================
--- code/branches/presentation2012/src/libraries/core/Loader.cc	(revision 9203)
+++ code/branches/presentation2012/src/libraries/core/Loader.cc	(revision 9208)
@@ -222,5 +222,5 @@
 
             orxout(verbose, context::loader) << "Namespace-tree:" << '\n' << rootNamespace->toString("  ") << endl;
-
+			
             return true;
         }
Index: code/branches/presentation2012/src/orxonox/LevelInfo.cc
===================================================================
--- code/branches/presentation2012/src/orxonox/LevelInfo.cc	(revision 9203)
+++ code/branches/presentation2012/src/orxonox/LevelInfo.cc	(revision 9208)
@@ -93,4 +93,5 @@
             LevelInfoItem::possibleTags_s.insert("gametype");
             LevelInfoItem::possibleTags_s.insert("minigame");
+            LevelInfoItem::possibleTags_s.insert("shipselection");
         }
     }
@@ -110,4 +111,19 @@
 
         this->tagsUpdated();
+    }
+    /**
+    @brief
+        Set the starting ship models of the level
+    @param tags
+        A comma-seperated string of all the allowed ship models for the shipselection.
+    */
+    void LevelInfoItem::setShips(const std::string& ships)
+    {
+        SubString substr = SubString(ships, ",", " "); // Split the string into tags.
+        const std::vector<std::string>& strings = substr.getAllStrings();
+        for(std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); it++)
+            this->addShip(*it, false);
+
+        this->shipsUpdated();
     }
 
@@ -137,4 +153,24 @@
     /**
     @brief
+        Add a ship model to allowed models for the shipselection
+    @param ship
+        The ship model to be added.
+    @param update
+        Whether the comma-seperated string of all ship models should be updated. Default is true.
+    @return
+        Returns true if the ship was successfully added, if the ship was already present it returns false.
+    */
+    bool LevelInfoItem::addShip(const std::string& ship, bool update)
+    {
+        bool success = this->ships_.insert(ship).second;
+        if(update && success)
+            this->shipsUpdated();
+            
+        return success;
+    }
+
+
+    /**
+    @brief
         Updates the comma-seperated string of all tags, if the set of tags has changed.
     */
@@ -155,4 +191,23 @@
     }
 
+    /**
+    @brief
+        Updates the comma-seperated string of all ships, if the set of tags has changed.
+    */
+    void LevelInfoItem::shipsUpdated(void)
+    {
+        std::stringstream stream;
+        std::set<std::string>::iterator temp;
+        for(std::set<std::string>::iterator it = this->ships_.begin(); it != this->ships_.end(); )
+        {
+            temp = it;
+            if(++it == this->ships_.end()) // If this is the last ship we don't add a comma.
+                stream << *temp;
+            else
+                stream << *temp << ", ";
+        }
+
+        this->startingShipsString_ = std::string(stream.str());
+    }
     // LevelInfo
 
@@ -192,4 +247,5 @@
         XMLPortParam(LevelInfo, "screenshot", setScreenshot, getScreenshot, xmlelement, mode);
         XMLPortParam(LevelInfo, "tags", setTags, getTags, xmlelement, mode);
+        XMLPortParam(LevelInfo, "startingships", setShips, getShips, xmlelement, mode);
     }
 
@@ -207,4 +263,5 @@
         info->setScreenshot(this->getScreenshot());
         info->setTags(this->getTags());
+        info->setShips(this->getShips());
         return info;
     }
Index: code/branches/presentation2012/src/orxonox/LevelInfo.h
===================================================================
--- code/branches/presentation2012/src/orxonox/LevelInfo.h	(revision 9203)
+++ code/branches/presentation2012/src/orxonox/LevelInfo.h	(revision 9208)
@@ -24,5 +24,5 @@
  *   Co-authors:
  *      ...
- *
+ *   
  */
 
@@ -43,4 +43,6 @@
 
 #include "core/BaseObject.h"
+#include <iostream>
+#include <fstream>
 #include "core/OrxonoxClass.h"
 
@@ -115,10 +117,27 @@
             */
             inline bool hasTag(const std::string& tag) const { return this->tags_.find(tag) != this->tags_.end(); } // tolua_export
-
+ 
+            void setShips(const std::string& ships); //!< Set the starting ship models of the level
+            bool addShip(const std::string& ship, bool update = true); //!< Add a model to shipselection
+            /**
+            @brief Get the set of starting ship models the Level allows
+            @return Returns a comma-seperated string of all the allowed ship models for the shipselection.
+            */
+            inline const std::string& getShips(void) const
+                { return this->startingShipsString_; }    
+            /**
+            @brief Get whether the Level allows a specific starting ship model
+            @param ship The ship model for which is checked.
+            @return Returns true if the Level allows the input ship model
+            */
+            inline bool hasShip(const std::string& ship) const { return this->ships_.find(ship) != this->ships_.end(); } // tolua_export        
             /**
             @brief Get the XML-filename of the Level.
             @return Returns the XML-filename (including *.oxw extension) of the Level.
             */
+
             inline const std::string& getXMLFilename(void) const { return this->xmlfilename_; } // tolua_export
+	    inline void selectShip (const std::string& ship) { this->changeShip(ship); } // tolua_export
+
 
         protected:
@@ -133,6 +152,33 @@
 
         private:
+
+	    inline void changeShip (const std::string& model) {
+	        static std::string shipSelectionTag = "shipselection";
+        	//HACK: Read Level XML File, find "shipselection", replace with ship model
+        	std::string levelPath = "../levels/";
+        	levelPath.append(this->getXMLFilename());
+        	std::string tempPath = "../levels/";
+        	tempPath.append("_temp.oxw");
+        	orxout(user_status) << levelPath << endl;
+        	orxout(user_status) << tempPath << endl;
+        	std::ifstream myLevel (levelPath.c_str());
+			std::ofstream tempLevel (tempPath.c_str());
+			while(!myLevel.eof())
+			{
+				std::string buff;
+				std::getline(myLevel, buff);
+				std::string pawndesignString = "pawndesign=";
+				size_t found = buff.find(pawndesignString.append(shipSelectionTag)); 
+				if (found!= std::string::npos) 
+					buff = buff.substr(0, found + 11) + model + buff.substr(found+11+shipSelectionTag.length(), std::string::npos);
+				tempLevel.write(buff.c_str(), buff.length());
+				tempLevel << std::endl;
+			}
+			myLevel.close();
+			tempLevel.close();
+			orxout(user_status) << "done" << endl;
+	    } 
             void tagsUpdated(void); //!< Updates the comma-seperated string of all tags, if the set of tags has changed.
-
+            void shipsUpdated(void); //!< Updates the comma-seperated string of all tags, if the set of tags has changed.
             static void initializeTags(void); //!< Initialize the set of allowed tags.
             /**
@@ -152,4 +198,6 @@
             std::set<std::string> tags_; //!< The set of tags the Level is tagged with.
             std::string tagsString_; //!< The comma-seperated string of all the tags the Level is tagged with.
+            std::set<std::string> ships_; //!< The set of starting ship models the Level allows.
+            std::string startingShipsString_; //!< The comma-seperated string of all the allowed ship models for the shipselection.            
     }; // tolua_export
 
@@ -161,6 +209,6 @@
         - @b description The description of the level.
         - @b screenshot The screenshot of the level.
-        - @b tags A comma-seperated string of tags. Allowed tags are: <em>test</em>, <em>singleplayer</em>, <em>multiplayer</em>, <em>showcase</em>, <em>tutorial</em>, <em>presentation</em>.
-
+        - @b tags A comma-seperated string of tags. Allowed tags are: <em>test</em>, <em>singleplayer</em>, <em>multiplayer</em>, <em>showcase</em>, <em>tutorial</em>, <em>presentation</em>, <em>shipselection</em>.
+        - @b (optional) startingships The comma-seperated string of starting ship models 
         An example would be:
         @code
@@ -176,5 +224,6 @@
     @author
         Damian 'Mozork' Frick
-
+	@edit
+		Matthias Hutter
     @ingroup Orxonox
     */
@@ -223,7 +272,17 @@
             inline const std::string& getTags(void) const
                 { return this->LevelInfoItem::getTags(); }
-
+            /**
+            @brief Set the starting ship models of the level
+            @param A comma-seperated string of all the allowed ship models for the shipselection.
+            */
+            inline void setShips(const std::string& ships)
+                { this->LevelInfoItem::setShips(ships); }
+            /**
+            @brief Get the starting ship models of the level
+            @return Returns a comma-seperated string of all the allowed ship models for the shipselection.
+            */
+            inline const std::string& getShips(void) const
+                { return this->LevelInfoItem::getShips(); }              
             LevelInfoItem* copy(void); //!< Copies the contents of this LevelInfo object to a new LevelInfoItem object.
-
     };
 
Index: code/branches/presentation2012/src/orxonox/LevelManager.cc
===================================================================
--- code/branches/presentation2012/src/orxonox/LevelManager.cc	(revision 9203)
+++ code/branches/presentation2012/src/orxonox/LevelManager.cc	(revision 9208)
@@ -256,5 +256,5 @@
         {
             // TODO: Replace with tag?
-            if (it->find("old/") != 0)
+            if (it->find("old/") != 0 )
             {
                 LevelInfoItem* info = NULL;
Index: code/branches/presentation2012/src/orxonox/ShipManager.cc
===================================================================
--- code/branches/presentation2012/src/orxonox/ShipManager.cc	(revision 9208)
+++ code/branches/presentation2012/src/orxonox/ShipManager.cc	(revision 9208)
@@ -0,0 +1,201 @@
+/*
+ *   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:
+ *      Matthias Hutter
+ *   
+ */
+
+/**
+    @file ShipManager.cc
+    @brief Work-in Progress: Implementation of the ShipManager singleton.
+    	   Should make SpaceShip info available to lua handlers.
+*/
+
+#include "LevelManager.h"
+
+#include <map>
+
+#include "util/ScopedSingletonManager.h"
+#include "core/ClassTreeMask.h"
+#include "core/CommandLineParser.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "core/Loader.h"
+#include "core/Resource.h"
+#include "core/XMLFile.h"
+#include "Level.h"
+#include "PlayerManager.h"
+
+namespace orxonox
+{
+    SetCommandLineArgument(level, "").shortcut("l").information("Default level file (overrides LevelManager::defaultLevelName_ configValue)");
+
+    ManageScopedSingleton(LevelManager, ScopeID::Root, false);
+
+    /**
+    @brief
+        Constructor.
+    */
+    ShipManager::ShipManager()
+    {
+        RegisterRootObject(LevelManager);
+        this->compileAvailableLevelList();
+        this->nextIndex_ = 0;
+        this->nextLevel_ = this->availableLevels_.begin();
+    }
+
+    ShipManager::~ShipManager()
+    {
+        // Delete all the Ship objects because the LevelManager created them
+        std::set<SpaceShip*, LevelInfoCompare>::iterator it = availableLevels_.begin();
+        for (; it != availableLevels_.end(); ++it)
+            delete *it;
+    }
+
+   
+    /**
+    @brief
+        Get the number of available Ships.
+    @return
+        Returns the number of available Ships.
+    */
+    unsigned int LevelManager::getNumberOfLevels(){ return this->availableLevels_.size(); }
+
+    /**
+    @brief
+        Get the SpaceShip at the given index in the list of available Ships.
+        The SpaceShips are sorted in alphabetical order accoridng to the name of the Ship.
+        This method is most efficiently called with consecutive indices (or at least ascending indices).
+    @param index
+        The index of the item that should be returned.
+    @return
+        Returns a pointer to the SpaceShip at the given index.
+    */
+    SpaceShip* ShipManager::getAvailableShipListItem(unsigned int index)
+    {
+        if(index >= this->availableShips_.size())
+            return NULL;
+
+        // If this index directly follows the last we can optimize a lot.
+        if(index == this->nextIndex_)
+        {
+            this->nextIndex_++;
+            std::set<SpaceShip*, SpaceShipCompare>::iterator it = this->nextShip_;
+            this->nextLevel_++;
+            return *it;
+        }
+        else
+        {
+            // If this index is bigger than the last, we can optimize a little.
+            if(index < this->nextIndex_)
+            {
+                this->nextIndex_ = 0;
+                this->nextShip_ = this->availableShips_.begin();
+            }
+
+            while(this->nextIndex_ != index)
+            {
+                this->nextIndex_++;
+                this->nextShip_++;
+            }
+            this->nextIndex_++;
+            std::set<SpaceShip*, SpaceShipCompare>::iterator it = this->nextLevel_;
+            this->nextLevel_++;
+            return *it;
+        }
+    }
+
+    /**
+    @brief
+        Compile the list of available Levels.
+        Iterates over all *.oxw files, loads the LevelInfo objects in them and from that it creates the LevelInfoItems which are inserted in a list.
+    */
+    void ShipManager::compileAvailableShipList()
+    {
+		/*
+		// We only want to load as little as possible
+		ClassTreeMask mask;
+		    mask.exclude(Class(BaseObject));
+		    mask.include(Class(SpaceShip));
+		SpaceShip* info = NULL;
+		XMLFile file = XMLFile(ship);
+		Loader::load(&file, mask, false, true);
+		for(ObjectList<SpaceShip>::iterator item = ObjectList<SpaceShip>::begin(); item != ObjectList<SpaceShip>::end(); ++item)
+		        if(item->getXMLFilename() == *it)
+		            info = item->copy();
+		Loader::unload(&file);
+		*/
+    
+        // Get all files matching the level criteria
+        Ogre::StringVectorPtr levels = Resource::findResourceNames("*.oxw");
+
+        // We only want to load as little as possible
+        ClassTreeMask mask;
+        mask.exclude(Class(BaseObject));
+        mask.include(Class(LevelInfo));
+
+        // Iterate over all the found *.oxw files
+        orxout(internal_info) << "Loading LevelInfos..." << endl;
+        std::set<std::string> names;
+        for (Ogre::StringVector::const_iterator it = levels->begin(); it != levels->end(); ++it)
+        {
+            // TODO: Replace with tag?
+            if (it->find("old/") != 0 )
+            {
+                LevelInfoItem* info = NULL;
+
+                // Load the LevelInfo object from the level file.
+                XMLFile file = XMLFile(*it);
+                Loader::load(&file, mask, false, true);
+
+                // Find the LevelInfo object we've just loaded (if there was one)
+                for(ObjectList<LevelInfo>::iterator item = ObjectList<LevelInfo>::begin(); item != ObjectList<LevelInfo>::end(); ++item)
+                    if(item->getXMLFilename() == *it)
+                        info = item->copy();
+
+                // We don't need the loaded stuff anymore
+                Loader::unload(&file);
+
+                if(info == NULL)
+                {
+                    // Create a default LevelInfoItem object that merely contains the name
+                    std::string filenameWOExtension = it->substr(0, it->find(".oxw"));
+                    info = new LevelInfoItem(filenameWOExtension, *it);
+                }
+
+                // Warn about levels with the same name.
+                if(!names.insert(info->getName()).second)
+                    orxout(internal_warning) << "Multiple levels (" << info->getXMLFilename() << ") with name '" << info->getName() << "' found!" << endl;
+
+                // Warn about multiple items so that it gets fixed quickly
+                if(availableLevels_.find(info) != availableLevels_.end())
+                {
+                    orxout(internal_warning) << "Multiple levels (" << info->getXMLFilename() << ") with same name '" << info->getName() << "' and filename found! Exluding..." << endl;
+                    // Delete LevelInfoItem to avoid a dangling pointer
+                    delete info;
+                }
+                else
+                    this->availableLevels_.insert(info);
+            }
+        }
+    }
+}
Index: code/branches/presentation2012/src/orxonox/ShipManager.h
===================================================================
--- code/branches/presentation2012/src/orxonox/ShipManager.h	(revision 9208)
+++ code/branches/presentation2012/src/orxonox/ShipManager.h	(revision 9208)
@@ -0,0 +1,93 @@
+/*
+ *   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:
+ *      Matthias Hutter
+ */
+
+/**
+    @file ShipManager.h
+    @brief Definition of the ShipManager singleton.
+    @ingroup Orxonox
+*/
+
+#ifndef _ShipManager_H__
+#define _ShipManager_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <cassert>
+#include <list>
+#include <map>
+#include <string>
+#include "worldentities/pawns/SpaceShip.h"
+
+#include "util/Singleton.h"
+#include "core/OrxonoxClass.h"
+
+// tolua_begin
+namespace orxonox
+{
+
+    /**
+    @author
+       Matthias Hutter
+
+    @ingroup Orxonox
+    */
+    class _OrxonoxExport ShipManager
+    // tolua_end
+        : public Singleton<ShipManager>, public OrxonoxClass
+    { // tolua_export
+            friend class Singleton<LevelManager>;
+        public:
+            ShipManager();
+            virtual ~ShipManager();
+
+            void setConfigValues(); //!< Set the config values for this object.
+            // tolua_begin
+            /**
+            @brief Get the instance of the LevelManager.
+            @return Returns the instance of the LevelManager.
+            */
+            static ShipManager& getInstance()
+                { return Singleton<ShipManager>::getInstance(); }
+            // tolua_end
+
+        private:
+            ShipManager(const ShipManager&);
+
+
+            void compileAvailableLevelList(void); //!< Compile the list of available Levels.
+            void updateAvailableLevelList(void); //!< Update the list of available Levels.
+
+            std::list<Level*> levels_; //!< A list of all the Levels whose activity has been requested, in the order in which they will become active.
+            std::set<LevelInfoItem*, LevelInfoCompare> availableLevels_; //!< The set of available Levels sorted alphabetically according to the name of the Level.
+
+            // Helpers to allow fast access to the availableLevels list.
+            unsigned int nextIndex_; //! The next expected index to be accessed.
+            std::set<LevelInfoItem*, LevelInfoCompare>::iterator nextLevel_; //! The next expected Level to be accessed.
+
+            static LevelManager* singletonPtr_s;
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _LevelManager_H__ */
