/*!\file OptionDouble.cpp
 * \brief: implementation of the optionsIssmDouble object
 */

/*Headers:*/
/*{{{*/
#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 "../../../shared/shared.h"
#include "../../../io/io.h"
#include "../../../Container/Container.h"
#include "../../../include/include.h"
/*}}}*/

/*Constructors/destructor/copy*/
/*FUNCTION OptionDouble::OptionDouble(){{{*/
OptionDouble::OptionDouble(){

	values    =NULL;

}
/*}}}*/
/*FUNCTION OptionDouble::~OptionDouble(){{{*/
OptionDouble::~OptionDouble(){

	if (values) xDelete<IssmDouble>(values);

}
/*}}}*/

/*Other*/
/*FUNCTION OptionDouble::Echo {{{*/
void  OptionDouble::Echo(){

	char  cstr[81];
	bool  flag=true;

	if(flag) _pprintLine_("OptionDouble Echo:");
	Option::Echo();

	if (values && size) {
		if(numel == 1) if(flag) _pprintLine_("        values: " << values[0]);
		else {
			StringFromSize(cstr,size,ndims);
			if(flag) _pprintLine_("        values: " << cstr << " " << "IssmDouble");
		}
	}
	else if(flag) _pprintLine_("        values: [empty]");
}
/*}}}*/
/*FUNCTION OptionDouble::DeepEcho() {{{*/
void  OptionDouble::DeepEcho(){

	char  indent[81]="";

	OptionDouble::DeepEcho(indent);

	return;
}
/*}}}*/
/*FUNCTION OptionDouble::DeepEcho(char* indent) {{{*/
void  OptionDouble::DeepEcho(char* indent){

	int   i;
	int*  dims;
	char  indent2[81];
	char  cstr[81];
	bool  flag=true;

	if(flag) _pprintLine_(indent << "OptionDouble DeepEcho:");
	Option::DeepEcho(indent);

	xMemCpy<char>(indent2,indent,(strlen(indent)+1));
	strcat(indent2,"  ");

	if (values) {
		dims=xNew<int>(ndims);
		if(numel==1) if(flag) _pprintLine_(indent << "        values: " << values[0]);
		else{
			for (i=0; i<numel; i++) {
				RowWiseDimsFromIndex(dims,i,size,ndims);
				StringFromDims(cstr,dims,ndims);
				if(flag) _pprintLine_(indent << "        values" << cstr << ": " << values[i]);
			}
		}
		xDelete<int>(dims);
	}
	else if(flag) _pprintLine_(indent << "        values: [empty]");
}
/*}}}*/
/*FUNCTION OptionDouble::Name {{{*/
char* OptionDouble::Name(){

	return(Option::Name());
}
/*}}}*/
/*FUNCTION OptionDouble::NumEl {{{*/
int   OptionDouble::NumEl(){

	return(Option::NumEl());
}
/*}}}*/
/*FUNCTION OptionDouble::NDims {{{*/
int   OptionDouble::NDims(){

	return(Option::NDims());
}
/*}}}*/
/*FUNCTION OptionDouble::Size {{{*/
int*  OptionDouble::Size(){

	return(Option::Size());
}
/*}}}*/
/*FUNCTION OptionDouble::Get(int* pvalue) {{{*/
void OptionDouble::Get(int* pvalue){

	/*We should first check that the size is one*/
	if(this->NumEl()!=1){
		_error2_("option \"" << this->name << "\" has " << this->NumEl() << " elements and cannot return a single int");
	}

	/*Assign output pointer*/
	*pvalue=reCast<int>(values[0]);
}
/*}}}*/
/*FUNCTION OptionDouble::Get(IssmDouble* pvalue) {{{*/
void OptionDouble::Get(IssmDouble* pvalue){

	/*We should first check that the size is one*/
	if(this->NumEl()!=1){
		_error2_("option \"" << this->name << "\" has " << this->NumEl() << " elements and cannot return a single IssmDouble");
	}

	/*Assign output pointer*/
	*pvalue=this->values[0];
}
/*}}}*/
/*FUNCTION OptionDouble::Get(IssmDouble** pvalue,int* numel) {{{*/
void OptionDouble::Get(IssmDouble** pvalue,int* numel){

	/*We should first check that the size is at least one*/
	if(this->NumEl()<=0){
		_error2_("option \"" << this->name << "\" is empty and cannot return a IssmDouble vector");
	}

	/*Copy vector*/
	IssmDouble* outvalue=xNew<IssmDouble>(this->NumEl());
	for(int i=0;i<this->NumEl();i++) outvalue[i]=this->values[i];

	/*Assign output pointer*/
	*pvalue=outvalue;
	if(numel) *numel=this->NumEl();
}
/*}}}*/
