//----------------------------------------------------------------------------
//	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 JacobiMatrix.h
 * @author Sascha Qualitz
 * @date created at 2009/10/26
 * @brief Declaration of odemx::base::Continuous::JacobiMatrix
 * @sa JacobiMatrix.cpp
 * @since 3.0
 */

#ifndef ODEMX_JACOBIMATRIX_INCLUDED
#define ODEMX_JACOBIMATRIX_INCLUDED


namespace odemx {
	namespace base {
		namespace continuous {

			//Forward declaration
			class Continuous;

			class ODEObject;
			/** \class JacobiMatrix

				\ingroup base

				\author Sascha Qualitz

				\brief Object for handling an equation-element in the class ODEObject

				To describe the jacobi-matrix of ordinary differential 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 a matrix. If used as a variable the user have to set the correct indeces, before using
				this object.

				\sa DerivatesMatrix
				\sa DfDt
			 */

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

					\note The variables row_, column_ and otherContinuous will be set to 0
				*/
				JacobiMatrix(Continuous* continuous);

				/**
					\brief Construction
					\param continuous
						pointer to the continuous object where the jacobi-element belongs to
					\param row
						The row number of the matrix
					\param column
						The column number of the matrix

					\note The variable otherContinuous will be set to 0
				*/
				JacobiMatrix(Continuous* continuous, unsigned row, unsigned column);

				/**
					\brief Construction
					\param continuous
						pointer to the continuous object where the jacobi-element belongs to
					\param otherContinuous
						pointer to a continuous instance which influences the right hand side

					\note The variables row_ and column_ will be set to 0
				*/
				JacobiMatrix(Continuous* continuous, Continuous* otherContinuous);

				/**
					\brief Construction
					\param continuous
						pointer to the continuous object where the jacobi-element belongs to
					\param otherContinuous
						pointer to a continuous instance which influences the right hand side
					\param row
						The row number of the matrix
					\param column
						The column number of the matrix
				*/
				JacobiMatrix(Continuous* continuous, Continuous* otherContinuous, unsigned row, unsigned column);

				/// destruction
				~JacobiMatrix();

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

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

				/**
					\brief Overrides the operator '()' to set the values of row_ and column_
					\param row
						The row number of the matrix
					\param column
						The column number of the matrix
				*/
				JacobiMatrix& operator ()(const unsigned row, const unsigned column);

				/**
					\brief Get value of the jacobi-matrix, at the indeces row_ and column_

					To get the correct value of the matrix you have to set row_ and column_ with the void setMatrixIndeces-Method, overwritten operator()
					or the constructor.
				*/
				double getValue() const;

				/**
					\brief Get the value of the jacobi-matrix, at the indeces row and column
					\param row
						The row number of the matrix
					\param column
						The column number of the matrix
				*/
				double getValue(unsigned row, unsigned column) const;

				/**
					\brief Set the value of the jacobi-matrix, at the indeces row_ and column_
					\param value
						The value that is set

					\note To set the value of the matrix at the right position you have to set row_ and column_ with the void setMatrixIndeces-Method, overwritten operator()
					or the constructor.
				*/
				void setValue(double value);

				/**
					\brief Set the value of the jacobi-matrix, at the indexes row and column
					\param row
						The row number of the matrix
					\param column
						The column number of the matrix
					\param value
						The value that is set
				*/
				void setValue(unsigned row, unsigned column, double value);

				/**
					\brief Sets the variables continuous, otherContinuous, row_ and column_ again
					\param continuous
						pointer to the continuous object where the jacobi-element belongs to
					\param otherContinuous
						pointer to a continuous instance which influences the right hand side
					\param row
						The row number of the matrix
					\param column
						The column number of the matrix

				void init(Continuous* continuous, Continuous* otherContinuous, unsigned row, unsigned column);*/

				/**
					\brief Sets the variables row_ and column_ new
					\param row
						The row number of the matrix
					\param column
						The column number of the matrix
				*/
				void setMatrixIndeces(unsigned row, unsigned column);

				/**
					\brief Sets the variable continuous and otherContinuous
					\param continuous
						pointer to the continuous object where equation-element belongs to
					\param otherContinuous
						pointer to a continuous instance which influences the right hand side

					The membervariable index_ will not be changed.

				void init(Continuous* continuous, Continuous* otherContinuous);*/

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

				/** pointer to a continuous instance which influences the right hand side
				*/
				Continuous* otherContinuous;

				/** row number of the matrix
				*/
				unsigned row_;

				/** column number of the matrix
				*/
				unsigned column_;
			};
		}
	}
}

#endif/* ODEMX_JACOBIMATRIX_INCLUDED */
