/*!\file OptionStruct.cpp
 * \brief: implementation of the optionsstruct 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 OptionStruct::OptionStruct(){{{*/
OptionStruct::OptionStruct(){

	values    =NULL;

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

	int   i;

	if(values){
		for(i=0; i<numel; i++) {
			delete values[i];
			values[i] =NULL;
		}
		xDelete<Options*>(values);
	}

}
/*}}}*/

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

	char  cstr[81];
	bool  flag=true;

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

	if (values && size) {
		StringFromSize(cstr,size,ndims);
		if(flag) _pprintLine_("        values: " << cstr << " " << "struct");
	}
	else if(flag) _pprintLine_("        values: [empty]");
}
/*}}}*/
/*FUNCTION OptionStruct::DeepEcho() {{{*/
void  OptionStruct::DeepEcho(){

	char  indent[81]="";

	OptionStruct::DeepEcho(indent);

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

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

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

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

	if (values) {
		dims=xNew<int>(ndims);
		for (i=0; i<numel; i++) {
			ColumnWiseDimsFromIndex(dims,i,size,ndims);
			StringFromDims(cstr,dims,ndims);
			if (values[i]->Size()){
				if(flag) _pprintLine_(indent << "        values: -------- begin " << cstr << " --------");
				for (j=0; j<values[i]->Size(); j++) ((Option *)values[i]->GetObjectByOffset(j))->DeepEcho(indent2);
				if(flag) _pprintLine_(indent << "        values: --------  end  " << cstr << " --------");
			}
			else if(flag) _pprintLine_(indent << "        values: " << cstr << " [empty]");
		}
		xDelete<int>(dims);
	}
	else if(flag) _pprintLine_(indent << "        values: [empty]");
}
/*}}}*/
/*FUNCTION OptionStruct::Name {{{*/
char* OptionStruct::Name(){

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

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

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

	return(Option::Size());
}
/*}}}*/
/*FUNCTION OptionStruct::Get(Options** pvalue) {{{*/
void OptionStruct::Get(Options** 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 options dataset");
	}

	/*Assign output pointer*/
	*pvalue=this->values[0];
}
/*}}}*/
/*FUNCTION OptionStruct::Get(Options*** ppvalue,int* numel) {{{*/
void OptionStruct::Get(Options*** ppvalue,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 an options dataset vector");
	}

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