/*
   This file contains documentation for GG that doesn't fit in the source code.
*/

/** \page design Design
    \section design_purpose Purpose 
    GG is designed to achieve several goals:
    - Platform-independence: GG should be buildable on any platform that supports OpenGL
    - Driver-independence: GG should be a standalone GUI framework that does not require any particular application framework;
    though an SDL driver is supplied, GG should be usable with any driver code the user wishes to supply
    - Easy extensibility: new controls and GUI behavior should be easy to incorporate
    - Complete graphical control for the user/designer: the user should not be limited by the authors' lack of artistic skill!
    - Independence of UI elements from the source code: GG UI elements should be configurable as text files, so that UI design 
    and alteration should not require a recompilation
    - Overall time efficiency: an application with a reasonable number of GG UI elements should not slow down significantly 
    because of the rendering or handling of those elements
    - Overall space efficiency: each GG UI element should have a reasonably small data size
    - Efficient mixture of 2D and 3D graphical elements: it should be appropriate to use GG in any frame-based 3D application, 
    even a realtime 3D video game
    - Simplicity of use: GG UI elements should be able to send arbitrary messages when manipulated by the user; there should be 
    no message passing hierarchy imposed on the user

    \section design_features Features
    GG has the following features and services:
    - Communication of UI controls via signals and slots
    - Support for 2D-, 3D-, and mixed-mode rendering
    - Managment of textures and fonts
    - Serialization of UI elements

    \section nonfeatures Non-Features
    - GG is not fully threadsafe, due to its use of signals and slots
    - No sound support is provided
*/

/** \page building Building GG
    \section building_reqs Requirements
    GG requires GCC 3.2 or later, or MSVC++ 7.1 or later.  Note that both are available for free download.
    <p>
    GG relies on a few other open-source libraries:
    - DevIL 1.6.1 - http://openil.sourceforge.net
    - FreeType 2.1.2 - http://www.freetype.org
    - boost 1.33.1 - http://www.boost.org

    Optional libraries:
    - SDL 1.2.7 - http://www.libsdl.org

    GG's documentation relies on Doxygen (http://www.stack.nl/~dimitri/doxygen). In the GG/doc directory, run Doxygen; the 
    documentation will appear in the GG/doc/html directory.
    <br>

    \section howto_build How To Build GG

    \subsection howto_build_linux Linux
    To build GG, you will need to have SCons installed.  Also, you will need to have first built the buildable portions
    of the boost libraries.  See www.boost.org for details on building boost.  These libraries and all the boost
    includes should be available in your path as well.  You will of course also need to build and make available all of
    the libraries listed in the requirements above.
   
    Once this is done, Linux, Cygwin, and MinGW users can simply type
    \verbatim
      scons
      scons install [as root, if necessary]\endverbatim
    from within the root of the GG directory tree.  Type
    \verbatim
      scons -h\endverbatim
    to see all the options for the build, including specifying nonstandard locations for libraries required by GG, which may 
    be especially useful on Cygwin/MinGW systems.

    \subsection howto_build_win32_gcc Windows (GCC)

    GG works quite well with GCC on Windows, under MinGW or Cygwin, using SCons.  See the SCons documentation for how to
    force SCons to use Cygwin or MinGW on the Windows platform (this will probably only be necessary if you also have
    the MSVC compiler), then refer to the Linux section above.  Also note that the DLLs for all the required libraries
    except the boost libraries can be found on the net pre-compiled.  You can just use the ones for win32/MSVC; since
    they're all C code, there will be no ABI compatibility issues.  You must compile the boost libraries yourself, since
    they are C++ code.

    \subsection howto_build_win32_microsoft Windows (Microsoft C++)

    For those of you who use the Microsoft compiler, SCons will also work from the command line.  You need to install
    SCons and Python, and make sure that python is in your path.  There is also a standalone version of SCons available
    somewhere on the SCons site.  Then you just open up a command prompt window, cd to the root of the GG directory
    tree, and type scons.  I have only been able to get the current version of GG to compile on MSVC++ 8.0, the version
    that comes with .NET 2005.
    <p>There is experimental support for generated MSVC project files.  To enable this, you can uncomment the large
    block of commented-out lines at the end of SConstruct and near the top of build_support.py (all the lines starting
    with "##").  After this, assuming you are using a recent-enough version of SCons, scons --help should give you all
    the instructions you need ot generate MSVC project files.  Note that you can get precompiled MSVC-compatible DLLs
    for many of the required libraries.  DevIL's 1.6.5 pre-compiled library can be substituted for the latest one, if
    there is no pre-compiled version available.
    <p>In order to build the boost libraries, do the following, with the boost zipfile unzipped into your root
    directory:
    - Unzip the boost zipfile into your root directory.
    - Open a "Visual Studio .NET 2003 Command Prompt".
    - Execute:\verbatim
    cd [BOOST_DIR]\tools\build\jam_src
    build.bat
    copy bin.ntx86\bjam.exe ..\..\..\..
    cd ..\..\..\..
    bjam\endverbatim
    <p>
    Finally, note that the solution file is set up to grab all include and library directories rooted at c:\, not just the boost 
    ones.  If you'd like to keep them somewhere else, you'll need to change the project settings.

    \subsection howto_build_macos Macintosh
    It would be nice to have access to a Mac OS X and/or Classic Mac box, to be able to ensure that GG even compiles on such a 
    thing.  Let me know if you have or are interested in testing out a Mac build, or even taking on porting duties.
*/

