Index: code/branches/gamestate/data/gui/scripts/InitialiseGUI.lua
===================================================================
--- code/branches/gamestate/data/gui/scripts/InitialiseGUI.lua	(revision 6630)
+++ code/branches/gamestate/data/gui/scripts/InitialiseGUI.lua	(revision 6658)
@@ -29,67 +29,108 @@
 system:setDefaultTooltip("MenuWidgets/Tooltip")
 
-loadedGUIs = {}
-cursorVisibility = {}
-activeSheets = {}
-nrOfActiveSheets = 0
-root = nil
-bShowsCursor = false
-bHidePrevious = {}
+local loadedSheets = {}
+local activeMenuSheets = {size = 0, topSheet = nil}
+--activeHUDSheets  = {size = 0, topSheet = nil}
+local root = nil
 
 -- Require all tools
 require("GUITools")
 
--- loads the GUI with the specified filename
--- be sure to set the global variable "filename" before calling this function
-function loadGUI(filename)
-    -- check if it already exists
-    loadedGui = loadedGUIs[filename]
-    if loadedGui == nil then
-        loadedGuiNS = require(filename)
-        if loadedGuiNS == nil then
+
+-----------------------
+--- 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)
+        if sheet == nil then
             return
         end
-        loadedGui = loadedGuiNS:load()
-        loadedGUIs[filename] = loadedGui
-        -- if there has no GUI been loaded yet, set new GUI as current
-        if table.getn(loadedGUIs) == 1 then
-            current = loadedGUIs[1]
-        end
-        -- hide new GUI as we do not want to show it accidentially
-        loadedGui:hide()
-    end
-    return loadedGui
-end
-
-function showGUI(filename, hidePrevious, bCursorVisible, ptr)
-    gui = showGUI(filename, hidePrevious, bCursorVisible)
+        sheet:load()
+        loadedSheets[name] = sheet
+        -- Hide new GUI as we do not want to show it accidentally
+        sheet:hide()
+    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
+
+local function find(table, value)
+    for i, v in ipairs(table) do
+        if v == value then
+            return i
+        end
+    end
+    return nil
+end
+
+
+------------------------
+--- Global functions ---
+------------------------
+
+-- ?
+function showGUI(name, bHidePrevious, bShowCursor, ptr)
+    gui = showGUI(name, bHidePrevious, bShowCursor)
     gui.overlay = ptr
 end
 
--- shows the specified GUI sheet and loads it if not loaded already
-function showGUI(filename, hidePrevious, bCursorVisible)
-    if bCursorVisible == nil then
-        if nrOfActiveSheets > 0 then
-            bCursorVisible = cursorVisibility[activeSheets[nrOfActiveSheets]]
+-- Shows the specified menu sheet and loads it if neccessary
+function showGUI(name, bHidePrevious, bShowCursor)
+    -- Handle default value for bShowCursor
+    if bShowCursor == nil then
+        if activeMenuSheets.size > 0 then
+            bShowCursor = activeMenuSheets.topSheet.bShowCursor
         else
-            bCursorVisible = true
-        end
-    end
-
-    if root == nil then
+            bShowCursor = true
+        end
+    end
+
+    -- Hide if already displayed (to make sure it is up front in the end)
+    if activeMenuSheets[name] ~= nil then
+        hideGUI(name)
+    end
+
+    if not root then
         setBackground("")
     end
 
-    local currentGUI = loadedGUIs[filename]
-    if(currentGUI == nil) then
-        currentGUI = loadGUI(filename)
-    end
-
-    if(root:isChild(currentGUI.window)) then
-        root:removeChildWindow(currentGUI.window)
-    end
-    root:addChildWindow(currentGUI.window)
-
-    if bCursorVisible then
+    -- Get sheet (or load it)
+    local menuSheet = loadSheet(name)
+    if not menuSheet then
+        return
+    end
+
+    -- Add sheet to the root window
+    root:addChildWindow(menuSheet.window)
+
+    -- Pause game control if this is the first menu to be displayed
+    -- HUGE HACK?
+    if activeMenuSheets.size == 0 then
+        orxonox.HumanController:pauseControl()
+    end
+
+    -- Handle input distribution
+    orxonox.InputManager:getInstance():enterState(menuSheet.inputState)
+
+    if bShowCursor then
         showCursor()
     else
@@ -97,103 +138,95 @@
     end
 
-    if find( activeSheets, filename ) ~= nil then
-        table.remove( activeSheets, find( activeSheets, filename ) )
-        nrOfActiveSheets = nrOfActiveSheets - 1
-    else
-        if nrOfActiveSheets == 0 then
-            --orxonox.InputManager:getInstance():enterState("guiMouseOnly")
-            orxonox.HumanController:pauseControl()
-        end
-    end
-    orxonox.InputManager:getInstance():enterState(currentGUI.inputState)
-
-    nrOfActiveSheets = nrOfActiveSheets + 1
-    table.insert(activeSheets, filename)
-    activeSheets[nrOfActiveSheets] = filename
-    bHidePrevious[filename]=hidePrevious
-    cursorVisibility[filename] = bCursorVisible
-
-    if hidePrevious == true then
-        for i=1,nrOfActiveSheets-1 do
-            loadedGUIs[ activeSheets[i] ]:hide()
-        end
-    end
-    currentGUI:show()
-    return currentGUI
-end
-
-function hideCursor()
-    if bShowsCursor==true then
-        bShowsCursor=false
-        cursor:hide()
-    end
-end
-
-function showCursor()
-    if bShowsCursor==false then
-        bShowsCursor=true
-        cursor:show()
-    end
-end
-
-function hideGUI(filename)
-    local currentGUI = loadedGUIs[filename]
-    if currentGUI == nil then
+    -- Add the sheet in a tuple of additional information
+    local sheetTuple =
+    {
+        ["menuSheet"]      = menuSheet,
+        ["name"]           = name,
+        ["bShowCursor"]    = bShowCursor,
+        ["bHidePrevious"]  = bHidePrevious
+    }
+    table.insert(activeMenuSheets, sheetTuple) -- indexed array access
+    activeMenuSheets[name] = sheetTuple -- name access
+    activeMenuSheets.size = activeMenuSheets.size + 1
+    activeMenuSheets.topSheet = sheetTuple
+
+    -- Hide all previous sheets if necessary
+    if bHidePrevious then
+        for i = 1, activeMenuSheets.size - 1 do
+            activeMenuSheets[i].menuSheet:hide()
+        end
+    end
+
+    menuSheet:show()
+    return menuSheet
+end
+
+function hideGUI(name)
+    local sheetTuple = activeMenuSheets[name]
+    if sheetTuple == nil then
         return
     end
