/*!\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 "../../../classes/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){

	Parameters *parameters       = NULL;
	bool        control_analysis,tao_analysis;
	int         nsteps;
	int         num_control_type;
	int         num_cm_responses;
	int        *control_type     = NULL;
	IssmDouble *cm_responses     = NULL;
	IssmDouble *cm_jump          = NULL;
	IssmDouble *optscal          = NULL;
	IssmDouble *maxiter          = NULL;

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

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

	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(InversionIncompleteAdjointEnum));
		if(!tao_analysis){
			parameters->AddObject(iomodel->CopyConstantObject(InversionCostFunctionThresholdEnum));
			parameters->AddObject(iomodel->CopyConstantObject(InversionGradientOnlyEnum));
		}

		/*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);
		if(!tao_analysis){
			iomodel->FetchData(&cm_jump,&nsteps,NULL,InversionStepThresholdEnum);
			iomodel->FetchData(&optscal,NULL,NULL,InversionGradientScalingEnum);
			iomodel->FetchData(&maxiter,NULL,NULL,InversionMaxiterPerStepEnum);
		}

		if(tao_analysis){
			parameters->AddObject(new IntVecParam(InversionControlParametersEnum,control_type,num_control_type));
			parameters->AddObject(new DoubleVecParam(InversionCostFunctionsEnum,cm_responses,num_cm_responses));
		}
		else{
			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);
		iomodel->DeleteData(cm_responses,InversionCostFunctionsEnum);
		iomodel->DeleteData(cm_jump,InversionStepThresholdEnum);
		iomodel->DeleteData(optscal,InversionGradientScalingEnum);
		iomodel->DeleteData(maxiter,InversionMaxiterPerStepEnum);
	}

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