Index: code/branches/core4/src/core/CorePrereqs.h
===================================================================
--- code/branches/core4/src/core/CorePrereqs.h	(revision 3269)
+++ code/branches/core4/src/core/CorePrereqs.h	(revision 3270)
@@ -179,4 +179,5 @@
     class InputManager;
     class InputState;
+    class JoyStick;
     class JoyStickHandler;
     class MouseHandler;
Index: code/branches/core4/src/core/input/CMakeLists.txt
===================================================================
--- code/branches/core4/src/core/input/CMakeLists.txt	(revision 3269)
+++ code/branches/core4/src/core/input/CMakeLists.txt	(revision 3270)
@@ -6,4 +6,5 @@
   InputCommands.cc
   InputManager.cc
+  JoyStick.cc
   JoyStickDeviceNumberListener.cc
   KeyBinder.cc
Index: code/branches/core4/src/core/input/InputManager.cc
===================================================================
--- code/branches/core4/src/core/input/InputManager.cc	(revision 3269)
+++ code/branches/core4/src/core/input/InputManager.cc	(revision 3270)
@@ -40,4 +40,5 @@
 #include <ois/OISException.h>
 #include <ois/OISInputManager.h>
+#include <boost/foreach.hpp>
 
 #include "util/Convert.h"
@@ -56,4 +57,5 @@
 #include "ExtendedInputState.h"
 #include "JoyStickDeviceNumberListener.h"
+#include "JoyStick.h"
 
 // HACK (include this as last, X11 seems to define some macros...)
@@ -106,9 +108,8 @@
         and registers the class in the class hierarchy.
     */
-    InputManager::InputManager()
+    InputManager::InputManager(size_t windowHnd, unsigned int windowWidth, unsigned int windowHeight)
         : inputSystem_(0)
         , keyboard_(0)
         , mouse_(0)
-        , joySticksSize_(0)
         , devicesNum_(0)
         , windowHnd_(0)
@@ -125,4 +126,6 @@
 
         setConfigValues();
+
+        initialise(windowHnd, windowWidth, windowHeight);
     }
 
@@ -133,16 +136,4 @@
     void InputManager::setConfigValues()
     {
-        SetConfigValue(calibrationFilename_, "joystick_calibration.ini")
-            .description("Ini filename for the the joy stick calibration data.")
-            .callback(this, &InputManager::_calibrationFileCallback);
-    }
-
-    /**
-    @brief
-        Callback for the joy stick calibration config file. @see setConfigValues.
-    */
-    void InputManager::_calibrationFileCallback()
-    {
-        ConfigFileManager::getInstance().setFilename(ConfigFileType::JoyStickCalibration, calibrationFilename_);
     }
 
@@ -157,8 +148,6 @@
     @param windowHeight
         The height of the render window
-    @param joyStickSupport
-        Whether or not to load the joy sticks as well
-    */
-    void InputManager::initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport)
+    */
+    void InputManager::initialise(size_t windowHnd, unsigned int windowWidth, unsigned int windowHeight)
     {
         CCOUT(3) << "Initialising Input System..." << std::endl;
@@ -211,17 +200,10 @@
             }
 
-            _initialiseMouse();
-
-            if (joyStickSupport)
-                _initialiseJoySticks();
-            // Do this anyway to also inform when a joystick was detached.
-            _configureJoySticks();
-
-            // Set mouse/joystick region
-            if (mouse_)
-                setWindowExtents(windowWidth, windowHeight);
+            _initialiseMouse(windowWidth, windowHeight);
+
+            _initialiseJoySticks();
 
             // clear all buffers
-            _clearBuffers();
+            clearBuffers();
 
             internalState_ |= OISReady;
@@ -298,5 +280,5 @@
         False if mouse stays uninitialised, true otherwise.
     */
-    void InputManager::_initialiseMouse()
+    void InputManager::_initialiseMouse(unsigned int windowWidth, unsigned int windowHeight)
     {
         if (mouse_ != 0)
@@ -313,4 +295,7 @@
                 mouse_->setEventCallback(this);
                 CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl;
+
+                // Set mouse region
+                setWindowExtents(windowWidth, windowHeight);
             }
             else
