Index: code/branches/gamestates2/data/gui/scripts/InitialiseGUI.lua
===================================================================
--- code/branches/gamestates2/data/gui/scripts/InitialiseGUI.lua	(revision 6736)
+++ code/branches/gamestates2/data/gui/scripts/InitialiseGUI.lua	(revision 6737)
@@ -1,9 +1,7 @@
-winMgr   = CEGUI.WindowManager:getSingleton()
-guiMgr   = orxonox.GUIManager:getInstance()
-inputMgr = orxonox.InputManager:getInstance()
-
-local schemeMgr = CEGUI.SchemeManager:getSingleton()
-local system    = CEGUI.System:getSingleton()
-local cursor    = CEGUI.MouseCursor:getSingleton()
+-- Define some global shortcuts for common Managers
+guiMgr    = orxonox.GUIManager:getInstance()
+inputMgr  = orxonox.InputManager:getInstance()
+schemeMgr = CEGUI.SchemeManager:getSingleton()
+winMgr    = CEGUI.WindowManager:getSingleton()
 
 -- Load all required skins
@@ -25,227 +23,9 @@
 schemeMgr:loadScheme("OrxonoxGUIScheme.scheme")
 
+local system = CEGUI.System:getSingleton()
 system:setDefaultMouseCursor(menuImageSet, "MouseArrow")
 system:setDefaultFont("BlueHighway-12")
 system:setDefaultTooltip("MenuWidgets/Tooltip")
 
-local loadedSheets = {}
-local activeMenuSheets = {size = 0, topSheetTuple = nil}
---activeHUDSheets  = {size = 0, topSheetTuple = nil}
-local root = nil
-
--- Require all tools
+-- Convenience function and additional tools
 require("GUITools")
