/*\file KMLMeshWrite.c
 *\brief: KML mesh writer module.
 */
#include "./KMLMeshWrite.h"

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

	int i,j,nnodes=0,verbose=1;

	/*input: */
	char*   name=NULL;
	char*   notes=NULL;
	const mxArray* notesi;
	mwIndex        nindex;
	int*    elem=NULL;
	int     melem=0,nelem=0;
	int*    nodecon=NULL;
	int     mncon=0,nncon=0;
	double* lat=NULL;
	int     mlat=0,nlat=0,llat=0;
	double* lng=NULL;
	int     mlng=0,nlng=0,llng=0;
	int     nparts=0;
	int*    part=NULL;
	int     mprt=0,nprt=0,lprt=0;
	double* data=NULL;
	int     mdata=0,ndata=0;
	double* cmap=NULL;
	int     mcmap=0,ncmap=0;
	char*   filnam=NULL;
	FILE*   fid=NULL;
	Options* options=NULL;

	/* output: */
	int     ierror=0;

	/*Boot module: */
	MODULEBOOT();

	/*checks on arguments on the matlab side: */
	if (nlhs > NLHS) {
		KMLMeshWriteUsage(); _error2_("KMLMeshWrite usage error");
	}
	if (nrhs < NRHS) {
		KMLMeshWriteUsage(); _error2_("KMLMeshWrite usage error");
	}

	/*Input datasets: */
	FetchData(&name,NAME);

/*  notes is typically a cell array of character strings  */
	if (mxIsCell(NOTES)) {
		for (nindex=0; nindex<mxGetNumberOfElements(NOTES); nindex++) {
			notesi=mxGetCell(NOTES,nindex);
			if (notesi && mxIsChar(notesi) && mxGetNumberOfElements(notesi)) {
				if (!notes) {
					notes=(char *) xmalloc((mxGetNumberOfElements(notesi)+1)*sizeof(char));
					mxGetString(notesi,notes,mxGetNumberOfElements(notesi)+1);
				}
				else {
/*  note that strlen does not include trailing null  */
					notes=(char*)xrealloc(notes,(strlen(notes)+1+mxGetNumberOfElements(notesi)+1)*sizeof(char));
					strcat(notes,"\n");
					mxGetString(notesi,&notes[strlen(notes)],mxGetNumberOfElements(notesi)+1);
				}
			}
		}
	}
	else
		FetchData(&notes,NOTES);
	FetchData(&elem,&melem,&nelem,ELEMHANDLE);
	FetchData(&nodecon,&mncon,&nncon,NODECONHANDLE);
	FetchData(&lat,&mlat,&nlat,LATHANDLE);
	llat=mlat*nlat;
	FetchData(&lng,&mlng,&nlng,LNGHANDLE);
	llng=mlng*nlng;
	FetchData(&part,&mprt,&nprt,PARTHANDLE);
	lprt=mprt*nprt;
	FetchData(&data,&mdata,&ndata,DATAHANDLE);
	FetchData(&cmap,&mcmap,&ncmap,CMAPHANDLE);
	FetchData(&filnam,FILENAME);
	FetchData(&options,NRHS,nrhs,prhs);

	/*some checks*/
	for (i=0; i<melem*nelem; i++) if(elem[i]>nnodes) nnodes=elem[i];
	if(part) for (i=0; i<lprt; i++) if (part[i]+1 > nparts) nparts=part[i]+1;

	if (nodecon && (mncon != nnodes))
	  {_error2_("Nodal connectivity table, if supplied, must be supplied for all nodes.");}
	else if (!nodecon)
		mncon=nnodes;
	if ((llat != nnodes) || (llng != nnodes) || (llat != llng))
		_error2_("Latitude and longitude vectors must be supplied for all nodes.");
	if (part && (lprt != nnodes))
		_error2_("Partitioning vector, if supplied, must be supplied for all nodes.");
	if (data && !((mdata == nnodes) || (mdata == melem)))
		_error2_("Data matrix, if supplied, must be supplied for all nodes or all elements.");
	if (cmap && (ncmap != 3))
		_error2_("Colormap matrix, if supplied, must have three columns for rgb.");
	if (!strlen(filnam))
		strcpy(filnam,"stdout");

	/* Run core computations: */
	fid=fopen(filnam,"w");
	KMLMeshWritex(&ierror,name,notes,elem,melem,nelem,nodecon,mncon,nncon,lat,lng,part,data,mdata,ndata,cmap,mcmap,ncmap,fid);
	fclose(fid);

	/*Write data: */
	WriteData(ERRORFLAG,ierror);

	/*Clean-up*/
	delete options;
	if (mxIsCell(NOTES) && notes) xfree((void**)&notes);

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

void KMLMeshWriteUsage(void){
	_pprintLine_("KMLMeshWrite - KML mesh writer module:");
	_pprintLine_("");
	_pprintLine_("   This module writes the mesh of a model as KML polygons into the specified KML file.");
	_pprintLine_("");
	_pprintLine_("   Usage:");
	_pprintLine_("      ierror=KMLMeshWrite(name,notes,elem,nodecon,lat,long,part,data,cmap,kmlfile);");
	_pprintLine_("");
	_pprintLine_("      name       model name (string, may be empty)");
	_pprintLine_("      notes      model notes (string or cell array of strings, may be empty)");
	_pprintLine_("      elem       elements (double array)");
	_pprintLine_("      nodecon    nodal connectivity array (double array, may be empty)");
	_pprintLine_("      lat        nodal latititudes (double vector)");
	_pprintLine_("      long       nodal longitudes (double vector)");
	_pprintLine_("      part       nodal partitions (double vector, may be empty)");
	_pprintLine_("      data       nodal or element data (double vector, may be empty)");
	_pprintLine_("      cmap       color map (double nx3 array, may be empty)");
	_pprintLine_("      kmlfile    KML file name (string)");
	_pprintLine_("");
	_pprintLine_("      ierror     error flag (double, non-zero for error)");
	_pprintLine_("");
	_pprintLine_("   Example:");
	_pprintLine_("      KMLMeshWrite(md.name,md.notes,md.elements,md.nodeconnectivity,md.lat,md.long,md.part,md.fm_criterion,options.cmap,filekml);");
	_pprintLine_("");
}