@@ -335,145 +320,35 @@
     void InputManager::_initialiseJoySticks()
     {
-        if (joySticksSize_ > 0)
+        if (!this->joySticks_.empty())
         {
             CCOUT(2) << "Warning: Joy sticks already initialised, skipping." << std::endl;
             return;
         }
-        if (inputSystem_->getNumberOfDevices(OIS::OISJoyStick) > 0)
-        {
-            for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++)
-            {
-                try
-                {
-                    OIS::JoyStick* stig = static_cast<OIS::JoyStick*>
-                        (inputSystem_->createInputObject(OIS::OISJoyStick, true));
-                    CCOUT(ORX_DEBUG) << "Created OIS joy stick with ID " << stig->getID() << std::endl;
-                    joySticks_.push_back(stig);
-                    // register our listener in OIS.
-                    stig->setEventCallback(this);
-                }
-                catch (OIS::Exception ex)
-                {
-                    CCOUT(ORX_WARNING) << "Warning: Failed to create OIS joy number" << i << "\n"
-                        << "OIS error message: \"" << ex.eText << "\"" << std::endl;
-                }
-            }
-        }
-    }
-
-    /**
-    @brief
-        Helper function that loads the config value vector of one coefficient
-    */
-    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue)
-    {
-        list.resize(size);
-        unsigned int configValueVectorSize = ConfigFileManager::getInstance().getVectorSize(ConfigFileType::JoyStickCalibration, sectionName, valueName);
-        if (configValueVectorSize > size)
-            configValueVectorSize = size;
-
-        for (unsigned int i = 0; i < configValueVectorSize; ++i)
-        {
-            list[i] = multi_cast<int>(ConfigFileManager::getInstance().getValue(
-                ConfigFileType::JoyStickCalibration, sectionName, valueName, i, multi_cast<std::string>(defaultValue), false));
-        }
-
-        // fill the rest with default values
-        for (unsigned int i = configValueVectorSize; i < size; ++i)
-        {
-            list[i] = defaultValue;
-        }
-    }
-
-    /**
-    @brief
-        Sets the size of all the different lists that are dependent on the number
-        of joy stick devices created and loads the joy stick calibration.
-    @remarks
-        No matter whether there are a mouse and/or keyboard, they will always
-        occupy 2 places in the device number dependent lists.
-    */
-    void InputManager::_configureJoySticks()
-    {
-        joySticksSize_ = joySticks_.size();
-        devicesNum_    = 2 + joySticksSize_;
-        joyStickIDs_         .resize(joySticksSize_);
-        joyStickButtonsDown_ .resize(joySticksSize_);
-        povStates_           .resize(joySticksSize_);
-        sliderStates_        .resize(joySticksSize_);
-        joyStickMinValues_   .resize(joySticksSize_);
-        joyStickMaxValues_   .resize(joySticksSize_);
-        joyStickMiddleValues_.resize(joySticksSize_);
-        joyStickCalibrations_.resize(joySticksSize_);
-
-        for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++)
-        {
-            // Generate some sort of execution unique id per joy stick
-            std::string id = "JoyStick_";
-            id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Button))  + "_";
-            id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Axis))    + "_";
-            id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Slider))  + "_";
-            id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_POV))     + "_";
-            id += multi_cast<std::string>(joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Vector3)) + "_";
-            id += joySticks_[iJoyStick]->vendor();
-            for (unsigned int i = 0; i < iJoyStick; ++i)
-            {
-                if (id == joyStickIDs_[i])
-                {
-                    // Two joysticks are probably equal --> add the index as well
-                    id += "_" + multi_cast<std::string>(iJoyStick);
-                }
-            }
-            joyStickIDs_[iJoyStick] = id;
-
-            size_t axes = sliderAxes + (size_t)this->joySticks_[iJoyStick]->getNumberOfComponents(OIS::OIS_Axis);
-            loadCalibration(joyStickMinValues_[iJoyStick], id, "MinValue", axes, -32768);
-            loadCalibration(joyStickMaxValues_[iJoyStick], id, "MaxValue", axes,  32768);
-            loadCalibration(joyStickMiddleValues_[iJoyStick], id, "MiddleValue", axes,      0);
-        }
-
-        _evaluateCalibration();
-
+
+        devicesNum_ = 2 + inputSystem_->getNumberOfDevices(OIS::OISJoyStick);
         // state management
         activeStatesTriggered_.resize(devicesNum_);
 
-        // inform all states
-        for (std::map<std::string, InputState*>::const_iterator it = inputStatesByName_.begin();
-            it != inputStatesByName_.end(); ++it)
-        {
-            it->second->setNumOfJoySticks(joySticksSize_);
+        for (int i = 0; i < inputSystem_->getNumberOfDevices(OIS::OISJoyStick); i++)
+        {
+            try
+            {
+                joySticks_.push_back(new JoyStick(activeStatesTriggered_[2 + i], i));
+            }
+            catch (std::exception ex)
+            {
+                CCOUT(2) << "Warning: Failed to create joy stick: " << ex.what() << std::endl;
+            }
         }
 
         // inform all JoyStick Device Number Listeners
         for (ObjectList<JoyStickDeviceNumberListener>::iterator it = ObjectList<JoyStickDeviceNumberListener>::begin(); it; ++it)
-            it->JoyStickDeviceNumberChanged(joySticksSize_);
-
-    }
-
-    void InputManager::_evaluateCalibration()
-    {
-        for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick)
-        {
-            for (unsigned int i = 0; i < this->joyStickMinValues_[iJoyStick].size(); i++)
-            {
-                this->joyStickCalibrations_[iJoyStick].middleValue[i] = this->joyStickMiddleValues_[iJoyStick][i];
-                this->joyStickCalibrations_[iJoyStick].negativeCoeff[i] = - 1.0f / (this->joyStickMinValues_[iJoyStick][i] - this->joyStickMiddleValues_[iJoyStick][i]);
-                this->joyStickCalibrations_[iJoyStick].positiveCoeff[i] =   1.0f / (this->joyStickMaxValues_[iJoyStick][i] - this->joyStickMiddleValues_[iJoyStick][i]);
-            }
-        }
+            it->JoyStickDeviceNumberChanged(joySticks_.size());
     }
 
     void InputManager::_startCalibration()
     {
-        for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick)
-        {
-            // Set initial values
-            for (unsigned int i = 0; i < this->joyStickMinValues_[iJoyStick].size(); ++i)
-                this->joyStickMinValues_[iJoyStick][i] = INT_MAX;
-            for (unsigned int i = 0; i < this->joyStickMaxValues_[iJoyStick].size(); ++i)
-                this->joyStickMaxValues_[iJoyStick][i] = INT_MIN;
-            for (unsigned int i = 0; i < this->joyStickMiddleValues_[iJoyStick].size(); ++i)
-                this->joyStickMiddleValues_[iJoyStick][i] = 0;
-        }
+        BOOST_FOREACH(JoyStick* stick, joySticks_)
+            stick->startCalibration();
 
         getInstance().internalState_ |= Calibrating;