-
-
------------------------
---- Local functions ---
------------------------
-
--- Loads the GUI with the specified name
--- The name corresponds to the filename of the *.lua and *.layout files
--- but without the extension
-local function loadSheet(name)
-    -- Check if it has already been loaded
-    local sheet = loadedSheets[name]
-    if sheet == nil then
-        -- Load the sheet
-        sheet = require(name)
-        sheet:load()
-        loadedSheets[name] = sheet
-    end
-    return sheet
-end
-
-local function hideCursor()
-    if cursor:isVisible() then
-        cursor:hide()
-    end
-end
-
-local function showCursor()
-    if not cursor:isVisible() and orxonox.InputManager:getInstance():isMouseExclusive() then
-        cursor:show()
-    end
-end
-
-
-------------------------
---- Global functions ---
-------------------------
-
--- ?
-function showMenuSheet(name, bHidePrevious, ptr)
-    local sheet = showMenuSheet(name, bHidePrevious)
-    sheet.overlay = ptr
-    return sheet
-end
-
--- Shows the specified menu sheet and loads it if neccessary
-function showMenuSheet(name, bHidePrevious)
-    -- Get sheet (or load it)
-    local menuSheet = loadSheet(name)
-    if not menuSheet then
-        return nil
-    end
-
-    -- Use sheet's value if nil was provided
-    if bHidePrevious == nil then
-        bHidePrevious = menuSheet.bHidePrevious
-        assert(bHidePrevious ~= nil)
-    end
-
-    -- Pause game control if this is the first menu to be displayed
-    -- HUGE HACK?
-    if activeMenuSheets.size == 0 then
-        orxonox.HumanController:pauseControl()
-    end
-
-    -- Hide if already displayed (to make sure it is up front in the end)
-    if activeMenuSheets[name] ~= nil then
-        hideMenuSheet(name)
-    end
-
-    -- Add the sheet in a tuple of additional information
-    local sheetTuple =
-    {
-        ["sheet"]          = menuSheet,
-        ["bHidePrevious"]  = bHidePrevious
-    }
-    table.insert(activeMenuSheets, sheetTuple) -- indexed array access
-    activeMenuSheets[name] = sheetTuple -- name access
-    activeMenuSheets.size = activeMenuSheets.size + 1
-    activeMenuSheets.topSheetTuple = sheetTuple
-
-    if not root then
-        setBackground("")
-    end
-
-    -- Add sheet to the root window
-    root:addChildWindow(menuSheet.window)
-
-    -- Handle input distribution
-    orxonox.InputManager:getInstance():enterState(menuSheet.inputState)
-
-    -- Only change cursor situation if menuSheet.tShowCursor ~= TriBool.Dontcare
-    if menuSheet.tShowCursor == TriBool.True then
-        showCursor()
-    elseif menuSheet.tShowCursor == TriBool.False then
-        hideCursor()
-    end
-
-    -- Hide all previous sheets if necessary
-    if bHidePrevious then
-        for i = 1, activeMenuSheets.size - 1 do
-            activeMenuSheets[i].sheet:hide()
-        end
-    end
-
-    menuSheet:show()
-
-    return menuSheet
-end
-
-function hideMenuSheet(name)
-    local sheetTuple = activeMenuSheets[name]
-    if sheetTuple == nil then
-        return
-    end
-
-    -- Hide the sheet
-    sheetTuple.sheet:hide()
-
-    -- Show sheets that were hidden by the sheet to be removed
-    local i = activeMenuSheets.size
-    -- Only do something if all sheets on top of sheetTuple
-    -- have bHidePrevious == true and sheetTuple.bHidePrevious == true
-    while i > 0 do
-        if activeMenuSheets[i].bHidePrevious then
-            if activeMenuSheets[i] == sheetTuple then
-                i = i - 1
-                while i > 0 do
-                    activeMenuSheets[i].sheet:show()
-                    if activeMenuSheets[i].bHidePrevious then
-                        break
-                    end
-                    i = i - 1
-                end
-            end
-            break
-        end
-        i = i - 1
-    end
-
-    -- Remove sheet with its tuple from the table
-    root:removeChildWindow(sheetTuple.sheet.window)
-    table.remove(activeMenuSheets, table.findIndex(activeMenuSheets, sheetTuple))
-    activeMenuSheets[name] = nil
-    activeMenuSheets.size = activeMenuSheets.size - 1
-    activeMenuSheets.topSheetTuple = activeMenuSheets[activeMenuSheets.size]
-
-    -- Leave the input state
-    orxonox.InputManager:getInstance():leaveState(sheetTuple.sheet.inputState)
-    
-    -- CURSOR SHOWING
-    local i = activeMenuSheets.size
-    -- Find top most sheet that doesn't have tShowCusor == TriBool.Dontcare
-    while i > 0 and activeMenuSheets[i].sheet.tShowCursor == TriBool.Dontcare do
-        i = i - 1
-    end
-    if i > 0 and activeMenuSheets[i].sheet.tShowCursor == TriBool.True then
-        showCursor()
-    else
-        hideCursor()
-    end
-
-    -- Resume control if the last menu is hidden
-    if activeMenuSheets.size == 0 then
-        orxonox.HumanController:resumeControl()
-        hideCursor()
-    end
-end
-
--- Hides all menu GUI sheets
-function hideAllMenuSheets()
-    while activeMenuSheets.size ~= 0 do
-        hideMenuSheet(activeMenuSheets.topSheetTuple.sheet.name)
-    end
-end
-
-function keyESC()
-    -- HUGE, very HUGE hacks!
-    if activeMenuSheets.size == 1 and activeMenuSheets[1].sheet.name == "MainMenu" then
-        orxonox.execute("exit")
-    elseif activeMenuSheets.size > 0 then
-        orxonox.execute("hideMenuSheet "..activeMenuSheets.topSheetTuple.sheet.name)
-    else
-        showMenuSheet("InGameMenu")
-    end
-end
-
-function setBackground(name)
-    local newroot
-    if root ~= nil then
-        root:rename("oldRootWindow")
-    end
-    if name ~= "" then
-        newroot = winMgr:loadWindowLayout(name .. ".layout")
-        newroot:rename("AbsoluteRootWindow")
-        system:setGUISheet(newroot)
-    else
-        newroot = winMgr:createWindow("DefaultWindow", "AbsoluteRootWindow")
-        newroot:setProperty("Alpha", "0.0")
-        newroot:setSize(CEGUI.UVector2(CEGUI.UDim(1.0,0),CEGUI.UDim(1.0,0)))
-        system:setGUISheet(newroot)
-    end
-    if root ~= nil then
-        local child
-        while root:getChildCount()~=0 do
-            child = root:getChildAtIdx(0)
-            root:removeChildWindow(child)
-            newroot:addChildWindow(child)
-        end
-        winMgr:destroyWindow(root)
-    end
-    newroot:show()
-    root = newroot
-end
Index: code/branches/gamestates2/data/gui/scripts/SheetManager.lua
===================================================================
--- code/branches/gamestates2/data/gui/scripts/SheetManager.lua	(revision 6737)
+++ code/branches/gamestates2/data/gui/scripts/SheetManager.lua	(revision 6737)
@@ -0,0 +1,197 @@
+-- SheetManager.lua
+
+local cursor = CEGUI.MouseCursor:getSingleton()
+local loadedSheets = {}
+local activeMenuSheets = {size = 0, topSheetTuple = nil}
+local menuSheetsRoot = guiMgr:getMenuRootWindow()
+
+-----------------------
+--- Local functions ---
+-----------------------
+
+local function hideCursor()
+    if cursor:isVisible() then
+        cursor:hide()
+    end
+end
+
+local function showCursor()
+    if not cursor:isVisible() and inputMgr:isMouseExclusive() then
+        cursor:show()
+    end
+end
+
+
+------------------------
+--- Global functions ---
+------------------------
+
+-- Loads the GUI with the specified name
+-- The name corresponds to the filename of the *.lua and *.layout files
+-- but without the extension
+function loadSheet(name)
+    -- Check if it has already been loaded
+    local sheet = loadedSheets[name]
+    if sheet == nil then
+        -- Load the sheet
+        sheet = require(name)
+        sheet:load()
+        loadedSheets[name] = sheet
+    end
+    return sheet
+end
+
+-- ?
+function showMenuSheet(name, bHidePrevious, ptr)
+    local sheet = showMenuSheet(name, bHidePrevious)
+    sheet.overlay = ptr
+    return sheet
+end
+
+-- Shows the specified menu sheet and loads it if neccessary
+function showMenuSheet(name, bHidePrevious)
+    if name == "" then
+        return nil
+    end
+    -- Get sheet (or load it)
+    local menuSheet = loadSheet(name)
+
+    -- Use sheet's value if nil was provided
+    if bHidePrevious == nil then
+        bHidePrevious = menuSheet.bHidePrevious
+        assert(bHidePrevious ~= nil)
+    end
+
+    -- Pause game control if this is the first menu to be displayed
+    -- HUGE HACK?
+    if activeMenuSheets.size == 0 then
+        orxonox.HumanController:pauseControl()
+    end
+
+    -- Hide if already displayed (to make sure it is up front in the end)
+    if activeMenuSheets[name] ~= nil then
+        hideMenuSheet(name)
+    end
+
+    -- Add the sheet in a tuple of additional information
+    local sheetTuple =
+    {
+        ["sheet"]          = menuSheet,
+        ["bHidePrevious"]  = bHidePrevious
+    }
+    table.insert(activeMenuSheets, sheetTuple) -- indexed array access
+    activeMenuSheets[name] = sheetTuple -- name access
+    activeMenuSheets.size = activeMenuSheets.size + 1
+    activeMenuSheets.topSheetTuple = sheetTuple
+
+    -- Add sheet to the root window
+    menuSheetsRoot:addChildWindow(menuSheet.window)
+
+    -- Handle input distribution
+    inputMgr:enterState(menuSheet.inputState)
+
+    -- Only change cursor situation if menuSheet.tShowCursor ~= TriBool.Dontcare
+    if menuSheet.tShowCursor == TriBool.True then
+        showCursor()
+    elseif menuSheet.tShowCursor == TriBool.False then
+        hideCursor()
+    end
+
+    -- Hide all previous sheets if necessary
+    if bHidePrevious then
+        for i = 1, activeMenuSheets.size - 1 do
+            activeMenuSheets[i].sheet:hide()
+        end
+    end
+
+    menuSheet:show()
+
+    return menuSheet
+end
+
+function hideMenuSheet(name)
+    local sheetTuple = activeMenuSheets[name]
+    if sheetTuple == nil then
+        return
+    end
+
+    -- Hide the sheet
+    sheetTuple.sheet:hide()
+
+    -- Show sheets that were hidden by the sheet to be removed
+    local i = activeMenuSheets.size
+    -- Only do something if all sheets on top of sheetTuple
+    -- have bHidePrevious == true and sheetTuple.bHidePrevious == true
+    while i > 0 do
+        if activeMenuSheets[i].bHidePrevious then
+            if activeMenuSheets[i] == sheetTuple then
+                i = i - 1
+                while i > 0 do
+                    activeMenuSheets[i].sheet:show()
+                    if activeMenuSheets[i].bHidePrevious then
+                        break
+                    end
+                    i = i - 1
+                end
+            end
+            break
+        end
+        i = i - 1
+    end
+
+    -- Remove sheet with its tuple from the table
+    menuSheetsRoot:removeChildWindow(sheetTuple.sheet.window)
+    table.remove(activeMenuSheets, table.findIndex(activeMenuSheets, sheetTuple))
+    activeMenuSheets[name] = nil
+    activeMenuSheets.size = activeMenuSheets.size - 1
+    activeMenuSheets.topSheetTuple = activeMenuSheets[activeMenuSheets.size]
+
+    -- Leave the input state
+    inputMgr:leaveState(sheetTuple.sheet.inputState)
+    
+    -- CURSOR SHOWING
+    local i = activeMenuSheets.size
+    -- Find top most sheet that doesn't have tShowCusor == TriBool.Dontcare
+    while i > 0 and activeMenuSheets[i].sheet.tShowCursor == TriBool.Dontcare do
+        i = i - 1
+    end
+    if i > 0 and activeMenuSheets[i].sheet.tShowCursor == TriBool.True then
+        showCursor()
+    else
+        hideCursor()
+    end
+
+    -- Resume control if the last menu is hidden
+    if activeMenuSheets.size == 0 then
+        orxonox.HumanController:resumeControl()
+        hideCursor()
+    end
+end
+
+-- Hides all menu GUI sheets
+function hideAllMenuSheets()
+    while activeMenuSheets.size ~= 0 do
+        hideMenuSheet(activeMenuSheets.topSheetTuple.sheet.name)
+    end
+end
+
+function keyESC()
+    -- HUGE, very HUGE hacks!
+    if activeMenuSheets.size == 1 and activeMenuSheets[1].sheet.name == "MainMenu" then
+        orxonox.execute("exit")
+    elseif activeMenuSheets.size > 0 then
+        orxonox.execute("hideMenuSheet "..activeMenuSheets.topSheetTuple.sheet.name)
+    else
+        showMenuSheet("InGameMenu")
+    end
+end
+
+function setBackgroundImage(imageSet, imageName)
+    guiMgr:setBackgroundImage(imageSet, imageName)
+end
+
+----------------------
+--- Initialisation ---
+----------------------
+
+hideCursor()
Index: code/branches/gamestates2/src/libraries/core/GUIManager.cc
===================================================================
--- code/branches/gamestates2/src/libraries/core/GUIManager.cc	(revision 6736)
+++ code/branches/gamestates2/src/libraries/core/GUIManager.cc	(revision 6737)
@@ -42,4 +42,5 @@
 #include <CEGUISystem.h>
 #include <CEGUIWindow.h>