/** \page architecture Architecture
    \section arch_rendering Rendering Overview
    GG uses OpenGL to render its graphics; it is assumed that the entire GUI is being redrawn multiple times each second.  
    Each GG UI element is draw using calls to OpenGL.  Therefore, each element can be rendered as a pre-rendered pixmap, flat 2D 
    mode graphic, or even a 3D mode rendering; the complexity of the graphics used to represent the UI elements is only limited
    by the target rendering hardware and the user's skill.
    \section arch_UI_overview UI Overview
    \subsection arch_input_events Input Events
    GG is organized as a layer on top of an existing user input framework.  GG has no way of determining that a mouse click, mouse move, 
    or any other user input event, has taken place.  To use GG, one must subclass off of the abstract class GG::GUI, and define several 
    of GG::GUI's pure virtual functions.  These functions poll the underlying operating system or input framework (by default the SDL),
    and generate GG input messages from them.  Such messages are mouse moves and clicks, key presses and releases, joystick movement, 
    etc. GG maintains internal state as to what part of the GUI is being dragged, clicked, etc.
    \subsection arch_UI_overview_example Example:
    Suppose the user clicks 
    the left mouse button at screen position (50, 37).  GG will receive a message from the underlying application framework that a 
    left mouse click has occurred; it then determines what UI element is under that screen location, if any.  If it turns out there is
    a button under that spot, GG sets internal state indicating that the left mouse button is being held down, and that it is over the
    button.  GG then sends a message to the button that it is depressed.  The button sets its own internal state and returns.  All 
    processing is complete for this input; the next time the button is redrawn, it knows to draw itself in a depressed state.  Very
    little computation is involved in processing a single user input event.  GG's performance is therefore usually limited only by the
    application-defined processing that is associated with manipulating the controls (e.g., a button click may trigger disk IO).
   \subsection arch_UI_element_conns UI Element Connections
    GG UI elements are connected using signals and slots, using the boost.signals library implementation.  This allows arbitrary 
    connections between one control and another, and between a control and other code; there is no hierarchy of passed messages 
    as there is in some other GUIs, and there are no unsafe callbacks used.  Refer to the \ref sigs_n_slots documentation for details.
    \subsection arch_gui_services GG::GUI Services
    The singleton GG::GUI object is globally available through a static member function, GG::GUI::GetGUI().  This allows all code
    in the application to rely on GG::GUI for certain essential services.  GUI-specific services include registering windows into
    the GUI, registering windows as always-on-top or modal windows, moving windows up or down in the z-order layers of the GUI,
    removing windows from the GUI, getting mouse state (position and button depression), setting mouse delay repeat (see GG::GUI 
    for a description of this), entering and exiting from an orthographic projection (2D) rendering mode, and creating polymorphic
    GUI elements from XML-formatted text.  Most of these services must be provided by the user when subclassing from GG::GUI; 
    if SDLGUI is used, these services are already implemented.
    <p>
    GG::GUI does a variety of things for the user, some of which are not strictly necessary for the core GUI functionality.  
    GG::GUI provides limited timing info via FPS() and DeltaT().  These are provided to indicate how fast the GUI is rendering, 
    and how long it has been since the last frame was rendered.  There is also a font manager, an application-wide font "pool",
    from which the user can request fonts.  The font pool loads and stores the fonts as needed by the application, and multiple 
    requests for the same font at the same size will result in the creation of only one rendered font object.  A texture manager
    exists which does a similar job with textures.  If the user wants to programmatically create textures, she can also add them
    to the texture pool, provide a name, and request that texture as many times as needed.  OpenGL texture objects are used as
    the underlying texture rendering method.
*/