@@ -483,41 +358,6 @@
     void InputManager::_completeCalibration()
     {
-        for (unsigned int iJoyStick = 0; iJoyStick < this->joySticksSize_; ++iJoyStick)
-        {
-            // Get the middle positions now
-            unsigned int iAxis = 0;
-            for (unsigned int i = 0; i < sliderAxes/2; ++i)
-            {
-                this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mSliders[i].abX;
-                this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mSliders[i].abY;
-            }
-            // Note: joyStickMiddleValues_[iJoyStick] was already correctly resized in _configureJoySticks()
-            assert(joySticks_[iJoyStick]->getJoyStickState().mAxes.size() == joyStickMiddleValues_[iJoyStick].size() - sliderAxes);
-            for (unsigned int i = 0; i < joyStickMiddleValues_[iJoyStick].size() - sliderAxes; ++i)
-            {
-                this->joyStickMiddleValues_[iJoyStick][iAxis++] = this->joySticks_[iJoyStick]->getJoyStickState().mAxes[i].abs;
-            }
-
-            for (unsigned int i = 0; i < joyStickMinValues_[iJoyStick].size(); ++i)
-            {
-                // Minimum values
-                if (joyStickMinValues_[iJoyStick][i] == INT_MAX)
-                    joyStickMinValues_[iJoyStick][i] = -32768;
-                ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
-                    this->joyStickIDs_[iJoyStick], "MinValue", i, multi_cast<std::string>(joyStickMinValues_[iJoyStick][i]), false);
-
-                // Maximum values
-                if (joyStickMaxValues_[iJoyStick][i] == INT_MIN)
-                    joyStickMaxValues_[iJoyStick][i] = 32767;
-                ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
-                    this->joyStickIDs_[iJoyStick], "MaxValue", i, multi_cast<std::string>(joyStickMaxValues_[iJoyStick][i]), false);
-
-                // Middle values
-                ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
-                    this->joyStickIDs_[iJoyStick], "MiddleValue", i, multi_cast<std::string>(joyStickMiddleValues_[iJoyStick][i]), false);
-            }
-        }
-
-        _evaluateCalibration();
+        BOOST_FOREACH(JoyStick* stick, joySticks_)
+            stick->stopCalibration();
 
         // restore old input state