+#include <CEGUIWindowManager.h>
 #include <ogreceguirenderer/OgreCEGUIRenderer.h>
 
@@ -147,10 +148,19 @@
         guiSystem_->injectMousePosition((float)mousePosition.first, (float)mousePosition.second);
 
-        // Hide the mouse cursor unless playing in full screen mode
-        if (!GraphicsManager::getInstance().isFullScreen())
-            CEGUI::MouseCursor::getSingleton().hide();
-
-        // Initialise the basic Lua code
+        // Initialise the Lua framework and load the schemes
         this->luaState_->doFile("InitialiseGUI.lua");
+
+        // Create the root nodes
+        this->rootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("MenuWidgets/StaticImage", "AbsoluteRootWindow");
+        this->rootWindow_->setProperty("FrameEnabled", "False");
+        this->hudRootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "HUDRootWindow");
+        this->menuRootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "MenuRootWindow");
+        // And connect them
+        CEGUI::System::getSingleton().setGUISheet(this->rootWindow_);
+        this->rootWindow_->addChildWindow(this->hudRootWindow_);
+        this->rootWindow_->addChildWindow(this->menuRootWindow_);
+
+        // Set up the sheet manager in the Lua framework
+        this->luaState_->doFile("SheetManager.lua");
     }
 
