Index: trunk/src/lib/parser/Makefile.am
===================================================================
--- trunk/src/lib/parser/Makefile.am	(revision 7221)
+++ trunk/src/lib/parser/Makefile.am	(revision 7256)
@@ -1,5 +1,7 @@
 SUBDIRS = \
           tinyxml \
-	  ini_parser
+	  ini_parser \
+	  preferences \
+	  cmdline_parser
 
 
Index: trunk/src/lib/parser/cmdline_parser/Makefile.am
===================================================================
--- trunk/src/lib/parser/cmdline_parser/Makefile.am	(revision 7256)
+++ trunk/src/lib/parser/cmdline_parser/Makefile.am	(revision 7256)
@@ -0,0 +1,10 @@
+
+noinst_LIBRARIES = libCmdLineParser.a
+
+libCmdLineParser_a_SOURCES = cmdline_parser.cc
+
+libCmdLineParser_a_CPPFLAGS = "-DNO_SHELL"
+
+noinst_HEADERS = cmdline_parser.h
+
+
Index: trunk/src/lib/parser/cmdline_parser/cmdline_parser.cc
===================================================================
--- trunk/src/lib/parser/cmdline_parser/cmdline_parser.cc	(revision 7256)
+++ trunk/src/lib/parser/cmdline_parser/cmdline_parser.cc	(revision 7256)
@@ -0,0 +1,252 @@
+/*
+   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: Christoph Renner
+   co-programmer: 
+*/
+
+#include "cmdline_parser.h"
+
+#include "src/lib/util/substring.h"
+
+using namespace std;
+
+
+/**
+ * standard constructor
+ */
+CmdLineParser::CmdLineParser ()
+{
+}
+
+
+/**
+ * standard deconstructor
+ */
+CmdLineParser::~CmdLineParser ()
+{
+}
+
+
+bool CmdLineParser::add( int id, const std::string & longOption, char shortOption, int numArgs, const std::string & argNames, const std::string& help, bool back )
+{
+  ArgTableEntry entry;
+  
+  entry.id = id;
+  entry.longOption = longOption;
+  entry.shortOption = shortOption;
+  entry.numArgs = numArgs;
+  entry.argNames = argNames;
+  entry.help = help;
+  
+  if ( back )
+    argTable.push_back( entry );
+  else
+    argTable.push_front( entry );
+}
+
+
+bool CmdLineParser::parse( ArgParserCallback cb, void * data, int argc, char ** argv )
+{
+  this->exeName = argv[0];
+  
+  //put all args in vector
+  std::vector<std::string> args;
+  
+  for ( int i = 1; i<argc; i++ )
+  {
+    std::string s = argv[i];
+    
+    if ( s.find( "=" ) == std::string::npos )
+    {
+      args.push_back(s);
+    }
+    else
+    {
+      std::string op = s;
+      std::string ar = s;
+      op.erase( op.find("=") );
+      ar.erase( 0, ar.find("=")+1);
+      
+      //PRINTF(0)("'%s' '%s'\n", op.c_str(), ar.c_str());
+      args.push_back( op );
+      args.push_back( ar );
+    }
+  }
+  
+  int i = 0;
+  
+  ArgTable::iterator it;
+  bool finish;
+  bool found;
+  
+  while ( i < args.size() )
+  {
+    found = false;
+    for ( it = argTable.begin(); it != argTable.end(); it++ )
+    {
+      if ( matches( *it, args[i], finish ) )
+      {
+        found = true;
+        
+        if ( it->numArgs + i >= args.size() )
+        {
+          PRINTF(1)( "%s needs %d arguments!\n", args[i].c_str(), it->numArgs );
+          return false;
+        }
+        
+        std::vector<MultiType> argArgs;
+        
+        for ( int j = 1; j <= it->numArgs; j++ )
+          argArgs.push_back( args[i+j] );
+        
+        if ( !cb( *it, data, args[i], argArgs ) )
+          return false;
+        
+        i += it->numArgs + 1;
+        
+        if ( finish )
+          break;
+        else 
+        {
+          assert( it->numArgs == 0 );
+        }
+      }
+    }
+    
+    if ( !found )
+    {
+      PRINTF(1)("%s: illegal option\n", args[i].c_str());
+      return false;
+    }
+  }
+  
+  return true;
+}
+
+bool CmdLineParser::matches( ArgTableEntry entry, std::string arg, bool & finish )
+{
+  finish = true;
+  
+  if ( arg.length() < 2 )
+    return false;
+  
+  if ( arg[0] == '-' )
+  {
+    if ( arg[1] == '-' )
+    {
+      arg.erase( 0, 2 );
+      
+      if ( entry.longOption.find('%') != std::string::npos )
+      {
+        //TODO implement bether match algo
+        assert( entry.longOption.find('%') == entry.longOption.length()-1 );
+        std::string lo = entry.longOption;
+        lo.erase( lo.length()-1, 1 );
+        //PRINTF(0)("%s %s\n", arg.c_str(), lo.c_str());
+        return arg.find( lo ) == 0;
+      }
+      else
+      {
+        return arg.find( entry.longOption ) != std::string::npos;
+      }
+    }
+    else
+    {
+      if ( arg.length() != 2 && entry.numArgs != 0 )
+      {
+        PRINTF(1)("using multiple flags together is only alowed if none needs an arugument. %s needs %d arguments\n", entry.shortOption, entry.numArgs);
+        return false;
+      }
+      finish = arg.length()==2;
+      return arg.find(entry.shortOption) != std::string::npos;
+    }
+  }
+}
+
+void CmdLineParser::showHelp()
+{
+  printf("Usage: %s [options]\n", exeName.c_str());
+  printf("\n");
+  
+  std::list<std::vector<std::string> > output;
+  
+  for ( ArgTable::iterator it = argTable.begin(); it != argTable.end(); it++ )
+  {
+    output.push_back( std::vector<std::string>() );
+    
+    SubString substr( it->argNames );
+    std::string args;
+    assert( it->numArgs == substr.getCount() );
+      
+    for ( int i = 0; i<it->numArgs; i++ )
+    {
+      args += " [" + substr[i] + "]";
+    }
+    
+    if ( it->shortOption != '\0' )
+    {
+      output.back().push_back( " -" + std::string((char*)&it->shortOption, 1) );
+      output.back().back() += args;
+    }
+    else
+      output.back().push_back( "" );
+    
+    if ( it->longOption != "" )
+    {
+      output.back().push_back( "--" + it->longOption );
+      
+      output.back().back() += args;
+    }
+    else
+      output.back().push_back( "" );
+    
+    output.back().push_back( it->help );
+  }
+  
+  output.push_back( std::vector<std::string>() );
+  output.back().push_back( "Option" );
+  output.back().push_back( "Long option" );
+  output.back().push_back( "Description" );
+  
+  output.reverse();
+  
+  int maxShort = 0;
+  int maxLong = 0;
+  
+  std::list<std::vector<std::string> >::const_iterator it;
+  
+  for ( it = output.begin(); it != output.end(); it++ )
+  {
+    if ( (*it)[0].length() > maxShort )
+      maxShort = (*it)[0].length();
+    
+    if ( (*it)[1].length() > maxLong )
+      maxLong = (*it)[1].length();
+  }
+  
+  for ( it = output.begin(); it != output.end(); it++ )
+  {
+    printf("%s ", (*it)[0].c_str());
+    
+    for ( int i = 0; i<maxShort-(*it)[0].length(); i++ )
+      printf(" ");
+    
+    printf("%s ", (*it)[1].c_str());
+    
+    for ( int i = 0; i<maxLong-(*it)[1].length(); i++ )
+      printf(" ");
+    
+    printf("%s\n", (*it)[2].c_str());
+  }
+  
+  exit(0);
+}
Index: trunk/src/lib/parser/cmdline_parser/cmdline_parser.h
===================================================================
--- trunk/src/lib/parser/cmdline_parser/cmdline_parser.h	(revision 7256)
+++ trunk/src/lib/parser/cmdline_parser/cmdline_parser.h	(revision 7256)
@@ -0,0 +1,53 @@
+/*!
+ * @file cmdline_parser.h
+ * @brief Definition of ...
+ */
+
+#ifndef _CMD_LINE_PARSER_H
+#define _CMD_LINE_PARSER_H
+
+#include <list>
+#include <string>
+#include <vector>
+
+#include "src/defs/debug.h"
+#include "src/lib/util/multi_type.h"
+
+
+struct ArgTableEntry
+{
+  int         id;
+  std::string longOption;
+  char        shortOption;
+  int         numArgs;
+  std::string argNames;
+  std::string help;
+};
+
+typedef std::list<ArgTableEntry> ArgTable;
+
+typedef bool (*ArgParserCallback)( ArgTableEntry, void*, const std::string &, const std::vector<MultiType> & );
+
+
+//! A class for parsing command line arguments
+class CmdLineParser {
+
+  public:
+    CmdLineParser();
+    virtual ~CmdLineParser();
+    
+    bool add( int id, const std::string& longOption, char shortOption, int numArgs, const std::string & argNames, const std::string& help, bool back=false );
+
+    bool parse( ArgParserCallback cb, void* data, int argc, char** argv );
+    
+    void showHelp();
+    
+  private:
+    ArgTable argTable;
+    std::string exeName;
+    
+    inline bool matches( ArgTableEntry entry, std::string arg, bool & finish );
+
+};
+
+#endif /* _CMD_LINE_PARSER_H */
Index: trunk/src/lib/parser/ini_parser/ini_parser.cc
===================================================================
--- trunk/src/lib/parser/ini_parser/ini_parser.cc	(revision 7221)
+++ trunk/src/lib/parser/ini_parser/ini_parser.cc	(revision 7256)
@@ -392,4 +392,69 @@
 }
 
