/*!\file DakotaResponsesx
 * \brief: update datasets using  parameter inputs
 */

#ifdef HAVE_CONFIG_H
	#include <config.h>
#else
#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
#endif

#include "./DakotaResponsesx.h"
#include "../../Container/Container.h"    
#include "../../shared/shared.h"
#include "../../include/include.h"
#include "../../EnumDefinitions/EnumDefinitions.h"
#include "../../toolkits/toolkits.h"
#include "../modules.h"


void DakotaResponsesx(double* d_responses,Elements* elements,Nodes* nodes, Vertices* vertices,Loads* loads,Materials* materials, Parameters* parameters,char** responses_descriptors,int numresponsedescriptors,int d_numresponses){

	int        i,j,k;
	extern int my_rank;
	bool       process_units = true;

	/*intermediary: */
	char   root[50];
	int    index;
	int    npart;
	double femmodel_response;
	int    flag;
	double *vertex_response   = NULL;
	double *qmu_response      = NULL;
	double *responses_pointer = NULL;

	/*retrieve npart: */
	parameters->FindParam(&npart,QmuNumberofpartitionsEnum);

	/*save the d_responses pointer: */
	responses_pointer=d_responses;

	//watch out, we have more d_numresponses than numresponsedescriptors, because the responses have been expanded if they were scaled. 
	//because we don't know the d_responses descriptors (the scaled ones) we can't key off them, so we will key off the responses_descriptors: */
		
	for(i=0;i<numresponsedescriptors;i++){
		
		flag=DescriptorIndex(root,&index,responses_descriptors[i]);

		if(flag==ScaledEnum){

			/*this response was scaled. pick up the response from the inputs: */
			GetVectorFromInputsx(&vertex_response,elements,nodes, vertices, loads, materials, parameters, StringToEnumx(root),VertexEnum);

			/*Now, average it onto the partition nodes: */
			AverageOntoPartitionx(&qmu_response,elements,nodes,vertices,loads,materials,parameters,vertex_response);

			/*Copy onto our dakota responses: */
			if(my_rank==0){
				/*plug response: */
				for(i=0;i<npart;i++)responses_pointer[i]=qmu_response[i];

				/*increment response_pointer :*/
				responses_pointer+=npart;
			}

			/*Free ressources:*/
			xDelete<double>(vertex_response);
			xDelete<double>(qmu_response);

		}
		else if (flag==IndexedEnum){

			/*indexed response: plug index into parameters and call response module: */
			parameters->SetParam(index,IndexEnum);

			//Responsex(responses_pointer,elements,nodes, vertices,loads,materials, parameters,root,process_units);
			Responsex(&femmodel_response,elements,nodes, vertices,loads,materials, parameters,root,process_units,0);//0 is the index for weights
			
			if(my_rank==0){
				/*plug response: */
				responses_pointer[0]=femmodel_response;

				/*increment response_pointer :*/
				responses_pointer++;
			}
		}
		else if (flag==NodalEnum){
			_error2_("nodal response functions not supported yet!");

			/*increment response_pointer :*/
			responses_pointer++;
		}
		else if (flag==RegularEnum){
			
			/*perfectly normal response function: */
			Responsex(&femmodel_response,elements,nodes, vertices,loads,materials, parameters,root,process_units,0);//0 is the weight index

			if(my_rank==0){
				/*plug response: */
				responses_pointer[0]=femmodel_response;

				/*increment response_pointer :*/
				responses_pointer++;
			}
		}
		else _error2_("flag type " << flag << " not supported yet for response analysis");
	}


	/*Synthesize echo: {{{*/
	if(my_rank==0){
		_printString_("   responses: " << d_numresponses << ": ");
		for(i=0;i<d_numresponses-1;i++)_printString_(d_responses[i] << "|");
		_printString_(d_responses[d_numresponses-1]);
		_printLine_("");
	}
	/*}}}*/

}