@@ -203,6 +213,4 @@
     @param str
         reference to string object holding the Lua code which is to be executed
-
-        This function gives total access to the GUI. You can execute ANY Lua code here.
     */
     void GUIManager::executeCode(const std::string& str)
@@ -217,5 +225,5 @@
     void GUIManager::loadGUI(const std::string& name)
     {
-        this->executeCode("loadGUI(\"" + name + "\")");
+        this->executeCode("loadSheet(\"" + name + "\")");
     }
 
@@ -292,7 +300,19 @@
     }
 
-    void GUIManager::setBackground(const std::string& name)
-    {
-        this->executeCode("setBackground(\"" + name + "\")");
+    void GUIManager::setBackgroundImage(const std::string& imageSet, const std::string imageName)
+    {
+        if (imageSet.empty() || imageName.empty())
+            this->setBackgroundImage("set: " + imageSet + " image: " + imageName);
+        else
+            this->setBackgroundImage("");
+    }
+
+    void GUIManager::setBackgroundImage(const std::string& image)
+    {
+        if (image.empty())
+            this->rootWindow_->setProperty("Alpha", "0.0");
+        else
+            this->rootWindow_->setProperty("Alpha", "1.0");
+        this->rootWindow_->setProperty("Image", image);
     }
 
Index: code/branches/gamestates2/src/libraries/core/GUIManager.h
===================================================================
--- code/branches/gamestates2/src/libraries/core/GUIManager.h	(revision 6736)
+++ code/branches/gamestates2/src/libraries/core/GUIManager.h	(revision 6737)
@@ -79,7 +79,14 @@
         static void hideGUI(const std::string& name);
         void keyESC();
-        void setBackground(const std::string& name);
+        void setBackgroundImage(const std::string& imageSet, const std::string imageName); // tolua_export
+        void setBackgroundImage(const std::string& image);
 
+        //! Creates a new InputState to be used with a GUI Sheet
         const std::string& createInputState(const std::string& name, TriBool::Value showCursor = TriBool::True, TriBool::Value useKeyboard = TriBool::True, bool bBlockJoyStick = false); // tolua_export
+
+        //! Returns the root window for all menu sheets
+        CEGUI::Window* getMenuRootWindow() { return this->menuRootWindow_; } // tolua_export
+        //! Returns the root window for all HUD sheets
+        CEGUI::Window* getHUDRootWindow() { return this->hudRootWindow_; } // tolua_export
 
         void setCamera(Ogre::Camera* camera);
@@ -120,4 +127,7 @@
         CEGUI::ResourceProvider*             resourceProvider_; //!< CEGUI's resource provider
         CEGUI::Logger*                       ceguiLogger_;      //!< CEGUI's logger to be able to log CEGUI errors in our log
+        CEGUI::Window*                       rootWindow_;       //!< Root node for all windows
+        CEGUI::Window*                       hudRootWindow_;    //!< Root node for the HUD sheets
+        CEGUI::Window*                       menuRootWindow_;   //!< Root node for the menu sheets (used by Lua)
         std::map<std::string, PlayerInfo*>   players_;          //!< Stores the player (owner) for each GUI
         Ogre::Camera*                        camera_;           //!< Camera used to render the scene with the GUI
Index: code/branches/gamestates2/src/orxonox/overlays/GUISheet.cc
===================================================================
--- code/branches/gamestates2/src/orxonox/overlays/GUISheet.cc	(revision 6736)
+++ code/branches/gamestates2/src/orxonox/overlays/GUISheet.cc	(revision 6737)
@@ -40,6 +40,6 @@
         : BaseObject(creator)
         , bShowOnLoad_(false)
-        , bShowCursor_(true)
         , bHidePrevious_(false)
+        , bHidePreviousSet_(false)
     {
         RegisterObject(GUISheet);
@@ -57,32 +57,33 @@
         SUPER(GUISheet, XMLPort, xmlElement, mode);
 
-        XMLPortParam(GUISheet, "showOnLoad",   setShowOnLoad,       getShowOnLoad,       xmlElement, mode);
-        XMLPortParam(GUISheet, "showCursor",   setCursorVisibility, getCursorVisibility, xmlElement, mode);
-        XMLPortParam(GUISheet, "hidePrevious", setPreviousHiding,   getPreviousHiding,   xmlElement, mode);
-        XMLPortParam(GUISheet, "script",       setScript,           getScript,           xmlElement, mode);
+        XMLPortParam(GUISheet, "showOnLoad",   setShowOnLoad,     getShowOnLoad,     xmlElement, mode);
+        XMLPortParam(GUISheet, "hidePrevious", setPreviousHiding, getPreviousHiding, xmlElement, mode);
+        XMLPortParam(GUISheet, "sheetName",    setSheetName,      getSheetName,      xmlElement, mode);
+        XMLPortParam(GUISheet, "backgroundImage",  setBackgroundImage,  getBackgroundImage,  xmlElement, mode);
+
+        if (this->bShowOnLoad_)
+            this->show();
     }
 
     void GUISheet::show()
     {
-        GUIManager::showGUI(this->script_, this->bHidePrevious_);
+        GUIManager::getInstance().setBackgroundImage(this->backgroundImage_);
+        if (this->bHidePreviousSet_)
+            GUIManager::getInstance().showGUI(this->sheetName_, this->bHidePrevious_);
+        else
+            GUIManager::getInstance().showGUI(this->sheetName_);
     }
 
     void GUISheet::hide()
     {
-        GUIManager::hideGUI(this->script_);
+        GUIManager::getInstance().hideGUI(this->sheetName_);
+        if (!this->backgroundImage_.empty())
+            GUIManager::getInstance().setBackgroundImage("");
     }
 
-    void GUISheet::setScript(const std::string& filename)
+    void GUISheet::setSheetName(const std::string& name)
     {
-        this->script_ = filename;
-        GUIManager::getInstance().loadGUI(this->script_);
-        if (this->bShowOnLoad_)
-            this->show();
-    }
-
-    void GUISheet::setCursorVisibility(bool bShow)
-    {
-        this->bShowCursor_ = bShow;
-        // TODO: This call has no effect when already showing!
+        this->sheetName_ = name;
+        GUIManager::getInstance().loadGUI(this->sheetName_);
     }
 
@@ -90,5 +91,6 @@
     {
         this->bHidePrevious_ = bHide;
-        // TODO: This call has no effect when already showing!
+        this->bHidePreviousSet_ = true;
+        // Note: This call has no effect when already showing!
     }
 }
