// Copyright (C) 2010 Deltares
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// 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 St, Fifth Floor, Boston, MA 02110-1301 USA

/**
 * @file
 * @brief xxx
 * @author Dirk Schwanenberg
 * @version 1.0
 * @date 2010
 */

#ifndef RTCTOOLS_SIMULATOR_H
#define RTCTOOLS_SIMULATOR_H

#include "schematization/schematisation.h"
#include "optimizationProblem/objectiveFunction.h"
#include "optimizationProblem/objectiveFunctionTerm.h"
#include "timeseries/scenarioTreeInterface.h"
#include "timeseries/timeSeriesTensorInterface.h"
#include "timeseries/timeSeriesMatrix.h"

using namespace rtctools::timeseries;
using namespace rtctools::optimizationProblem;

namespace rtctools
{

class rtcToolsSimulator
{
public:
	rtcToolsSimulator() {};
	rtcToolsSimulator(int iEnsemble, timeSeriesMatrixInterface* tsMatrix, schematisation *schema, 
		objectiveFunction *obj, double p, rtcRuntimeConfigSettings* runtimeSettings);
	~rtcToolsSimulator(void) {};

    double simulate(int iStart, int iEnd, bool executeObjectiveFunction = true, int iTerm = -1, double** JInc2DArray = (double**)0);
	void simulate(int iStep);
    void evaluateGradient(int iStart, int iEnd, int iTerm = -1); 
	void eval_g(int n, const double* x, int m, double* g); 
	void eval_jac_g(int m, int nnz, int* iRow, int* iCol, double* values); 

private:
	int iEnsemble;
	double p;
	timeSeriesMatrixInterface* tsMatrix;
	schematisation* schema;
	objectiveFunction* obj;
	rtcRuntimeConfigSettings* runtimeSettings;

	void eval_jac_g_variableRateOfChange(int m, int nnz, int* iRow, int* jCol, 
		double* values, objectiveFunction::variableRateOfChange* c, double dt);
	void eval_jac_g_VariableAverage(int m, int nnz, int* iRow, int* jCol, 
		double* values, objectiveFunction::variableAverage* c);
	void eval_jac_g_State(int m, int nnz, int* iRow, int* jCol, 
		double* values, objectiveFunction::state* c);
};

}
#endif //RTCTOOLS_SIMULATOR_H