+/**
+ * @brief edits the entry speciefied by entryName in sectionName/currentSection or creates it if it doesn't exist
+ * @param entryName the Name of the Entry to add
+ * @param value the value to assign to this entry
+ * @param sectionName if NULL then this entry will be set to the currentSection
+ * otherwise to the section refered to by sectionName.
+ * If both are NULL no entry will be added
+ * @return true if everything is ok false on error
+ */
+bool IniParser::editVar(const std::string& entryName, const std::string& value, const std::string& sectionName)
+{
+  std::list<IniSection>::iterator section;
+
+  if (!sectionName.empty())
+  {
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+      if ((*section).name == sectionName)
+        break;
+  }
+  else
+    section = this->currentSection;
+
+  if (section == this->sections.end())
+  {
+    IniSection sec;
+    sec.comment = "";
+    sec.name = sectionName;
+    section = this->sections.insert(this->sections.end(), sec);
+  }
+
+  if (section == this->sections.end())
+  {
+    PRINTF(2)("section '%s' not found for value '%s'\n", sectionName.c_str(), entryName.c_str());
+    return false;
+  }
+  else
+  {
+    //try find item
+    std::list<IniEntry>::iterator entry;
+    for (entry = section->entries.begin(); entry!=section->entries.end(); entry++)
+      if (entry->name == entryName )
+        break;
+
+    //found it?
+    if ( entry != section->entries.end() )
+    {
+      entry->value = value;
+
+      return true;
+    }
+
+    //not found -> create it
+    (*section).entries.push_back(IniEntry());
+    (*section).entries.back().comment = "";
+    (*section).entries.back().name = entryName;
+    (*section).entries.back().value = value;
+    PRINTF(5)("Added Entry %s with Value '%s' to Section %s\n",
+    (*section).entries.back().name.c_str(),
+    (*section).entries.back().value.c_str(),
+    (*section).name);
+    this->currentEntry = --(*section).entries.end();
+    return true;
+  }
+}
+
 
 /**
Index: trunk/src/lib/parser/ini_parser/ini_parser.h
===================================================================
--- trunk/src/lib/parser/ini_parser/ini_parser.h	(revision 7221)
+++ trunk/src/lib/parser/ini_parser/ini_parser.h	(revision 7256)
@@ -69,4 +69,5 @@
     bool addVar(const std::string& entryName, const std::string& value, const std::string& sectionName = "" );
     const std::string& getVar(const std::string& entryName, const std::string& sectionName, const std::string& defaultValue = "") const;
+    bool IniParser::editVar(const std::string& entryName, const std::string& value, const std::string& sectionName = "");
     void setEntryComment(const std::string& comment, const std::string& entryName, const std::string& sectionName);
     const std::string& getEntryComment(const std::string& entryName, const std::string& sectionName) const;
Index: trunk/src/lib/parser/preferences/Makefile.am
===================================================================
--- trunk/src/lib/parser/preferences/Makefile.am	(revision 7256)
+++ trunk/src/lib/parser/preferences/Makefile.am	(revision 7256)
@@ -0,0 +1,13 @@
+MAINSRCDIR=../../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libPrefsParser.a
+
+libPrefsParser_a_SOURCES = \
+		cmd_line_prefs_reader.cc \
+		ini_file_prefs_reader.cc
+
+
+noinst_HEADERS = \
+		cmd_line_prefs_reader.h \
+		ini_file_prefs_reader.h
Index: trunk/src/lib/parser/preferences/cmd_line_prefs_reader.cc
===================================================================
--- trunk/src/lib/parser/preferences/cmd_line_prefs_reader.cc	(revision 7256)
+++ trunk/src/lib/parser/preferences/cmd_line_prefs_reader.cc	(revision 7256)
@@ -0,0 +1,158 @@
+/*
+   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: Christoph Renner
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "cmd_line_prefs_reader.h"
+
+#include "preferences.h"
+
+using namespace std;
+
+RegistredArgs CmdLinePrefsReader::regArgs;
+
+/**
+ * standard constructor
+*/
+CmdLinePrefsReader::CmdLinePrefsReader( )
+{
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+CmdLinePrefsReader::~CmdLinePrefsReader ()
+{
+}
+
+bool CmdLinePrefsReader::callBack( ArgTableEntry entry, void * data, const std::string & arg, const std::vector<MultiType> & argArgs )
+{
+  CallbackData * cbd = (CallbackData *)data;
+  
+  switch ( entry.id )
+  {
+    case ID_SET_INI:
+    {
+      std::string section = arg;
+      section.erase( 0, entry.longOption.length()+1 );
+      std::string key = section;
+      section.erase( section.find(".") );
+      key.erase( 0, key.find(".")+1 );
+      //PRINTF(0)("SECTION '%s', KEY '%s'\n", section.c_str(), key.c_str());
+      
+      if ( key == "" || section == "" || argArgs.size() != 1 )
+      {
+        PRINTF(1)("usage: --set-section.key=value\n");
+        return false;
+      }
+      
+      //Preferences::getInstance()->setMultiType( section, key, argArgs[0], true );
+      cbd->iniEntries.push_back( IniEntry() );
+      cbd->iniEntries.back().section = section;
+      cbd->iniEntries.back().key = key;
+      cbd->iniEntries.back().value = argArgs[0].getString();
+      return true;
+    }
+    case ID_HELP:
+      cbd->parser->showHelp();
+      return true;
+  }
+  
+  if ( entry.id >= ID_PREFS && entry.id - ID_PREFS < regArgs.size() )
+  {
+    if ( regArgs[entry.id - ID_PREFS].value == "%arg%" )
+    {
+      assert( argArgs.size() == 1 );
+      
+      cbd->iniEntries.push_back( IniEntry() );
+      cbd->iniEntries.back().section = regArgs[entry.id - ID_PREFS].section;
+      cbd->iniEntries.back().key = regArgs[entry.id - ID_PREFS].key;
+      cbd->iniEntries.back().value = argArgs[0].getString();
+    }
+    else
+    {
+      cbd->iniEntries.push_back( IniEntry() );
+      cbd->iniEntries.back().section = regArgs[entry.id - ID_PREFS].section;
+      cbd->iniEntries.back().key = regArgs[entry.id - ID_PREFS].key;
+      cbd->iniEntries.back().value = regArgs[entry.id - ID_PREFS].value;
+    }
+  }
+  else
+  {
+    assert(false);
+  }
+  
+  return true;
+}
+
+
+bool CmdLinePrefsReader::parse( int argc, char ** argv )
+{
+  CmdLineParser parser;
+  
+  parser.add( ID_HELP, "help", 'h', 0, "", "Shows this help");
+  
+  for ( int i = 0; i<regArgs.size(); i++ )
+  {
+    if ( regArgs[i].value == "%arg%" )
+    {
+      parser.add( ID_PREFS + i, regArgs[i].longOption, regArgs[i].shortOption, 1, regArgs[i].argName, regArgs[i].help );
+    }
+    else
+    {
+      parser.add( ID_PREFS + i, regArgs[i].longOption, regArgs[i].shortOption, 0, "", regArgs[i].help );
+    }
+  }
+  
+  parser.add( ID_SET_INI, "set-%", '\0', 1, "value", "Override a configuration element." );
+  
+  CallbackData cbd;
+  
+  cbd.parser = &parser;
+  
+  if ( parser.parse( &callBack, &cbd, argc, argv ) )
+  {
+    std::list<IniEntry>::const_iterator it;
+    for ( it = cbd.iniEntries.begin(); it != cbd.iniEntries.end(); it++ )
+    {
+      Preferences::getInstance()->setString( it->section, it->key, it->value, true);
+    }
+  }
+  else
+  {
+    exit(EXIT_FAILURE);
+  }
+  
+  return true;
+}
+
+bool CmdLinePrefsReader::registerArgument( const char shortOption, const std::string & longOption, const std::string & section, const std::string & key, const std::string & help, const std::string & argName, const std::string & value )
+{
+  RegistredArgument arg;
+  
+  arg.longOption = longOption;
+  arg.shortOption = shortOption;
+  arg.value = value;
+  arg.help = help;
+  arg.argName = argName;
+  arg.section = section;
+  arg.key = key;
+  
+  regArgs.push_back( arg );
+}
+
+
Index: trunk/src/lib/parser/preferences/cmd_line_prefs_reader.h
===================================================================
--- trunk/src/lib/parser/preferences/cmd_line_prefs_reader.h	(revision 7256)
+++ trunk/src/lib/parser/preferences/cmd_line_prefs_reader.h	(revision 7256)
@@ -0,0 +1,72 @@
+/*!
+ * @file proto_class.h
+ * @brief Definition of CmdLinePrefsReader
+*/
+
+#ifndef _CMD_LINE_PREFS_READER_H
+#define _CMD_LINE_PREFS_READER_H
+
+#include "stdincl.h"
+#include "debug.h"
+
+#include "src/lib/parser/cmdline_parser/cmdline_parser.h"
+
+struct IniEntry
+{
+  std::string section;
+  std::string key;
+  std::string value;
+};
+
+struct CallbackData
+{
+  std::list<IniEntry> iniEntries;
+  CmdLineParser * parser;
+};
+
+struct RegistredArgument
+{
+  char shortOption;
+  std::string longOption;
+  std::string value;
+  std::string help;
+  std::string argName;
+  std::string section;
+  std::string key;
+};
+
+typedef std::vector<RegistredArgument> RegistredArgs;
+
+enum
+{
+  ID_SET_INI = 1,
+  ID_HELP,
+  ID_PREFS
+};
+
+#define REGISTER_ARG_FLAG(shortOption,longOption,section,key,description,value) bool _ARGVAR_##shortOption##_##longOption = CmdLinePrefsReader::registerArgument(#shortOption[0],#longOption,section,key,description,"",value) 
+
+#define REGISTER_ARG_ARG(shortOption,longOption,section,key,description,argname) bool _ARGVAR_##shortOption##_##longOption = CmdLinePrefsReader::registerArgument(#shortOption[0],#longOption,section,key,description,argname) 
+
+//! A class for reading commandline arguments into Preferences
+class CmdLinePrefsReader 
+{
+
+ public:
+   CmdLinePrefsReader();
+   virtual ~CmdLinePrefsReader();
+
+    bool parse(int argc, char** argv);
+    
+    static bool registerArgument( const char shortOption, const std::string & longOption, const std::string & section, const std::string & key, const std::string & help,  const std::string & argName = "", const std::string & value = "%arg%" );
+    
+    static bool asdf;
+    
+  private:
+    static bool callBack( ArgTableEntry entry, void* data, const std::string & arg, const std::vector<MultiType> & argArgs );
+    
+    static RegistredArgs regArgs;
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: trunk/src/lib/parser/preferences/ini_file_prefs_reader.cc
===================================================================
--- trunk/src/lib/parser/preferences/ini_file_prefs_reader.cc	(revision 7256)
+++ trunk/src/lib/parser/preferences/ini_file_prefs_reader.cc	(revision 7256)
@@ -0,0 +1,63 @@
+/*
+   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: Christoph Renner
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "ini_file_prefs_reader.h"
+
+using namespace std;
+
+
+/**
+ * standard constructor
+*/
+IniFilePrefsReader::IniFilePrefsReader ( const std::string& fileName )
+{
+  IniParser iniParser;
+
+  if ( !iniParser.readFile( fileName ) )
+    return;
+
+  Preferences* prefs = Preferences::getInstance();
+
+  iniParser.firstSection();
+
+  do
+  {
+    do
+    {
+      prefs->setString( iniParser.getCurrentSection(), iniParser.getCurrentName(), iniParser.getCurrentValue(), true );
+    } while (iniParser.nextVar());
+  } while ( iniParser.nextSection() != "" );
+
+  /*iniParser.firstVar();
+
+  Preferences* prefs = Preferences::getInstance();
+
+  while ( iniParser.nextVar() )
+  {
+    prefs->setString( iniParser.getCurrentSection(), iniParser.getCurrentName(), iniParser.getCurrentValue(), true );
+}*/
+}
+
+
+/**
+ * standard deconstructor
+*/
+IniFilePrefsReader::~IniFilePrefsReader ()
+{
+}
+
+
Index: trunk/src/lib/parser/preferences/ini_file_prefs_reader.h
===================================================================
--- trunk/src/lib/parser/preferences/ini_file_prefs_reader.h	(revision 7256)
+++ trunk/src/lib/parser/preferences/ini_file_prefs_reader.h	(revision 7256)
@@ -0,0 +1,23 @@
+/*!
+ * @file ini_file_prefs_reader.h
+ * @brief Definition of IniFilePrefsReader
+*/
+
+#ifndef _INI_FILE_PREFS_READER_H
+#define _INI_FILE_PREFS_READER_H
+
+#include "src/lib/parser/ini_parser/ini_parser.h"
+#include "src/lib/util/preferences.h"
+
+
+//! A class for reading inifiles into Preferences
+class IniFilePrefsReader {
+
+ public:
+   IniFilePrefsReader(const std::string& fileName);
+   virtual ~IniFilePrefsReader();
+
+
+};
+
+#endif /* _INI_FILE_PREFS_READER_H */
