Index: orxonox/branches/physics/src/util/garbage_collector.cc
===================================================================
--- orxonox/branches/physics/src/util/garbage_collector.cc	(revision 4283)
+++ orxonox/branches/physics/src/util/garbage_collector.cc	(revision 4283)
@@ -0,0 +1,149 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GARBAGE_COLLECTOR
+
+#include "garbage_collector.h"
+
+#include "world.h"
+#include "world_entity.h"
+#include "null_parent.h"
+
+#include "list.h"
+
+using namespace std;
+
+
+GarbageCollector* GarbageCollector::singletonRef = 0;
+
+/**
+   \brief standard constructor
+   \todo this constructor is not jet implemented - do it
+*/
+GarbageCollector::GarbageCollector () 
+{
+   this->setClassName ("GarbageCollection");
+   this->time = 0;
+   this->delay = 1.5f; /* clean up all 5.0 seconds */
+}
+
+
+/**
+   \brief standard deconstructor
+
+*/
+GarbageCollector::~GarbageCollector () 
+{
+  // delete what has to be deleted here
+}
+
+
+/**
+   \brief this returns the singleton reference this this class
+   \returns singleton reference
+*/
+GarbageCollector* GarbageCollector::getInstance()
+{
+  if( singletonRef == NULL)
+    singletonRef = new GarbageCollector();
+  return singletonRef;
+}
+
+
+/**
+   \brief this sets the collection delay
+   \param delay
+   
+   after this delay, the garbage collector starts its work and begins to collect unused object
+   to delete them afterwards. only objects in the worldentity list from the world object are lookded
+   at. 
+*/
+void GarbageCollector::setCollectionDelay(float delay)
+{
+  this->delay = delay;
+}
+
+
+/**
+   \brief this foreces a garbage collection
+
+   if this function is called, the gc tries to initiate the garbage collection routines. actually
+   this should always work.
+*/
+void GarbageCollector::forceCollection()
+{
+  /* just make the time slitely bigger than the delay */
+  this->time = this->delay + 1;
+  /* and update, to get rid of the unused objects */
+  this->update();
+}
+
+
+/**
+   \brief this ticks the GarbageCollector to give it the time pulse
+   \param the time passed since last tick
+
+   like every other tick function eg. worldentity
+*/
+void GarbageCollector::tick(float time)
+{
+  this->time += time;
+}
+
+
+/**
+   \brief this updated the gargabe collection, if the time is ready
+
+
+*/
+void GarbageCollector::update()
+{
+  if( this->time < this->delay)
+    return;
+  /* garbage collect */
+  PRINTF(3)("=============================\n");
+  PRINTF(3)("Processing Garbage Collection\n");
+  PRINTF(3)("=============================\n");
+  int counter = 0;
+  WorldInterface* wi = WorldInterface::getInstance();
+  tList<WorldEntity>* list = wi->getEntityList();
+
+  tIterator<WorldEntity>* iterator = list->getIterator();
+  WorldEntity* entity = iterator->nextElement();
+  while( entity != NULL) 
+    { 
+      if( entity->isFinalized())
+	{
+	  PRINTF(4)("= finalizing object\n");
+	  ++counter;
+	  
+	  /* first remove out of entity list */
+	  list->remove(entity);
+	  /* second remove out of pnode tree */
+	  entity->remove();
+	  /* then finaly delete reference */
+	  delete entity;
+	}
+      entity = iterator->nextElement();
+    }
+
+  PRINTF(3)("= collected %i unused objects\n", counter);
+  PRINTF(3)("=============================\n");
+
+  /* reset time to count again up to this->delay */
+  this->time = 0;
+}
Index: orxonox/branches/physics/src/util/garbage_collector.h
===================================================================
--- orxonox/branches/physics/src/util/garbage_collector.h	(revision 4283)
+++ orxonox/branches/physics/src/util/garbage_collector.h	(revision 4283)
@@ -0,0 +1,42 @@
+/*! 
+    \file proto_class.h
+    \brief Definition of the proto class template, used quickly start work
+    \todo Example: this shows how to use simply add a Marker that here has to be done something.
+
+    The Protoclass exists, to help you quikly getting the run for how to develop in orxonox.
+    It is an example for the CODING-CONVENTION, and a starting-point for every class.
+*/
+
+#ifndef _GARBAGE_COLLECTOR_H
+#define _GARBAGE_COLLECTOR_H
+
+#include "base_object.h"
+
+
+//! this class maintains the garbage collection.
+/**
+   the class is been ticked by the world.cc and goes through the 
+   world_entity list to clean out all unused entities.
+*/
+class GarbageCollector : public BaseObject {
+
+ public:
+  GarbageCollector();
+  virtual ~GarbageCollector();
+  static GarbageCollector* getInstance();
+
+  void setCollectionDelay(float delay);
+
+  void forceCollection();
+
+  void tick(float time);
+  void update();
+
+ private:
+  static GarbageCollector* singletonRef;
+  float delay;                                        //!< this is the delay to wait until collection
+  float time;                                         //!< the current time
+
+};
+
+#endif /* _GARBAGE_COLLECTOR_H */
Index: orxonox/branches/physics/src/util/loading/factory.cc
===================================================================
--- orxonox/branches/physics/src/util/loading/factory.cc	(revision 4283)
+++ orxonox/branches/physics/src/util/loading/factory.cc	(revision 4283)
@@ -0,0 +1,110 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+*/
+
+
+#include "factory.h"
+#include "game_loader.h"
+
+using namespace std;
+
+/*  --------------------------------------------------
+ *		 Factory
+ *   --------------------------------------------------
+ */
+
+/**
+   \brief constructor
+   
+   set everything to zero and define factoryName
+*/
+Factory::Factory (const char* name)
+{
+  this->factoryName = NULL;
+  this->setFactoryName(name);
+  next = NULL;
+  
+  initialize();
+}
+
+/**
+   \brief destructor
+   
+   clear the Q
+*/
+Factory::~Factory ()
+{
+  //  printf("%s\n", this->factoryName);
+  //  Factory* tmpDel = this->next;
+  //  this->next = NULL;
+  if (this->next)
+    delete this->next;
+}
+
+void Factory::setFactoryName(const char* name)
+{
+  if (factoryName)
+    delete factoryName;
+  factoryName = new char[strlen(name)+1];
+  strcpy(factoryName, name);
+}
+
+
+/**
+   \brief generates the associated object from data
+*/
+BaseObject* Factory::fabricate(const TiXmlElement* data)
+{
+  return NULL;
+}
+
+/**
+   \brief make this particular factory known to the LevelFactory
+*/
+void Factory::initialize()
+{
+  GameLoader* gl = GameLoader::getInstance();
+  gl->registerFactory( this);
+}
+
+/**
+   \brief add a Factory to the Q
+*/
+void Factory::registerFactory( Factory* factory)
+{
+  if( next == NULL) setNext( factory);
+  else next->registerFactory( factory);
+}
+
+const char* grabParameter(const TiXmlElement* root, const char* name)
+{
+  const TiXmlElement* element;
+  const TiXmlNode* node;
+	
+  if (root == NULL)
+    return NULL;
+  assert( name != NULL);
+	
+  element = root->FirstChildElement( name);
+  if( element == NULL) return NULL;
+	
+  node = element->FirstChild();
+  while( node != NULL)
+    {
+      if( node->ToText()) return node->Value();
+      node = node->NextSibling();
+    }
+  return NULL;
+}
+
Index: orxonox/branches/physics/src/util/loading/factory.h
===================================================================
--- orxonox/branches/physics/src/util/loading/factory.h	(revision 4283)
+++ orxonox/branches/physics/src/util/loading/factory.h	(revision 4283)
@@ -0,0 +1,95 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+*/
+
+/*! 
+  \file factory.h
+  \brief philosophy stuff
+*/
+
+
+#ifndef _FACTORY_H
+#define _FACTORY_H
+
+class BaseObject;
+
+#include "tinyxml.h"
+#include "load_param.h"
+#include "debug.h"
+
+/** 
+    Creates a factory to a Loadable Class.
+    this should be used at the beginning of all the Classes that should be loadable (in the cc-file)
+*/
+#define CREATE_FACTORY(CLASS_NAME) tFactory<CLASS_NAME>* global_##CLASS_NAME##Factory = new tFactory<CLASS_NAME>(#CLASS_NAME)		
+//! The Factory is
+class Factory {
+
+ public:
+  Factory (const char* name = NULL);
+  ~Factory ();
+  
+
+  virtual BaseObject* fabricate(const TiXmlElement* root);
+  void initialize();
+  void registerFactory( Factory* factory);
+  void setFactoryName(const char* name);
+  const char* getFactoryName() {return factoryName;};
+  void setNext( Factory* factory) {next = factory;}
+  Factory* getNext() {return next;}
+	
+ private:
+  char* factoryName;
+	
+  Factory* next;
+};
+
+template<class T> class tFactory : public Factory
+{
+ public:
+  tFactory(const char* name);
+  virtual ~tFactory();
+  
+  private:
+  BaseObject* fabricate(const TiXmlElement* root);
+};
+
+template<class T>
+tFactory<T>::tFactory(const char* name) : Factory(name)
+{
+  PRINTF(5)("fileName: %s\n", name);
+}
+  
+
+template<class T>
+tFactory<T>::~tFactory()
+{}
+
+template<class T>
+BaseObject* tFactory<T>::fabricate(const TiXmlElement* root) 
+{ 
+  if(!strcmp(root->Value(), getFactoryName()))
+    return new T ( root);
+  else if( getNext() != NULL) 
+    return getNext()->fabricate( root);
+  else 
+    return NULL;
+}
+
+// helper function
+
+const char* grabParameter(const TiXmlElement* root, const char* name);
+
+#endif /* _FACTORY_H */
+
Index: orxonox/branches/physics/src/util/loading/game_loader.cc
===================================================================
--- orxonox/branches/physics/src/util/loading/game_loader.cc	(revision 4283)
+++ orxonox/branches/physics/src/util/loading/game_loader.cc	(revision 4283)
@@ -0,0 +1,318 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#include "game_loader.h"
+#include "campaign.h"
+#include "world.h"
+#include "player.h"
+#include "orxonox.h"
+#include "camera.h"
+#include "command_node.h"
+#include "vector.h"
+#include "resource_manager.h"
+#include "factory.h"
+
+#include <string.h>
+
+
+using namespace std;
+
+
+GameLoader* GameLoader::singletonRef = 0;
+
+
+GameLoader::GameLoader () 
+{
+  first = NULL;
+}
+
+
+GameLoader::~GameLoader () {}
+
+
+/**
+   \brief this class is a singleton class
+   \returns an instance of itself
+
+   if you are unsure about singleton classes, check the theory out on the internet :)
+*/
+GameLoader* GameLoader::getInstance()
+{
+  if(singletonRef == NULL)
+    singletonRef = new GameLoader();
+  return singletonRef;
+}
+
+
+ErrorMessage GameLoader::init()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->init();
+}
+
+
+/**
+   \brief reads a campaign definition file into a campaign class
+   \param filename to be loaded
+   \returns the loaded campaign
+
+   this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
+*/
+ErrorMessage GameLoader::loadCampaign(const char* name)
+{
+  ErrorMessage errorCode;
+  char* campaignName = ResourceManager::getFullName(name);
+  if (campaignName)
+    {
+      this->currentCampaign = this->fileToCampaign(campaignName);
+      delete campaignName;
+    }
+}
+
+/**
+   \brief loads a debug campaign for test purposes only.
+   \param the identifier of the campaign.
+   \returns error message if not able to do so.
+*/
+ErrorMessage GameLoader::loadDebugCampaign(Uint32 campaignID)
+{
+  switch(campaignID)
+    {
+      /* 
+	 Debug Level 0: Debug level used to test the base frame work.
+	 As you can see, all storyentity data is allocated before game
+	 start. the storyentity will load themselfs shortly before start
+	 through the StoryEntity::init() funtion.
+      */
+    case DEBUG_CAMPAIGN_0:
+      {
+	Campaign* debugCampaign = new Campaign();
+
+	World* world0 = new World(DEBUG_WORLD_0);
+	world0->setNextStoryID(WORLD_ID_1);
+	debugCampaign->addEntity(world0, WORLD_ID_0);
+
+	World* world1 = new World(DEBUG_WORLD_1);
+	world1->setNextStoryID(WORLD_ID_2);
+	debugCampaign->addEntity(world1, WORLD_ID_1);
+
+	World* world2 = new World(DEBUG_WORLD_2);
+	world2->setNextStoryID(WORLD_ID_GAMEEND);
+	debugCampaign->addEntity(world2, WORLD_ID_2);
+
+	this->currentCampaign = debugCampaign;
+	break;
+      }
+    }
+}
+
+ErrorMessage GameLoader::start()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->start();
+}
+
+
+ErrorMessage GameLoader::stop()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->stop();
+  this->currentCampaign = NULL;
+}
+
+
+ErrorMessage GameLoader::pause()
+{
+  this->isPaused = true;
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->pause();
+}
+
+
+ErrorMessage GameLoader::resume()
+{
+  this->isPaused = false;
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->resume();
+}
+
+/**
+   \brief release the mem
+ */
+ErrorMessage GameLoader::destroy()
+{}
+
+
+/**
+   \brief reads a campaign definition file into a campaign class
+   \param filename to be loaded
+   \returns the loaded campaign
+
+   this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
+*/
+Campaign* GameLoader::fileToCampaign(const char *name)
+{
+  /* do not entirely load the campaign. just the current world
+     before start of each world, it has to be initialized so it
+     can load everything it needs into memory then.
+  */
+  
+  if( name == NULL)
+    {
+      PRINTF(2)("No filename specified for loading");
+      return NULL;
+    }
+  
+  TiXmlDocument* XMLDoc = new TiXmlDocument( name);
+  // load the campaign document
+  if( !XMLDoc->LoadFile())
+    {
+      // report an error
+      PRINTF(1)("Could not load XML File %s: %s @ %d:%d\n", name, XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
+      delete XMLDoc;
+      return NULL;
+    }
+	
+  // check basic validity
+  TiXmlElement* root = XMLDoc->RootElement();
+  assert( root != NULL);
+	
+  if( strcmp( root->Value(), "Campaign"))
+    {
+      // report an error
+      PRINTF(2)("Specified XML File is not an orxonox campaign file (Campaign element missing)\n");
+      delete XMLDoc;
+      return NULL;
+    }
+	
+  // construct campaign
+  Campaign* c = new Campaign( root);
+	
+  // free the XML data
+  delete XMLDoc;
+	
+  return c;
+}
+
+
+/**
+   \brief handle keyboard commands 
+   \param cmd: the command to handle
+   \returns true if the command was handled by the system
+*/
+bool GameLoader::worldCommand (Command* cmd)
+{
+  if( !strcmp( cmd->cmd, CONFIG_NAME_NEXT_WORLD))
+    {
+      if( !cmd->bUp) 
+	{
+	  this->nextLevel();
+	}
+      return true;
+    }
+  else if( !strcmp( cmd->cmd, CONFIG_NAME_PREV_WORLD))
+    {
+      if( !cmd->bUp)
+	{
+	  this->previousLevel();
+	}
+      return true;
+    }
+  else if( !strcmp( cmd->cmd, CONFIG_NAME_PAUSE))
+    {
+      if( !cmd->bUp)
+	{
+	  if(this->isPaused)
+	    this->resume();
+	  else
+	    this->pause();
+	}
+      return true;
+    }
+  else if( !strcmp( cmd->cmd, CONFIG_NAME_QUIT))
+    {
+      if( !cmd->bUp) this->stop();
+      return true;
+    }
+  return false;
+}
+
+
+/*
+  \brief this changes to the next level
+*/
+void GameLoader::nextLevel()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->nextLevel();
+}
+
+
+/*
+  \brief change to the previous level - not implemented
+
+  this propably useless
+*/
+void GameLoader::previousLevel()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->previousLevel();
+}
+
+/**
+   \brief add a Factory to the Factory Q
+   \param factory a Factory to be registered
+*/
+void GameLoader::registerFactory( Factory* factory)
+{
+	assert( factory != NULL);
+	
+	PRINTF(4)("Registered factory for '%s'\n", factory->getFactoryName());
+	
+	if( first == NULL) first = factory;
+	else first->registerFactory( factory);
+}
+
+/**
+   \brief load a StoryEntity
+   \param element a XMLElement containing all the needed info
+*/
+BaseObject* GameLoader::fabricate( TiXmlElement* element)
+{
+  assert( element != NULL);
+	
+  if( first == NULL)
+    {
+      PRINTF(1)("GameLoader does not know any factories, fabricate() failed\n");
+      return NULL;
+    }
+	
+  if( element->Value() != NULL)
+    {
+      PRINTF(4)("Attempting fabrication of a '%s'\n", element->Value());
+      BaseObject* b = first->fabricate( element);
+      if( b == NULL) 
+	PRINTF(2)("Failed to fabricate a '%s'\n", element->Value());
+      else 
+	PRINTF(4)("Successfully fabricated a '%s'\n", element->Value());
+      return b;
+    }
+	
+  PRINTF(2)("Fabricate failed, TiXmlElement did not contain a value\n");
+	
+  return NULL;
+}
Index: orxonox/branches/physics/src/util/loading/game_loader.h
===================================================================
--- orxonox/branches/physics/src/util/loading/game_loader.h	(revision 4283)
+++ orxonox/branches/physics/src/util/loading/game_loader.h	(revision 4283)
@@ -0,0 +1,74 @@
+/*! 
+    \file game_loader.h
+    \brief loads campaigns, worlds and all other story_entities
+*/ 
+
+#ifndef _GAME_LOADER_H
+#define _GAME_LOADER_H
+
+//#include "stdincl.h"
+#include "story_def.h"
+#include "comincl.h"
+
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class Campaign;
+class World;
+class Camera;
+class CammandNode;
+class Factory;
+class TiXmlElement;
+class BaseObject;
+
+//! The GameLoader
+/**
+   The game loader loads all game date. this is performed in the following way:
+   1. Read the structure of campaings and worlds
+   2. Create the instances of the tree: here _ALL_ StoryEntities are created
+      also if they are not yet used. the worlds should load their data in
+      the StoryEntity::load() and StoryEntity::init() functions! NOWHERE ELSE!
+      Elsewhere, all the data will be allocated at the beginning... mess...
+   3. StoryEntities are load() and init() before they start
+   4. once the gamloader starts the game there will be a campaing starting a
+      world. this is done by callaing those StoryEntity::start()
+*/
+class GameLoader 
+{
+
+ public:
+  static GameLoader* getInstance();
+
+  ErrorMessage init();
+  ErrorMessage loadCampaign(const char* name);
+  ErrorMessage start();
+  ErrorMessage stop();
+  ErrorMessage pause();
+  ErrorMessage resume();
+  ErrorMessage destroy();
+
+  void nextLevel();
+  void previousLevel();
+
+  bool worldCommand(Command* cmd);
+  ErrorMessage loadDebugCampaign(Uint32 campaignID);
+  
+  void registerFactory( Factory* factory);
+  BaseObject* fabricate( TiXmlElement* data);
+
+ private:
+  GameLoader ();
+  ~GameLoader ();
+  Uint32 startTime; //!> start time of the campaign
+  static GameLoader* singletonRef;
+  bool isPaused;
+
+  Campaign* currentCampaign; //!> the current campaign playing
+  
+  Campaign* fileToCampaign(const char* name);
+
+  Factory* first;
+};
+
+#endif /* _GAME_LOADER_H */
Index: orxonox/branches/physics/src/util/loading/load_param.cc
===================================================================
--- orxonox/branches/physics/src/util/loading/load_param.cc	(revision 4283)
+++ orxonox/branches/physics/src/util/loading/load_param.cc	(revision 4283)
@@ -0,0 +1,234 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+#include "load_param.h"
+
+#include "list.h"
+#include "base_object.h"
+
+#include <stdarg.h>
+
+/**
+   \param object The object this Parameter is loaded too.
+   \param paramName The name of the parameter loaded.
+   \param paramCount how many parameters this loading-function takes
+   \param ... the parameter information
+*/
+BaseLoadParam::BaseLoadParam(BaseObject* object, const char* paramName, int paramCount, ...)
+{
+  this->paramDesc = NULL;
+  if (LoadClassDescription::parametersDescription)
+    {
+      // locating the class
+      this->classDesc = LoadClassDescription::addClass(object->getClassName());
+      this->paramDesc = this->classDesc->addParam(paramName);
+
+      this->paramDesc->types = new char*[paramCount];
+      this->paramDesc->paramCount = paramCount;
+
+      va_list types;
+      va_start (types, paramCount);
+      for(int i = 0; i < paramCount; i++)
+	{
+	  const char* tmpTypeName = va_arg (types, const char*);
+	  this->paramDesc->types[i] = new char[strlen(tmpTypeName)+1];
+	  strcpy(this->paramDesc->types[i], tmpTypeName);
+	}
+      va_end(types);  
+
+      int argCount = 0;
+    }
+}
+
+/**
+   \param descriptionText The text to set as a description for this Parameter
+   \returns a pointer to itself.
+*/
+BaseLoadParam* BaseLoadParam::describe(const char* descriptionText)
+{
+  if (LoadClassDescription::parametersDescription && this->paramDesc && !this->paramDesc->getDescription())
+    {
+      this->paramDesc->setDescription(descriptionText);
+    }
+  return this;
+}
+
+/**
+   \param paramName the name of the parameter to load
+*/
+LoadParamDescription::LoadParamDescription(const char* paramName)
+{
+  this->types = NULL;
+  this->description = NULL;
+  this->paramName = new char[strlen(paramName)+1];
+  strcpy(this->paramName, paramName);
+}
+
+/**
+   \brief removes all the alocated memory
+*/
+LoadParamDescription::~LoadParamDescription(void)
+{
+  for(int i = 0; i < this->paramCount; i++)
+    {
+      delete this->types[i];
+    }
+  delete []this->types;
+  delete []this->paramName;
+  delete []this->description;
+}
+
+/**
+   \param descriptionText The text to set as a description for this Parameter
+*/
+void LoadParamDescription::setDescription(const char* descriptionText)
+{
+  this->description = new char[strlen(descriptionText)+1];
+  strcpy(this->description, descriptionText);
+}
+
+/**
+   \brief prints out this parameter, its input method and the description (if availiable)
+*/
+void LoadParamDescription::print(void) const
+{
+  PRINT(3)(" <%s>", this->paramName);
+  for (int i = 0; i < this->paramCount; i++)
+    {
+      if (i > 0)
+	PRINT(3)(",");
+      PRINT(3)("%s", this->types[i]);
+    }
+  PRINT(3)("</%s>", this->paramName);
+  if (this->description)
+    PRINT(3)(" -- %s", this->description);
+  PRINT(3)("\n");
+}
+
+/**
+   \brief A list, that holds all the classes that are loadable (classes not objects!!)
+*/
+tList<LoadClassDescription>* LoadClassDescription::classList = new tList<LoadClassDescription>;
+
+/**
+   \brief if the description of Parameters should be executed
+*/
+bool LoadClassDescription::parametersDescription = true;
+
+/**
+   \param className the name of the class to be loadable
+*/
+LoadClassDescription::LoadClassDescription(const char* className)
+{
+  this->className = new char[strlen(className)+1];
+  strcpy(this->className, className);
+
+  classList->add(this);
+
+  this->paramList = new tList<LoadParamDescription>;
+}
+
+/**
+   \brief deletes a classDescription (deletes all the parameterDescriptions as well
+*/
+LoadClassDescription::~LoadClassDescription(void)
+{
+  delete []this->className;
+
+  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
+  LoadParamDescription* enumParamDesc = iterator->nextElement();
+  while (enumParamDesc)
+    {
+      delete enumParamDesc;
+      enumParamDesc = iterator->nextElement();
+    }
+  delete iterator;
+}
+
+/**
+   \brief adds a class to the list of loadable classes
+   \param className The name of the class to add
+
+   this function searches for the className string, and if found just returns the appropriate Class.
+   Otherwise it returns a new classDescription
+*/
+LoadClassDescription* LoadClassDescription::addClass(const char* className)
+{
+  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
+  LoadClassDescription* enumClassDesc = iterator->nextElement();
+  while (enumClassDesc)
+    {
+      if (!strcmp(enumClassDesc->className, className))
+	{
+	  delete iterator;
+	  return enumClassDesc;
+	}
+      enumClassDesc = iterator->nextElement();
+    }
+  delete iterator;
+
+  return new LoadClassDescription(className);
+}
+
+/**
+   \brief does the same as addClass(const char* className), but with params
+   \param paramName the name of the parameter to add.
+*/
+LoadParamDescription* LoadClassDescription::addParam(const char* paramName)
+{
+  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
+  LoadParamDescription* enumParamDesc = iterator->nextElement();
+  while (enumParamDesc)
+    {
+      if (!strcmp(enumParamDesc->paramName, paramName))
+	{
+	  delete iterator;
+	  return enumParamDesc;
+	}
+      enumParamDesc = iterator->nextElement();
+    }
+  delete iterator;
+
+  this->paramList->add(new LoadParamDescription(paramName));
+  return paramList->lastElement();
+}
+
+/**
+   \brief prints out all loadable Classes, and their parameters
+*/
+void LoadClassDescription::printAll(const char* fileName)
+{
+  PRINT(3)("===============================================================\n");
+  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
+  tIterator<LoadClassDescription>* classIT = LoadClassDescription::classList->getIterator();
+  LoadClassDescription* enumClassDesc = classIT->nextElement();
+  while (enumClassDesc)
+    {
+      PRINT(3)("<%s>\n", enumClassDesc->className);
+      tIterator<LoadParamDescription>* paramIT = enumClassDesc->paramList->getIterator();
+      LoadParamDescription* enumParamDesc = paramIT->nextElement();
+      while (enumParamDesc)
+	{
+	  enumParamDesc->print();
+	  enumParamDesc = paramIT->nextElement();
+	}
+      delete paramIT;
+
+      PRINT(3)("</%s>\n\n", enumClassDesc->className);
+      enumClassDesc = classIT->nextElement();
+    }
+  delete classIT;
+  PRINT(3)("===============================================================\n");
+}
Index: orxonox/branches/physics/src/util/loading/load_param.h
===================================================================
--- orxonox/branches/physics/src/util/loading/load_param.h	(revision 4283)
+++ orxonox/branches/physics/src/util/loading/load_param.h	(revision 4283)
@@ -0,0 +1,233 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*! 
+    \file load_param.h
+    \brief A Class and macro-functions, that makes our lives easy to load-in parameters
+*/
+
+#ifndef _LOAD_PARAM_H
+#define _LOAD_PARAM_H
+
+#include "factory.h"
+#include "debug.h"
+#include "substring.h"
+
+// Forward Declaration //
+template<class T> class tList;
+
+/**
+   useable FunctionParameters are:
+   l_INT:    int
+   l_LONG:   long
+   l_SHORT:  short
+   l_FLOAT:  float
+   l_STRING: const char*
+*/
+
+#define l_INT_TYPE int
+#define l_INT_FUNC atoi
+#define l_INT_NAME "int"
+
+#define l_LONG_TYPE long
+#define l_LONG_FUNC atol
+#define l_LONG_NAME "long"
+
+#define l_SHORT_TYPE short
+#define l_SHORT_FUNC atoi
+#define l_SHORT_NAME "short"
+
+#define l_FLOAT_TYPE float
+#define l_FLOAT_FUNC atof
+#define l_FLOAT_NAME "float"
+
+#define l_STRING_TYPE const char*
+#define l_STRING_FUNC
+#define l_STRING_NAME "string"
+
+
+/**
+   \brief a Macro to easily implement many different Constructors for the LoadParam-Class
+   \param type1 The type of the first functionParameter
+*/
+#define LoadParam1(type1) \
+ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE)) \
+  : BaseLoadParam(pt2Object, paramName, 1, type1##_NAME) \
+    { \
+      const char* loadString = grabParameter(root, paramName); \
+      if (loadString != NULL && root != NULL) \
+	(*pt2Object.*function)(type1##_FUNC(loadString)); \
+      else \
+	PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
+    }
+
+
+// 2. TYPES
+#define LoadParam2(type1, type2) \
+ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE)) \
+  : BaseLoadParam(pt2Object, paramName, 2, type1##_NAME, type2##_NAME) \
+    { \
+      const char* loadString = grabParameter(root, paramName); \
+      if (loadString != NULL && root != NULL) \
+	{ \
+	  SubString subLoads(loadString); \
+	  if (subLoads.getCount() == 2) \
+	    (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1))); \
+	  else \
+	    PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
+		      paramName, pt2Object->getClassName(), 2, subLoads.getCount()); \
+	} \
+      else \
+	PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
+    }
+
+
+// 3. TYPES
+#define LoadParam3(type1, type2, type3) \
+ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE))\
+  : BaseLoadParam(pt2Object, paramName, 3, type1##_NAME, type2##_NAME, type3##_NAME) \
+    { \
+      const char* loadString = grabParameter(root, paramName); \
+      if (loadString != NULL && root != NULL) \
+	{ \
+	  SubString subLoads(loadString); \
+	  if (subLoads.getCount() == 3) \
+	    (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1)), type3##_FUNC(subLoads.getString(2))); \
+	  else \
+	    PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
+		      paramName, pt2Object->getClassName(), 3, subLoads.getCount()); \
+	} \
+      else \
+	PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
+    }
+
+
+// 4. TYPES
+#define LoadParam4(type1, type2, type3, type4) \
+ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE, type4##_TYPE)) \
+  : BaseLoadParam(pt2Object, paramName, 4, type1##_NAME, type2##_NAME, type3##_NAME, type2##_NAME, type4##_NAME) \
+    { \
+      const char* loadString = grabParameter(root, paramName); \
+      if (loadString != NULL && root != NULL) \
+	{ \
+	  SubString subLoads(loadString); \
+	  if (subLoads.getCount() == 4) \
+	    (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1)), type3##_FUNC(subLoads.getString(2)), type4##_FUNC(subLoads.getString(3))); \
+	  else \
+	    PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
+		      paramName, pt2Object->getClassName(), 4, subLoads.getCount()); \
+	} \
+      else \
+	PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
+    }
+
+
+// 5. TYPES
+#define LoadParam5(type1, type2, type3, type4, type5) \
+ LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE, type4##_TYPE, type5##_TYPE)) \
+  : BaseLoadParam(pt2Object, paramName, 5, type1##_NAME, type2##_NAME, type3##_NAME, type2##_NAME, type4##_NAME, type5##_NAME) \
+    { \
+      const char* loadString = grabParameter(root, paramName); \
+      if (loadString != NULL && root != NULL) \
+	{ \
+	  SubString subLoads(loadString); \
+	  if (subLoads.getCount() == 5) \
+	    (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1)), type3##_FUNC(subLoads.getString(2)), type4##_FUNC(subLoads.getString(3)), type5##_FUNC(subLoads.getString(4))); \
+	  else \
+	    PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
+		      paramName, pt2Object->getClassName(), 5, subLoads.getCount()); \
+	} \
+      else \
+	PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
+    }
+
+
+//! A class that handles the description of loadable parameters
+class LoadParamDescription
+{
+  friend class BaseLoadParam;
+  friend class LoadClassDescription;
+ public:
+  LoadParamDescription(const char* paramName);
+  ~LoadParamDescription(void);
+
+  void setDescription(const char* descriptionText);
+  /** \returns the descriptionString */
+  const char* getDescription(void) { return this->description;};
+
+  void print(void) const;
+ private:
+  char* paramName;              //!< The name of the parameter
+  int paramCount;               //!< The count of parameters
+  char** types;                 //!< What kind of parameters does this function take ??
+  char* description;            //!< A longer description about this function
+};
+
+class LoadClassDescription
+{
+  friend class BaseLoadParam;
+ public:
+  LoadClassDescription(const char* className);
+  ~LoadClassDescription(void);
+
+  static LoadClassDescription* addClass(const char* className);
+  LoadParamDescription* addParam(const char* paramName);
+
+  static void printAll(const char* fileName = NULL);
+
+  static bool parametersDescription;             //!< if parameter-description should be enabled.
+  static tList<LoadClassDescription>* classList; //!< a list, that holds all the loadable classes. (after one instance has been loaded)
+ private:
+  char* className;                               //!< name of the class
+  tList<LoadParamDescription>* paramList;        //!< List of parameters this class knows.
+};
+
+// abstract Base class
+class BaseLoadParam
+{
+ public:
+  BaseLoadParam* describe(const char* descriptionText);
+
+ protected:
+  BaseLoadParam(BaseObject* object, const char* paramName, int paramCount, ...);
+
+ protected:
+  LoadClassDescription* classDesc;               //!< The LoadClassDescription of this LoadParameter
+  LoadParamDescription* paramDesc;               //!< The LoadParameterDescription of this LoadParameter
+};
+
+
+//! derived template class, so all the Classes can load something.
+template<class T> class LoadParam : public BaseLoadParam
+{
+ public:
+  LoadParam1(l_STRING);
+  LoadParam2(l_STRING, l_STRING);
+  LoadParam3(l_STRING, l_STRING, l_STRING);
+  LoadParam4(l_STRING, l_STRING, l_STRING, l_STRING);
+
+  LoadParam1(l_INT);
+  LoadParam2(l_INT, l_INT);
+  LoadParam3(l_INT, l_INT, l_INT);
+  LoadParam4(l_INT, l_INT, l_INT, l_INT);
+
+  LoadParam1(l_FLOAT);
+  LoadParam2(l_FLOAT, l_FLOAT);
+  LoadParam3(l_FLOAT, l_FLOAT, l_FLOAT);
+  LoadParam4(l_FLOAT, l_FLOAT, l_FLOAT, l_FLOAT);
+};
+
+
+#endif /* _LOAD_PARAM_H */
Index: orxonox/branches/physics/src/util/object_manager.cc
===================================================================
--- orxonox/branches/physics/src/util/object_manager.cc	(revision 4283)
+++ orxonox/branches/physics/src/util/object_manager.cc	(revision 4283)
@@ -0,0 +1,55 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_OBJECT_MANAGER
+
+#include "object_manager.h"
+
+using namespace std;
+
+
+/**
+   \brief standard constructor
+*/
+ObjectManager::ObjectManager () 
+{
+   this->setClassName ("ObjectManager");
+
+}
+
+/**
+   \brief the singleton reference to this class
+*/
+ObjectManager* ObjectManager::singletonRef = NULL;
+
+/**
+   \returns a Pointer to this Class
+*/
+ObjectManager* ObjectManager::getInstance(void)
+{
+  if (!ObjectManager::singletonRef)
+    ObjectManager::singletonRef = new ObjectManager();
+  return ObjectManager::singletonRef;
+}
+
+/**
+   \brief standard deconstructor
+
+*/
+ObjectManager::~ObjectManager () 
+{
+  ObjectManager::singletonRef = NULL;
+
+}
Index: orxonox/branches/physics/src/util/object_manager.h
===================================================================
--- orxonox/branches/physics/src/util/object_manager.h	(revision 4283)
+++ orxonox/branches/physics/src/util/object_manager.h	(revision 4283)
@@ -0,0 +1,43 @@
+/*! 
+    \file object_manager.h
+    \brief this manager will ceep track of the objects  in the world
+    
+    This is specially designed to:
+    - Give an interface to the world data
+    - separate the world data from the world build,update,draw process
+    - recycle deleted objects: specific for Projectils since there is a lot of world entity creation/deletion (and this needs a lot of time)
+    - control the garbage collector
+*/
+
+
+#ifndef _OBJECT_MANAGER_H
+#define _OBJECT_MANAGER_H
+
+#include "base_object.h"
+
+#define OM_
+
+class WorldEntity;
+
+
+template<class T> class tList; 
+
+//! the object manager itself
+class ObjectManager : public BaseObject {
+
+ public:
+  static ObjectManager* getInstance(void);
+  virtual ~ObjectManager(void);
+
+  void preLoad();
+
+ private:
+  ObjectManager(void);
+  static ObjectManager* singletonRef;
+
+  tList<WorldEntity>* projectileBuffer;            //!< a list of projectiles that is generated at the beginning to make orx faster
+
+
+};
+
+#endif /* _OBJECT_MANAGER_H */
Index: orxonox/branches/physics/src/util/track/track_manager.cc
===================================================================
--- orxonox/branches/physics/src/util/track/track_manager.cc	(revision 4283)
+++ orxonox/branches/physics/src/util/track/track_manager.cc	(revision 4283)
@@ -0,0 +1,1210 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_TRACK_MANAGER
+
+#include "track_manager.h"
+
+#include "base_object.h"
+#include "p_node.h"
+#include "track_node.h"
+#include "stdincl.h"
+#include "list.h"
+#include "text_engine.h"
+#include "t_animation.h"
+#include "substring.h"
+#include "tinyxml.h"
+
+#include <stdarg.h>
+
+using namespace std;
+
+/**
+   \brief initializes a TrackElement (sets the default values)
+*/
+TrackElement::TrackElement(void)
+{
+  this->isFresh = true;
+  this->isHotPoint = false;
+  this->isSavePoint = false;
+  this->isFork = false;
+  this->isJoined = false;
+  this->mainJoin = false;
+  this->ID = -1;
+  this->startingTime = 0;
+  this->duration = TMAN_DEFAULT_DURATION;
+  this->endTime = 1;
+  this->jumpTime = 0;
+  this->width = TMAN_DEFAULT_WIDTH;
+  this->nodeCount = 0;
+  this->curve = NULL;
+  this->childCount = 0;
+  this->children = NULL;
+  this->name = NULL;
+
+  this->history = NULL;
+
+  this->subject = NULL;
+  this->condFunc = &TrackElement::random;
+}
+
+/** 
+    \brief destroys all alocated memory)
+    \todo eventually when deleting a TrackElement you would not like to delete all its preceding TrackElements
+*/
+TrackElement::~TrackElement(void)
+{
+  // deleting the Name
+  delete []name;
+  // deleting the Curve
+  delete this->curve;
+
+  // deleting all the Children of this TrackNode.
+  if ((!this->isJoined &&this->childCount > 0) 
+      || (this->isJoined && this->mainJoin)) // only if this is the MainJoin.
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->nextElement();
+      while (enumElem)
+	{
+	  delete enumElem;
+	  enumElem = iterator->nextElement();
+	}
+      delete iterator;
+      delete this->children;
+    }
+}
+
+/**
+   \brief Searches through all the TrackElements for trackID.
+   \param trackID The ID to search for.
+   \returns The TrackElement if Found, NULL otherwise.
+*/
+TrackElement* TrackElement::findByID(unsigned int trackID)
+{
+  // return if Found.
+  if (this->ID == trackID)
+    return this;
+  // search all children
+  if (this->childCount > 0)
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->nextElement();
+      TrackElement* tmpElem;
+      while (enumElem)
+	{
+	  if ((tmpElem = enumElem->findByID(trackID)))
+	    return tmpElem;
+	  enumElem = iterator->nextElement();
+	}
+      delete iterator;
+    }
+  // if not found
+  return NULL;
+}
+
+
+/**
+   \brief Searches through all the TrackElements for a trackName
+   \param trackName The name to search for.
+   \returns The TrackElement if Found, NULL otherwise.
+*/
+TrackElement* TrackElement::findByName(const char* trackName)
+{
+  // return if Found.
+  if (this->name && !strcmp(this->name, trackName))
+    return this;
+  // search all children
+  if (this->childCount > 0)
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->nextElement();
+      TrackElement* tmpElem;
+      while (enumElem)
+	{
+	  if ((tmpElem = enumElem->findByName(trackName)))
+	    return tmpElem;
+	  enumElem = iterator->nextElement();
+	}
+      delete iterator;
+    }
+  // if not found
+  return NULL;
+}
+
+/**
+   \brief checks if there are any BackLoops in the Track (Backloops only 
+   \param trackElem the trackElement to check about
+   \returns true if NO loop was found, false Otherwise
+   You actually have to act on false!!
+   it simply does this by looking if the current trackElem is found again somewhere else in the Track
+*/
+bool TrackElement::backLoopCheck(const TrackElement* trackElem, unsigned int depth) const
+{
+  if(depth == 0 || this != trackElem)
+    {
+      if (this->children)
+	{
+	  tIterator<TrackElement>* iterator = this->children->getIterator();
+	  TrackElement* enumElem = iterator->nextElement();
+	  while (enumElem)
+	    {
+	      if(!enumElem->backLoopCheck(trackElem, depth + 1))
+		return false;
+	      enumElem = iterator->nextElement();
+	    }
+	  delete iterator;
+	}
+    }
+  else
+    return false;
+
+  // only returns if everything worked out
+  return true;
+}
+
+/**
+   \param childNumber which child to return
+   \returns the n-the children (starting at 0). 
+   Be aware, that when the trackElement has no Children, NULL will be returned
+*/
+TrackElement* TrackElement::getChild(int childCount) const
+{
+  // if the the trackElement has no children return NULL.
+  if (this->childCount == 0)
+    return NULL;
+  // we cannot return the childCount+m's Child, so we return the last.
+  if (childCount > this->childCount)
+    childCount = this->childCount;
+  
+  tIterator<TrackElement>* iterator = this->children->getIterator();
+  TrackElement* enumElem = iterator->nextElement();
+  for (int i = 0; i < childCount; i++)
+    enumElem = iterator->nextElement();
+  delete iterator;
+  return enumElem;
+}
+
+/**
+   \param name the Name to set.
+*/
+void TrackElement::setName(const char* name)
+{
+  //  delete the old name
+  if (this->name)
+    delete []this->name;
+  // if a name was given.
+  if (name)
+    {
+      this->name = new char[strlen(name)+1];
+      strcpy(this->name, name);
+    }
+  else 
+    this->name = NULL;
+}
+
+/**
+   \returns The name of this TrackElement
+*/
+const char* TrackElement::getName(void) const
+{
+  return this->name;
+}
+
+/**
+   \brief prints out debug information about this TrackElement
+*/
+void TrackElement::debug(void) const
+{
+  PRINT(0)("--== TrackElement:%i ==--", this->ID);
+  if(this->getName())
+    PRINT(0)("--++Name: %s++--", this->getName());
+  if(this->isFresh)
+    PRINT(0)("  -- has not jet eddited in any way --\n");
+  PRINT(0)("\n   TimeTable: startingTime=%f; endTime=%f; duration=%f; jumpTime=%f\n", this->startingTime, this->endTime, this->duration, this->jumpTime);
+  PRINT(0)("   consists of %d Points\n", this->nodeCount);
+  if (this->childCount == 0)
+    PRINT(0)("   has no child\n");
+  else if (this->childCount == 1)
+    PRINT(0)("   has 1 child: =%d=\n", this->getChild(0)->ID);
+  else if (this->childCount > 1)
+    {
+      PRINT(0)("   has %d children: ", this->childCount);
+      //TrackElement* enumElem = this->children->enumerate();
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->nextElement();
+      while (enumElem)
+	{
+	  PRINT(0)("=%d= ", enumElem->ID);
+	  enumElem = iterator->nextElement();
+	}
+      delete iterator;
+      PRINT(0)("\n");
+    }
+  
+  if(this->isHotPoint)
+    PRINT(0)("   is a special Point:\n");
+  if(this->isSavePoint)
+    PRINT(0)("    is a SavePoint\n");
+  if(this->isFork)
+    {
+      PRINT(0)("    is A Fork with with %d children.\n", this->childCount);
+    }
+  if(this->isJoined)
+    PRINT(0)("   is Joined at the End\n");
+  
+  if(!this->backLoopCheck(this)) /* this should not happen */
+    PRINT(2)(" THERE IS A BACKLOOP TO THIS ELEMENT\n");
+}
+
+/**
+   \brief CONDITION that chooses the first child for the decision (static)
+   \param nothing Nothing in this function
+   \returns the chosen child
+*/
+int TrackElement::lowest(const void* nothing) const
+{
+  return 0;
+}
+
+/**
+   \brief CONDITION that chooses the last child for the decision (static)
+   \param nothing Nothing in this function
+   \returns the chosen child
+*/
+int TrackElement::highest(const void* nothing) const
+{ 
+  return this->childCount-1;
+}
+
+/**
+   \brief CONDITION that chooses a random child for the decision (static)
+   \param nothing Nothing in this function
+   \returns the chosen child
+*/
+int TrackElement::random(const void* nothing) const
+{
+  int i = (int)floor ((float)rand()/(float)RAND_MAX * (float)this->childCount);
+  if (i >= this->childCount)
+    return this->childCount-1;
+  else 
+    return i;
+}
+
+/**
+   \brief CONDITION that chooses child 0, if the node(probably Player)
+   is left of its parent (z<0)) and 1/right otherwise.
+   \param node The node to act upon.
+   \returns the chosen child
+*/
+int TrackElement::leftRight(const void* node) const
+{
+  PNode* tmpNode = (PNode*)node;
+
+  if (tmpNode->getRelCoor().z < 0)
+    return 0;
+  else 
+    return 1;
+}
+
+
+/**
+   \brief CONDITION that chooses the child, that has the nearest distance to the node (probably player).
+   \param node The node to act upon.
+   \returns the chosen child
+
+   This is rather dangerous, because one must carefully set the points on the curve.
+   The best Way is to set the nodes as wide away of each other as possible,
+   but take into consideration, that if the nodes are to far from a center node, the center will be chosen.
+   (play with this!!).
+*/
+int TrackElement::nearest(const void* node) const
+{
+  PNode* tmpNode = (PNode*)node;
+
+  Vector nodeRelCoord = tmpNode->getRelCoor();
+  float minDist = 100000000;
+  int childNumber = 0;
+  int i = 0;
+
+  //TrackElement* enumElem = this->children->enumerate();
+  tIterator<TrackElement>* iterator = this->children->getIterator();
+  TrackElement* enumElem = iterator->nextElement();
+  while (enumElem)
+    {
+      float dist = (nodeRelCoord - enumElem->curve->getNode(4)).len();
+      if (dist < minDist)
+	{
+	  minDist = dist;
+	  childNumber = i;
+	}
+      i++;
+      enumElem = iterator->nextElement();
+    }
+  delete iterator;
+
+  PRINTF(4)("PathDecision with nearest algorithm: %d\n", childNumber);
+  return childNumber;
+}
+
+
+////////////////////////
+///// TRACKMANAGER /////
+////////////////////////
+/**
+   \brief standard constructor
+
+*/
+TrackManager::TrackManager(void)
+{
+  this->setClassName("TrackManager");
+  
+  TrackManager::singletonRef = this; // do this because otherwise the TrackNode cannot get The instance of the TrackManager
+
+  PRINTF(3)("Initializing the TrackManager\n");
+  // setting up the First TrackElement
+  this->firstTrackElem = new TrackElement();
+  this->firstTrackElem->ID = 1;
+  this->firstTrackElem->setName("root");
+
+  this->currentTrackElem = firstTrackElem;
+
+  this->curveType = CURVE_BEZIER;
+  this->localTime = 0;
+  this->maxTime = 0;
+  this->trackElemCount = 1;
+
+  this->trackNode = new TrackNode();
+  this->setBindSlave(this->trackNode);
+  // initializing the Text
+  this->trackText = TextEngine::getInstance()->createText("fonts/earth.ttf", 30, TEXT_DYNAMIC, 0, 255, 0);
+  this->trackText->setAlignment(TEXT_ALIGN_SCREEN_CENTER);
+  // initializing the Animation for the Text.
+  this->textAnimation = new tAnimation<Text>(this->trackText, &Text::setBlending);
+  this->textAnimation->addKeyFrame(1.0, 3.0, ANIM_NEG_EXP);
+  this->textAnimation->addKeyFrame(0.0, .001);
+  this->textAnimation->setInfinity(ANIM_INF_CONSTANT);
+}
+
+
+/**
+   \brief loads a trackElement from a TiXmlElement
+   \param root the TiXmlElement to load the Data from
+*/
+bool TrackManager::load( TiXmlElement* root)
+{
+  TiXmlElement* element;
+  TiXmlNode* container;
+  double x, y, z, d;
+	
+  element = root->FirstChildElement();
+	
+  while( element != NULL)
+    {
+      if( !strcmp( element->Value(), "Point"))
+	{
+	  container = element->FirstChild();
+	  if( container->ToText())
+	    {
+	      assert( container->Value() != NULL);
+	      if( sscanf( container->Value(), "%lf,%lf,%lf", &x, &y, &z) == 3)
+		{
+		  PRINTF(5)("Loaded Point: %lf,%lf,%lf (%s)\n", x, y, z, container->Value());
+		  addPoint( Vector( x, y, z));
+		}
+	      else
+		{
+		  PRINTF(0)("Invalid Point in Track (skipped)\n");
+		}			
+	    }
+	}
+      else if( !strcmp( element->Value(), "Duration"))
+	{
+	  container = element->FirstChild();
+	  if( container->ToText())
+	    {
+	      assert( container->Value() != NULL);
+	      if( sscanf( container->Value(), "%lf", &d) == 1)
+		{
+		  PRINTF(5)("Loaded Duration: %lf (%s)\n", d, container->Value());
+		  setDuration( d);
+		}
+	      else
+		{
+		  PRINTF(2)("Invalid Duration in Track (skipped)\n");
+		}			
+	    }
+	}
+      else if( !strcmp( element->Value(), "SavePoint"))
+	{
+	  PRINTF(5)("Loaded Savepoint\n");
+	  setSavePoint();
+	}
+      else if( !strcmp( element->Value(), "Fork"))
+	{
+	  container = element->FirstChild();
+	  if( container->ToText())
+	    {
+	      assert( container->Value() != NULL);
+	      PRINTF(4)("Loaded Fork: %s\n", container->Value());
+	      forkS(container->Value());
+	    }
+	}
+      else if( !strcmp( element->Value(), "Join"))
+	{
+	  container = element->FirstChild();
+	  if( container->ToText())
+	    {
+	      assert( container->Value() != NULL);
+	      PRINTF0("Loaded Join: %s\n", container->Value());
+	      joinS(container->Value());
+	    }
+	}
+      else if( !strcmp( element->Value(), "WorkOn"))
+	{
+	  container = element->FirstChild();
+	  if( container->ToText())
+	    {
+	      assert( container->Value() != NULL);
+	      PRINTF(4)("Loaded WorkOn: %s\n", container->Value());
+	      workOn( container->Value());
+	    }
+	}
+		
+      element = element->NextSiblingElement();
+    }
+
+}
+
+
+
+/**
+   \brief standard destructor
+*/
+TrackManager::~TrackManager(void)
+{
+  PRINTF(3)("Destruct TrackManager\n");
+
+  PRINTF(4)("Deleting all the TrackElements\n");
+  delete this->firstTrackElem;
+
+  // the tracknode should be deleted here, but is deleted by pNode: -> null_parent
+
+  // we do not have a TrackManager anymore
+  TrackManager::singletonRef = NULL;
+}
+
+//! Singleton Reference to TrackManager
+TrackManager* TrackManager::singletonRef = NULL;
+
+/**
+   \returns The reference on the TrackManager.
+
+   If the TrackManager does not exist, it will be created.
+*/
+TrackManager* TrackManager::getInstance(void) 
+{
+  if (!TrackManager::singletonRef)
+    TrackManager::singletonRef = new TrackManager();
+  return TrackManager::singletonRef;
+}
+
+
+// INITIALIZE //
+/**
+   \brief reserves Space for childCount children
+   \param childCount The Count of children to make space for.
+   \param trackElem The TrackElement to appy this to. (if NULL chose this->currentTrackElement)
+*/
+void TrackManager::initChildren(unsigned int childCount, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  trackElem->childCount = childCount;
+  trackElem->mainJoin = true;  // this tells join, that this one is the Main Join, if it tries to join multiple Tracks
+  trackElem->children =  new tList<TrackElement>();
+  for (int i = 0; i < childCount; i++)
+    {
+      // create a new Element
+      TrackElement* newElem = new TrackElement();
+      // setting up the new ID
+      newElem->ID = ++trackElemCount;
+      // setting up the Time
+      newElem->startingTime = trackElem->endTime + trackElem->jumpTime;
+      // adds the conection Point
+      this->addPoint(trackElem->curve->getNode(trackElem->curve->getNodeCount()),
+		     newElem);
+      // add the new child to the childList.
+      trackElem->children->add(newElem);
+    }
+
+  // setting the Name of the new TrackElement to the name of the last one + _childI
+
+  if (trackElem->getName())
+    {
+      for (int i = 0; i < trackElem->childCount; i++)
+      {
+	char* childName = new char[strlen(trackElem->getName())+10];
+	sprintf(childName, "%s_child%d", trackElem->getName(), i);
+	trackElem->getChild(i)->setName(childName);
+      }
+    }
+  // select the first Child to work on.
+  this->currentTrackElem = trackElem->getChild(0);
+}
+
+
+/**
+   \brief Sets the trackID we are working on.
+   \param trackID the trackID we are working on
+*/
+void TrackManager::workOn(unsigned int trackID)
+{
+  TrackElement* tmpElem = this->firstTrackElem->findByID(trackID);
+  if (tmpElem)
+    this->currentTrackElem = tmpElem;
+  else
+    PRINTF(2)("TrackElement %d not Found, leaving unchanged\n", trackID);
+  PRINTF(4)("now Working on %d\n", this->currentTrackElem->ID);
+}
+
+/**
+   \brief Sets the TrackElement to work on
+   \param trackName the Name of the Track to work on
+*/
+void TrackManager::workOn(const char* trackName)
+{
+  TrackElement* tmpElem = this->firstTrackElem->findByName(trackName);
+  if (tmpElem)
+    this->currentTrackElem = tmpElem;
+  else
+    PRINTF(2)("TrackElement %s not Found, leaving unchanged\n", trackName);
+  PRINTF(4)("now Working on %d\n", this->currentTrackElem->ID);
+}
+
+/**
+   \brief Sets the Type of the Curve
+   \param curveType The Type to set
+   \param trackElem the TrackElement that should get a new Curve.
+
+   \brief this will possibly get obsolete during the process.
+*/
+void TrackManager::setCurveType(CurveType curveType, TrackElement* trackElem)
+{
+  if (!trackElem->isFresh)
+    {
+      PRINTF(2)("It is not possible to change the type of a Curve after you have have appended some points to it\n");
+      return;
+    }
+  this->curveType = curveType;
+  switch (curveType)
+    {
+    case CURVE_BEZIER:
+      trackElem->curve = new BezierCurve();
+      break;
+    }
+}
+
+/**
+   \brief Sets the duration of the current path in seconds.
+   \param duration The duration in seconds.
+   \param trackElem The TrackElement to apply this to.
+*/
+void TrackManager::setDuration(float duration, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  trackElem->duration = duration;
+  trackElem->endTime = trackElem->startingTime + duration;
+}
+
+/**
+   \brief adds a point to trackElem
+   \param newPoint The point to add.
+   \param trackElem The TrackElement to add the Point to
+*/
+bool TrackManager::addPoint(Vector newPoint, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  if (trackElem->isFresh)
+    {
+      this->setCurveType(TMAN_DEFAULT_CURVETYPE, trackElem);
+      trackElem->isFresh = false;
+    }
+  trackElem->curve->addNode(newPoint);
+  trackElem->nodeCount++;
+}
+
+/**
+   \brief adds save/splitpoint.
+   \param newPoint The point to add.
+   \returns A Pointer to a newly appended Curve
+*/
+int TrackManager::addHotPoint(Vector newPoint, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  PRINTF(4)("setting up a HotPoint\n");
+  if (trackElem->isFresh)
+    {
+      trackElem->isFresh = false;
+    }
+
+  // \todo HotPoint Handling.
+  trackElem->curve->addNode(newPoint);
+  trackElem->nodeCount++;
+  this->initChildren(1, trackElem);
+}
+
+/**
+   \brief Sets the last HotPoint into a savePoint.
+   \param trackElem The TrackElement to appy this to. (if NULL chose this->currentTrackElement)
+   \returns A Pointer to a newly appended Curve
+
+   If no HotPoint was defined the last added Point will be rendered into a savePoint. \n
+   If the HotPoint was defined as a fork the Point will \b not be set into a savePoint.
+*/
+int TrackManager::setSavePoint(TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  PRINTF(4)("setting up a SavePoint.\n");
+  if (trackElem->isFork || trackElem->isSavePoint)
+    {
+      PRINTF(2)("%d is already finished \n", trackElem->ID);
+      return trackElem->getChild(0)->ID;
+    }
+  trackElem->isSavePoint = true;
+  trackElem->isHotPoint = true;
+
+  this->initChildren(1, trackElem);
+}
+
+/**
+   \brief adds some interessting non-linear movments through the level.
+   \param count The Count of children the fork will produce
+
+   If no HotPoint was defined the last added Point will be rendered into a fork. \n
+   If the HotPoint was defined as a savePoint the Point will \b not be set into a fork.
+*/
+void TrackManager::fork(unsigned int count, ...)
+{
+  int* trackIDs = new int[count];
+  this->forkV(count, trackIDs, NULL);
+  va_list ID;
+  va_start (ID, count);
+  for(int i = 0; i < count; i++)
+    {
+      *va_arg (ID, int*) = trackIDs[i];
+    }
+  va_end(ID);  
+  delete []trackIDs;
+}
+
+/**
+   \param string the String to parse.
+   \see TrackManager::fork(unsigned int count, ...)
+
+   does the same as fork, but has an array of strings as an input.
+*/
+void TrackManager::forkS(unsigned int count, ...)
+{
+  int* trackIDs = new int[count];
+  this->forkV(count, trackIDs, NULL);
+  va_list name;
+  va_start (name, count);
+  for(int i = 0; i < count; i++)
+    {
+      this->firstTrackElem->findByID(trackIDs[i])->setName(va_arg(name, const char*));
+    }
+  va_end(name);  
+  delete []trackIDs;
+}
+
+/**
+   \see TrackManager::fork(unsigned int count, ...)
+*/
+void TrackManager::forkS(const char* forkString)
+{
+  SubString strings(forkString);
+
+  int* trackIDs = new int[strings.getCount()];
+  this->forkV(strings.getCount(), trackIDs, NULL);
+
+  for(int i = 0; i < strings.getCount(); i++)
+    {
+      this->firstTrackElem->findByID(trackIDs[i])->setName(strings.getString(i));
+    }  
+}
+
+/**
+   \brief adds some interessting non-linear movments through the level.
+   \param count The Count of childrens the current HotPoint will have.
+   \param trackIDs A Pointer to an Array of ints which will hold the trackID's (the user will have to reserve space for this).
+   \param trackElem The TrackElement to appy this to. (if NULL choose this->currentTrackElement)
+   \see TrackManager::fork(unsigned int count, ...)
+*/
+void TrackManager::forkV(unsigned int count, int* trackIDs, char** trackNames, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  PRINTF(4)("Forking with %d children\n", count);
+  if (trackElem->isSavePoint)
+    return;
+  trackElem->isFork = true;
+  trackElem->isHotPoint = true;
+  for(int i = 0; i < count; i++)
+    trackIDs[i]=this->trackElemCount+1+i;
+  this->initChildren(count, trackElem);
+}
+
+/**
+   \brief decides under what condition a certain Path will be chosen.
+   \param trackID the trackID to apply this to.
+   \param cond the CONDITION of the decision
+   \param subject the Subject that will be decided upon with CONDITION cond.
+*/
+void TrackManager::condition(unsigned int trackID, CONDITION cond, void* subject)
+{
+  this->condition(cond, subject, this->firstTrackElem->findByID(trackID));
+}
+
+/**
+   \brief decides under what condition a certain Path will be chosen.
+   \param cond the CONDITION of the decision
+   \param subject the Subject that will be decided upon with CONDITION cond.
+   \param trackElem The TrackElement to appy this to. (if NULL chose this->currentTrackElement)
+*/
+void TrackManager::condition(CONDITION cond, void* subject, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  if (!trackElem->isFork)
+    {
+      PRINTF(2)("%d is not a Fork, and no condition can be set in this case\n", trackElem->ID);
+      return;
+    }
+  else
+    {
+      switch (cond)
+	{
+	case LOWEST:
+	  trackElem->condFunc = &TrackElement::lowest;
+	  break;
+	case HIGHEST:
+	  trackElem->condFunc = &TrackElement::highest;
+	  break;
+	case RANDOM: 
+	  trackElem->condFunc = &TrackElement::random;
+	  break;
+	case LEFTRIGHT:
+	  trackElem->condFunc = &TrackElement::leftRight;
+	  break;
+	case NEAREST:
+	  trackElem->condFunc = &TrackElement::nearest;
+	  break;
+	case ENEMYKILLED:
+	  break;
+	}
+      trackElem->subject=subject;
+    }
+}
+
+/**
+   \brief joins some tracks together again. 
+   \param count The count of Paths to join.
+
+   Join will set the localTime to the longest time a Path has to get to this Point. \n
+   Join will join all curves to the first curve, meaning that all the tangents will be matched.
+*/
+void TrackManager::join(unsigned int count, ...)
+{
+  int* trackIDs = new int [count];
+  va_list ID;
+  va_start (ID, count);
+  for(int i = 0; i < count; i++)
+    {
+      trackIDs[i] = va_arg (ID, int);
+    }
+  va_end(ID);
+  this->joinV(count, trackIDs);
+  delete []trackIDs;
+}
+
+/**
+   \brief Joins some Tracks together again.
+   \param count The count of trackElements to join
+   \see void TrackManager::join(unsigned int count, ...)
+
+   The difference to void TrackManager::join(unsigned int count, ...) is, that this function takes
+   the Names of the TrackElements as inputs and not their ID
+*/
+void TrackManager::joinS(unsigned int count, ...)
+{
+  int* trackIDs = new int [count];
+  va_list NAME;
+  va_start (NAME, count);
+  for(int i = 0; i < count; i++)
+    {
+      const char* name = va_arg (NAME, char*);
+      TrackElement* tmpElem = this->firstTrackElem->findByName(name);
+      if (tmpElem)
+	trackIDs[i] = tmpElem->ID;
+      else
+	PRINTF(1)("Trying to join a Track, of which the name does not exist: %s\n", name);
+    }
+  va_end(NAME);
+  this->joinV(count, trackIDs);
+  delete []trackIDs;
+}
+
+/**
+   \see void TrackManager::join(unsigned int count, ...)
+*/
+void TrackManager::joinS(const char* joinString)
+{
+  SubString strings(joinString);
+
+  int* trackIDs = new int[strings.getCount()];
+  this->joinV(strings.getCount(), trackIDs);
+
+  for(int i = 0; i < strings.getCount(); i++)
+    {
+      TrackElement* tmpElem = this->firstTrackElem->findByName(strings.getString(i));
+      if (tmpElem)
+	trackIDs[i] = tmpElem->ID;
+      else
+	PRINTF(1)("Trying to join a Track, of which the name does not exist: %s\n", strings.getString(i));
+    }
+
+  this->joinV(strings.getCount(), trackIDs);
+  delete []trackIDs;
+}
+
+/**
+   \brief joins some tracks together again. 
+   \param count The count of Paths to join.
+   \param trackIDs an Array with the trackID's to join
+
+   \see void TrackManager::join(unsigned int count, ...)
+*/
+void TrackManager::joinV(unsigned int count, int* trackIDs)
+{
+  TrackElement* tmpTrackElem;
+  TrackElement* tmpJoinElem;
+  for (int i = 0; i < count; i++)
+    if (!this->firstTrackElem->findByID(trackIDs[i]))
+      {
+	PRINTF(1)("Trying to Connect Paths that do not exist yet: %d\n Not Joining Anything\n", trackIDs[i]);
+	return;
+      }
+		  
+
+  PRINTF(3)("Joining %d tracks and merging to Track %d\n", count, trackIDs[0]);
+
+  // checking if there is a back-loop-connection and ERROR if it is.
+  tmpTrackElem = this->firstTrackElem->findByID(trackIDs[0]);
+  if (!tmpTrackElem->backLoopCheck(tmpTrackElem))
+    {
+      PRINTF(2)("Backloop connection detected at joining trackElements\n -> TRACK WILL NOT BE JOINED\n");
+      return;
+    }
+
+  TrackElement* firstJoint =   this->firstTrackElem->findByID(trackIDs[0]);
+  float tmpLatestTime = firstJoint->endTime;
+
+  Vector tmpEndPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount());
+  Vector tmpTangentPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount()-1);
+  Vector tmpc2Point = firstJoint->curve->getNode(firstJoint->curve->getNodeCount()-2);
+  firstJoint->isJoined = true;
+  //  firstJoint->mainJoin = true;
+  if(!firstJoint->isHotPoint)
+    this->setSavePoint(firstJoint);
+  // Timing:
+  for (int i = 0; i < count; i++)
+    {
+      if(tmpJoinElem = this->firstTrackElem->findByID(trackIDs[i]))
+	{
+	  if (tmpJoinElem->childCount == 0
+	      && tmpJoinElem->endTime > tmpLatestTime)
+	    tmpLatestTime = tmpJoinElem->endTime;
+	}
+    }
+  // time the main Join.
+  firstJoint->jumpTime = tmpLatestTime - firstJoint->endTime;
+  
+  // Joining:
+  for (int i = 1; i < count; i++)
+    {
+      if( tmpJoinElem = this->firstTrackElem->findByID(trackIDs[i]))
+	{
+	  if (tmpJoinElem->childCount > 0)
+	    printf("!!This Curve has children, and as such will not be joined!!\n You can try joining other childless TrackElements to this one!");
+	  else
+	    {
+	      this->addPoint(tmpc2Point, tmpJoinElem);
+	      this->addPoint(tmpTangentPoint, tmpJoinElem);
+	      this->addPoint(tmpEndPoint, tmpJoinElem);
+	      // time all other Joins
+	      tmpJoinElem->jumpTime = tmpLatestTime - tmpJoinElem->endTime;
+	      
+	      //Copying Joint-Info
+	      tmpJoinElem->children = firstJoint->children;
+	      tmpJoinElem->childCount = firstJoint->childCount;
+	      tmpJoinElem->isSavePoint = firstJoint->isSavePoint;
+	      tmpJoinElem->isFork = firstJoint->isFork;
+	      
+	      tmpJoinElem->isJoined = true;
+	    }
+	}
+    }
+  if(firstJoint->children)
+    {
+      //TrackElement* enumElem = firstJoint->children->enumerate();
+      tIterator<TrackElement>* iterator = firstJoint->children->getIterator();
+      TrackElement* enumElem = iterator->nextElement();
+      while (enumElem)
+	{
+	  PRINTF(5)("Setting startingTime of %d to %f.\n", enumElem->ID, tmpLatestTime);
+	  enumElem->startingTime = tmpLatestTime;
+	  enumElem->endTime = tmpLatestTime + enumElem->duration;
+	  
+	  enumElem = iterator->nextElement();
+	}
+      delete iterator;
+    }
+}
+
+/**
+   \brief finalizes the TrackSystem. after this it will not be editable anymore
+
+   \todo check for any inconsistencies, output errors
+*/
+void TrackManager::finalize(void)
+{
+  for (int i = 1; i<= trackElemCount ;i++)
+    {
+      TrackElement* tmpElem = this->firstTrackElem->findByID(i);
+      if( tmpElem->childCount > 0 && tmpElem->mainJoin)
+	{
+	  tIterator<TrackElement>* iterator = tmpElem->children->getIterator();
+	  TrackElement* enumElem = iterator->nextElement();
+	  //TrackElement* enumElem = tmpElem->children->enumerate();
+	  while (enumElem)
+	    {
+	      
+	      // c1-continuity
+	      enumElem->curve->addNode(enumElem->curve->getNode(0) +
+						   ((enumElem->curve->getNode(0) - 
+						    tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-1))
+						    ),2);
+	      enumElem->nodeCount++;
+	      // c2-continuity
+	      enumElem->curve->addNode((tmpElem->curve->getNode(tmpElem->curve->getNodeCount())-
+						    tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-1)) * 4 +
+						   tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-2), 3);
+	      enumElem->nodeCount++;						    
+	      PRINTF(5)("accelerations: %d-in: count: %d, %f, %f, %f\n                  %d-out: count: %d %f, %f, %f\n",
+		     tmpElem->ID, tmpElem->nodeCount,
+		     tmpElem->curve->calcAcc(0.999).x, tmpElem->curve->calcAcc(0.999).y, tmpElem->curve->calcAcc(0.999).z,
+		     enumElem->ID, enumElem->nodeCount,
+		     enumElem->curve->calcAcc(0).x, enumElem->curve->calcAcc(0).y, enumElem->curve->calcAcc(0).z);
+	      
+	      enumElem = iterator->nextElement();
+	    }
+	  delete iterator;
+	}
+    }
+  for (int i = 1; i <= trackElemCount;i++)
+    if (this->firstTrackElem->findByID(i)->endTime > this->maxTime)
+      this->maxTime = this->firstTrackElem->findByID(i)->endTime; // very bad implemented :/
+}
+
+
+// RUNTIME //
+
+/**
+   \brief calculates the Position for the localTime of the Track.
+   \returns the calculated Position
+*/
+Vector TrackManager::calcPos() const
+{
+  return this->currentTrackElem->curve->calcPos((this->localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
+}
+
+/**
+   \brief calculates the Rotation for the localTime of the Track.
+   \returns the calculated Rotation
+*/
+Vector TrackManager::calcDir() const
+{
+  return this->currentTrackElem->curve->calcDir((this->localTime - this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
+}
+
+/**
+   \returns the current Width of the track
+*/
+float TrackManager::getWidth(void) const
+{
+  return this->currentTrackElem->width;
+}
+
+/**
+   \brief Advances the local-time of the Track around dt
+   \param dt The time about which to advance.
+
+   This function also checks, if the TrackElement has to be changed.
+*/
+void TrackManager::tick(float dt)
+{
+  dt /= 1000;
+  PRINTF(4)("CurrentTrackID: %d, LocalTime is: %f, timestep is: %f\n", this->currentTrackElem->ID, this->localTime, dt);
+  if (this->localTime <= this->firstTrackElem->duration)
+    this->jumpTo(this->localTime);
+  if (this->localTime <= this->maxTime)
+    this->localTime += dt;
+  if (this->localTime > this->currentTrackElem->endTime
+      && this->currentTrackElem->children)
+    {
+      if (this->currentTrackElem->jumpTime != 0.0)
+	this->jumpTo(this->localTime + this->currentTrackElem->jumpTime);
+      // jump to the next TrackElement and also set the history of the new Element to the old one.
+      TrackElement* tmpHistoryElem = this->currentTrackElem;
+      this->currentTrackElem = this->currentTrackElem->getChild(this->choosePath(this->currentTrackElem));
+      this->currentTrackElem->history = tmpHistoryElem;
+      if (this->currentTrackElem->getName())
+	{
+	  this->trackText->setText(this->currentTrackElem->getName());
+	  this->textAnimation->replay();
+	}
+    }
+  if (this->bindSlave)
+    {
+      Vector tmp = this->calcPos();
+      Quaternion quat = Quaternion(this->calcDir(), Vector(this->currentTrackElem->curve->calcAcc((localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration).x,1,this->currentTrackElem->curve->calcAcc((localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration).z)); 
+
+      Vector v(0.0, 1.0, 0.0);
+      Quaternion q(-PI/2, v);
+      quat = quat * q;
+
+      this->bindSlave->setAbsCoor(tmp);
+      this->bindSlave->setAbsDir(quat);
+    }
+}
+
+/**
+   \brief Jumps to a certain point on the Track.
+   \param time The time on the Track to jump to.
+
+   This should be used to Jump backwards on a Track, because moving forward means to change between the Path. (it then tries to choose the default.)
+   Max is trackLengthMax.
+*/
+void TrackManager::jumpTo(float time)
+{
+  if (time == 0)
+    {
+      this->currentTrackElem = this->firstTrackElem;
+      if (this->currentTrackElem->getName())
+	{
+	  this->trackText->setText(this->currentTrackElem->getName());
+	  this->textAnimation->play();
+	}
+    }
+  this->localTime = time;
+}
+
+/**
+   \brief a Function that decides which Path we should follow.
+   \param trackElem The Path to choose.
+   
+*/
+int TrackManager::choosePath(TrackElement* trackElem)
+{
+  return (trackElem->*(trackElem->condFunc))(trackElem->subject);
+}
+
+/**
+   \brief Sets the PNode, that should be moved along the Tack
+   \param bindSlave the PNode to set
+*/
+void TrackManager::setBindSlave(PNode* bindSlave)
+{
+  this->bindSlave = bindSlave;
+}
+
+/**
+   \returns the main TrackNode
+*/
+PNode* TrackManager::getTrackNode(void)
+{
+  return this->trackNode;
+}
+
+// DEBUG //
+
+/**
+   \brief Imports a model of the Graph into the OpenGL-environment.
+   \param dt The Iterator used in seconds for Painting the Graph.
+
+   This is for testing facility only. Do this if you want to see the Path inside the Level.
+   eventually this will all be packed into a gl-list.
+*/
+void TrackManager::drawGraph(float dt) const
+{
+  for (int i = 1; i <= trackElemCount; i++)
+    {
+      glBegin(GL_LINE_STRIP);
+      TrackElement* tmpElem = this->firstTrackElem->findByID(i);
+      if (tmpElem->curve)
+	for(float f = 0.0; f < 1.0; f+=dt)
+	  {
+	    //      printf("%f, %f, %f\n",trackManager->calcPos().x, trackManager->calcPos().y, trackManager->calcPos().z);
+	    Vector tmpVector = tmpElem->curve->calcPos(f);
+	    glVertex3f(tmpVector.x, tmpVector.y, tmpVector.z);
+	  }
+      glEnd();
+    }
+}
+
+/**
+   \brief outputs debug information about the trackManager
+   \param level how much debug
+*/
+void TrackManager::debug(unsigned int level) const
+{
+  PRINT(0)("=========================================\n");
+  PRINT(0)("= CLASS TRACKMANAGER::debug information =\n");
+  PRINT(0)("=========================================\n");
+  //  PRINT(0)("Status is: %
+  PRINT(0)(" Consists of %d elements\n", this->trackElemCount);
+  PRINT(0)(" localTime is: %f\n", this->localTime);
+  if (level >= 2)
+    {
+      for (int i = 1; i <= trackElemCount; i++)
+	{
+	  TrackElement* tmpElem = this->firstTrackElem->findByID(i);
+	  tmpElem->debug();
+	}
+    }
+  PRINT(0)("-----------------------------------------\n");
+}
Index: orxonox/branches/physics/src/util/track/track_manager.h
===================================================================
--- orxonox/branches/physics/src/util/track/track_manager.h	(revision 4283)
+++ orxonox/branches/physics/src/util/track/track_manager.h	(revision 4283)
@@ -0,0 +1,197 @@
+/*! 
+    \file track_manager.h
+    \brief manages all tracks defined in the world and the path the player takes
+
+    it is a container for all tracks and all track-nodes. it manages the movement of
+    the track helper-parent (that drives the player). it is responsable for calculating
+    smooth curves etc.
+*/
+
+
+#ifndef _TRACK_MANAGER_H
+#define _TRACK_MANAGER_H
+
+#include "curve.h"
+#include "base_object.h"
+
+// Forward Definition
+class PNode;
+class Text;
+class TiXmlElement;
+template<class T> class tAnimation;
+template<class T> class tList;
+
+// Static Definitions
+
+//! The Default Curve-Type to set for the whole path (if not chosen otherwise).
+#define TMAN_DEFAULT_CURVETYPE CURVE_BEZIER
+#define TMAN_DEFAULT_DURATION 10
+#define TMAN_DEFAULT_WIDTH    10
+
+//! A Graph-Element, that holds the curve-structure of a Level.
+/**
+   A TrackElement is used, to define the structure of the Track itself.
+   It is a graph and not a tree, because paths can fork and join again.
+*/
+class TrackElement
+{
+ public:
+  TrackElement(void);
+  ~TrackElement(void);
+
+  TrackElement* findByID(unsigned int trackID);
+  TrackElement* findByName(const char* trackName);
+  bool backLoopCheck(const TrackElement* trackElem, unsigned int depth = 0) const;
+
+  TrackElement* getChild(int childNumber) const;
+  void setName(const char* name);
+  const char* getName(void) const;
+
+  // atributes
+  bool isFresh;              //!< If no Points where added until now
+  bool isHotPoint;           //!< If the first node is a specialPoint;
+  bool isSavePoint;          //!< If the first node is a savePoint
+  bool isFork;               //!< If the first node is a Fork
+  bool isJoined;             //!< If the End of the Curve is joined.
+  bool mainJoin;             //!< If the End of the Curve is joined, and this is the one Curve the others join to.
+  int ID;                    //!< The ID of this TrackElement
+  float startingTime;        //!< The time at which this Track begins.
+  float duration;            //!< The time used to cross this TrackElement (curve).
+  float endTime;             //!< The time at which this Track ends.
+  float jumpTime;            //!< The Time this Track has to jump to its preceding Track (only >0 if Track isJoined==true)
+  float width;               //!< Th width of the Path. This tells the Player(s), how far he(they) can go to the left/right.
+  int nodeCount;             //!< The count of points this TrackElement has.
+  Curve* curve;              //!< The Curve of this TrackElement
+  int childCount;            //!< The number of Children This TrackElement has.
+  tList<TrackElement>* children;   //!< A TrackElement can have a Tree of following TrackElements.
+
+
+  // runtime
+  TrackElement* history;     //!< a pointer to the last TrackElement we were on. This is if you want to walk the path backwards again.
+
+  void debug(void) const;
+
+  // CONDITION FUNCTIONS and STUFF
+  void* subject;             //!< The Subject the Condition should act upon.
+  int (TrackElement::*condFunc)(const void*) const; //!< Pointer to the condition function
+
+  int lowest(const void* nothing) const;
+  int highest(const void* nothing) const;
+  int random(const void* nothing) const;
+
+  int leftRight(const void* node) const;
+  int nearest(const void* node) const;
+  // todo  int enemyKilled(void* entity);
+
+ private:
+  char* name;                //!< A name for the Trac.
+ 
+};
+
+//! the Condition to choose between the different ways of the game.
+enum CONDITION {LOWEST, HIGHEST, RANDOM, LEFTRIGHT, NEAREST, ENEMYKILLED};
+
+//! The TrackManager handles the flow of the Players through the game.
+/**
+
+   <b>The TrackManager works as followed:</b> \n
+     \n
+   <b>1. Initialize it, by setting up the Graph. You can do this by using the following Commands.</b>
+    \li workOn(): changes the ID that will be altered through the changes.
+    \li setCurveType(): lets you set the CurveType of the Curve we are Working on. (default is BezierCurve, set this as early as possible, for this uses resources).
+    \li setDuration(): sets the length of the current path in seconds.
+    \li addPoint(): adds a point to the Curve.
+    \li addHotPoint(): adds save/splitpoint.\n
+    \li fork(): adds some interessting non-linear movments through the level (fork will force addHotPoint if not done then).
+    \li condition(): decides under what condition a certain Path will be chosen.
+    \li join(): joins some tracks together again. Join will set the localTime to the longest time a Path has to get to this Point)
+    \li setSavePoint(): Sets a HotPoint into a savePoint. A Savepoint can be used as a rollbackpoint if a Player gets shot.
+
+    HotPoints and Joins are at the beginning of a TrackElement. \n
+    SavePoints and Forks are at the end of a TrackElement \n
+    look out: <b>SAVEPOINTS CAN NOT BE FORKS</b> (but joins), because the condition is really hard to guess if you do not give some impuls. \n
+\n
+   <b> 2. Runtime knows the following: </b>
+    \li calcPos(): returns the current position on the track
+    \li calcDir(): returns the current Direction the track is flying on.
+    \li tick(): makes a Step on the Path. increases localTime by dt.
+    \li choosePath(): a Function that decides which Path we should follow.
+   
+   TrackManager can be handled as a StateMachine.
+   \n\n
+    Names: 
+    \li TrackManager: handles Tracks
+    \li Track:        The Track that the ship can follow
+    \li Path:         one way through the Level, that is dependent on conditionals.
+    \li Conditional:  A decition making device, that chooses betwen different TrackElements for the Path.
+    \li TrackElement: A Part of A whole Track
+*/
+class TrackManager : public BaseObject
+{
+ private:
+  TrackManager(void);
+
+  static TrackManager* singletonRef;  //!< There may only be one TrackManager.
+
+  TrackElement* firstTrackElem;       //!< The first TrackElement that exists.
+  TrackElement* currentTrackElem;     //!< The TrackElement we are working on.
+  CurveType curveType;                //!< The CurveType the entire TrackSystem will have.
+  float localTime;                    //!< The time that has been passed since the traveling the Track.
+  float maxTime;                      //!< The maximal time the track has.
+  int trackElemCount;                 //!< The count of TrackElements that exist.
+
+  // external
+  PNode* bindSlave;                   //!< The node that is slave to the TrackManager. This node will be moved while update the TrackManager, and must NOT move itself.
+  PNode* trackNode;                   //!< The main TrackNode of this Track.
+  Text* trackText;                    //!< The text to display when switching between Worlds.
+  tAnimation<Text>* textAnimation;    //!< An Animation for the Text.
+  
+  void initChildren(unsigned int childCount, TrackElement* trackElem = NULL);
+
+ public:
+  virtual ~TrackManager(void);
+
+  static TrackManager* getInstance(void);
+
+  bool load(TiXmlElement* root);
+
+  // Methods to change the Path (initialisation)
+  void workOn(unsigned int trackID);
+  void workOn(const char* trackName);
+
+  /** \see setCurveType(CurveType curveType, TrackElement* trackElem); \param curveType the type of the Curve */
+  inline void setCurveType(CurveType curveType) { this->setCurveType (curveType, this->currentTrackElem);};
+  void setCurveType(CurveType curveType, TrackElement* trackElem);
+  void setDuration(float duration, TrackElement* trackElem = NULL);
+  bool addPoint(Vector newPoint, TrackElement* trackElem = NULL);
+  int addHotPoint(Vector newPoint, TrackElement* trackElem = NULL);
+  int setSavePoint(TrackElement* trackElem = NULL);
+  void fork(unsigned int count, ...);
+  void forkS(unsigned int count, ...);
+  void forkS(const char* forkString);
+  void forkV(unsigned int count, int* trackIDs, char** trackNames, TrackElement* trackElem = NULL);
+  void condition(unsigned int trackID, CONDITION cond, void* subject);
+  void condition(CONDITION cond, void* subject, TrackElement* trackElem = NULL);
+  void join(unsigned int count, ...);
+  void joinS(const char* joinString);
+  void joinS(unsigned int cound, ...);
+  void joinV(unsigned int count, int* trackIDs);
+  void finalize(void);
+
+  // Methods to calculate the position on the Path (runtime)
+  inline Vector calcPos(void) const;
+  inline Vector calcDir(void) const;
+  float getWidth(void) const;
+  void tick(float dt);
+  void jumpTo(float time);
+  inline int choosePath(TrackElement* trackElem);
+
+  void setBindSlave(PNode* bindSlave);
+  PNode* getTrackNode(void);
+
+  // DEBUG //
+  void drawGraph(float dt) const;
+  void debug(unsigned int level) const;
+};
+
+#endif /* _TRACK_MANAGER_H */
Index: orxonox/branches/physics/src/util/track/track_node.cc
===================================================================
--- orxonox/branches/physics/src/util/track/track_node.cc	(revision 4283)
+++ orxonox/branches/physics/src/util/track/track_node.cc	(revision 4283)
@@ -0,0 +1,60 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+#include "track_node.h"
+
+#include "null_parent.h"
+
+#include "track_manager.h"
+
+using namespace std;
+
+/**
+   \brief standard constructor
+
+   \todo this constructor is not jet implemented - do it
+*/
+TrackNode::TrackNode () 
+{
+  this->setClassName("TrackNode");
+  this->setName("TrackNode"); /* absolete but still used... */
+
+  NullParent::getInstance()->addChild(this);
+  this->trackManager = TrackManager::getInstance();
+  this->setMode(PNODE_ALL);
+}
+
+
+TrackNode::TrackNode (const Vector& absCoordinate)
+{
+  this->parent = NullParent::getInstance();
+  this->trackManager = TrackManager::getInstance();
+  this->setMode(PNODE_ALL);
+  this->setAbsCoor(absCoordinate);
+}
+
+
+/**
+   \brief standard deconstructor
+
+   \todo this deconstructor is not jet implemented - do it
+*/
+TrackNode::~TrackNode () 
+{
+
+}
Index: orxonox/branches/physics/src/util/track/track_node.h
===================================================================
--- orxonox/branches/physics/src/util/track/track_node.h	(revision 4283)
+++ orxonox/branches/physics/src/util/track/track_node.h	(revision 4283)
@@ -0,0 +1,33 @@
+/*! 
+    \file track_node.h
+    \brief Definition of the TrackNode are located here
+    
+    the TrackNode is the node, that follows the Track (and the TrackManager) 
+    through the level.
+    Under normal confitions the Plyaer(s) are 
+*/
+
+
+#ifndef _TRACK_NODE_H
+#define _TRACK_NODE_H
+
+#include "p_node.h"
+
+/* FORWARD DEFINITION */
+class TrackManager;
+
+class TrackNode : public PNode 
+{
+
+ public:
+  TrackNode ();
+  TrackNode (const Vector& absCoordinate);
+
+  virtual ~TrackNode ();
+
+ private:
+  TrackManager* trackManager;
+
+};
+
+#endif /* _TRACK_NODE_H */
