/*!\file: CreateParametersControl.cpp
 * \brief driver for creating parameters dataset, for control analysis.
 */ 

#include "../../../Container/Container.h"
#include "../../../toolkits/toolkits.h"
#include "../../../io/io.h"
#include "../../../EnumDefinitions/EnumDefinitions.h"
#include "../../../objects/objects.h"
#include "../../../shared/shared.h"
#include "../../../include/include.h"
#include "../ModelProcessorx.h"

void CreateParametersControl(Parameters** pparameters,IoModel* iomodel,int solution_type,int analysis_type){
	
	int         i;
	Parameters *parameters       = NULL;
	bool        control_analysis;
	int         nsteps;
	int         num_control_type;
	int         num_cm_responses;
	int        *control_type     = NULL;
	double     *cm_responses     = NULL;
	double     *cm_jump          = NULL;
	double     *optscal          = NULL;
	double     *maxiter          = NULL;

	/*Get parameters: */
	parameters=*pparameters;

	/*retrieve some parameters: */
	iomodel->Constant(&control_analysis,InversionIscontrolEnum);

	if(control_analysis){

		/*How many controls and how many responses?*/
		parameters->AddObject(iomodel->CopyConstantObject(InversionNumControlParametersEnum));
		parameters->AddObject(iomodel->CopyConstantObject(InversionNumCostFunctionsEnum));
		parameters->AddObject(iomodel->CopyConstantObject(InversionNstepsEnum));
		parameters->AddObject(iomodel->CopyConstantObject(InversionCostFunctionThresholdEnum));
		parameters->AddObject(iomodel->CopyConstantObject(InversionGradientOnlyEnum));
		parameters->AddObject(iomodel->CopyConstantObject(InversionIncompleteAdjointEnum));

		/*What solution type?*/
		if (solution_type==SteadystateSolutionEnum){
			parameters->AddObject(new BoolParam(ControlSteadyEnum,true));
		}
		else{
			parameters->AddObject(new BoolParam(ControlSteadyEnum,false));
		}

		/*Now, recover fit, optscal and maxiter as vectors: */
		iomodel->FetchData(&control_type,NULL,&num_control_type,InversionControlParametersEnum);
		iomodel->FetchData(&cm_responses,&nsteps,&num_cm_responses,InversionCostFunctionsEnum);
		iomodel->FetchData(&cm_jump,&nsteps,NULL,InversionStepThresholdEnum);
		iomodel->FetchData(&optscal,NULL,NULL,InversionGradientScalingEnum);
		iomodel->FetchData(&maxiter,NULL,NULL,InversionMaxiterPerStepEnum);

		parameters->AddObject(new IntVecParam(InversionControlParametersEnum,control_type,num_control_type));
		parameters->AddObject(new DoubleMatParam(InversionGradientScalingEnum,optscal,nsteps,num_control_type));
		parameters->AddObject(new DoubleMatParam(InversionCostFunctionsEnum,cm_responses,nsteps,num_cm_responses));
		parameters->AddObject(new DoubleVecParam(InversionStepThresholdEnum,cm_jump,nsteps));
		parameters->AddObject(new DoubleVecParam(InversionMaxiterPerStepEnum,maxiter,nsteps));

		xDelete<int>(control_type);
		xDelete<double>(cm_responses);
		xDelete<double>(cm_jump);
		xDelete<double>(optscal);
		xDelete<double>(maxiter);
	}

	/*Assign output pointer: */
	*pparameters=parameters;
}