-    currentGUI:hide()
-    if bHidePrevious[filename] == true then
-        local i = nrOfActiveSheets-1
-        while i>0 do
-            loadedGUIs[ activeSheets[i] ]:show()
-            if bHidePrevious[filename]==true then
-                break
-            else
-                i=i-1
+
+    -- Hide the sheet
+    sheetTuple.menuSheet: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 == false and sheetTuple.bHidePrevious == true
+    while i > 0 do
+        if activeMenuSheets[i].bHidePrevious == true then
+            if activeMenuSheets[i] == sheetTuple then
+                i = i - 1
+                while i > 0 do
+                    activeMenuSheets[i].menuSheet:show()
+                    if activeMenuSheets[i].bHidePrevious == true then
+                        break
+                    end
+                    i = i - 1
+                end
             end
-        end
-    end
-    root:removeChildWindow(currentGUI.window)
-    local i=1
-    while activeSheets[i] do
-        if activeSheets[i+1] == nil then
-            if activeSheets[i-1] ~= nil then
-                if cursorVisibility[ activeSheets[i-1] ] == true then
-                    showCursor()
-                else
-                    hideCursor()
-                end
-            else
-                hideCursor()
-            end
-        end
-        if activeSheets[i] == filename then
-            table.remove( activeSheets, i )
-            nrOfActiveSheets = nrOfActiveSheets-1
-        else
-            i = i+1
-        end
-    end
-    cursorVisibility[filename] = nil -- remove the cursor visibility of the current gui from the table
-    bHidePrevious[filename] = nil
-    if nrOfActiveSheets == 0 then
-        --orxonox.InputManager:getInstance():leaveState("guiMouseOnly")
+            break
+        end
+        i = i - 1
+    end
+
+    -- Remove sheet with its tuple from the table
+    root:removeChildWindow(sheetTuple.menuSheet.window)
+    table.remove(activeMenuSheets, find(activeMenuSheets, sheetTuple))
+    activeMenuSheets[name] = nil
+    activeMenuSheets.size = activeMenuSheets.size - 1
+    activeMenuSheets.topSheet = activeMenuSheets[activeMenuSheets.size]
+
+    -- Leave the input state
+    orxonox.InputManager:getInstance():leaveState(sheetTuple.menuSheet.inputState)
+    
+    -- See whether to show or hide cursor
+    if activeMenuSheets.size > 0 and activeMenuSheets.topSheet.bShowCursor then
+        showCursor()
+    else
+        hideCursor()
+    end
+
+    -- Resume control if the last menu is hidden
+    if activeMenuSheets.size == 0 then
         orxonox.HumanController:resumeControl()
         hideCursor()
     end
-    orxonox.InputManager:getInstance():leaveState(currentGUI.inputState)
-end
-
+end
+
+-- Hides all menu GUI sheets
 function hideAllGUIs()
-    while nrOfActiveSheets ~= 0 do
-        hideGUI(activeSheets[nrOfActiveSheets])
+    while activeMenuSheets.size ~= 0 do
+        hideGUI(activeMenuSheets.topSheet.name)
     end
 end
 
 function keyESC()
-    if nrOfActiveSheets == 1 and activeSheets[1] == "MainMenu" then
+    -- HUGE, very HUGE hacks!
+    if activeMenuSheets.size == 1 and activeMenuSheets[1].name == "MainMenu" then
         orxonox.execute("exit")
-    elseif nrOfActiveSheets > 0 then
-        orxonox.execute("hideGUI "..activeSheets[nrOfActiveSheets])
+    elseif activeMenuSheets.size > 0 then
+        orxonox.execute("hideGUI "..activeMenuSheets.topSheet.name)
     else
         showGUI("InGameMenu")
@@ -201,11 +234,11 @@
 end
 
-function setBackground(filename)
+function setBackground(name)
     local newroot
     if root ~= nil then
         root:rename("oldRootWindow")
     end
-    if filename ~= "" then
-        newroot = winMgr:loadWindowLayout(filename .. ".layout")
+    if name ~= "" then
+        newroot = winMgr:loadWindowLayout(name .. ".layout")
         newroot:rename("AbsoluteRootWindow")
         system:setGUISheet(newroot)
@@ -228,18 +261,2 @@
     root = newroot
 end
-
-function find(table, value)
-    local i=0
-    while table[i] ~= nil do
-        if table[i]==value then
-            return i
-        else
-            i=i+1
-        end
-    end
-    return nil
-end
-
-function test(e)
-    debug(0, "Blubb")
-end
