/*!
 * \mainpage HOG2 Documentation
 * 
 * \section Welcome  Welcome to HOG2's documentation!
 *
 * HOG2 [Hierarchical Open %Graph 2] is the second iteration of the HOG project
 * which aims to provide users with an testing environment for grid based simulations.
 * HOG2 comprises of a collection of classes and a
 * simulation which are designed as a simple model of RTS or other
 * clocked simulation environments. This page will give a simple
 * overview of how HOG2 works and how to get started using it.
 *
 * If you prefer just to dig into the code and get started,
 * \ref sample.cpp is a sample file showing how to create and
 * customize the simulation, add units, process key commands, and
 * process command-line arguments.
 * 
 * Documentation contents:
 * - \ref Introduction
 *   - \ref Introduction "Introduction"
 *   - \ref Install "Getting Started"
 * - \ref GUI "HOG2 GUI overview"
 * - \ref Development
 * - \ref Code "Included Code"

 */

///////////////////////////////////////////////

/*! \page Introduction Introduction

\section Overview Overview of HOG2's capabilities

HOG2 is a rich environment for deterministic search algorithms. It
supports running search algorithms across a large number of domains,
and also supports simulating agents with domains.

Simulated agents are run in a clock-based simulation. An external program
advances HOG2's simulation clock and displays the current
view of the world. 

\section Install Getting started

To begin using HOG2, first install the dependancies to you machine:

- Ubuntu:@code # apt install build-essential libglu1-mesa-dev freeglut3-dev@endcode
- Debian:@code # apt install git libglu1-mesa-dev freeglut3-dev@endcode
- Arch:@code # pacman -S git base-devel mesa glu freeglut@endcode
- CentOS:@code # yum install git make gcc-c++ mesa-libGL-devel mesa-libGLU-devel freeglut-devel@endcode
- MacOS: Install XCode

then clone the git repo from [github](https://github.com/nathansttt/hog2) with: @code $ git clone https://github.com/nathansttt/hog2.git@endcode

Finally move to the hog2/build/gmake directory and run@code $ make@endcode

One the Mac there are also XCode projects in build/XCode.

If you wish to deploy to the web, you must install emscripten, and then you can build from build/web

Next: \ref Usage
*/

///////////////////////////////////////////////

/*! \page Code Included Code

After the code base has been compiled, there will be a verity of executable binaries that can
be run to see the capabilities of HOG2. These binaries are compiled into @code bin/release/@endcode
and are described below.

\section Apps
- \ref APPS_3D_MAPS "3dmaps" (map3d?)
- \ref APPS_AIRPLANE "airplane"
- \ref APPS_ARM "arm"
- \ref APPS_BIDIRECTIONAL "bidirectional"
- \ref APPS_CANONICAL_GRAPHS "canonicalGraphs" (not compiled)
- \ref APPS_CANONICAL_GRIDS "canonicalGrids"
- \ref APPS_DELTA "delta"
- \ref APPS_DIRECTIONAL "directional" (not compiled)
- \ref APPS_DRAGONAGE "dragonage" (not compiled)
- \ref APPS_EMOTION "emotion" (not compiled)
- \ref APPS_FLING "fling"
- \ref APPS_GA "ga" (not compiled)
- \ref APPS_INCONSISTANCY "inconsistancy" (not compiled)
- \ref APPS_LOCAL_SEARCH "localsearch" (not compiled)
- \ref APPS_LOCAL_SENSING_SEARCH "localsensingsearch"
- \ref APPS_MAPF "MAPF" (not compiled)
- \ref APPS_MAP_UTILS "mapUtils"
- \ref APPS_MULTI_AGENT "multiagent" (not compiled)
- \ref APPS_PATH_SAMPLE "pathsample"
- \ref APPS_PDB "PDB"
- \ref APPS_PREDICTION "prediction" (not compiled)
- \ref APPS_PUZZLE_SAMPLE "puzzlesample"
- \ref APPS_ROADS "roads"
- \ref APPS_RUBIK "rubik"
- \ref APPS_SIMPLE_MOVEMENT "simpleMovement" (not compiled)
- \ref APPS_SNAKEBIRD "snakebird"
- \ref APPS_STP "stp"
- \ref APPS_SUPERVISED_LEARNING "supervisedLearning" (not compiled)
- \ref APPS_TEST "test" (not compiled)
- \ref APPS_TOH "TOH" (not compiled)
- \ref APPS_VOXEL "voxel"
- \ref APPS_WITNESS "witness" (not compiled)

\section Demos
- \ref DEMOS_ASTAR "astar"
- \ref DEMOS_ASTAR_MAP "astar-map" (in web build)
- \ref DEMOS_BB "bb" (in web build)
- \ref DEMOS_BIDIR "bidir" (in web build)
- \ref DEMOS_BIDIR_NECESSARY "bidirnecessary" (in web build)
- \ref DEMOS_CANONICAL_DIJKSTRA "canonical-dijkstra" (in web build)
- \ref DEMOS_CANONICAL_MAPS "canonical-maps" (in web build)
- \ref DEMOS_DFID "DFID"
- \ref DEMOS_DH "dh" (in web build)
- \ref DEMOS_DH_PLACE "dh-place" (in web build)
- \ref DEMOS_DIJKSTRA "dijkstra"
- \ref DEMOS_FASTMAP "fastmap" (in web build)
- \ref DEMOS_GMX "GMX" (in web build)
- \ref DEMOS_GRID_ABSTRACTION "gridabstraction" (in web build)
- \ref DEMOS_ID_ASTAR "idaastar"
- \ref DEMOS_INCONSISTENCY_GRAPH "inconsistency-graph" (in web build)
- \ref DEMOS_JPS "JPS" (in web build)
- \ref DEMOS_KMEANS "kmeans" (in web build)
- \ref DEMOS_MM_GRAPH "mm-graph" (in web build)
- \ref DEMOS_MNIST "mnist" (in web build)
- \ref DEMOS_NBS "nbs" (in web build)
- \ref DEMOS_REACH "reach" (in web build)
- \ref DEMOS_SIMPLE_AGENT "simple-agent" (in web build)
- \ref DEMOS_STP "STP" (in web build)
- \ref DEMOS_SUBOPTIMA_MAP "suboptima-map" (in web build)
- \ref DEMOS_TRANIST_ROUTING_MAPS "transit-routing-maps" (in web build)
- \ref DEMOS_WITNESS "witness" (in web build)
- \ref DEMOS_WITNESS3 "witness3" (in web build)

Prev: \ref Introduction Next: \ref Development 
*/

