--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- 
-- Quick Example
--


local rooms = WG.rooms -- availabe in all widgets
local Window = rooms.Window
local Tab = rooms.Tab


window = Window:Create{ -- all arguments have defaults and are optional
  text = "This is automatically word wrapped text",
  -- or lineArray = {"this is the first line", "this is the second"}
  x = 200,
  y = 200,
  closed = true, -- start closed?
  OnClick = function()
    Spring.Echo("I just clicked on the window")
  end,
  tabs = {
    {title="Example window"},
    {preset = Tab:Close()},
    {title = "Do stuff",
      position = "left",
      OnClick = function()
        lineArray[1] = "hi thar"
      end,
    },
  }
}


window:Open()
window:Close()


----------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- 
-- Documentation
--




The main interface component is the window, which is just a rectangular box. It
can contain text, word wrapped if requested. Its background can be a solid
color, a texture or a gradient. Windows can be moved if required. All windows
with the same group argument are moved together. Arbitrary functions can be
called when events like a mouse click take place. Windows can be grouped in
modules called rooms, which are files named "room_*.lua" in the
"LuaUI/Wigets/Rooms" directory. The table WG.rooms provides access to Rooms from
other widgets.


Any number of the second interface component, the tab, can be attached to a
window. Tabs are external buttons. Rooms automatically takes care of placing the
tabs so they don't overlap, and of expanding the window in order to make the
tabs fit. As in windows, tab events can trigger arbitrary function calls.


Internal buttons, panes, images and check boxes can be built by placing smaller
windows on top of the desired window, and using the same group as it (reminder:
windows in the same group move together). That, however, should not be
necessary, as tabs offer similar functionality with less hassle.


 
-- Examples --------------------------------------------------------------------


-- Shadow Detail Window example. The window can be seen in-game from the 
-- "Display Options" menu, accessible from the main menu.


-- Let's call the window construction method:

shadowDetail = Window:Create{
  
  -- All parameters have default values. You can define just the arguments 
  -- you need. See the ProcessArguments functions to see the defaults.
  
  -- Windows in the same group move together, even if they are closed.
  group = "ingameMenu",
  
  -- If "closed" is true, the window starts closed.
  
  closed = true,
  
  -- If a "text" value exists, Rooms word wraps the text with the "textWidth"
  -- parameter as width limit. Newlines are ignored. To input text line by line,
  -- use the "lineArray" parameter.
  -- In this case, the text string is returned by the "shadowDetailText()"
  -- function.
  
  text = shadowDetailText(),
  
  -- Attached tab objects are entered in the "tabs" array.
  tabs = {
  
  -- Tabs with no explicitely defined postition are placed on top of the window.
  -- To make a tab that looks like a window title, just define the title string.
  
    {title = "Shadow Detail"},
    
  -- Let's make a "Close" button on the right. Note: "shadowDetail:Close()" does  
  -- not destroy the window, it just hides it.
  
    {title = "Close",
      position = "right",
      OnClick = function()
        shadowDetail:Close()
      end
    },
  
  -- Let's make a "Back" button. Since we will request it to be on the right, 
  -- Rooms will place it under the other existing tab on the right, the "Close"
  -- button. "displayMenu" is the previous window in this case.
  
    {title = "Back",
      position = "right",
      OnClick = function()
        shadowDetail:Close()
        displayMenu:Open()
      end
    },
    
  -- Now lets make a tab that disables shadows on click. It works just like the
  -- "Back" and "Close" tabs. "shadowDetail.lineArray[1]" is the first line of
  -- the text in the window. The "shadowDetail.lineArray[1]=shadowDetailText()"
  -- line updates it. The change is reflected immediately on the screen.
  
    {title = "Disable Shadows",
      position = "left",
      OnClick = function()
        Spring.SendCommands{"Shadows 0"}
        Spring.SetConfigInt("Shadows", 0)
        shadowDetail.lineArray[1] = shadowDetailText()
      end
    },
    
  -- Let's give a few more options.
  
    {title = "Low Detail Shadows",
      position = "left",
      OnClick = function()
        Spring.SendCommands{"shadows 1 1024"}
        Spring.SetConfigInt("Shadows", 1)
        Spring.SetConfigInt("ShadowMapSize", 1024)
        shadowDetail.lineArray[1] = shadowDetailText()
      end
    },
    {title = "Medium Detail Shadows",
      position = "left",
      OnClick = function()
        Spring.SendCommands{"shadows 1 2048"}
        Spring.SetConfigInt("Shadows", 1)
        Spring.SetConfigInt("ShadowMapSize", 2048)
        shadowDetail.lineArray[1] = shadowDetailText()
      end
    },
    {title = "High Detail Shadows",
      position = "left",
      OnClick = function()
        Spring.SendCommands{"shadows 1 4096"}
        Spring.SetConfigInt("Shadows", 1)
        Spring.SetConfigInt("ShadowMapSize", 4096)
        shadowDetail.lineArray[1] = shadowDetailText()
      end
    },
    
    -- Hurrah, we're done! Wait, let's not forget the outstanding braces.
  }
}

-- Display Menu example. Accessible in-game from the main menu.
-- The previous example involves a lot of repetitive code. In practice, you will
-- use presets for the most common tabs. Presets are accessible through preset
-- functions. See the function reference in the next section for detailed
-- information.

-- Let's make another window:

