/*!\file DoubleVecExternalResult.c
 * \brief: implementation of the DoubleVecExternalResult object
 */

/*header files: */
/*{{{*/
#ifdef HAVE_CONFIG_H
	#include <config.h>
#else
#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
#endif

#include <stdio.h>
#include <string.h>
#include "../objects.h"
#include "../../../EnumDefinitions/EnumDefinitions.h"
#include "../../../shared/shared.h"
#include "../../../Container/Container.h"
#include "../../../include/include.h"
/*}}}*/

/*DoubleVecExternalResult constructors and destructor*/
/*FUNCTION DoubleVecExternalResult::DoubleVecExternalResult(){{{*/
DoubleVecExternalResult::DoubleVecExternalResult(){
	return;
}
/*}}}*/
/*FUNCTION DoubleVecExternalResult::DoubleVecExternalResult(int enum_type,IssmDoubleVec values,int M,int in_step,IssmDouble in_time){{{*/
DoubleVecExternalResult::DoubleVecExternalResult(int in_id, int in_enum_type,IssmDouble* in_values, int in_M,int in_step,IssmDouble in_time){

	id=in_id;
	enum_type=in_enum_type;
	M=in_M;

	if(M){
		values=xNew<IssmDouble>(M);
		xMemCpy<IssmDouble>(values,in_values,M);
	}
	else values=NULL;

	step=in_step;
	time=in_time;
}
/*}}}*/
/*FUNCTION DoubleVecExternalResult::~DoubleVecExternalResult(){{{*/
DoubleVecExternalResult::~DoubleVecExternalResult(){
	xDelete<IssmDouble>(values);
	return;
}
/*}}}*/

/*Object virtual functions definitions:*/
/*FUNCTION DoubleVecExternalResult::Echo {{{*/
void DoubleVecExternalResult::Echo(void){

	_printLine_("DoubleVecExternalResult:");
	_printLine_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")");
	_printLine_("   vector size: " << this->M);
	_printLine_("   step: " << this->step);
	_printLine_("   time: " << this->time);

}
/*}}}*/
/*FUNCTION DoubleVecExternalResult::DeepEcho{{{*/
void DoubleVecExternalResult::DeepEcho(void){

	int i;
	
	_printLine_("DoubleVecExternalResult:");
	_printLine_("   id: " << this->id);
	_printLine_("   enum: " << this->enum_type << " (" << EnumToStringx(this->enum_type) << ")");
	_printLine_("   vector size: " << this->M);
	for(i=0;i<this->M;i++){
		_printLine_(i << " " << this->values[i]);
	}
	_printLine_("   step: " << this->step);
	_printLine_("   time: " << this->time);
}
/*}}}*/
/*FUNCTION DoubleVecExternalResult::Id{{{*/
int    DoubleVecExternalResult::Id(void){ return -1; }
/*}}}*/
/*FUNCTION DoubleVecExternalResult::MyRank{{{*/
int    DoubleVecExternalResult::MyRank(void){ 
	extern int my_rank;
	return my_rank; 
}
/*}}}*/
/*FUNCTION DoubleVecExternalResult::ObjectEnum{{{*/
int DoubleVecExternalResult::ObjectEnum(void){

	return DoubleVecExternalResultEnum;

}
/*}}}*/
/*FUNCTION DoubleVecExternalResult::copy{{{*/
Object* DoubleVecExternalResult::copy() {
	
	return new DoubleVecExternalResult(this->id,this->enum_type,this->values,this->M,this->step,this->time);

}
/*}}}*/

/*DoubleVecExternalResult management: */
/*FUNCTION DoubleVecExternalResult::WriteData{{{*/
void   DoubleVecExternalResult::WriteData(FILE* fid,bool io_gather){

	int     length;
	int     type;
	int     size;
	char   *name    = NULL;
	extern  int my_rank;
	IssmPDouble *passiveDouble_p=NULL;
	IssmPDouble passiveDouble;

	/*return if now on cpu 0: */
	if(my_rank)return;

	passiveDouble_p=xNew<IssmPDouble>(M);
	/*First write enum: */
	EnumToStringx(&name,this->enum_type);
	length=(strlen(name)+1)*sizeof(char);
	fwrite(&length,sizeof(int),1,fid);
	fwrite(name,length,1,fid);
	xDelete<char>(name);

	/*Now write time and step: */
        passiveDouble=reCast<IssmPDouble>(time);
	fwrite(&passiveDouble,sizeof(IssmPDouble),1,fid);
	fwrite(&step,sizeof(int),1,fid);

	/*writing a IssmDouble, type is 1, size is 1: */
	type=1;
	size=this->M;
	fwrite(&type,sizeof(int),1,fid);
	fwrite(&size,sizeof(int),1,fid);
        for (int i=0; i<M; ++i) passiveDouble_p[i]=reCast<IssmPDouble>(values[i]);
	fwrite(passiveDouble_p,size*sizeof(IssmPDouble),1,fid);
        xDelete(passiveDouble_p);
}
/*}}}*/
/*FUNCTION DoubleVecExternalResult::GetResultName{{{*/
void DoubleVecExternalResult::GetResultName(char** pname){
	EnumToStringx(pname,this->enum_type);
}
/*}}}*/
/*FUNCTION DoubleVecExternalResult::GetStep{{{*/
int DoubleVecExternalResult::GetStep(void){

	return this->step;
}
/*}}}*/
