//----------------------------------------------------------------------------
//	Copyright (C) 2002, 2004, 2007 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 ODEObject.cpp

 \author Michael Fiedler

 \date created at 2009/01/02

 \brief Implementation of classes in ODEObject.h

 \sa ODEObject.h

 \since 3.0
 */

#include <odemx/base/continuous/ODEObject.h>
#include <odemx/base/continuous/Continuous.h>
#include <odemx/base/continuous/Rate.h>
#include <odemx/base/continuous/State.h>
#include <odemx/base/continuous/JacobiMatrix.h>
#include <odemx/base/continuous/DfDt.h>

using namespace odemx::base;
using namespace odemx::base::continuous;
using namespace std;

//------------------------------------------------------------------------------construction/destruction
ODEObject::ODEObject() : continuous(0) {
	//set that there is no Continuous-instance where this instance belongs to jet
}

ODEObject::~ODEObject() {}

//--------------------------------------------------------------handle corresponding Continuous instance
void ODEObject::setContinuous(Continuous *continuous) {
	if (this->continuous != 0) { //remove from old
		this->continuous->removeODE(this); //all actions are implemented in Continuous
	}
	if (continuous != 0) { //add to new
		continuous->addODE(this); //all actions are implemented in Continuous
	}
}

Continuous* ODEObject::getContinuous() {
	return continuous;
}

//------------------------------------------------------------------------------------------derivates
void ODEObject::derivates(SimTime time) {
	if (continuous == 0) {
		throw new NotAssignedException("Continuous", "ODEObject");
	}
	continuous->setDerivative(0, continuous->getValueForDerivative(1));
	continuous->setDerivative(1, -1 * continuous->getValueForDerivative(0));

	//new representation
	Rate rate(continuous);
	State state(continuous);

	rate[0] = state[1];
	rate[1] = -1 * state[0];
}

//--------------------------------------------------------------------------------------------jacobi
void ODEObject::jacobi(SimTime time) {
	if (continuous == 0) {
		throw new NotAssignedException("Continuous", "ODEObject");
	}
	continuous->setJacobi(0, 0, 0);
	continuous->setJacobi(0, 1, 1);
	continuous->setJacobi(1, 0, -1);
	continuous->setJacobi(1, 1, 0);
	continuous->setDfDt(0, 0);
	continuous->setDfDt(1, 0);

	//new representation
	JacobiMatrix jacobi(continuous);

	DfDt dfdt(continuous);

	jacobi(0,0) = 0;
	jacobi(0,1) = 1;
	jacobi(1,0) = -1;
	jacobi(1,1) = 0;
	dfdt[0] = 0;
	dfdt[1] = 0;
}

//------------------------------------------------------------------------------NotAssignedException
NotAssignedException::NotAssignedException(const char* missingObject, const char* object) {
	this->msg = "This ";
	this->msg += object;
	this->msg += "-Object has no ";
	this->msg += missingObject;
	this->msg += " assigned.";
}

NotAssignedException::~NotAssignedException() throw() {}

const char* NotAssignedException::what() const throw() {
	return this->msg.c_str();
}

