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

	values    =NULL;

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

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

}
/*}}}*/

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

	char  cstr[81];
	bool  flag=true;

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

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

	char  indent[81]="";

	OptionChar::DeepEcho(indent);

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

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

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

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

	if (values) {
		if (ndims == 2 && size[0] == 1) {
			if(flag) _pprintLine_(indent << "        values: \"" << values << "\"");
		}
		else {
			nstr=size[0];
			for (i=2; i<ndims; i++) nstr*=size[i];

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

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

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

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

	return(Option::Size());
}
/*}}}*/
/*FUNCTION OptionChar::Get(char** pvalue) {{{*/
void OptionChar::Get(char** pvalue){

	char* outstring=NULL;
	int   stringsize;

	stringsize=strlen(this->values)+1;

	outstring=xNew<char>(stringsize);
	xMemCpy<char>(outstring,this->values,stringsize);

	*pvalue=outstring;
}
/*}}}*/
/*FUNCTION OptionChar::Get(char*** ppvalue,int *pnumel) {{{*/
void OptionChar::Get(char*** ppvalue,int *pnumel){

	char* outstring=NULL;
	int   stringsize;
	int   i,nstr,ipt=0;

	/*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 string vector");
	}

	/*Calculate the size and number of strings*/
	stringsize=this->size[1]+1;
	nstr=this->size[0];
	for (i=2; i<this->ndims; i++) nstr*=this->size[i];

	/*Break concatenated string into individual strings*/
	*ppvalue=xNew<char*>(nstr);
	for (i=0; i<nstr; i++) {
		outstring=xNew<char>(stringsize);
		xMemCpy<char>(outstring,&(this->values[ipt]),(stringsize-1));
		outstring[stringsize-1]='\0';
		(*ppvalue)[i]=outstring;
		ipt+=stringsize-1;
	}

	/*Assign output pointer*/
	if(numel) *pnumel=nstr;
}
/*}}}*/
