#include "LayMeOut.h"

int edgeCountMat2D(int numVerts, short int** mat2d) {
	int i, j, count;
	count = 0;
	for(i=0;i<numVerts;i++) {
		for(j=0;j<i;j++) {
			if(mat2d[i][j]!=INAN)
				count++;
		}
	}
	return count;
}

//------------------------------------------------------------------------
//   Utility function for bootstrapping the layout engine
//------------------------------------------------------------------------
void layoutConverser(int* largc, char*** largv, char* fn, float thresh, int absFlag) {
   int i,argc;
   char* buffer;
   char** argv;
		int springAlgo=0;
		int attractFlag=1;
		float gravity = 0.1f;

   buffer=(char*)malloc( (sizeof(int)*8+1)*sizeof(char) );
   if(buffer==NULL) {
      perror("layoutConverser() buffer"); return;
   }

   argc=7;
   argv=(char**)malloc(argc*sizeof(char*));
   if(argv==NULL) {
      perror("layoutConverser() argv"); return;
   }

   argv[0]=NULL; //executable name irrelevant
   argv[1]=(char*)malloc((strlen(fn)+1)*sizeof(char));
   if(argv[1]==NULL) {
      perror("layoutConverser() argv[]"); return;
   }
   strcpy(argv[1],fn); //filename

   for(i=2;i<argc;i++) {
      argv[i]=(char*)malloc((strlen(buffer)+1)*sizeof(char));
      if(argv[i]==NULL) {
         perror("layoutConverser() argv[]"); return;
      }
   }

   sprintf(argv[2],"%f",thresh);//threshold
   sprintf(argv[3], "%d", absFlag); //absolute value flag
   sprintf(argv[4], "%d", attractFlag); //attract flag
   sprintf(argv[5],"%f",gravity);//gravity
   sprintf(argv[6], "%d", springAlgo); //spring algo

   /*for(i=0;i<argc;i++) printf("%s ",argv[i]);
   printf("\n");*/

   (*largc)=argc;
   (*largv)=argv;
}

//------------------------------------------------------------------------
//   Utility function for telling if a file exists
//------------------------------------------------------------------------
bool fexists(char* filename) {
	FILE* fp;
	fp = fopen(filename, "r");
	if (fp) {
		fclose(fp);
		return 1;
	}
	return 0;
}

//------------------------------------------------------------------------
//   Joshua New's little temperature minimization graph layouts program
//------------------------------------------------------------------------
int createLayout(int argc, char** argv, bool useTwoDLayout, bool useEBLayout)
{
	/* Data */
	graph* g;
	parameter* param;
	char filename[250];
	char* outname;
	char* extension;
	int numVerts;
	LabelList* label;
	short int** mat2d;
	clock_t startTime,currentTime;
	float totalTime;

	//Read the input file
	param = init_param_default();
	if(argc!=2 && argc!=4 && argc!=7) {
		printf("Usage: laymeout filename.[wel,ltm] threshold[0.0-1.0] absValFlag[0,1] attractFlag[0,1] gravity[0.0,1.0] springAlgo[0,4]\n");
		printf("Usage: laymeout filename.[wel,ltm] springAlgo[0,4] attractFlag[0,1]\n");
		printf("Usage: laymeout fileanme.[wel,ltm]\n");
		printf("   Ex: laymeout rma_pearsons.85.wel 0 1\n");
		return -1;
	}
	else if(argc==2) {
		strcpy(filename,argv[1]);
		param->springAlgo=0;
		param->attractFlag=1;
		param->thresh=0.0;
		param->absValFlag=1;
		param->grav = 0.1f;
	}
	else if(argc==4) {
		strcpy(filename,argv[1]);
		param->springAlgo=atoi(argv[2]);
		param->attractFlag=atoi(argv[3]);
		param->thresh=0.0;
		param->absValFlag=1;
		param->grav = 0.1f;
	}
	else {
		strcpy(filename,argv[1]);
		param->thresh=(float)atof(argv[2]);
		param->absValFlag=atoi(argv[3]);
		param->attractFlag=atoi(argv[4]);
		param->grav = (float)atof(argv[5]);
		param->springAlgo=atoi(argv[6]);
	}

	//Read the input file
	printf("Reading the edge list...\n");
	startTime=clock();
	
	extension=filename+(strlen(filename)-4);
	if(strcmp(extension,".ltm")==0)
		numVerts = readLTMDefaultWeighted2D_deprecated(filename, &mat2d,param->thresh,param->absValFlag);
	else
		numVerts = readDefaultWeighted2D_deprecated(filename, &mat2d, &label, param->thresh, param->absValFlag);

   if(numVerts<0) {
      exit(-1);
   }
	//Normalize and separate pos/neg
	normalizeWeights(numVerts,mat2d);

	currentTime=clock();
	totalTime=(float)(currentTime-startTime)/CLOCKS_PER_SEC;
	printf("  NumVerts = %d, NumEdges = %d\n",numVerts,edgeCountMat2D(numVerts,mat2d));
	printf("  Reading took %4.3f seconds\n",totalTime);

	//Spring Model Calculation
	printf("Calculating spring model...\n");
	g = init_graph(filename, numVerts, edgeCountMat2D(numVerts,mat2d), mat2d, label);
	startTime=clock();
	
	//Assumes maximum of 99 files
	outname=(char*)malloc((strlen(filename)+7)*sizeof(char));
	strcpy(outname,filename);
	if(useTwoDLayout) strcpy(&outname[strlen(filename)-4],"_2d.gvl");
   else strcpy(&outname[strlen(filename)-4],".gvl");
	
	//layout_graph_main(g,param,100,10);
	//layout_graph_delay(g,param,100);
	//layout_graph_iterations(g,param,10);
   if (useTwoDLayout) layout_graph_two_d(g,param);
   else layout_graph(g,param, filename, outname, useEBLayout);
	
	currentTime=clock();
	totalTime=((float)(currentTime-startTime)/CLOCKS_PER_SEC)/60.f;
	if(totalTime>0.f && totalTime<60.f)
	{
		printf("  Creating the layout took %4.3f seconds\n",totalTime*60.f);
	}
	else if(totalTime>0.f) {
		printf("  Creating the layout took %4.3f minutes\n",totalTime);
	} // Otherwise, we overflowed and can't tell what time it is}
	
	if (useEBLayout != 1)
	{
		//Write the Output
		printf("Writing the calculated layout...\n");
		startTime=clock();
	
		int number=0;
		char suffix[8]={0};//maximum of 99 file or memory overwrite 1 byte per digit
		FILE* checkFP;
		checkFP=fopen(outname,"r");
		while(checkFP!=NULL && number<10) {
			fclose(checkFP);
			number++;
			strcpy(outname,filename);
			sprintf(suffix,"_%d.gvl",number);
			strcpy(&outname[strlen(filename)-4],suffix);
			checkFP=fopen(outname,"r");
		}
		printf("  Writing to file = %s\n",outname);

		write_layout(outname,g,param);
		currentTime=clock();
		totalTime=(float)(currentTime-startTime)/CLOCKS_PER_SEC;
	}
	//printf("  Writing took %4.3f seconds\n",totalTime);

	//Print the edge list (to access mat2d as mat1d: (*mat)[1])
	//printf("Printing the edge list...\n");
	//printDefaultWeightedEdgeList("rma_pearsons.85.out.wel", numVerts, (void*)mat, label->list, -3.0);
   
   free(outname);
   if( fexists((char*)"temp.gvl") )
      if(remove("temp.gvl")) fprintf(stderr,"Unable to remove %s\n","temp.gvl");

	return 0;
}