/** \page sigs_n_slots Signals and Slots
    \section sigs_n_slots_definition Sig-who? Slo-what?
    If you've never been exposed to the signals and slots pattern before, it can be a little confusing.  Simply put, a slot is a
    function or funtion object that is "listening" for a signal.  A slot "listening" to a certain signal is said to be connected 
    to that signal.  When a signal is emitted, all slots that are connected to that signal invoke their function(s)/function 
    object(s).  If a signal is emitted to which no slots are connected, nothing happens.
    \section sigs_n_slots_motivation Motivation for the Signals and Slots Pattern
    \subsection prob The Problem
    Originally, GG used a very simple strategy for passing messages between windows/controls.  The method was to call a
    Command() function, which passed to the callee an integer representing the type of message (button click, scroll, or
    whatever), an ID number associated with the calling control, and a single integer parameter.  It could have been
    made more general and even less typesafe by replacing the int parameter with a void pointer, but in either case it
    suffers from two huge limitations.  First, the type of message and the parameter must be known to both caller and
    callee; this means that, for example, the user must keep track of the integer value representing a button click
    message, and make sure that separate sections of code are using the same value to represent it.  Second, any code
    that doesn't contain a control, but that wants to know about button pushes, scrolling scrollbars, etc., must deal
    with that control's parent (or break encapsulation).  This creates a lot of chains of passed messages, and a large
    number of kludges to get messages to the sections of code that need them.
    \subsection sigs_n_slots_soln The Solution
    Now, each control emits a signal every time a significant event occurs.  If no processing needs to be associated
    with such an event, its signal need not be connected to anything.  Futhermore, no matter how many modules need to
    react to a certain signal, they can all be connected.
    \section sigs_n_slots_use Using Signals and Slots
    \subsection sigs_n_slots_connecting Connecting Signals To Slots
    There are two types of connections between signals and slots.  The first type of connection is between a signal and
    a slot, which may be a functor (which in turn may be a boost::bind object), a free function or a static member
    function or function object.  Just call Connect(sig, slot).  The second type is between a signal and a non-static
    member function.  In this case, the call to Connect() requires a third parameter: a pointer to the object whose
    member function is to be called.  For instance, if I have a class Foo and an object foo1 of class Foo, I cannot call
    foo1.bar() by simply knowing the address of bar().  I need to call Connect(sig, &Foo::bar, &foo1) so that the signal
    knows which object's bar() to call.  Both versions of Connect() return a connection object.  By keeping this
    connection object, you can later disconnect() the connection you made.  In addition, signal-signal connections are
    possible.  Calling Connect(sig1, sig2) forwards all sig1's signal emissions to sig2.  This is provided as a
    convenience to avoid having to write dummy forwarding functions that do this.
    \subsection sigs_n_slots_emitting Emitting Signals
    To emit a signal, just call its () operator, like this: sig();
    \subsection disconnecting Disconnecting Signals and Slots
    If you kept the connection object returned by Connect(), a connection_obj.disconnect() call will disconnect the associated 
    signal and slot.  Also, consider this: what happens if a non-static member function slot and signal are connected, the 
    object owning the slot is destructed, and the signal is emitted?  A segfault, unless the object's class inherits from 
    boost::trackable, which auto-disconnects slots on object destruction.  GG::Wnd is derived from boost::trackable, so all 
    GG::Wnd-derived classes should handle such situations gracefully.  See the boost tutorial below for details.
    \see http://boost.org/doc/html/signals.html for a tutorial on other aspects of signals and slots; you can create 
    connections that have scope, control the order of the invocation of multiple slots that are called by a signal, and combine 
    the return values of such slots (take the first return value, the last, the average of all of them, etc.).
*/