@@ -625,25 +465,17 @@
     void InputManager::_destroyJoySticks()
     {
-        if (joySticksSize_ > 0)
-        {
-            assert(inputSystem_);
-            for (unsigned int i = 0; i < joySticksSize_; i++)
-            {
-                try
-                {
-                    if (joySticks_[i] != 0)
-                        inputSystem_->destroyInputObject(joySticks_[i]);
-                }
-                catch (...)
-                {
-                    CCOUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl;
-                }
-            }
-
-            joySticks_.clear();
-            // don't use _configureNumberOfJoySticks(), might mess with registered handler if
-            // downgrading from 2 to 1 joystick
-            //_configureNumberOfJoySticks();
-            joySticksSize_ = 0;
+        assert(inputSystem_);
+        while (!joySticks_.empty())
+        {
+            try
+            {
+                delete joySticks_.back();
+            }
+            catch (...)
+            {
+                CCOUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl;
+            }
+            joySticks_.pop_back();
+            devicesNum_ = 2;
         }
         CCOUT(4) << "Joy sticks destroyed." << std::endl;
@@ -669,22 +501,4 @@
     }
 
-    void InputManager::_clearBuffers()
-    {
-        keysDown_.clear();
-        keyboardModifiers_ = 0;
-        mouseButtonsDown_.clear();
-        for (unsigned int i = 0; i < joySticksSize_; ++i)
-        {
-            joyStickButtonsDown_[i].clear();
-            for (int j = 0; j < 4; ++j)
-            {
-                sliderStates_[i].sliderStates[j].x = 0;
-                sliderStates_[i].sliderStates[j].y = 0;
-                povStates_[i][j] = 0;
-            }
-        }
-    }
-
-
     // ############################################################
     // #####                     Reloading                    #####
@@ -696,8 +510,6 @@
         Public interface. Only reloads immediately if the call stack doesn't
         include the update() method.
-    @param joyStickSupport
-        Whether or not to initialise joy sticks as well.
-    */
-    void InputManager::reloadInputSystem(bool joyStickSupport)
+    */
+    void InputManager::reloadInputSystem()
     {
         if (internalState_ & Ticking)
@@ -707,12 +519,7 @@
             // include an OIS method. So it would be a very bad thing to destroy it..
             internalState_ |= ReloadRequest;
-            // Misuse of internalState_: We can easily store the joyStickSupport bool.
-            // use Uninitialised as 0 value in order to make use of the overloaded |= operator
-            internalState_ |= joyStickSupport ? JoyStickSupport : Uninitialised;
         }
         else if (internalState_ & OISReady)
-        {
-            _reload(joyStickSupport);
-        }
+            _reload();
         else
         {
@@ -726,5 +533,5 @@
         Internal reload method. Destroys the OIS devices and loads them again.
     */
-    void InputManager::_reload(bool joyStickSupport)
+    void InputManager::_reload()
     {
         try
@@ -747,7 +554,7 @@
 
             // clear all buffers containing input information
-            _clearBuffers();
-
-            initialise(windowHnd_, mouseWidth, mouseHeight, joyStickSupport);
+            clearBuffers();
+
+            initialise(windowHnd_, mouseWidth, mouseHeight);
 
             CCOUT(3) << "Reloading done." << std::endl;
@@ -776,7 +583,6 @@
         else if (internalState_ & ReloadRequest)
         {
-            _reload(internalState_ & JoyStickSupport);
+            _reload();
             internalState_ &= ~ReloadRequest;
-            internalState_ &= ~JoyStickSupport;
         }
 
@@ -811,11 +617,6 @@
                 {
                     // Get smallest possible priority between 1 and maxStateStackSize_s
-#if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator
                     for(std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
                         rit != activeStates_.rend(); ++rit)
-#else
-                    for(std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin();
-                        rit != activeStates_.rend(); ++rit)
-#endif
                     {
                         if (rit->first < InputStatePriority::HighPriority)
@@ -868,6 +669,6 @@
         if (mouse_)
             mouse_->capture();
-        for (unsigned  int i = 0; i < joySticksSize_; i++)
-            joySticks_[i]->capture();
+        BOOST_FOREACH(JoyStick* stick, joySticks_)
+            stick->capture();
 
         if (!(internalState_ & Calibrating))
@@ -888,12 +689,4 @@
                     activeStatesTriggered_[Mouse][iState]->mouseButtonHeld(mouseButtonsDown_[iButton]);
             }
-
-            // call all the handlers for the held joy stick button events
-            for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
-                for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
-                {
-                    for (unsigned int iState = 0; iState < activeStatesTriggered_[JoyStick0 + iJoyStick].size(); ++iState)
-                        activeStatesTriggered_[JoyStick0 + iJoyStick][iState]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
-                }
 
             // update the handlers for each active handler
@@ -923,11 +716,6 @@
             bool occupied = false;
             activeStatesTriggered_[i].clear();
-#if defined( __MINGW32__ ) // Avoid the strange mingw-stl bug with const_reverse_iterator
-            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
-            {
-#else
             for (std::map<int, InputState*>::const_reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
             {
-#endif
                 if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_))
                 {
@@ -960,8 +748,9 @@
     void InputManager::clearBuffers()
     {
-        this->keysDown_.clear();
-        this->mouseButtonsDown_.clear();
-        for (unsigned int i = 0; i < this->joySticksSize_; ++i)
-            this->joyStickButtonsDown_[i].clear();
+        keysDown_.clear();
+        keyboardModifiers_ = 0;
+        mouseButtonsDown_.clear();
+        BOOST_FOREACH(JoyStick* stick, joySticks_)
+            stick->clearBuffer();
     }
 
@@ -1124,138 +913,22 @@
 
 
-    // ###### Joy Stick Events ######
-
-    /**
-    @brief
-        Returns the joy stick ID (orxonox) according to a OIS::JoyStickEvent
-    */
-    inline unsigned int InputManager::_getJoystick(const OIS::JoyStickEvent& arg)
-    {
-        // use the device to identify which one called the method
-        OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
-        unsigned int iJoyStick = 0;
-        while (joySticks_[iJoyStick] != joyStick)
-            iJoyStick++;
-        // assert: Unknown joystick fired an event.
-        assert(iJoyStick != joySticksSize_);
-        return iJoyStick;
-    }
-
-    bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        // check whether the button already is in the list (can happen when focus was lost)
-        std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
-        unsigned int iButton = 0;
-        while (iButton < buttonsDown.size() && buttonsDown[iButton] != button)
-            iButton++;
-        if (iButton == buttonsDown.size())
-            buttonsDown.push_back((JoyStickButtonCode::ByEnum)button);
-
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
-            activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonPressed(iJoyStick, (JoyStickButtonCode::ByEnum)button);
-
-        return true;
-    }
-
-    bool InputManager::buttonReleased(const OIS::JoyStickEvent &arg, int button)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        // remove the button from the joyStickButtonsDown_ list
-        std::vector<JoyStickButtonCode::ByEnum>& buttonsDown = joyStickButtonsDown_[iJoyStick];
-        for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++)
-        {
-            if (buttonsDown[iButton] == button)
-            {
-                buttonsDown.erase(buttonsDown.begin() + iButton);
-                break;
-            }
-        }
-
-        for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
-            activeStatesTriggered_[2 + iJoyStick][iState]->joyStickButtonReleased(iJoyStick, (JoyStickButtonCode::ByEnum)button);
-
-        return true;
-    }
-
-    /**
-    @brief
-        Calls the states for a particular axis with our enumeration.
-        Used by OIS sliders and OIS axes.
-    */
-    void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value)
-    {
-        if (internalState_ & Calibrating)
-        {
-            if (value < joyStickMinValues_[iJoyStick][axis])
-                joyStickMinValues_[iJoyStick][axis] = value;
-            if (value > joyStickMaxValues_[iJoyStick][axis])
-                joyStickMaxValues_[iJoyStick][axis] = value;
-        }
-        else
-        {
-            float fValue = static_cast<float>(value - joyStickCalibrations_[iJoyStick].middleValue[axis]);
-            if (fValue > 0.0f)
-                fValue *= joyStickCalibrations_[iJoyStick].positiveCoeff[axis];
-            else
-                fValue *= joyStickCalibrations_[iJoyStick].negativeCoeff[axis];
-
-            for (unsigned int iState = 0; iState < activeStatesTriggered_[2 + iJoyStick].size(); ++iState)
-                activeStatesTriggered_[2 + iJoyStick][iState]->joyStickAxisMoved(iJoyStick, axis, fValue);
-        }
-    }
-
-    bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        // keep in mind that the first 8 axes are reserved for the sliders
-        _fireAxis(iJoyStick, axis + sliderAxes, arg.state.mAxes[axis].abs);
-
-        return true;
-    }
-
-    bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX)
-            _fireAxis(iJoyStick, id * 2, arg.state.mSliders[id].abX);
-        else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY)
-            _fireAxis(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY);
-
-        return true;
-    }
-
-    bool InputManager::povMoved(const OIS::JoyStickEvent &arg, int id)
-    {
-        unsigned int iJoyStick = _getJoystick(arg);
-
-        // translate the POV into 8 simple buttons
-
-        int lastState = povStates_[iJoyStick][id];
-        if (lastState & OIS::Pov::North)
-            buttonReleased(arg, 32 + id * 4 + 0);
-        if (lastState & OIS::Pov::South)
-            buttonReleased(arg, 32 + id * 4 + 1);
-        if (lastState & OIS::Pov::East)
-            buttonReleased(arg, 32 + id * 4 + 2);
-        if (lastState & OIS::Pov::West)
-            buttonReleased(arg, 32 + id * 4 + 3);
-
-        povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction;
-
-        int currentState = povStates_[iJoyStick][id];
-        if (currentState & OIS::Pov::North)
-            buttonPressed(arg, 32 + id * 4 + 0);
-        if (currentState & OIS::Pov::South)
-            buttonPressed(arg, 32 + id * 4 + 1);
-        if (currentState & OIS::Pov::East)
-            buttonPressed(arg, 32 + id * 4 + 2);
-        if (currentState & OIS::Pov::West)
-            buttonPressed(arg, 32 + id * 4 + 3);
-
+    // ############################################################
+    // #####                Friend functions                  #####
+    // ##########                                        ##########
+    // ############################################################
+
+    /**
+    @brief
+        Checks whether there is already a joy stick with the given ID string.
+    @return
+        Returns true if ID is ok (unique), false otherwise.
+    */
+    bool InputManager::checkJoyStickID(const std::string& idString)
+    {
+        BOOST_FOREACH(JoyStick* stick, joySticks_)
+        {
+            if (stick->getIDString() == idString)
+                return false;
+        }
         return true;
     }
@@ -1336,5 +1009,5 @@
             }
             inputStatesByName_[name] = state;
