#ifndef _VARIABLESGLOBAL_H
#define _VARIABLESGLOBAL_H

namespace Engine {
/** \brief Represents a variable that can be modified and read within the game
 *
 * \note Variables \b MUST be declared as static variables, otherwise the memory that
 * hold their values get invalidated and the system gets unstable!
 */
class Variable {
	public:
		/** \brief The constructor to be used when initializing a Variable
		 *
		 * \param name  The name under which the variable is engine wide
		 * accessible
		 * \param value  The value it is assigned to.
		 *
		 * The value string gets automatically converted to a float with atof ().
		 * Modification of a Variable must always be made with the Get*, Set*
		 * functions.
		 */
		Variable (const std::string &name, const std::string &value);

		/** \brief Parses and sets the corresponding value */
		void Set (const std::string &value);

		/** \brief Returns the string value of the Variable */
		std::string& GetStringValue () {
			return mStringValue;
		}
		/** \brief Returns the float value of the Variable */
		float& GetFloatValue () {
			return mFloatValue;
		}
		/** \brief Returns the float value of the Variable */
		bool& GetBoolValue () {
			return mBoolValue;
		}
		void SetStringValue (const std::string &value) {
			mStringValue = value;
		}
		void SetFloatValue (float value) {
			mFloatValue = value;
		}
		void SetBoolValue (bool value) {
			mBoolValue = value;
		}
		void SetBoolValueFromString (std::string str_value) {
			mBoolValue = ParseBoolValue (str_value);
		}

	private:
		/** \brief The default constructor must not be used.
		 *
		 * Use \code
		 * Variable (const std::string &name, const std::string &value)
		 * \endcode
		 * instead.
		 * */
		Variable () { assert (0); }
		/** \brief Registeres this Variable with the Variables System */
		void RegisterVariable (const std::string &name);

		/** \brief Parses the input value and checks whether it resembles true or not
		 *
		 * Valid true expressions are:
		 *   - any float values that are unequal to zero
		 *   - true (case insensitive)
		 *   - yes (case insensitive)
		 *
		 * \returns true if value contains a value that qualifies as a valid "true" expression
		 */
		bool ParseBoolValue (std::string value);

		std::string mName;
		std::string mStringValue;
		float mFloatValue;
		bool mBoolValue;

		friend class Variables;
};

/** \brief Provides access to a Variable stored under the given name */
Variable* GetVariable (const std::string &name);
/** \brief Sets the vaule of the Variable */
bool SetVariableValue (const std::string &name, const std::string &value);
/** \brief Returns the string value of the Variable with the given name */
std::string& GetVariableString (const std::string &name, std::string def = "");
/** \brief Returns the float value of the Variable with the given name */
float& GetVariableFloat (const std::string &name, float def = 0.);
/** \brief Returns the boolean value of the Variable with the given name */
bool& GetVariableBool (const std::string &name, bool def = false);


}
#endif // _VARIABLESGLOBAL_H
