/*! \file  ContourtoMesh
    \brief: takes an  contour file, and figures out which nodes or elements from the mesh  
    are inside this contour. 
	usage:
	[in_nod,in_elem]=ContourToMesh(index,x,y,contours,interptype,edgevalue);
	
	where:

	input:

		index,x,y: delaunay triangulation.
		
		contours: structure holding sets of vertices making open contours. 
		
		interptype: string definining type of interpolation ('element', or 'node', or 'element and node');

		edgevalue: integer (0, 1 or 2) defining the value associated to the nodes on the edges of the polygons

	output:
		in_nod: vector of flags (0 or 1), of size nods if interptype is set to 'node' or 'element and node', 
				or of size 0 otherwise.
		in_elem: vector of flags (0 or 1), of size nel if interptype is set to 'element' or 'element and node', 
				or of size 0 otherwise.
*/
	
#include "./ContourToMesh.h"

void mexFunction( int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {

	int i,j;

	/* required input: */
	double* index=NULL;
	double* x=NULL;
	double* y=NULL;
	int     edgevalue;
	char*   interptype=NULL;

	/* output: */
	Vec  in_nod=NULL;
	int  nods;
	Vec  in_elem=NULL;
	int  nel;

	//contours
	int numcontours;
	Contour** contours=NULL;
	Contour*  contouri=NULL;

	/*Boot module: */
	MODULEBOOT();

	/*checks on arguments on the matlab side: */
	//CheckNumMatlabArguments(nlhs,NLHS,nrhs,NRHS,__FUNCT__,&ContourToMeshUsage); Cant' use it here, as we have variable  outputs.
	if((nlhs==0) && (nrhs=0)){
		ContourToMeshUsage();
		throw ErrorException(__FUNCT__," usage. See above");
	}

	/*Fetch inputs: */
	FetchData((void**)&index,&nel,NULL,INDEXHANDLE,"Matrix","Mat");
	FetchData((void**)&x,&nods,NULL,XHANDLE,"Matrix","Mat");
	FetchData((void**)&y,NULL,NULL,YHANDLE,"Matrix","Mat");
	FetchData((void**)&edgevalue,NULL,NULL,EDGEVALUEHANDLE,"Integer",NULL);

	/*Recover list of contours from the 'contours' structure: */
	//number of contours;
	numcontours=mxGetNumberOfElements(CONTOURSHANDLE);
	//allocate array:
	contours=(Contour**)xmalloc(numcontours*sizeof(Contour*));

	//go through contours, and populate xcontours and ycontours accordingly.
	for(i=0;i<numcontours;i++){
		//allocate
		contouri=(Contour*)xmalloc(sizeof(Contour));
		//retrieve dimension of this contour.
		contouri->nods=(int)mxGetScalar(mxGetField(CONTOURSHANDLE,i,"nods"));
		//set pointers.
		contouri->x=mxGetPr(mxGetField(CONTOURSHANDLE,i,"x"));
		contouri->y=mxGetPr(mxGetField(CONTOURSHANDLE,i,"y"));
		*(contours+i)=contouri;
	}

	#ifdef _DEBUG_
		printf("Contour echo: number of contours  %i \n",numcontours);
		contouri=*(contours+numcontours-1);
		printf("Number of grids %i\n",contouri->nods);
		for (i=0;i<contouri->nods;i++){
			printf("%lf %lf\n",*(contouri->x+i),*(contouri->y+i));
		}
	#endif

	/*Recover  interptype: */
	FetchData((void**)&interptype,NULL,NULL,INTERPTYPEHANDLE,"String",NULL);

	/*Run interpolation routine: */
	ContourToMeshx( &in_nod,&in_elem,index,x,y,contours,numcontours,interptype,nel,nods,edgevalue);

	/* output: */
	if (strcmp(interptype,"node")==0){
		WriteData(PLHS0,in_nod,0,0,"Vector",NULL);
	}
	else if (strcmp(interptype,"element")==0){
		WriteData(PLHS0,in_elem,0,0,"Vector",NULL);
	}
	else if (strcmp(interptype,"element and node")==0){
		WriteData(PLHS0,in_nod,0,0,"Vector",NULL);
		WriteData(PLHS1,in_elem,0,0,"Vector",NULL);
	}
	else throw ErrorException(__FUNCT__," wrong interpolation type");

	/*end module: */
	MODULEEND();
	
}

void ContourToMeshUsage(void)
{
	printf("   usage:\n");
	printf("   [in_nod,in_elem]=ContourToMesh(index,x,y,contours,interptype,edgevalue);\n\n");
	printf("   where:\n");
	printf("      index,x,y: delaunay triangulation.\n");
	printf("      contours: structure holding sets of vertices making open contours.\n");
	printf("      interptype: string definining type of interpolation ('element', or 'node').\n");
	printf("      edgevalue: integer (0, 1 or 2) defining the value associated to the nodes on the edges of the polygons.\n");
	printf("      in_nod: vector of flags (0 or 1), of size nods if interptype is set to 'node' or 'element and node', \n");
	printf("              or of size 0 otherwise.\n");
	printf("      in_elem: vector of flags (0 or 1), of size nel if interptype is set to 'element' or 'element and node', \n");
	printf("               or of size 0 otherwise.\n");
	printf("\n");
}