-            state->setNumOfJoySticks(numberOfJoySticks());
+            state->JoyStickDeviceNumberChanged(numberOfJoySticks());
             state->setName(name);
             state->bAlwaysGetsInput_ = bAlwaysGetsInput;
@@ -1502,7 +1175,7 @@
         Reloads the input system
     */
-    void InputManager::reload(bool joyStickSupport)
-    {
-        getInstance().reloadInputSystem(joyStickSupport);
+    void InputManager::reload()
+    {
+        getInstance().reloadInputSystem();
     }
 
Index: code/branches/core4/src/core/input/InputManager.h
===================================================================
--- code/branches/core4/src/core/input/InputManager.h	(revision 3269)
+++ code/branches/core4/src/core/input/InputManager.h	(revision 3270)
@@ -54,32 +54,4 @@
 namespace orxonox
 {
-    /**
-    @brief
-        Helper class to realise a vector<int[4]>
-    */
-    class POVStates
-    {
-    public:
-        int& operator[](unsigned int index) { return povStates[index]; }
-        int povStates[4];
-    };
-
-    /**
-    @brief
-        Helper class to realise a vector< {int[4], int[4]} >
-    */
-    class SliderStates
-    {
-    public:
-        IntVector2 sliderStates[4];
-    };
-
-    struct JoyStickCalibration
-    {
-        int middleValue[24];
-        float positiveCoeff[24];
-        float negativeCoeff[24];
-    };
-
     struct InputStatePriority : OrxEnum<InputStatePriority>
     {
@@ -101,8 +73,9 @@
     class _CoreExport InputManager
         : public OrxonoxClass,
-        public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener
+        public OIS::KeyListener, public OIS::MouseListener
     {
         // --> setConfigValues is private
         friend class ClassIdentifier<InputManager>;
+        friend class JoyStick;
 
     public:
@@ -115,13 +88,12 @@
             Calibrating      = 0x08,
             ReloadRequest    = 0x10,
-            JoyStickSupport  = 0x20 // used with ReloadRequest to store a bool
         };
 
-        InputManager ();
+        InputManager (size_t windowHnd, unsigned int windowWidth, unsigned int windowHeight);
         ~InputManager();
 
-        void initialise(size_t windowHnd, int windowWidth, int windowHeight, bool joyStickSupport = true);
-
-        void reloadInputSystem(bool joyStickSupport = true);
+        void initialise(size_t windowHnd, unsigned int windowWidth, unsigned int windowHeight);
+
+        void reloadInputSystem();
 
         void clearBuffers();
@@ -129,5 +101,5 @@
         unsigned int  numberOfKeyboards() { return keyboard_ ? 1 : 0; }
         unsigned int  numberOfMice()      { return mouse_    ? 1 : 0; }
-        unsigned int  numberOfJoySticks() { return joySticksSize_; }
+        unsigned int  numberOfJoySticks() { return joySticks_.size(); }
 
         void setWindowExtents(const int width, const int height);
@@ -156,9 +128,12 @@
         // console commands
         static void calibrate();
-        static void reload(bool joyStickSupport = true);
+        static void reload();
 
     public: // variables
         static EmptyHandler                 EMPTY_HANDLER;
-        static const unsigned int           sliderAxes = 8;
+
+    private: // functions for friends
+        OIS::InputManager* getInputSystem() { return this->inputSystem_; }
+        bool checkJoyStickID(const std::string&);
 
     private: // functions
@@ -168,5 +143,5 @@
         // Intenal methods
         void _initialiseKeyboard();
-        void _initialiseMouse();
+        void _initialiseMouse(unsigned int windowWidth, unsigned int windowHeight);
         void _initialiseJoySticks();
         void _configureJoySticks();
@@ -181,7 +156,6 @@
         void _destroyJoySticks();
         void _destroyState(InputState* state);
-        void _clearBuffers();
-
-        void _reload(bool joyStickSupport);
+
+        void _reload();
 
         void _fireAxis(unsigned int iJoyStick, int axis, int value);
@@ -197,11 +171,4 @@
         bool keyPressed    (const OIS::KeyEvent      &arg);
         bool keyReleased   (const OIS::KeyEvent      &arg);
-        bool buttonPressed (const OIS::JoyStickEvent &arg, int button);
-        bool buttonReleased(const OIS::JoyStickEvent &arg, int button);
-        bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
-        bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
-        bool povMoved      (const OIS::JoyStickEvent &arg, int id);
-        // don't remove that! Or else add OIS as dependency library to orxonox.
-        bool vector3Moved  (const OIS::JoyStickEvent &arg, int id) { return true; }
 
         void setConfigValues();
@@ -212,7 +179,5 @@
         OIS::Keyboard*                      keyboard_;             //!< OIS mouse
         OIS::Mouse*                         mouse_;                //!< OIS keyboard
-        std::vector<OIS::JoyStick*>         joySticks_;            //!< OIS joy sticks
-        unsigned int                        joySticksSize_;
-        std::vector<std::string>            joyStickIDs_;          //!< Execution unique identification strings for the joy sticks
+        std::vector<JoyStick*>              joySticks_;            //!< Orxonox joy sticks
         unsigned int                        devicesNum_;
         size_t                              windowHnd_;            //!< Render window handle
@@ -234,21 +199,8 @@
         std::vector<InputState*>            activeStatesTicked_;
 
-        // joystick calibration
-        std::vector<std::vector<int> >      joyStickMinValues_;
-        std::vector<std::vector<int> >      joyStickMaxValues_;
-        std::vector<std::vector<int> >      joyStickMiddleValues_;
-        std::vector<ConfigValueContainer*>  calibrationConfigValueContainers_;
-        std::vector<JoyStickCalibration>    joyStickCalibrations_; 
-
         unsigned int                        keyboardModifiers_;    //!< Bit mask representing keyboard modifiers.
-        std::vector<POVStates>              povStates_;            //!< Keeps track of the joy stick POV states.
-        std::vector<SliderStates>           sliderStates_;         //!< Keeps track of the possibly two slider axes.
 
         std::vector<Key>                    keysDown_;
-        std::vector<MouseButtonCode::ByEnum>      mouseButtonsDown_;
-        std::vector<std::vector<JoyStickButtonCode::ByEnum> >  joyStickButtonsDown_;
-
-        // ConfigValues
-        std::string                         calibrationFilename_;  //!< Joy stick calibration ini filename
+        std::vector<MouseButtonCode::ByEnum> mouseButtonsDown_;
 
         static InputManager*                singletonRef_s;
Index: code/branches/core4/src/core/input/InputState.h
===================================================================
--- code/branches/core4/src/core/input/InputState.h	(revision 3269)
+++ code/branches/core4/src/core/input/InputState.h	(revision 3270)
@@ -40,8 +40,9 @@
 #include <vector>
 #include "InputInterfaces.h"
+#include "JoyStickDeviceNumberListener.h"
 
 namespace orxonox
 {
-    class _CoreExport InputState
+    class _CoreExport InputState : public JoyStickDeviceNumberListener
     {
         friend class InputManager;
@@ -111,5 +112,5 @@
 
     private:
-        void setNumOfJoySticks(unsigned int n)
+        void JoyStickDeviceNumberChanged(unsigned int n)
         {
             bInputDeviceEnabled_.resize(n + 2);
Index: code/branches/core4/src/core/input/JoyStick.cc
===================================================================
--- code/branches/core4/src/core/input/JoyStick.cc	(revision 3270)
+++ code/branches/core4/src/core/input/JoyStick.cc	(revision 3270)
@@ -0,0 +1,340 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the JoyStick wrapper class.
+*/
+
+#include "JoyStick.h"
+
+#include <ois/OISJoyStick.h>
+#include <ois/OISInputManager.h>
+#include <boost/foreach.hpp>
+
+#include "core/ConfigFileManager.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "util/Convert.h"
+#include "InputState.h"
+#include "InputManager.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Helper function that loads the config value vector of one coefficient
+    */
+    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue);
+
+    JoyStick::JoyStick(const std::vector<InputState*>& states, unsigned int id)
+        : id_(id)
+        , bCalibrating_(false)
+        , inputStates_(states)
+    {
+        RegisterRootObject(JoyStick);
+        this->setConfigValues();
+
+        OIS::InputManager* system = InputManager::getInstance().getInputSystem();
+        oisJoyStick_ = static_cast<OIS::JoyStick*>(system->createInputObject(OIS::OISJoyStick, true));
+        oisJoyStick_->setEventCallback(this);
+
+        idString_ = "JoyStick_";
+        std::string name = oisJoyStick_->vendor();
+        replaceCharacters(name, ' ', '_');
+        idString_ += name + "_";
+        idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Button))  + "_";
+        idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Axis))    + "_";
+        idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Slider))  + "_";
+        idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_POV));
+        //idString_ += multi_cast<std::string>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Vector3));
+
+        if (InputManager::getInstance().checkJoyStickID(idString_) == false)
+        {
+            // Make the ID unique for this execution time.
+            idString_ += "_" + multi_cast<std::string>(id_);
+        }
+
+        COUT(4) << "Created OIS joy stick with ID " << idString_ << std::endl;
+
+        // Load calibration
+        size_t axes = sliderAxes_s + static_cast<size_t>(oisJoyStick_->getNumberOfComponents(OIS::OIS_Axis));
+        loadCalibration(configMinValues_,  idString_, "MinValue",  axes,  -32768);
+        loadCalibration(configMaxValues_,  idString_, "MaxValue",  axes,   32768);
+        loadCalibration(configZeroValues_, idString_, "ZeroValue", axes, 0);
+        this->evaluateCalibration();
+    }
+
+    JoyStick::~JoyStick()
+    {
+        try
+        {
+            OIS::InputManager* system = InputManager::getInstance().getInputSystem();
+            system->destroyInputObject(oisJoyStick_);
+        }
+        catch (...)
+        {
+            COUT(1) << "Joy stick destruction failed! Potential resource leak!" << std::endl;
+        }
+    }
+
+    /**
+    @brief
+        Callback for the joy stick calibration config file. @see setConfigValues.
+    */
+    void JoyStick::calibrationFileCallback()
+    {
+        ConfigFileManager::getInstance().setFilename(ConfigFileType::JoyStickCalibration, calibrationFilename_);
+    }
+
+    /**
+    @brief
+        Sets the configurable values.
+    */
+    void JoyStick::setConfigValues()
+    {
+        SetConfigValue(calibrationFilename_, "joystick_calibration.ini")
+            .description("Ini filename for the the joy stick calibration data.")
+            .callback(this, &JoyStick::calibrationFileCallback);
+    }
+
+    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue)
+    {
+        list.resize(size);
+        unsigned int configValueVectorSize = ConfigFileManager::getInstance().getVectorSize(ConfigFileType::JoyStickCalibration, sectionName, valueName);
+        if (configValueVectorSize > size)
+            configValueVectorSize = size;
+
+        for (unsigned int i = 0; i < configValueVectorSize; ++i)
+        {
+            list[i] = multi_cast<int>(ConfigFileManager::getInstance().getValue(
+                ConfigFileType::JoyStickCalibration, sectionName, valueName, i, multi_cast<std::string>(defaultValue), false));
+        }
+
+        // fill the rest with default values
+        for (unsigned int i = configValueVectorSize; i < size; ++i)
+        {
+            list[i] = defaultValue;
+        }
+    }
+
+    void JoyStick::startCalibration()
+    {
+        bCalibrating_ = true;
+
+        // Set initial values
+        BOOST_FOREACH(int& minVal, configMinValues_)
+            minVal = INT_MAX;
+        BOOST_FOREACH(int& minVal, configMaxValues_)
+            minVal = INT_MIN;
+        BOOST_FOREACH(int& zeroVal, configZeroValues_)
+            zeroVal = 0;
+    }
+
+    void JoyStick::stopCalibration()
+    {
+        // Get the middle positions now
+        unsigned int iAxis = 0;
+        for (unsigned int i = 0; i < sliderAxes_s/2; ++i)
+        {
+            configZeroValues_[iAxis++] = oisJoyStick_->getJoyStickState().mSliders[i].abX;
+            configZeroValues_[iAxis++] = oisJoyStick_->getJoyStickState().mSliders[i].abY;
+        }
+        // Note: joyStickMiddleValues_[iJoyStick] was already correctly resised in loadCalibration()
+        assert(oisJoyStick_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s);
+        for (unsigned int i = 0; i < configZeroValues_.size() - sliderAxes_s; ++i)
+            configZeroValues_[iAxis++] = oisJoyStick_->getJoyStickState().mAxes[i].abs;
+
+        for (unsigned int i = 0; i < configMinValues_.size(); ++i)
+        {
+            // Minimum values
+            if (configMinValues_[i] == INT_MAX)
+                configMinValues_[i] = -32768;
+            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
+                idString_, "MinValue", i, multi_cast<std::string>(configMinValues_[i]), false);
+
+            // Maximum values
+            if (configMaxValues_[i] == INT_MIN)
+                configMaxValues_[i] = 32767;
+            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
+                idString_, "MaxValue", i, multi_cast<std::string>(configMaxValues_[i]), false);
+
+            // Middle values
+            ConfigFileManager::getInstance().setValue(ConfigFileType::JoyStickCalibration,
+                idString_, "ZeroValue", i, multi_cast<std::string>(configZeroValues_[i]), false);
+        }
+
+        this->evaluateCalibration();
+
+        bCalibrating_ = false;
+    }
+
+    void JoyStick::evaluateCalibration()
+    {
+        for (unsigned int i = 0; i < configMinValues_.size(); i++)
+        {
+            zeroValues_[i] = configZeroValues_[i];
+            negativeCoeffs_[i] = - 1.0f / (configMinValues_[i] - configZeroValues_[i]);
+            positiveCoeffs_[i] =   1.0f / (configMaxValues_[i] - configZeroValues_[i]);
+        }
+    }
+
+    void JoyStick::clearBuffer()
+    {
+        pressedButtons_.clear();
+        for (int j = 0; j < 4; ++j)
+        {
+            povStates_[j] = 0;
+            sliderStates_[j][0] = 0;
+            sliderStates_[j][1] = 0;
+        }
+    }
+
+
+    // ###### Events ######
+
+    void JoyStick::capture()
+    {
+        oisJoyStick_->capture();
+
+        // call all the handlers for the held joy stick button events
+        for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
+        {
+            BOOST_FOREACH(InputState* state, inputStates_)
+                state->joyStickButtonHeld(id_, pressedButtons_[iButton]);
+        }
+    }
+
+    bool JoyStick::buttonPressed(const OIS::JoyStickEvent &arg, int button)
+    {
+        // check whether the button already is in the list (can happen when focus was lost)
+        unsigned int iButton = 0;
+        while (iButton < pressedButtons_.size() && pressedButtons_[iButton] != button)
+            iButton++;
+        if (iButton == pressedButtons_.size())
+            pressedButtons_.push_back(static_cast<JoyStickButtonCode::ByEnum>(button));
+
+        BOOST_FOREACH(InputState* state, inputStates_)
+            state->joyStickButtonPressed(id_, static_cast<JoyStickButtonCode::ByEnum>(button));
+
+        return true;
+    }
+
+    bool JoyStick::buttonReleased(const OIS::JoyStickEvent &arg, int button)
+    {
+        // remove the button from the pressedButtons_ list
+        for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
+        {
+            if (static_cast<int>(pressedButtons_[iButton]) == button)
+            {
+                pressedButtons_.erase(pressedButtons_.begin() + iButton);
+                break;
+            }
+        }
+
+        BOOST_FOREACH(InputState* state, inputStates_)
+            state->joyStickButtonPressed(id_, static_cast<JoyStickButtonCode::ByEnum>(button));
+
+        return true;
+    }
+
+    /**
+    @brief
+        Calls the states for a particular axis with our enumeration.
+        Used by OIS sliders and OIS axes.
+    */
+    void JoyStick::fireAxis(int axis, int value)
+    {
+        if (bCalibrating_)
+        {
+            if (value < configMinValues_[axis])
+                configMinValues_[axis] = value;
+            if (value > configMaxValues_[axis])
+                configMaxValues_[axis] = value;
+        }
+        else
+        {
+            float fValue = static_cast<float>(value - zeroValues_[axis]);
+            if (fValue > 0.0f)
+                fValue *= positiveCoeffs_[axis];
+            else
+                fValue *= negativeCoeffs_[axis];
+
+            BOOST_FOREACH(InputState* state, inputStates_)
+                state->joyStickAxisMoved(id_, axis, fValue);
+        }
+    }
+
+    bool JoyStick::axisMoved(const OIS::JoyStickEvent &arg, int axis)
+    {
+        // keep in mind that the first 8 axes are reserved for the sliders
+        this->fireAxis(axis + sliderAxes_s, arg.state.mAxes[axis].abs);
+
+        return true;
+    }
+
+    bool JoyStick::sliderMoved(const OIS::JoyStickEvent &arg, int id)
+    {
+        if (sliderStates_[id][0] != arg.state.mSliders[id].abX)
+            fireAxis(id * 2, arg.state.mSliders[id].abX);
+        else if (sliderStates_[id][1] != arg.state.mSliders[id].abY)
+            fireAxis(id * 2 + 1, arg.state.mSliders[id].abY);
+
+        return true;
+    }
+
+    bool JoyStick::povMoved(const OIS::JoyStickEvent &arg, int id)
+    {
+        // translate the POV into 8 simple buttons
+
+        int lastState = povStates_[id];
+        if (lastState & OIS::Pov::North)
+            buttonReleased(arg, 32 + id * 4 + 0);
+        if (lastState & OIS::Pov::South)
+            buttonReleased(arg, 32 + id * 4 + 1);
+        if (lastState & OIS::Pov::East)
+            buttonReleased(arg, 32 + id * 4 + 2);
+        if (lastState & OIS::Pov::West)
+            buttonReleased(arg, 32 + id * 4 + 3);
+
+        povStates_[id] = arg.state.mPOV[id].direction;
+
+        int currentState = povStates_[id];
+        if (currentState & OIS::Pov::North)
+            buttonPressed(arg, 32 + id * 4 + 0);
+        if (currentState & OIS::Pov::South)
+            buttonPressed(arg, 32 + id * 4 + 1);
+        if (currentState & OIS::Pov::East)
+            buttonPressed(arg, 32 + id * 4 + 2);
+        if (currentState & OIS::Pov::West)
+            buttonPressed(arg, 32 + id * 4 + 3);
+
+        return true;
+    }
+}
Index: code/branches/core4/src/core/input/JoyStick.h
===================================================================
--- code/branches/core4/src/core/input/JoyStick.h	(revision 3270)
+++ code/branches/core4/src/core/input/JoyStick.h	(revision 3270)
@@ -0,0 +1,108 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief 
+*/
+
+#ifndef _JoyStick_H__
+#define _JoyStick_H__
+
+#include "core/CorePrereqs.h"
+
+#include <string>
+#include <vector>
+#include "InputInterfaces.h"
+
+namespace orxonox
+{
+    class _CoreExport JoyStick : public OrxonoxClass, public OIS::JoyStickListener
+    {
+    private:
+        struct JoyStickCalibration
+        {
+        };
+
+    public:
+        JoyStick(const std::vector<InputState*>& states, unsigned int id);
+        ~JoyStick();
+
+        void setConfigValues();
+
+        OIS::JoyStick* getOISJoyStick() { return this->oisJoyStick_; }
+        const std::string& getIDString() const { return this->idString_; }
+
+        void startCalibration();
+        void stopCalibration();
+
+        void capture();
+        void clearBuffer();
+
+    private:
+        void calibrationFileCallback();
+        void evaluateCalibration();
+        void fireAxis(int axis, int value);
+
+        bool buttonPressed (const OIS::JoyStickEvent &arg, int button);
+        bool buttonReleased(const OIS::JoyStickEvent &arg, int button);
+        bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
+        bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
+        bool povMoved      (const OIS::JoyStickEvent &arg, int id);
+        // don't remove that! Or else add OIS as dependency library to orxonox (it actually is..)
+        bool vector3Moved  (const OIS::JoyStickEvent &arg, int id) { return true; }
+
+        static const unsigned int sliderAxes_s = 8;
+
+        OIS::JoyStick* oisJoyStick_;
+        const unsigned int id_;
+        std::string idString_;
+
+        // calibration
+        bool bCalibrating_;
+        int zeroValues_[24];
+        float positiveCoeffs_[24];
+        float negativeCoeffs_[24];
+
+        std::vector<int> configMinValues_;
+        std::vector<int> configMaxValues_;
+        std::vector<int> configZeroValues_;
+
+        int povStates_[4];
+        int sliderStates_[4][2];
+        std::vector<JoyStickButtonCode::ByEnum> pressedButtons_;
+
+        // InputState handling
+        const std::vector<InputState*>& inputStates_;
+
+        // ConfigValues
+        std::string calibrationFilename_;  //!< Joy stick calibration ini filename
+    };
+}
+
+#endif /* _JoyStick_H__ */
Index: code/branches/core4/src/core/input/SimpleInputState.cc
===================================================================
--- code/branches/core4/src/core/input/SimpleInputState.cc	(revision 3269)
+++ code/branches/core4/src/core/input/SimpleInputState.cc	(revision 3270)
@@ -59,10 +59,4 @@
         }
         update();
