/*!\file:  DomainOutlineRead.cpp
 * \brief DomainOutlineRead.c: read the vertex coordinates defined in a domain 
 * outline from Argus (.exp file). The first contour in the file is for 
 * the outside domain outline. The following contours represent holes in
 * the domain.
 */

#include <stdio.h>
#include "../Alloc/alloc.h"
#include "../../include/include.h"
#include "../../objects/objects.h"
#include "../Exceptions/exceptions.h"
#include "../../Container/DataSet.h"

int DomainOutlineRead(int* pnprof,int** pprofnvertices,double*** ppprofx,double*** ppprofy,bool** pclosed,char* domainname){
	
	/*indexing: */
	int i,counter;

	/*I/O: */
	FILE* fid=NULL;
	char chardummy[256];
	double  ddummy;

	/*output: */
	int nprof; //number of profiles in the domainname file
	int* profnvertices=NULL; //array holding the number of vertices for the nprof profiles
	double** pprofx=NULL; //array of profiles x coordinates
	double** pprofy=NULL; //array of profiles y coordinates
	bool* closed=NULL; //array holding closed flags for the nprof profiles

	/*For each profile: */
	int n;
	double* x=NULL;
	double* y=NULL;
	bool cl;

	/*open domain outline file for reading: */
	if ((fid=fopen(domainname,"r"))==NULL){
		_error_("%s%s","could not find domain file ",domainname); 
	}

	/*Do a first pass through the domainname file, to figure out how many profiles 
	 *we need to read: */
	nprof=1;
	for(;;){
		fscanf(fid,"%256s %256s\n",chardummy,chardummy);
		fscanf(fid,"%256s %256s\n",chardummy,chardummy);
		fscanf(fid,"%256s %256s %256s %256s\n",chardummy,chardummy,chardummy,chardummy);
		fscanf(fid,"%20u %256s\n",&n,chardummy);
		fscanf(fid,"%256s %256s %256s %256s %256s\n",chardummy,chardummy,chardummy,chardummy,chardummy);
		for (i=0;i<n;i++){
			fscanf(fid,"%20lf %20lf\n",&ddummy,&ddummy);
		}
		/*Ok, we have faked one profile reading, check whether we are at the end of the file, otherwise, keep fake reading next profile:*/
		if (feof(fid)){
			break;
		}
		nprof++;
	}
	
	/*Allocate and initialize all the profiles: */
	profnvertices=(int*)xmalloc(nprof*sizeof(int));
	pprofx=(double**)xmalloc(nprof*sizeof(double*));
	pprofy=(double**)xmalloc(nprof*sizeof(double*));
	for (i=0;i<nprof;i++){
		pprofx[i]=NULL;
		pprofy[i]=NULL;
	}
	closed=(bool*)xmalloc(nprof*sizeof(bool));

	/*Reaset file pointer to beginning of file: */
	fseek(fid,0,SEEK_SET);

	/*Start reading profiles: */
	for(counter=0;counter<nprof;counter++){

		/*Skip header: */
		fscanf(fid,"%256s %256s\n",chardummy,chardummy);
		fscanf(fid,"%256s %256s\n",chardummy,chardummy);
		fscanf(fid,"%256s %256s %256s %256s\n",chardummy,chardummy,chardummy,chardummy);
		
		/*Get number of profile vertices: */
		fscanf(fid,"%20u %256s\n",&n,chardummy);
	
		/*Skip next line: */
		fscanf(fid,"%256s %256s %256s %256s %256s\n",chardummy,chardummy,chardummy,chardummy,chardummy);

		/*Allocate vertices: */
		x=(double*)xmalloc(n*sizeof(double));
		y=(double*)xmalloc(n*sizeof(double));
		

		/*Read vertices: */
		for (i=0;i<n;i++){
			fscanf(fid,"%20lf %20lf\n",&x[i],&y[i]);
		}

		/*Now check that we are dealing with open contours: */
		cl=false;
		if((x[0]==x[n-1]) && (y[0]==y[n-1])){
			cl=true;
		}

		/*Assign pointers: */
		profnvertices[counter]=n;
		pprofx[counter]=x;
		pprofy[counter]=y;
		closed[counter]=cl;
	}

	/*close domain outline file: */
	fclose(fid);

	/*Assign output pointers: */
	*pnprof=nprof;
	*pprofnvertices=profnvertices;
	*ppprofx=pprofx;
	*ppprofy=pprofy;
	if(pclosed)*pclosed=closed;
	else       xfree((void**)&closed);
}

DataSet* DomainOutlineRead(char* domainname){

	/*intermediary: */
	int       nprof;
	int      *profnvertices = NULL;
	double  **pprofx        = NULL;
	double  **pprofy        = NULL;
	Contour  *contour       = NULL;

	/*output: */
	DataSet* domain=NULL;

	/*If domainname is an empty string, return empty dataset*/
	if (strcmp(domainname,"")==0){
		nprof=0;
	}
	else{
		DomainOutlineRead(&nprof,&profnvertices,&pprofx, &pprofy, NULL,domainname);
	}

	/*now create dataset of contours: */
	domain=new DataSet(0);

	for(int i=0;i<nprof;i++){
		domain->AddObject(new Contour(i,profnvertices[i],pprofx[i],pprofy[i],1));
	}
	return domain;
}
