/* \file WriteNodeSets.c:
 * \brief: interface for writing nodesets to matlab workspace
 */

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

#undef __FUNCT__ 
#define __FUNCT__  "WriteNodeSets"

#ifdef _SERIAL_
#include <mex.h>

#include "../objects/NodeSets.h"
#include "./io.h"
#include "../shared/shared.h"

void WriteNodeSets(DataHandle* pdataref,NodeSets* nodesets){

	/*output: */
	mxArray* dataref=NULL;
	int gsize=0;
	int msize=0;
	int nsize=0;
	int fsize=0;
	int ssize=0;
	mwSize nfields=9;
	const	char*	fnames[nfields];
	mwSize		onebyone[2] = {1,1};
	mwSize		ndim=2;

	
	/*intermediary: */
	double* pv_m=NULL;
	double* pv_n=NULL;
	double* pv_f=NULL;
	double* pv_s=NULL;
	mxArray*    field=NULL;

	/*Recover data from the nodesets class: */
	gsize=nodesets->GetGSize();
	msize=nodesets->GetMSize();
	nsize=nodesets->GetNSize();
	fsize=nodesets->GetFSize();
	ssize=nodesets->GetSSize();

	if(msize){
		pv_m=(double*)xmalloc(msize*sizeof(double));
		memcpy(pv_m,nodesets->GetPV_M(),msize*sizeof(double));
	}
	if(nsize){
		pv_n=(double*)xmalloc(nsize*sizeof(double));
		memcpy(pv_n,nodesets->GetPV_N(),nsize*sizeof(double));
	}
	if(fsize){
		pv_f=(double*)xmalloc(fsize*sizeof(double));
		memcpy(pv_f,nodesets->GetPV_F(),fsize*sizeof(double));
	}
	if(ssize){
		pv_s=(double*)xmalloc(ssize*sizeof(double));
		memcpy(pv_s,nodesets->GetPV_S(),ssize*sizeof(double));
	}

	/*Build structure in matlab workspace with all these fields: */
	fnames[0] = "gsize";
	fnames[1] = "msize";
	fnames[2] = "nsize";
	fnames[3] = "fsize";
	fnames[4] = "ssize";
	fnames[5] = "pv_m";
	fnames[6] = "pv_n";
	fnames[7] = "pv_f";
	fnames[8] = "pv_s";

	dataref=mxCreateStructArray( ndim,onebyone,nfields,fnames);
	
	mxSetField( dataref, 0, "gsize",mxCreateDoubleScalar((double)gsize));
	mxSetField( dataref, 0, "msize",mxCreateDoubleScalar((double)msize));
	mxSetField( dataref, 0, "nsize",mxCreateDoubleScalar((double)nsize));
	mxSetField( dataref, 0, "fsize",mxCreateDoubleScalar((double)fsize));
	mxSetField( dataref, 0, "ssize",mxCreateDoubleScalar((double)ssize));

	if(msize){
		field = mxCreateDoubleMatrix(0,0,mxREAL);
		mxSetM(field,msize); mxSetN(field,1); mxSetPr(field,pv_m);
	}
	else{
		field = mxCreateDoubleMatrix(0,0,mxREAL);
	}
	mxSetField( dataref, 0, "pv_m",field);

	if(nsize){
		field = mxCreateDoubleMatrix(0,0,mxREAL);
		mxSetM(field,nsize); mxSetN(field,1); mxSetPr(field,pv_n);
	}
	else{
		field = mxCreateDoubleMatrix(0,0,mxREAL);
	}
	mxSetField( dataref, 0, "pv_n",field);

	
	if(fsize){
		field = mxCreateDoubleMatrix(0,0,mxREAL);
		mxSetM(field,fsize); mxSetN(field,1); mxSetPr(field,pv_f);
	}
	else{
		field = mxCreateDoubleMatrix(0,0,mxREAL);
	}
	mxSetField( dataref, 0, "pv_f",field);
	
	if(ssize){
		field = mxCreateDoubleMatrix(0,0,mxREAL);
		mxSetM(field,ssize); mxSetN(field,1); mxSetPr(field,pv_s);
	}
	else{
		field = mxCreateDoubleMatrix(0,0,mxREAL);
	}
	mxSetField( dataref, 0, "pv_s",field);

	/*Assign output pointers:*/
	*pdataref=dataref;

}
#endif