displayMenu = Window:Create{

-- Same as in the previous example.


  group = "ingameMenu",
  closed = true,
  text = "Todo: LOD scales",
  tabs = {
    {title = white.."Display Options"},
  
  -- Here it befomes interesting. To use a preset, set the "preset" value to a 
  -- preset function. Here we will use the Tab:Close() function. Presets are 
  -- processed after all the other arguments, so using a preset might ovewrite
  -- other arguments for the tab in question.
  
    {preset = Tab:Close()},
    
  -- To use a "Back" button preset, Rooms needs a little more information:
  -- in a table, give it the window you want to go back to as the value
  -- corresponding to "previousWindow". The value needs to be a string
  -- containing the variable name that points to the window, because of a dirty
  -- hack in the implementation.
  
    {preset = Tab:Back{previousWindow = "mainMenu"}},
  
  -- For a "Goto" preset, you need to give the tab title string too. Unlike tabs
  -- and windows, preset functions can have mandatory parameters. See the
  -- function reference for more details.
  
    {preset = 
      Tab:Goto{title="GUI Lines Anti-Aliasing",  destination="smoothLines"}},
    {preset = 
      Tab:Goto{title="GUI Points Anti-Aliasing", destination="smoothPoints"}},
    {preset = 
      Tab:Goto{title="Team Nanospray Color",     destination="teamNanospray"}},
    {preset = 
      Tab:Goto{title="Advanced Unit Shading",    destination="advUnitShading"}},
    {preset = 
      Tab:Goto{title="Water Detail",             destination="waterDetail"}},
    {preset = 
      Tab:Goto{title="Shadow Detail",            destination="shadowDetail"}},
  }
}


-- Function reference ----------------------------------------------------------


function Window:Create(table args) -> table windowObject

function windowObject:Create() -> nil
function windowObject:Open()   -> nil
function windowObject:Close()  -> nil


args = { nil |
  [text = string] -- Automatically word wrapped.
  [lineArray = { [1] = string line, [2] = string line, ... },]
  [textWidth = number,]
  [x = number,]
  [y = number,]
  [x1 = number -- Same as x.,]
  [y1 = number -- Same as y.,]
  [x2 = number,]
  [y2 = number,]
  [noAutoShrink = boolean,]-- Autoshrink reduces the window width if the text is
                           -- narrower than the specified text width.
  [lineSpacing = number,]
  [topMargin = number,]
  [leftMargin = number,]
  [rightMargin = number,]
  [bottomMargin = number,]
  [noBorder = boolean,]
  [borderOffset1 = number,] -- Border offsets determine how much the border
  [borderOffset2 = number,] -- lines protrude.
  [closed = boolean,] -- Starts closed?
  [noMove = boolean,]
  [noAnimation = boolean,]
  [isAboveColors = { -- Window background colors when the cursor is above
                     -- the window.
                     table bottomLeft, = {r, g, b, a}
                     table topLeft,    = {r, g, b, a}
                     table topRight,   = {r, g, b, a}
                     table bottomRight = {r, g, b, a}
                   },]
  [backGroundColor = {r, g, b, a},]
  [gradient = boolean,]
  [bottomLeftColor = {r, g, b, a},]
  [topLeftColor    = {r, g, b, a},]
  [topRightColor   = {r, g, b, a},]
  [bottomLeftColor = {r, g, b, a},]
  [unitPicByName = string,]
  [unitPicByID = number,]
  [backGroundTextureString = string,] -- Same as the gl.Texture parameter.
  [group = string,]  -- All objects in the same group are moved together.
  [OnMousePressAction = function(number button) -> boolean capture,]
  [OnClick = function(number button) -> boolean capture,]
  [OnClick = OnClick,]
  [tabs = table tabs,]
  [OnUnitFinished = function(unitID, unitDefID, unitTeam) -> nil,]
  [OnUnitCreated = function(unitID, unitDefID, unitTeam) -> nil,]
  [GetConfigData = function() -> table data,]
  [SetConfigData = function(table data) -> nil,]
  [OnUpdate = function(number dt, number realSeconds) -> nil,]
  [OnDrawWorld = function() -> nil,]
}

tabs = { nil |

  [1] = {
    [title = string,]
    [offset = number,]
    [rightMargin = number,]
    [leftMargin = number,]
    [topMargin = number,]
    [bottomMargin = number,]
    [border = boolean,]
    [borderOffset1 = number,] -- Border offsets determine how much the border
    [borderOffset2 = number,] -- lines protrude.
    [position = "top" | "bottom" | "left" | "right",]
    [borderColor = {r, g, b, a},]
    [isAboveColors = { -- Tab background colorswhen the cursor is above
                       -- the tab.
                       table bottomLeft, = {r, g, b, a}
                       table topLeft,    = {r, g, b, a}
                       table topRight,   = {r, g, b, a}
                       table bottomRight = {r, g, b, a}
                     },]
    [gradient = boolean,]
    [topLeftColor     = {r, g, b, a},]
    [topRightColor    = {r, g, b, a},]
    [bottomLeftColor  = {r, g, b, a},]
    [bottomRightColor = {r, g, b, a},]
    [backgroundColor  = {r, g, b, a},]
    [borderColor      = {r, g, b, a},]
    [OnMousePressAction = function(number button) -> boolean capture,]
    [OnClick = function(number button) -> boolean capture,]
    [preset =   function Tab:Close
              | function Tab:Goto
              | function Tab:Back
              | function Tab:SetConfigInt
              | function Tab:ConfigEnable
              | function Tab:ConfigDisable,]
  },

  [2] = {...},

  (...)
}

function Tab:Close() -> nil
function Tab:Goto{title = string, destinaton = string}  -> nil
function Tab:Back{previousWindow = string} -> nil
function Tab:SetConfigInt{title = string,
                          config = string,
                          int = number,
                          [text = string]} -> nil
function Tab:ConfigEnable{config = string, [text = string]} -> nil
function Tab:ConfigDisable{config = string, [text = string]} -> nil

function OpenGroup(string group) -> nil
function CloseGroup(string group, boolean openMainButton) -> nil