///////////////////////////////////////////////

/*! \page GUI HOG2 GUI

\section Building a HOG2 app

HOG2 uses an event-based GUI, which is described here.
First you should install handlers for any events that you would like to receive.
Then, you hand control over to HOG2:

int main(int argc, char* argv[])
{
	InstallHandlers();
	RunHOGGUI(argc, argv, 640, 640);
	return 0;
}

\ref createSimulation

\ref initializeKeyboardHandlers

\ref initializeCommandLineHandlers

\subsection CLH Command-Line Handlers

The first thing you need to be concerned with is installing command line handlers.
These handles will allow you to process command-line arguments. By installing
handlers with text descriptions, it is possible to have the application automatically
print help for all command line arguments when it can't process them correctly.

Here is an example of a comand-line handler:

installCommandLineHandler(myCLHandler, "-map", "-map <filename>", "Selects the default map to be loaded.");

A command-line handler looks something like this. It gets a pointer to the current argument list, where
the first argument is the parameter for the handler. The handler then processes as many arguments as
it wants, and returns how many arguments were processed.

int myCLHandler(char *argument[], int maxNumArgs)
{
	if (maxNumArgs <= 1)
		return 0;
	strncpy(gDefaultMap, argument[1], 1024);
	return 2;
}

Multiple handlers can be defined for the same argument. They will each get called in turn (no
order guarantees) until one of the handlers returns a value greater than 0. Given the command-line
arguments, you probably want to use a global variable to store any parameters that were set.

Given proper command-line arguments, you could just allocate your own simulation, run it,
and then exit the program, although you may want to do this in createSimulation, after all
command-line arguments have been handled, unless you can guarantee that a particular command-line
argument will always be last.

\subsection Creating a window

You will be notified when a window is created via the window handler.

void MyWindowHandler(unsigned long windowID, tWindowEventType eType)

You install a window handler using the following code:

InstallWindowHandler(MyWindowHandler);

A window handler receives events (kWindowDestroyed, kWindowCreated) when windows are created
or destroyed, and should setup any variables associated with that window. The windowID is a
unique identifier that is used in other functions to identify that window.

A window handler should typically install a frame handler to be able to draw into the window
each frame.

\subsection Frame Handlers

Frame handlers are used for drawing each frame of the GUI.

InstallFrameHandler(MyFrameHandler, windowID, 0);

A frame handler function looks like this:

void MyFrameHandler(unsigned long windowID, unsigned int viewport, void *)

It is passed the window being drawn, the viewport of the window, and a (void *) which can pass
any data.

You can call GetContext(windowID) to get contextual information about a window. In particular,
a virtual display can be retrieved and drawn into:

Graphics::Display &d = GetContext(windowID)->display;
d.FillRect({-1, -1, 1, 1}, Colors::lightgray);


\subsection KBH Keyboard Handlers

Keyboard handlers are similar to command-line handlers, in that you install any handlers to
allow your application to respond to keyboard events. By installing handlers, the program
can print out all legal key combinations it accepts. \ref initializeKeyboardHandlers might
look something like this:

void initializeKeyboardHandlers()
{
installKeyboardHandler(myDisplayHandler, "Toggle Abstraction", "Toggle display of the ith level of the abstraction", kAnyModifier, '0', '9');
}

In this case, any keys in the range 0..9 will be sent to the function myDisplayHandler, regardless of
any modifier keys that are down. It is important to note that modifier keys such as SHIFT can often
change the ASCII value that is passed to the keyboard handler. Keyboard handlers will be called with
the lowercase equivalent of the key that was pressed, but SHIFT-1 will be reported
as SHIFT-!, and so will not trigger this handler. Here is an example handler which implements
the above functionality.

void myDisplayHandler(unitSimulation *unitSim, tKeyboardModifier mod, char key)
{
  if (unitSim->getMapAbstractionDisplay())
    unitSim->getMapAbstractionDisplay()->toggleDrawAbstraction(((mod == kControlDown)?10:0)+(key-'0'));
}



///////////////////////////////////////////////

/*! \page Development

Note: This is older documentation for simulating agents. It is still accurate, but
a majority of projects involve other environments besides agent-based environments.

\section Units Basic World Objects

There are two basic types of units that can exist in the world, display units
and world units. Display units are drawn into the world, and can be used as
placeholders in the world, but they can never move or do any calculations.
Also, display units do not block other units in the world.
A world unit is the basic type of unit that can move around the world, which
will be described in more detail in the next section.

The unit type is specified from the result returned by the function
\ref getObjectType (No longer exits! TODO: Update).

\subsection U_MOVING Moving in the world

The Unit is the most basic object in the world. At each time step in the world
a unit is asked which direction it wants to move via the function
\ref Unit::MakeMove "MakeMove". For a moment we'll ignore the parameters to \ref Unit::MakeMove "MakeMove", and focus
on the calling conventions. When asked to make a move, a unit must
return the \ref tDirection "direction" it would like to move, one of:
kN, kNE, kE, kSE, kS, kSW, kW, kNW. Additionally, if the unit does not wish
to move, it can return kStay. And, if the unit is allowed to teleport, it
can return kTeleport.

After returing a value from \ref Unit::MakeMove "MakeMove", the unit simulation verifies that the move
is legal, and then calls \ref Unit::UpdateLocation "UpdateLocation" on the unit, informing the unit of its
current location and whether the previous move was successful or not.
If a unit returns kTeleport the simulation will call \ref Unit::GetLocation "GetLocation" on the
unit and move the unit directly to the returned location.

The unit simulation measures the amount of thinking time used by each unit in
both the \ref Unit::MakeMove "MakeMove" and \ref Unit::SetLocation "SetLocation" functions. Details of how these measurements are
used can be found in \ref Simulations.

\subsection PROVIDERS Map and Reservation providers

When a unit is asked to move it is provided with a mapProvider (No longer exists! TODO: Update) and a reservationProvider.
A map provider can return both a map of the world and an abstract map
of the world. The unit can locate itself on the map and use that information to
do any planning in the map world. The maps are not guaranteed to be exact
representations of the world. For instance, if a unit is exploring the world
the map may change as new parts of the world are explored.

Similarly, a reservationProvider can provide information about the other
units in the world and make reservations for paths the unit would like to
travel. But, like the maps, the information provided by the reservation provider
may not be completely accurate. A unit, for instance, may only know about
the other units in his vicinity, or reservations may only be shared by a select
group of units. There is no default implementation for reservations, so
units will always successfully make their reservations.

\subsection UNIT_IMP Provided unit implementations

The file \ref unit.h declares the basic unit class, as well as a few simple
implementations: a teleporting unit, a randomly moving unit, and a unit that
uses the right-hand-rule to walk around the world. (Note that if the right-hand-rule
unit is not next to a wall it will just walk in cicles.)

In the shared directory more one useful unit class is defined: a search unit. The
search unit takes a search algorithm as a parameter. This unit asks the search
algorithm to plan a path for the unit, and then caches the path returned
by the unit, executing it one step at a time in the world.





\section Unit-Groups Shared memory for units


By itself a single unit has only limited usefulness for experiments. In practice
we may want many units to share a view of the world, or to cooperate in building
a map or pathing through the world. Unit groups are the best mechanism for such
needs.

If a unit is part of a unit group, the simulation will ask the unit group to make
a move on behalf of each unit in that group. Usually the simulation will do some
pre-processing on that request, and then ask the unit which move it would like
to make, returning the result to the simulation.

An example would be a group of units that build a map together \ref SharedAMapGroup.
In this example the unit group is responsible for building a localized unit view
of the world based on the global view provided by the simulation. So, each
time a unit moves, the SharedAMapGroup first intervenes to see if the unit has
explored any new territory, and if it has, it updates the local (partially complete)
map in the unitGroup. Then, the unitGroup tells the unit to move, passing itself
as a map provider.

For each step in the unit simulation, a unit group has the chance to do its
own processing via the \ref think function.





\section Simulations Simulating the world

The unitSimulation is in charge of allowing units to move around the world,
enforcing limits on where units can move. The unitSimulation also maintains
the world clock and draws the world when a visual display is needed.

As units and unit groups are created they must be added to the simulation.
Units can optionally be specified as non-blocking when they are added to the
simulation.

The most important function for a unitSimulation is stepTime, where all units
are advanced forward in time by that increment of time. There are many different
simulation options that can be set to provide slightly different simulation
parameters. See the \ref unitSimulation documentation for more details on these.

A unit simulation can be paused. If paused, all calls to stepTime will be
ignored until the simulation is unpaused.



\section Abstractions Spacial abstractions of maps

The point of this document is not to completely explain spacial abstractions,
but to give an overview of how they work. Technical reserach papers are available
which give a more in-depth overview of the concepts involved. See:

http://www.cs.ualberta.ca/~nathanst/papers.html

That being said, map abstractions are used widely within the HOG2 environment.
The \ref mapAbstraction class contains the relevant functions for converting between
map coordinates (getNodeFromMap) and extracting information about the abstractions
available.

The function \ref getAbstractGraph will return an abstract graph at any particular
level of abstraction. At the lowest level of abstraction this is just a connectivity
map of the underlying map, with each node in the graph corresponding to a tile on the
Map, and each edge representing that a unit can travel directly from one tile (node)
to another.

Each node has a set of labels describing the place of that node in the hierarcy of
abstractions. Each label can either be accessed as a LONG value or a FLOATING POINT
value. The labels are as follows:

  kAbstractionLevel (LONG) The level of abstraction in the graph. Level 0 is the original map.

  kNumAbstractedNodes (LONG) The number of nodes abstracted by a particular node. The node ID's of these
                             nodes are stored in kFirstData (1...kNumAbstracted Nodes). At level 0
                             this value will always be 0.

  kParent (LONG) The parent that abstracts this node in the next abstraction level of the graph.

  kTemporaryLabel This label can be used temporarily by any 

  kXCoordinate (private cache) kYCoordinate (private cache) kZCoordinate (private cache)
  kNodeBlocked (currently unused - LONG) kNodeWidth (currently unused - LONG)

  kFirstData (LONG) Other relevant data is stored here. At level 0 you can find the x/y coordinates
                    of the underlying map location here. At other levels you find a list of
                    children. Arbitrary data can be stored in successive ID's, although there is
                    no guarantee it will be preserved if nodes are deleted out of the graph.





\section Memory Memory Management

It is important to use memory effienctly when building simulations that
run over extended periods of time.

Any time an object is added to the unit simulation, the unit simulation
is responsible for freeing that object. This includes, units, unitGroups,
and abstract maps. Maps, which are added to mapAbstractions, will be freed
by the mapAbstraction. Similarly, algorithms added to searchUnits will be freed
by the searchUnit when appropriate.

New code should follow the general guideline that when one object is added to
another, the parent object is in charge of freeing memory for the other object
upon termination. Units and unitGroups are both added to each other, but they
are also both added to the unit simulation, so the simulation is responsible
for deallocating both of these objects.


Prev: \ref Usage
*/