-    }
-
-    void SimpleInputState::keyPressed(const KeyEvent& evt)
-    {
-        if (keyHandler_)
-            keyHandler_->keyPressed(evt);
     }
 
Index: code/branches/core4/src/core/input/SimpleInputState.h
===================================================================
--- code/branches/core4/src/core/input/SimpleInputState.h	(revision 3269)
+++ code/branches/core4/src/core/input/SimpleInputState.h	(revision 3270)
@@ -119,4 +119,10 @@
     }
 
+    inline void SimpleInputState::keyPressed(const KeyEvent& evt)
+    {
+        if (keyHandler_)
+            keyHandler_->keyPressed(evt);
+    }
+
     inline void SimpleInputState::keyReleased(const KeyEvent& evt)
     {
Index: code/branches/core4/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- code/branches/core4/src/orxonox/gamestates/GSGraphics.cc	(revision 3269)
+++ code/branches/core4/src/orxonox/gamestates/GSGraphics.cc	(revision 3270)
@@ -122,6 +122,5 @@
 
         // Calls the InputManager which sets up the input devices.
-        inputManager_ = new InputManager();
-        inputManager_->initialise(windowHnd, renderWindow->getWidth(), renderWindow->getHeight(), true);
+        inputManager_ = new InputManager(windowHnd, renderWindow->getWidth(), renderWindow->getHeight());
 
         // load master key bindings
Index: code/branches/core4/src/util/StringUtils.cc
===================================================================
--- code/branches/core4/src/util/StringUtils.cc	(revision 3269)
+++ code/branches/core4/src/util/StringUtils.cc	(revision 3270)
@@ -490,3 +490,24 @@
         return std::string::npos;
     }
+
+    /**
+        @brief Replaces individual charaters
+        @param str String to be manipulated
+        @param target Character to be replaced
+        @param replacement Replacement character
+        @return Number of replacements
+    */
+    _UtilExport size_t replaceCharacters(std::string& str, char target, char replacement)
+    {
+        size_t j = 0;
+        for (size_t i = 0; i < str.size(); ++i)
+        {
+            if (str[i] == target)
+            {
+                str[i] = replacement;
+                ++j;
+            }
+        }
+        return j;
+    }
 }
Index: code/branches/core4/src/util/StringUtils.h
===================================================================
--- code/branches/core4/src/util/StringUtils.h	(revision 3269)
+++ code/branches/core4/src/util/StringUtils.h	(revision 3270)
@@ -77,4 +77,6 @@
     _UtilExport size_t      getCommentPosition(const std::string& str);
     _UtilExport size_t      getNextCommentPosition(const std::string& str, size_t start = 0);
+
+    _UtilExport size_t      replaceCharacters(std::string& str, char target, char replacement);
 }
 
