Index: /trunk/src/lib/event/command_chain.cc
===================================================================
--- /trunk/src/lib/event/command_chain.cc	(revision 5460)
+++ /trunk/src/lib/event/command_chain.cc	(revision 5460)
@@ -0,0 +1,701 @@
+/*
+   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_
+
+#include "shell_command.h"
+
+#include "list.h"
+#include "debug.h"
+#include "class_list.h"
+
+#include "key_names.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+/**
+ * creates a new ShellCommandClass
+ * @param className the Name of the command-class to create
+ */
+ShellCommandClass::ShellCommandClass(const char* className)
+{
+  this->setClassID(CL_SHELL_COMMAND_CLASS, "ShellCommandClass");
+  this->setName(className);
+
+  this->className = className;
+  this->classID = CL_NULL;
+  this->commandList = new tList<ShellCommandBase>;
+
+  ShellCommandClass::commandClassList->add(this);
+}
+
+/**
+ * destructs the shellCommandClass again
+ */
+ShellCommandClass::~ShellCommandClass()
+{
+  tIterator<ShellCommandBase>* iterator = this->commandList->getIterator();
+  ShellCommandBase* elem = iterator->firstElement();
+  while(elem != NULL)
+  {
+    delete elem;
+    elem = iterator->nextElement();
+  }
+  delete iterator;
+  delete this->commandList;
+}
+
+/**
+ * collects the Commands registered to some class.
+ * @param className the name of the Class to collect the Commands from.
+ * @param stringList a List to paste the Commands into.
+ * @returns true on success, false otherwise
+ */
+bool ShellCommandClass::getCommandListOfClass(const char* className, tList<const char>* stringList)
+{
+  if (stringList == NULL || className == NULL)
+    return false;
+
+  tIterator<ShellCommandClass>* iterator = ShellCommandClass::commandClassList->getIterator();
+  ShellCommandClass* elem = iterator->firstElement();
+  while(elem != NULL)
+  {
+    if (!strcmp (elem->getName(), className))
+    {
+      tIterator<ShellCommandBase>* itFkt = elem->commandList->getIterator();
+      ShellCommandBase* command = itFkt->firstElement();
+      while (command != NULL)
+      {
+        stringList->add(command->getName());
+        command = itFkt->nextElement();
+      }
+      delete itFkt;
+    }
+
+    elem = iterator->nextElement();
+  }
+  delete iterator;
+  return true;
+}
+
+/**
+ * collects the Aliases registered to the ShellCommands
+ * @param stringList a List to paste the Aliases into.
+ * @returns true on success, false otherwise
+ */
+bool ShellCommandClass::getCommandListOfAlias(tList<const char>* stringList)
+{
+  if (stringList == NULL || ShellCommandClass::aliasList == NULL)
+    return false;
+
+  tIterator<ShellCommandAlias>* iterator = ShellCommandClass::aliasList->getIterator();
+   ShellCommandAlias* elem = iterator->firstElement();
+   while(elem != NULL)
+   {
+     stringList->add(elem->getName());
+     elem = iterator->nextElement();
+   }
+   delete iterator;
+   return true;
+}
+
+/**
+ * unregisters all Commands that exist
+ */
+void ShellCommandClass::unregisterAllCommands()
+{
+  // unregister all commands
+  tIterator<ShellCommandClass>* iterator = ShellCommandClass::commandClassList->getIterator();
+  ShellCommandClass* elem = iterator->firstElement();
+  while(elem != NULL)
+  {
+    delete elem;
+
+    elem = iterator->nextElement();
+  }
+  delete iterator;
+
+  delete ShellCommandClass::commandClassList;
+  ShellCommandClass::commandClassList = NULL;
+
+  // unregister all aliases (there should be nothing to do here :))
+  if (ShellCommandClass::aliasList != NULL)
+  {
+    tIterator<ShellCommandAlias>* itAL = ShellCommandClass::aliasList->getIterator();
+    ShellCommandAlias* elemAL = itAL->firstElement();
+    while(elemAL != NULL)
+    {
+      delete elemAL;
+      elemAL = itAL->nextElement();
+    }
+    delete itAL;
+    delete ShellCommandClass::aliasList;
+    ShellCommandClass::aliasList = NULL;
+  }
+}
+
+/**
+ * checks if a Class is already registered to the Commands' class-stack
+ * @param className the Name of the Class to check for
+ * @returns the CommandClass if found, NULL otherwise
+ */
+const ShellCommandClass* ShellCommandClass::isRegistered(const char* className)
+{
+  if (ShellCommandClass::commandClassList == NULL)
+    initCommandClassList();
+
+  tIterator<ShellCommandClass>* iterator = ShellCommandClass::commandClassList->getIterator();
+  ShellCommandClass* elem = iterator->firstElement();
+  while(elem != NULL)
+  {
+    if (!strcmp(className, elem->className))
+    {
+      if (elem->classID == CL_NULL)
+        elem->classID = ClassList::StringToID(className);
+
+      delete iterator;
+      return elem;
+    }
+    elem = iterator->nextElement();
+  }
+  delete iterator;
+  return NULL;
+}
+
+/**
+ * searches for a CommandClass
+ * @param className the name of the CommandClass
+ * @returns the CommandClass if found, or a new CommandClass if not
+ */
+ShellCommandClass* ShellCommandClass::getCommandClass(const char* className)
+{
+  if (ShellCommandClass::commandClassList == NULL)
+    initCommandClassList();
+
+  tIterator<ShellCommandClass>* iterator = ShellCommandClass::commandClassList->getIterator();
+  ShellCommandClass* elem = iterator->firstElement();
+  while(elem != NULL)
+  {
+    if (!strcmp(className, elem->className))
+    {
+      delete iterator;
+      return elem;
+    }
+    elem = iterator->nextElement();
+  }
+  delete iterator;
+  return new ShellCommandClass(className);
+}
+
+/**
+ * initializes the CommandList (if it is NULL)
+ */
+void ShellCommandClass::initCommandClassList()
+{
+  if (ShellCommandClass::commandClassList == NULL)
+  {
+    ShellCommandClass::commandClassList = new tList<ShellCommandClass>;
+    ShellCommandStatic<ShellCommandBase>::registerCommand("debug", "ShellCommand", ShellCommandBase::debug);
+  }
+}
+
+void ShellCommandClass::help(const char* className)
+{
+  if (className == NULL)
+    return;
+  if (likely(ShellCommandClass::commandClassList != NULL))
+  {
+    tIterator<ShellCommandClass>* itCL = ShellCommandClass::commandClassList->getIterator();
+    ShellCommandClass* elemCL = itCL->firstElement();
+    while(elemCL != NULL)
+    {
+      if (elemCL->className && !strcasecmp(className, elemCL->className))
+      {
+        PRINT(0)("Class:'%s' registered %d commands: \n", elemCL->className, elemCL->commandList->getSize());
+        tIterator<ShellCommandBase>* iterator = elemCL->commandList->getIterator();
+        const ShellCommandBase* elem = iterator->firstElement();
+        while(elem != NULL)
+        {
+          PRINT(0)("  command:'%s' : params:%d: ", elem->getName(), elem->paramCount);
+          for (unsigned int i = 0; i< elem->paramCount; i++)
+            PRINT(0)("%s ", ShellCommandBase::paramToString(elem->parameters[i]));
+          if (elem->description != NULL)
+            PRINT(0)("- %s", elem->description);
+          PRINT(0)("\n");
+          elem = iterator->nextElement();
+        }
+        delete iterator;
+
+        delete itCL;
+        return;
+      }
+      elemCL = itCL->nextElement();
+    }
+    delete itCL;
+    PRINTF(3)("Class %s not found in Command's classes\n", className);
+  }
+  else
+  {
+    PRINTF(1)("List of commandClasses does not exist");
+  }
+}
+
+tList<ShellCommandClass>* ShellCommandClass::commandClassList = NULL;
+tList<ShellCommandAlias>* ShellCommandClass::aliasList = NULL;
+
+/**
+ * constructs and registers a new Command
+ * @param commandName the name of the Command
+ * @param className the name of the class to apply this command to
+ * @param paramCount the count of parameters this command takes
+ * @return self
+ */
+ShellCommandBase::ShellCommandBase(const char* commandName, const char* className, unsigned int paramCount, ...)
+{
+  this->setClassID(CL_SHELL_COMMAND, "ShellCommand");
+  this->setName(commandName);
+  this->description = NULL;
+  this->alias = NULL;
+
+//  this->classID = classID;
+  this->shellClass = ShellCommandClass::getCommandClass(className); //ClassList::IDToString(classID);
+  if (this->shellClass != NULL)
+    this->shellClass->commandList->add(this);
+  // handling parameters, and storing them:
+  if (paramCount > FUNCTOR_MAX_ARGUMENTS)
+    paramCount = FUNCTOR_MAX_ARGUMENTS;
+  this->paramCount = paramCount;
+  this->parameters = new unsigned int[paramCount];
+
+  va_list parameterList;
+  va_start(parameterList, paramCount);
+
+  for (unsigned int i = 0; i < paramCount; i++)
+  {
+    this->parameters[i] = va_arg(parameterList, int);
+
+    switch (this->parameters[i])
+    {
+      case ParameterBool:
+        this->defaultBools[i] = va_arg(parameterList, int);
+        break;
+      case ParameterChar:
+        this->defaultStrings[i] = new char[2];
+        sprintf(this->defaultStrings[0], "%c",  va_arg(parameterList, int));
+        break;
+      case ParameterString:
+        this->defaultStrings[i] = va_arg(parameterList, char*);
+        break;
+      case ParameterInt:
+        this->defaultInts[i] = va_arg(parameterList, int);
+        break;
+      case ParameterUInt:
+        this->defaultInts[i] = va_arg(parameterList, unsigned int);
+        break;
+      case ParameterFloat:
+        this->defaultFloats[i] = va_arg(parameterList, double);
+        break;
+      case ParameterLong:
+        this->defaultInts[i] = va_arg(parameterList, long);
+        break;
+      default:
+        break;
+    }
+  }
+}
+
+/**
+ * deconstructs a ShellCommand
+ * @return
+ */
+ShellCommandBase::~ShellCommandBase()
+{
+  delete[] this->parameters;
+  if (this->alias != NULL && ShellCommandClass::aliasList != NULL)
+  {
+    ShellCommandClass::aliasList->remove(this->alias);
+    delete this->alias;
+  }
+}
+
+/**
+ * unregister an existing commandName
+ * @param className the name of the Class the command belongs to.
+ * @param commandName the name of the command itself
+ */
+void ShellCommandBase::unregisterCommand(const char* commandName, const char* className)
+{
+  if (ShellCommandClass::commandClassList == NULL)
+    ShellCommandClass::initCommandClassList();
+
+ const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className);
+
+ if (checkClass != NULL)
+  {
+    tIterator<ShellCommandBase>* iterator = checkClass->commandList->getIterator();
+    ShellCommandBase* elem = iterator->firstElement();
+    while(elem != NULL)
+    {
+      if (!strcmp(commandName, elem->getName()))
+      {
+        checkClass->commandList->remove(elem);
+        delete elem;
+        break;
+      }
+      elem = iterator->nextElement();
+    }
+    delete iterator;
+
+    if (checkClass->commandList->getSize() == 0)
+    {
+      ShellCommandClass::commandClassList->remove(checkClass);
+      delete checkClass;
+    }
+  }
+}
+
+/**
+ * checks if a command has already been registered.
+ * @param commandName the name of the Command
+ * @param className the name of the Class the command should apply to.
+ * @param paramCount how many arguments the Command takes
+ * @returns true, if the command is registered/false otherwise
+ *
+ * This is used internally, to see, if we have multiple command subscriptions.
+ * This is checked in the registerCommand-function.
+ */
+bool ShellCommandBase::isRegistered(const char* commandName, const char* className, unsigned int paramCount, ...)
+{
+  if (ShellCommandClass::commandClassList == NULL)
+  {
+    ShellCommandClass::initCommandClassList();
+    return false;
+  }
+
+  const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className);
+  if (checkClass != NULL)
+  {
+    tIterator<ShellCommandBase>* iterator = checkClass->commandList->getIterator();
+    ShellCommandBase* elem = iterator->firstElement();
+    while(elem != NULL)
+   {
+     if (!strcmp(commandName, elem->getName()))
+     {
+       PRINTF(2)("Command already registered\n");
+       delete iterator;
+       return true;
+      }
+     elem = iterator->nextElement();
+   }
+   delete iterator;
+   return false;
+  }
+  else
+    return false;
+}
+
+
+/**
+ * executes commands
+ * @param executionString the string containing the following input
+ * ClassName [ObjectName] functionName [parameter1[,parameter2[,...]]]
+ * @return true on success, false otherwise.
+ */
+#include  "stdlibincl.h"
+bool ShellCommandBase::execute(const char* executionString)
+{
+  if (ShellCommandClass::commandClassList == NULL)
+    return false;
+
+  long classID = CL_NULL;                 //< the classID retrieved from the Class.
+  ShellCommandClass* commandClass = NULL; //< the command class this command applies to.
+  tList<BaseObject>* objectList = NULL;   //< the list of Objects stored in classID
+  BaseObject* objectPointer = NULL;       //< a pointer to th Object to Execute the command on
+  bool emptyComplete = false;             //< if the completion input is empty string. e.g ""
+  unsigned int fktPos = 1;                //< the position of the function (needed for finding it)
+//  long completeType = SHELLC_NONE;      //< the Type we'd like to complete.
+  SubString inputSplits(executionString, true);
+
+  if (inputSplits.getCount() == 0)
+    return false;
+  if (inputSplits.getCount() >= 1)
+  {
+    // CHECK FOR ALIAS
+    if (ShellCommandClass::aliasList != NULL)
+    {
+      tIterator<ShellCommandAlias>* itAL = ShellCommandClass::aliasList->getIterator();
+      ShellCommandAlias* elemAL = itAL->firstElement();
+      while(elemAL != NULL)
+      {
+        if (elemAL->getName() != NULL && !strcmp(elemAL->getName(), inputSplits.getString(0)) && elemAL->getCommand() != NULL &&
+            elemAL->getCommand()->shellClass != NULL )
+        {
+          objectList = ClassList::getList(elemAL->getCommand()->shellClass->getName());
+          if (objectList != NULL)
+          {
+            if (inputSplits.getCount() > 1)
+              elemAL->getCommand()->executeCommand(objectList->firstElement(), executionString+inputSplits.getOffset(1));
+            else
+              elemAL->getCommand()->executeCommand(objectList->firstElement(), "");
+            delete itAL;
+            return true;
+          }
+        }
+        elemAL = itAL->nextElement();
+      }
+      delete itAL;
+    }
+    // looking for a Matching Class
+    if (likely(ShellCommandClass::commandClassList != NULL))
+    {
+      tIterator<ShellCommandClass>* itCL = ShellCommandClass::commandClassList->getIterator();
+      ShellCommandClass* elemCL = itCL->firstElement();
+      while(elemCL != NULL)
+      {
+        if (elemCL->getName() && !strcasecmp(inputSplits.getString(0), elemCL->getName()))
+        {
+          //elemCL->getName();
+          classID = ClassList::StringToID(elemCL->getName());
+          commandClass = elemCL;
+          objectList = ClassList::getList(classID);
+          break;
+        }
+        elemCL = itCL->nextElement();
+      }
+      delete itCL;
+    }
+
+    if (commandClass != NULL && inputSplits.getCount() >= 2)
+    {
+      if (objectList != NULL)
+      {
+        // Checking for a Match in the Objects of classID (else take the first)
+        tIterator<BaseObject>* itBO = objectList->getIterator();
+        BaseObject* enumBO = itBO->firstElement();
+        while(enumBO)
+        {
+          if (enumBO->getName() != NULL && !strcasecmp(enumBO->getName(), inputSplits.getString(1)))
+          {
+            objectPointer = enumBO;
+            fktPos = 2;
+            break;
+          }
+          enumBO = itBO->nextElement();
+         }
+         delete itBO;
+
+      //
+        if (objectPointer == NULL)
+          objectPointer = objectList->firstElement();
+      }
+      // match a function.
+      if (commandClass != NULL && (fktPos == 1 || (fktPos == 2 && inputSplits.getCount() >= 3)))
+      {
+        tIterator<ShellCommandBase>* itCMD = commandClass->commandList->getIterator();
+        ShellCommandBase* enumCMD = itCMD->firstElement();
+        while (enumCMD != NULL)
+        {
+          if (!strcmp(enumCMD->getName(), inputSplits.getString(fktPos)))
+          {
+            if (objectPointer == NULL && enumCMD->functorType == ShellCommand_Objective)
+            {
+              delete itCMD;
+              return false;
+            }
+            if (inputSplits.getCount() > fktPos+1)
+              enumCMD->executeCommand(objectPointer, executionString+inputSplits.getOffset(fktPos +1));
+            else
+              enumCMD->executeCommand(objectPointer, "");
+            delete itCMD;
+            return true;
+          }
+
+          enumCMD = itCMD->nextElement();
+        }
+        delete itCMD;
+      }
+    }
+  }
+}
+
+/**
+ * lets a command be described
+ * @param description the description of the Given command
+ */
+ShellCommandBase* ShellCommandBase::describe(const char* description)
+{
+  if (this == NULL)
+    return NULL;
+ else
+ {
+   this->description = description;
+   return this;
+ }
+}
+
+/**
+ * adds an Alias to this Command
+ * @param alias the name of the Alias to set
+ * @returns itself
+ */
+ShellCommandBase* ShellCommandBase::setAlias(const char* alias)
+{
+  if (this == NULL)
+    return NULL;
+
+  if (this->alias != NULL)
+  {
+    PRINTF(2)("not more than one Alias allowed for functions (%s::%s)\n", this->getName(), this->shellClass->getName());
+  }
+  else
+  {
+    if (ShellCommandClass::aliasList == NULL)
+      ShellCommandClass::aliasList = new tList<ShellCommandAlias>;
+
+    ShellCommandAlias* aliasCMD = new ShellCommandAlias(alias, this);
+    ShellCommandClass::aliasList->add(aliasCMD);
+    this->alias = aliasCMD;
+  }
+  return this;
+}
+
+/**
+ * sets default Values of the Commands
+ * @param count how many default Values to set.
+ * @param ... the default Values in order. They will be cast to the right type
+ * @returns itself
+ *
+ * Be aware, that when you use this Function, you !!MUST!! match the input as
+ * count, [EXACTLY THE SAME AS IF YOU WOULD CALL THE FUNCTION UP TO count ARGUMENTS]
+ */
+ShellCommandBase* ShellCommandBase::defaultValues(unsigned int count, ...)
+{
+  if (this == NULL)
+    return NULL;
+  if (count == 0)
+    return this;
+  if (count > this->paramCount)
+    count = this->paramCount;
+
+  va_list defaultList;
+  va_start(defaultList, count);
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    switch (this->parameters[i])
+    {
+      case ParameterBool:
+        this->defaultBools[i] = va_arg(defaultList, int);
+        break;
+      case ParameterChar:
+        this->defaultStrings[i] = new char[2];
+        sprintf(this->defaultStrings[0], "%c",  va_arg(defaultList, int));
+        break;
+      case ParameterString:
+        this->defaultStrings[i] = va_arg(defaultList, char*);
+        break;
+      case ParameterInt:
+        this->defaultInts[i] = va_arg(defaultList, int);
+        break;
+      case ParameterUInt:
+        this->defaultInts[i] = va_arg(defaultList, unsigned int);
+        break;
+      case ParameterFloat:
+        this->defaultFloats[i] = va_arg(defaultList, double);
+        break;
+      case ParameterLong:
+        this->defaultInts[i] = va_arg(defaultList, long);
+        break;
+      default:
+        break;
+    }
+  }
+
+  return this;
+}
+
+/**
+ * prints out nice information about the Shells Commands
+ */
+void ShellCommandBase::debug()
+{
+  if (ShellCommandClass::commandClassList == NULL)
+  {
+    PRINT(0)("No Command registered.\n");
+    return;
+  }
+
+  tIterator<ShellCommandClass>* iteratorCL = ShellCommandClass::commandClassList->getIterator();
+  ShellCommandClass* elemCL = iteratorCL->firstElement();
+  while(elemCL != NULL)
+  {
+    PRINT(0)("Class:'%s' registered %d commands: \n", elemCL->className, elemCL->commandList->getSize());
+    tIterator<ShellCommandBase>* iterator = elemCL->commandList->getIterator();
+    const ShellCommandBase* elem = iterator->firstElement();
+    while(elem != NULL)
+    {
+      PRINT(0)("  command:'%s' : params:%d: ", elem->getName(), elem->paramCount);
+      for (unsigned int i = 0; i< elem->paramCount; i++)
+       printf("%s ", ShellCommandBase::paramToString(elem->parameters[i]));
+      if (elem->description != NULL)
+       printf("- %s", elem->description);
+      printf("\n");
+
+      elem = iterator->nextElement();
+    }
+    delete iterator;
+    elemCL = iteratorCL->nextElement();
+  }
+  delete iteratorCL;
+}
+
+/**
+ * converts a Parameter to a String
+ * @param parameter the Parameter we have.
+ * @returns the Name of the Parameter at Hand
+ */
+const char* ShellCommandBase::paramToString(long parameter)
+{
+  switch (parameter)
+  {
+    case ParameterBool:
+      return "BOOL";
+      break;
+    case ParameterChar:
+      return "CHAR";
+      break;
+    case ParameterString:
+      return "STRING";
+      break;
+    case ParameterInt:
+      return "INT";
+      break;
+    case ParameterUInt:
+      return "UINT";
+      break;
+    case ParameterFloat:
+      return "FLOAT";
+      break;
+    case ParameterLong:
+      return "LONG";
+      break;
+    default:
+      return "NULL";
+      break;
+  }
+}
Index: /trunk/src/lib/event/command_chain.h
===================================================================
--- /trunk/src/lib/event/command_chain.h	(revision 5460)
+++ /trunk/src/lib/event/command_chain.h	(revision 5460)
@@ -0,0 +1,434 @@
+/*!
+ * @file shell_command.h
+ * Definition of a on-screen-shell
+ */
+
+#ifndef _SHELL_COMMAND_H
+#define _SHELL_COMMAND_H
+
+#include "base_object.h"
+
+#include "helper_functions.h"
+#include "substring.h"
+#include "functor_list.h"
+
+#include <stdarg.h>
+
+#define     SHELL_COMMAND_MAX_SIZE      //!< The maximum size of a Shell Command
+
+
+
+// FORWARD DECLARATION
+template<class T> class tList;
+
+/**
+ * an easy to use Macro to create a Command
+ * @param command the name of the command (without "" around the string)
+ * @param class the name of the class to apply this command to (without the "" around the string)
+ * @param function the function to call
+ *
+ * MEANING:
+ *  ShellCommandBase* someUniqueVarName =
+ *       ShellCommand<ClassName>::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall);
+ *
+ * In the Shell you would call this Command using:
+ * $ ClassName [ObjectName] commandNameInShell [parameters]
+ */
+#define SHELL_COMMAND(command, class, function) \
+        ShellCommandBase* shell_command_##class##_##command = ShellCommand<class>::registerCommand(#command, #class, &class::function)
+/**
+ * an easy to use Macro to create a Command
+ * @param command the name of the command (without "" around the string)
+ * @param class the name of the class to apply this command to (without the "" around the string)
+ * @param function the function to call
+ *
+ * MEANING:
+ *  ShellCommandBase* someUniqueVarName =
+ *       ShellCommand<ClassName>::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall);
+ *
+ * In the Shell you would call this Command using:
+ * $ ClassName [ObjectName] commandNameInShell [parameters]
+ */
+#define SHELL_COMMAND_STATIC(command, class, function) \
+                         ShellCommandBase* shell_command_##class##_##command = ShellCommandStatic<class>::registerCommand(#command, #class, function)
+
+
+//! an enumerator for the definition of the Type.
+typedef enum {
+  ShellCommand_Objective = 1,
+  ShellCommand_Static    = 2,
+} ShellCommand_Type;
+
+////////////////
+// BASE CLASS //
+////////////////
+class ShellCommandBase;
+class ShellCommandAlias;
+
+//! A class to hold all Classes that have (once) registered Commands.
+class ShellCommandClass : public BaseObject
+{
+  friend class ShellCommandBase;
+
+  public:
+    /** @returns the CommandClassList */
+    static const tList<ShellCommandClass>* getCommandClassList() { return ShellCommandClass::commandClassList; };
+    static bool getCommandListOfClass(const char* className, tList<const char>* stringList);
+    static bool getCommandListOfAlias(tList<const char>* aliasList);
+
+    static ShellCommandClass* getCommandClass(const char* className);
+    static void unregisterAllCommands();
+
+    static void help (const char* className);
+
+  private:
+    ShellCommandClass(const char* className);
+    ~ShellCommandClass();
+
+    static const ShellCommandClass* isRegistered(const char* className);
+    static void initCommandClassList();
+
+  private:
+    const char*                      className;                 //!< The Name of the Class. This should match the ClassName of the Commands Class.
+    long                             classID;                   //!< The classID of this Class
+    tList<ShellCommandBase>*         commandList;               //!< A list of Commands from this Class
+    static tList<ShellCommandClass>* commandClassList;          //!< A list of Classes
+    static tList<ShellCommandAlias>* aliasList;                 //!< An Alias to A Command. (only for classes with one Instance)
+};
+
+
+//! a baseClass for all possible ShellCommands
+class ShellCommandBase : public BaseObject
+{
+  friend class ShellCommandClass;
+  public:
+    static bool execute (const char* executionString);
+
+    ShellCommandBase* describe(const char* description);
+    ShellCommandBase* setAlias(const char* alias);
+    ShellCommandBase* defaultValues(unsigned int count, ...);
+
+    /** @returns the CommandList of the Shell */
+    static void unregisterCommand(const char* commandName, const char* className);
+
+    static void debug();
+
+  protected:
+    ShellCommandBase(const char* commandName, const char* className, unsigned int paramCount, ...);
+    ~ShellCommandBase();
+
+    /** @returns the Type of this Function (either static or objective) */
+    inline ShellCommand_Type getType() { return this->functorType; };
+
+    static bool isRegistered(const char* commandName, const char* className, unsigned int paramCount, ...);
+    static const char* paramToString(long parameter);
+
+  private:
+    /** executes a Command @param object the object to apply this to @param parameters the parameters the command takes */
+    virtual void executeCommand (BaseObject* object, const char* parameters) = 0;
+
+  protected:
+    ShellCommand_Type                functorType;                          //!< The type of Function we've got (either static or objective).
+    void*                            functionPointer;                      //!< The pointeer to the function of the Class (or static pointer if ClassID == CL_NULL )
+    unsigned int                     paramCount;                           //!< the count of parameters.
+    unsigned int*                    parameters;                           //!< Parameters the function of this Command takes.
+    char*                            defaultStrings[FUNCTOR_MAX_ARGUMENTS];//!< A list of default Strings stored.
+    int                              defaultInts[FUNCTOR_MAX_ARGUMENTS];   //!< A list of default Ints stored.
+    float                            defaultFloats[FUNCTOR_MAX_ARGUMENTS]; //!< A list of default Floats stored.
+    bool                             defaultBools[FUNCTOR_MAX_ARGUMENTS];  //!< A list of default Bools stored.
+
+
+  private:
+    ShellCommandClass*               shellClass;                           //!< A Pointer to the Shell-Class this Command belongs to.
+    ShellCommandAlias*               alias;                                //!< An Alias for the Class.
+
+    const char*                      description;                          //!< A description for this commnand. (initially NULL). Assigned with (create)->describe("blablabla");
+};
+
+///////////////////////////////////////////////////
+///////////////////////////////////////////////////
+
+/////////////////////////////////
+// MACRO DEFINITION EXTENSIONS //
+/////////////////////////////////
+//! where to chek for default BOOL values
+#define   l_BOOL_DEFGRAB(i)         this->defaultBools[i]
+//! where to chek for default INT values
+#define   l_INT_DEFGRAB(i)          this->defaultInts[i]
+//! where to chek for default UINT values
+#define   l_UINT_DEFGRAB(i)         (unsigned int)this->defaultInts[i]
+//! where to chek for default LONG values
+#define   l_LONG_DEFGRAB(i)         (long)this->defaultInts[i]
+//! where to chek for default FLOAT values
+#define   l_FLOAT_DEFGRAB(i)        this->defaultFloats[i]
+//! where to chek for default STRING values
+#define   l_STRING_DEFGRAB(i)       this->defaultStrings[i]
+
+//////////////////////////
+// COMMAND REGISTRATION //
+//////////////////////////
+// SHELLCOMMAND can be redefined as ShellCommand or ShellCommandStatic
+// SHELLCOMMANDEXECUTER can be redefined too.
+// SHELLCOMMANDINCLASS
+// SHELLCOMMANDTYPE
+//! registers a command without any parameters
+#define ShellCommandRegister0() \
+  static SHELLCOMMAND<T>* registerCommand(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)()) \
+  { \
+    if (isRegistered(commandName, className, 0)== true) \
+      return NULL; \
+    return new SHELLCOMMAND<T>(commandName, className, function); \
+  }
+
+//! registers a command with 1 parameter
+#define ShellCommandRegister1(t1) \
+  static SHELLCOMMAND<T>* registerCommand(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)(t1##_TYPE), t1##_TYPE d1 = t1##_DEFAULT) \
+  { \
+    if (isRegistered(commandName, className, 1, t1##_PARAM)== true) \
+      return NULL; \
+    return new SHELLCOMMAND<T>(commandName, className, function, d1); \
+  }
+
+//! registers a command with 2 parameters
+#define ShellCommandRegister2(t1,t2) \
+  static SHELLCOMMAND<T>* registerCommand(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)(t1##_TYPE, t2##_TYPE), t1##_TYPE d1 = t1##_DEFAULT, t2##_TYPE d2 = t2##_DEFAULT) \
+  { \
+    if (isRegistered(commandName, className, 2, t1##_PARAM, t2##_PARAM)== true) \
+      return NULL; \
+    return new SHELLCOMMAND<T>(commandName, className, function, d1, d2); \
+  }
+
+//! registers a command with 3 parameters
+#define ShellCommandRegister3(t1,t2,t3) \
+  static SHELLCOMMAND<T>* registerCommand(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE), t1##_TYPE d1 = t1##_DEFAULT, t2##_TYPE d2 = t2##_DEFAULT, t3##_TYPE d3 = t3##_DEFAULT) \
+  { \
+    if (isRegistered(commandName, className, 3, t1##_PARAM, t2##_PARAM, t3##_PARAM)== true) \
+      return NULL; \
+    return new SHELLCOMMAND<T>(commandName, className, function, d1, d2, d3); \
+  }
+
+//! registers a command with 4 parameters
+#define ShellCommandRegister4(t1,t2,t3,t4) \
+  static SHELLCOMMAND<T>* registerCommand(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE), t1##_TYPE d1 = t1##_DEFAULT, t2##_TYPE d2 = t2##_DEFAULT, t3##_TYPE d3 = t3##_DEFAULT, t4##_TYPE d4 = t4##_DEFAULT) \
+  { \
+    if (isRegistered(commandName, className, 4, t1##_PARAM, t2##_PARAM, t3##_PARAM, t4##_PARAM)== true) \
+      return NULL; \
+    return new SHELLCOMMAND<T>(commandName, className, function, d1, d2, d3, d4); \
+  }
+
+//! registers a command with 5 parameters
+#define ShellCommandRegister5(t1,t2,t3,t4,t5) \
+  static SHELLCOMMAND<T>* registerCommand(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE, t5##_TYPE), t1##_TYPE d1 = t1##_DEFAULT, t2##_TYPE d2 = t2##_DEFAULT, t3##_TYPE d3 = t3##_DEFAULT, t4##_TYPE d4 = t4##_DEFAULT, t5##_TYPE d5 = t5##_DEFAULT) \
+  { \
+    if (isRegistered(commandName, className, 5, t1##_PARAM, t2##_PARAM, t3##_PARAM, t4##_PARAM, t5##_PARAM)== true) \
+      return NULL; \
+    return new ShellCommand<T>(commandName, className, function, d1, d2, d3, d4, d5); \
+  }
+
+//////////////////
+// CONSTRUCTORS //
+/////////////////
+//! creates a command that takes no parameters
+#define ShellCommandConstructor0() \
+  void SHELLCOMMANDINCLASS(*functionPointer_0)(); \
+  SHELLCOMMAND(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)()) \
+  : ShellCommandBase(commandName, className, 0) \
+  { \
+    this->functorType = SHELLCOMMANDTYPE; \
+    this->functionPointer_0 = function; \
+  }
+
+//! creates a command that takes one parameter
+#define ShellCommandConstructor1(t1) \
+  void SHELLCOMMANDINCLASS(*functionPointer_1_##t1)(t1##_TYPE); \
+  SHELLCOMMAND(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)(t1##_TYPE), t1##_TYPE d1) \
+  : ShellCommandBase(commandName, className, 1, t1##_PARAM, d1) \
+  { \
+    this->functorType = SHELLCOMMANDTYPE; \
+    this->functionPointer_1_##t1 = function; \
+  }
+
+//! creates a command that takes two parameters
+#define ShellCommandConstructor2(t1,t2) \
+  void SHELLCOMMANDINCLASS(*functionPointer_2_##t1##_##t2)(t1##_TYPE, t2##_TYPE); \
+  SHELLCOMMAND(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)(t1##_TYPE, t2##_TYPE), t1##_TYPE d1, t2##_TYPE d2) \
+  : ShellCommandBase(commandName, className, 2, t1##_PARAM, d1, t2##_PARAM, d2) \
+  { \
+    this->functorType = SHELLCOMMANDTYPE; \
+    this->functionPointer_2_##t1##_##t2 = function; \
+  }
+
+//! creates a command that takes three parameter
+#define ShellCommandConstructor3(t1,t2,t3) \
+  void SHELLCOMMANDINCLASS(*functionPointer_3_##t1##_##t2##_##t3)(t1##_TYPE, t2##_TYPE, t3##_TYPE); \
+  SHELLCOMMAND(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE), t1##_TYPE d1, t2##_TYPE d2, t3##_TYPE d3) \
+  : ShellCommandBase(commandName, className, 3, t1##_PARAM, d1, t2##_PARAM, d2, t3##_PARAM, d3) \
+  { \
+    this->functorType = SHELLCOMMANDTYPE; \
+    this->functionPointer_3_##t1##_##t2##_##t3 = function; \
+  }
+
+//! creates a command that takes four parameter
+#define ShellCommandConstructor4(t1,t2,t3,t4) \
+  void SHELLCOMMANDINCLASS(*functionPointer_4_##t1##_##t2##_##t3##_##t4)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE); \
+  SHELLCOMMAND(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE), t1##_TYPE d1, t2##_TYPE d2, t3##_TYPE d3, t4##_TYPE d4) \
+  : ShellCommandBase(commandName, className, 4, t1##_PARAM, d1, t2##_PARAM, d2, t3##_PARAM, d3, t4##_PARAM, d4) \
+  { \
+    this->functorType = SHELLCOMMANDTYPE; \
+    this->functionPointer_4_##t1##_##t2##_##t3##_##t4 = function; \
+  }
+
+//! creates a command that takes five parameter
+#define ShellCommandConstructor5(t1,t2,t3,t4,t5) \
+  void SHELLCOMMANDINCLASS(*functionPointer_5_##t1##_##t2##_##t3##_##t4##_##t5)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE, t5##_TYPE); \
+  SHELLCOMMAND(const char* commandName, const char* className, void SHELLCOMMANDINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE, t5##_TYPE), t1##_TYPE d1, t2##_TYPE d2, t3##_TYPE d3, t4##_TYPE d4, t5##_TYPE d5) \
+  : ShellCommandBase(commandName, className, 5, t1##_PARAM, d1, t2##_PARAM, d2, t3##_PARAM, d3, t4##_PARAM, d4, t5##_PARAM, d5) \
+  { \
+    this->functorType = SHELLCOMMANDTYPE; \
+    this->functionPointer_5_##t1##_##t2##_##t3##_##t4##_##t5 = function; \
+  }
+
+///////////////
+// EXECUTION //
+///////////////
+//! execute-macro for functions with no parameters
+#define ShellCommandExecute0() \
+  if (this->paramCount == 0) \
+    SHELLCOMMANDEXECUTER(_0)()
+
+//! execute-macro for functions with one parameter
+#define ShellCommandExecute1(t1) \
+   else if (this->paramCount == 1 && this->parameters[0] == t1##_PARAM) \
+    SHELLCOMMANDEXECUTER(_1_##t1)(t1##_FUNC(parameters, t1##_DEFGRAB(0)))
+
+//! execute-macro for functions with two parameters
+#define ShellCommandExecute2(t1,t2) \
+   else if (this->paramCount == 2 && this->parameters[0] == t1##_PARAM && this->parameters[1] == t2##_PARAM) \
+    SHELLCOMMANDEXECUTER(_2_##t1##_##t2)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)))
+
+//! execute-macro for functions with three parameters
+#define ShellCommandExecute3(t1,t2,t3) \
+   else if (this->paramCount == 3 && this->parameters[0] == t1##_PARAM && this->parameters[1] == t2##_PARAM && this->parameters[2] == t3##_PARAM) \
+    SHELLCOMMANDEXECUTER(_3_##t1##_##t2##_##t3)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)), t3##_FUNC(sub.getString(2), t3##_DEFGRAB(2)))
+
+//! execute-macro for functions with four parameters
+#define ShellCommandExecute4(t1,t2,t3,t4) \
+   else if (this->paramCount == 4 && this->parameters[0] == t1##_PARAM && this->parameters[1] == t2##_PARAM && this->parameters[2] == t3##_PARAM && this->parameters[3] == t4##_PARAM) \
+    SHELLCOMMANDEXECUTER(_4_##t1##_##t2##_##t3##_##t4)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)), t3##_FUNC(sub.getString(2), t3##_DEFGRAB(2)), t4##_FUNC(sub.getString(3), t4##_DEFGRAB(3)))
+
+//! execute-macro for functions with five parameters
+#define ShellCommandExecute5(t1,t2,t3,t4,t5) \
+   else if (this->paramCount == 5 && this->parameters[0] == t1##_PARAM && this->parameters[1] == t2##_PARAM && this->parameters[2] == t3##_PARAM && this->parameters[3] == t4##_PARAM && this->parameters[4] == t5##_PARAM) \
+    SHELLCOMMANDEXECUTER(_5_##t1##_##t2##_##t3##_##t4##_##t5)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)), t3##_FUNC(sub.getString(2), t3##_DEFGRAB(2)), t4##_FUNC(sub.getString(3), t4##_DEFGRAB(3)), t5##_FUNC(sub.getString(4), t5##_DEFGRAB(4)))
+
+
+//! keeps information about a ShellCommand
+template<class T> class ShellCommand : public ShellCommandBase
+{
+  public:
+#ifdef FUNCTOR_LIST
+#undef FUNCTOR_LIST
+#endif
+#ifdef SHELLCOMMAND
+#undef SHELLCOMMAND
+#endif
+#define SHELLCOMMAND                       ShellCommand
+#ifdef SHELLCOMMANDEXECUTER
+#undef SHELLCOMMANDEXECUTER
+#endif
+#define SHELLCOMMANDEXECUTER(nameExt)      (dynamic_cast<T*>(object)->*functionPointer##nameExt)
+#ifdef SHELLCOMMANDINCLASS
+#undef SHELLCOMMANDINCLASS
+#endif
+#define SHELLCOMMANDINCLASS(FUNCTION)      (T::FUNCTION)
+#ifdef SHELLCOMMANDTYPE
+#undef SHELLCOMMANDTYPE
+#endif
+#define SHELLCOMMANDTYPE                   ShellCommand_Objective
+//! FUNCTOR_LIST is the List of command-registerers
+#define FUNCTOR_LIST(x) ShellCommandRegister ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+
+
+  private:
+//! FUNCTOR_LIST is the List of CommandConstructors
+#define FUNCTOR_LIST(x) ShellCommandConstructor ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+
+    virtual void executeCommand (BaseObject* object, const char* parameters)
+    {
+      SubString sub(parameters, true);
+//! FUNCTOR_LIST is the List of Executive Functions
+#define FUNCTOR_LIST(x) ShellCommandExecute ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+    }
+};
+
+//! keeps information about a ShellCommand, that points to a Static Function
+template<class T> class ShellCommandStatic : public ShellCommandBase
+{
+  public:
+#ifdef FUNCTOR_LIST
+#undef FUNCTOR_LIST
+#endif
+#ifdef SHELLCOMMAND
+#undef SHELLCOMMAND
+#endif
+#define SHELLCOMMAND                      ShellCommandStatic
+#ifdef SHELLCOMMANDEXECUTER
+#undef SHELLCOMMANDEXECUTER
+#endif
+#define SHELLCOMMANDEXECUTER(nameExt)     functionPointer##nameExt
+#ifdef SHELLCOMMANDINCLASS
+#undef SHELLCOMMANDINCLASS
+#endif
+#define SHELLCOMMANDINCLASS(FUNCTION)     (FUNCTION)
+#ifdef SHELLCOMMANDTYPE
+#undef SHELLCOMMANDTYPE
+#endif
+#define SHELLCOMMANDTYPE                   ShellCommand_Static
+
+//! FUNCTOR_LIST is the List of command-registerers
+#define FUNCTOR_LIST(x) ShellCommandRegister ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+
+  private:
+//! FUNCTOR_LIST is the List of CommandConstructors
+#define FUNCTOR_LIST(x) ShellCommandConstructor ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+
+    virtual void executeCommand (BaseObject* object, const char* parameters)
+    {
+  SubString sub(parameters, true);
+//! FUNCTOR_LIST is the List of Executive Functions
+#define FUNCTOR_LIST(x) ShellCommandExecute ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+    }
+};
+
+//! A Class, that handles aliases.
+class ShellCommandAlias
+{
+  friend class ShellCommandBase;
+  public:
+    /** @returns the Name of the Alias. */
+    const char* getName() const { return this->aliasName; };
+    /** @returns the Command, this Alias is asociated with */
+    ShellCommandBase* getCommand() const { return this->command; };
+
+  private:
+    /** @param aliasName the name of the Alias @param command the Command, to associate this alias with */
+    ShellCommandAlias(const char* aliasName, ShellCommandBase* command) { this->aliasName = aliasName; this->command = command; };
+
+  private:
+    const char*         aliasName;       //!< the name of the Alias
+    ShellCommandBase*   command;         //!< a pointer to the command, this alias executes.
+};
+
+#endif /* _SHELL_COMMAND_H */
