//----------------------------------------------------------------------------
//	Copyright (C) 2002, 2003, 2004 Humboldt-Universitaet zu Berlin
//
//	This library is free software; you can redistribute it and/or
//	modify it under the terms of the GNU Lesser General Public
//	License as published by the Free Software Foundation; either
//	version 2.1 of the License, or (at your option) any later version.
//
//	This library 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
//	Lesser General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public
//	License along with this library; if not, write to the Free Software
//	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//----------------------------------------------------------------------------
/**	\file DfDt.h

 \author Sascha Qualitz

 \date created at 2009/10/26

 \brief Declaration of DfDt

 \since 3.0
 */

#ifndef ODEMX_DFDT_INCLUDED
#define ODEMX_DFDT_INCLUDED


namespace odemx {
	namespace base {
		namespace continuous {

			//Forward declaration
			class Continuous;

			class ODEObject;

			/** \class DfDt

				\ingroup base

				\author Sascha Qualitz

				\brief Object for handling a derived by time equation-element in the class ODEObject

				To describe ordinary derived by time equations the user have to to use this class. The user can use this class in different ways.
				With look and feel of a variable or with look and feel of an array. If used as a variable the user have to set the correct index, before using
				this object.

				\sa JacobiMatrix
				\sa Derivates
			 */
			class DfDt {
			public:
				/**
					\brief Construction
					\param continuous
						pointer to the continuous object where the dfdt-element belongs to

					\note The variable index_ will be set to 0
				*/
				DfDt(Continuous* continuous);

				/**
					\brief Construction
					\param continuous
						pointer to the continuous object where the dfdt-element belongs to
					\param index
						index for getter and setter (range 0..(Dimension-1))
				*/
				DfDt(Continuous* continuous, unsigned index);

				/// destruction
				virtual ~DfDt();

				/**
					\brief Overrides the converting operator double to convert implicit an object of type DfDt to double

					\note If this operator is called, the double value is the value that is returned by the method getDfDt(index_) of the corresponding continuous-object.
					The variable index_ is set to an index between 0 and continuous->getDimension before. To set the variables index_ see also the methods
					operator [] and setIndex(unsigned index).
				*/
				operator double() {
					return this->getValue();
				}

				/**
					\brief Overrides the assignment operator to store the value in the object of type DfDt in the VariableContainer
					\param value
						The value that is set
				*/
				DfDt& operator =(const DfDt& value);

				/**
					\brief Overrides the assignment operator to store the value of type double in the VariableContainer
					\param value
						The value that is set
				*/
				DfDt& operator =(const double value);

				/**
					\brief Overrides the index operator to set the internal variable index_
					\param index
						index of the variable to get/set (range 0..(Dimension-1))
				*/
				DfDt& operator [](const unsigned i);

				/**
					\brief Get value of the dfdt-element, at the index index_

					To get the correct value you have to set index_ with the setIndex-Method, overwritten operator[]
					or the constructor.
				*/
				double getValue() const;

				/**
					\brief Get value of the dfdt-element
					\param index
						index of the variable to get (range 0..(Dimension-1))
				*/
				double getValue(unsigned index) const;

				/**
					\brief Set the value of type double
					\param index
						index of the variable to set (range 0..(Dimension-1))
					\param value
						The value that is set
				*/
				void setValue(unsigned index, double value);

				/**
					\brief Set the value of type DfDt
					\param index
						index of the variable to set (range 0..(Dimension-1))
					\param value
						The value that is set
				*/
				void setValue(unsigned index, DfDt& value);

				/**
					\brief Set the value of type DfDt, at the index index_
					\param value
						The value that is set

					To set the value of the dfdt-element at the correct position you have to set index_ with the setIndex-Method, overwritten operator[]
					or the constructor.
				*/
				void setValue(DfDt& value);

				/**
					\brief Set the value of type double, at the index index_
					\param value
						The value that is set

					To set the value of the dfdt-element at the correct position you have to set index_ with the setIndex-Method, overwritten operator[]
					or the constructor.
				*/
				void setValue(double value);

				/**
					\brief Sets the variable index_
					\param index
						index of the variable to set/get (range 0..(Dimension-1))
				*/
				void setIndex(unsigned index);

				/**
					\brief Sets the variables continuous and index_
					\param continuous
						pointer to the continuous object where dfdt-element belongs to
					\param index
						index of the variable to set/get (range 0..(Dimension-1))

				void init(Continuous* continuous, unsigned index);*/

				/**
					\brief Sets the variable continuous
					\param continuous
						pointer to the continuous object where equation-element belongs to
				*/
				void setContinuous(Continuous* continuous);

			private:
				/** pointer to the continuous object where the dfdt-element belongs to
				 */
				Continuous* continuous;

				/** index of the variable to get/set (range 0..(Dimension-1))
				*/
				unsigned index_;

				/* double variable to store the value of continuous->getValueForDerivative(index) for later use
				*/
				double value_;

				/* boolean variable that store the information, if value_ is set or not
				*/
				bool isValueSet_;
			};
		}
	}
}

#endif /* ODEMX_DFDT_INCLUDED */