Index: code/branches/gamestates2/src/orxonox/overlays/GUISheet.h
===================================================================
--- code/branches/gamestates2/src/orxonox/overlays/GUISheet.h	(revision 6736)
+++ code/branches/gamestates2/src/orxonox/overlays/GUISheet.h	(revision 6737)
@@ -49,7 +49,7 @@
         void hide();
 
-        void setScript(const std::string& filename);
-        inline const std::string& getScript() const
-            { return this->script_; }
+        void setSheetName(const std::string& name);
+        inline const std::string& getSheetName() const
+            { return this->sheetName_; }
 
         inline void setShowOnLoad(bool bShow)
@@ -58,17 +58,19 @@
             { return this->bShowOnLoad_; }
 
-        void setCursorVisibility(bool bShow);
-        inline bool getCursorVisibility() const
-            { return this->bShowCursor_; }
-
         void setPreviousHiding(bool bHide);
         inline bool getPreviousHiding() const
             { return this->bHidePrevious_; }
 
+        void setBackgroundImage(const std::string& image)
+            { this->backgroundImage_ = image; }
+        inline const std::string& getBackgroundImage() const
+            { return this->backgroundImage_; }
+
     private:
-        std::string script_;
+        std::string sheetName_;
         bool bShowOnLoad_;
-        bool bShowCursor_;
         bool bHidePrevious_;
+        bool bHidePreviousSet_;
+        std::string backgroundImage_;
   };
 }