/** \page drag_n_drop Drag and Drop
    \section drag_n_drop_basics Basics
    GG has drag and drop support that allows you to drag any Wnd and drop it onto any other Wnd.  The results of this
    drop depend on the two Wnds involved.  Each Wnd has a DragDropDataType() method that returns a string describing
    what kind of data the Wnd represents.  The string can be a MIME type or any arbitrary string the user likes.  Upon
    the drop, the Wnd receiving the drop has its AcceptDrop() method called, in which it can examine the data type or
    any other relevant aspects of the dropped Wnd and decide whether or not to accept it.  If the receiver accepts, the
    dropped Wnd is removed from its parent, if it has one.  Note that only Wnds with non-empty-string
    DragDropDataType()s may be dragged, and that such Wnds may be, but do not need to be, created with the DRAGABLE
    flag.
    \section drag_n_drop_advanced Advanced Use
    Sometimes it is desirable to have the drop-receiving Wnd emit a signal to which clients may attach slots.  Further,
    it may be desirable to allow the attached client slots to veto the drop.  If this is desired, the recommended means
    of accomplishing this is to follow the pattern of ListBox.  ListBox catches ListBox::DontAcceptDrop exceptions that
    are thrown in slots attached to its DroppedSignal signal.  The signal is emitted after the drop is completed, and if
    DontAcceptDrop is caught, the stack is unwound in two steps.  First, the insertion of the dropped item is rolled
    back, and then the exception is rethrown so that AcceptDrop() can return false.  See the ListBox implementation for
    furhter details.
*/

/** \page serialization Serialization
    \section serialization_motivation Motivation
    One of the main design goals for GG is the editability of UI elements without recompilation.  Another main goal is the 
    capability of saving and restoring the state of the GUI.  A secondary design goal is the capability of serializing UI
    elements for network transmission and receipt.  To satisfy all these requirements, GG uses the boost.serialization 
    library to serialize Wnd-derived objects.
    \section serialization_approach Details
    GG does not contain any actual code that will serialize a Wnd.  Instead, each Wnd subclass contains a serialize() template
    method which may be invoked by user code to perform serialization.  The user must then create a boost serialization
    archive, and save/load the desired windows to/from the archive.  To be serializable, user-created subclasses need to define
    a serialize method that first serializes its base class, then serializes any subclass-specific data; see any Wnd subclass
    for example code.  For full details on how the serialization works, see the serialization tutorial and the
    boost.serialization documentation.
    \section caveats Caveats
    Signals are not currently serializable.  This means that when a class is created from an input serialization
    archive, all its signals must be reconnected to their slots (and any signals connected to it should be reconnected
    as well).  Many of the built-in GG controls must reconnect signals when loaded; such classes have a private
    ConnectSignals() method that is called at load time.  See RadioButtonGroup::serialize() in GGButton.h for an
    example.  Another caveat: Font and Texture objects that were part of the GUI's FontManager and TextureManager when
    saved will not be added back to these two structures when they are loaded.
*/

/** \page tutorials Tutorials
    \section tut_using Using the Tutorials
    The following tutorials are available in the tutorial directory.  You can build them all using SCons.  SCons can be
    found at http://www.scons.org .  An MSVC solution file is also provided.
    \section tut_1 Tutorial 1: Minimal (minimal.cpp)
    This is the minimal interesting GG application, and uses the default input driver, SDL.
    \section tut_2 Tutorial 2: Controls (controls.cpp)
    This builds upon Tutorial 1 by adding one of every type of Control, and connecting some signals and slots.
    \section tut_3 Tutorial 3: Serialization (serialization.cpp)
    This builds upon Tutorial 2 by adding serialization code, and saving and loading all the controls at the start of the app's run.
*/

/** \mainpage GG Documentation Overviews
    \section Overviews
    -# \ref design
    -# \ref architecture
    -# \ref sigs_n_slots
    -# \ref drag_n_drop
    -# \ref serialization
    -# \ref building
    -# \ref tutorials
*/
