#include <stdio.h>
#include <stdlib.h>
#include "globals.h"
#include "graphProcessing.h"
#include "graphio.h"
#include "axislayout.h"

/* Data */
graph* g;
#define MAX_SUBGRAPHS 16
int numSGs = 0;
graph* sg[MAX_SUBGRAPHS];

/* Layout Algorithms */
#define GREEDY 0
#define GREEDY_PAIRS 1
#define COMBO_HILO 2
#define BRUTE_FORCE 3
int layoutOption = COMBO_HILO;

/* Params */
float threshold;
int absoluteValue;

//------------------------------------------------------------------------
// Prints the correct usage and exits upon incorrect parameters
//------------------------------------------------------------------------
void PrintUsage() {
	printf("Usage: axislayout filename.wel 0.85  -OR-\n");
  printf("Usage: axislayout file1.wel file2.wel ... file_numAxes.wel  -OR-\n");
	printf("   Ex: axislayout rma_pearsons.85.wel 0.85\n");
	exit(-1);
}

//------------------------------------------------------------------------
/// The code here initializes data from our dataset(s)
//------------------------------------------------------------------------
void initData(int argc, char** argv) {
	int i;
	char *filename, *extension;

	//Read the input file
	if(argc==1) {
		PrintUsage();
	}
  else if (argc==2 || argc==3) {
      if (layoutOption == COMBO_HILO) PrintUsage();
      filename=argv[1];
      if(argc==3) {
         threshold = (float)atof(argv[2]);
      }
      else {
	      printf("Reading the edge list for threshold...\n");
         if( getLowestWeight(filename,&threshold)==-1 ) {
	         printf("  Read %s\n",filename);
            PrintUsage();
         }
	      printf("  Read %s - threshold %f\n",filename,threshold);
      }

      absoluteValue = 1;
  }
  else if (argc==6) {
    if (layoutOption != COMBO_HILO) PrintUsage();
    numSGs=5;
    for(i=0;i<numSGs;i++) {
      threshold = 0.0;
      absoluteValue = 1;

      sg[i]=createGraph();
      filename=argv[i+1];
      sg[i]->name=(char*)malloc( (strlen(filename)+1)*sizeof(char) );
      if(sg[i]->name==NULL) {
         perror("initData() g->name");
      }
	    strcpy(sg[i]->name,filename);

      //Assumes 3-letter extension convention
	    extension=filename+(strlen(filename)-4);
	    if(strcmp(extension,".ltm")==0)
		    sg[i]->numVerts = readLTMDefaultWeighted2D(filename, threshold,absoluteValue, sg[i]);
	    else
		    sg[i]->numVerts = readDefaultWeighted2D(filename, threshold, absoluteValue, sg[i]);

       if(sg[i]->numVerts<0) exit(-1);
       else printf("  Read %s\n",filename);

    }
    g=sg[0];
    return;
  }
	else {
		printf("Unknown view option selected\n");
		PrintUsage();
	}

	//Main graph data structure
	for(i=0;i<MAX_SUBGRAPHS;i++) sg[i]=NULL;
	g=createGraph();
   if (g->name!=NULL) free(g->name);
	g->name=(char*)malloc( (strlen(filename)+1)*sizeof(char) );
   if(g->name==NULL) {
      perror("initData() g->name");
   }
	strcpy(g->name,filename);

	//Read the input file
	printf("Reading the edge list...\n");
	
	//Assumes 3-letter extension convention
	extension=filename+(strlen(filename)-4);
	if(strcmp(extension,".ltm")==0)
		g->numVerts = readLTMDefaultWeighted2D(filename, threshold,absoluteValue, g);
	else
		g->numVerts = readDefaultWeighted2D(filename, threshold, absoluteValue, g);

   if(g->numVerts<0) exit(-1);
   else printf("  Read %s\n",filename);

}

//------------------------------------------------------------------------
//   It's the main application function for testing axis layouts.
//------------------------------------------------------------------------
int axisLayoutTest(int argc, char** argv)
{
  int i,j;
  int tmpLayout[2];
  int *layout1, *max1,*max2, *min1,*min2; 
  char temp[2];
  
  initData(argc,argv);

  if(layoutOption == GREEDY_PAIRS) {
    layout1 = bestByPairs(7, g);
    printf("  Best by pairs - ");
    printf("(%f)-",getFitness(7,layout1,g)/DENOM_THRESH);
    for(i=0;i<7;i++) {
       printf(" %d",layout1[i]);
    }
    printf("\n");
  }

  if(layoutOption == COMBO_HILO) {
    int numAxes=5;
    int combo[32][5] = {{0,0,0,0,0},{0,0,0,0,1},{0,0,0,1,0},{0,0,0,1,1},
      {0,0,1,0,0},{0,0,1,0,1},{0,0,1,1,0},{0,0,1,1,1},
      {0,1,0,0,0},{0,1,0,0,1},{0,1,0,1,0},{0,1,0,1,1},
      {0,1,1,0,0},{0,1,1,0,1},{0,1,1,1,0},{0,1,1,1,1},
      {1,0,0,0,0},{1,0,0,0,1},{1,0,0,1,0},{1,0,0,1,1},
      {1,0,1,0,0},{1,0,1,0,1},{1,0,1,1,0},{1,0,1,1,1},
      {1,1,0,0,0},{1,1,0,0,1},{1,1,0,1,0},{1,1,0,1,1},
      {1,1,1,0,0},{1,1,1,0,1},{1,1,1,1,0},{1,1,1,1,1}};

    printf("\n\nPairwise example of min/max for each metric:\n");
    for(i=0;i<numAxes;i++) {
      getBestPairs(1,sg[i],&max1,&max2,1);
      getWorstPairs(1,sg[i],&min1,&min2,1);
      printf("%s:\n",sg[i]->name);
      tmpLayout[0]=min1[0]; tmpLayout[1]=min2[0];
      printf("(%f)-%d %d\n",getFitness(2,tmpLayout,sg[i])/DENOM_THRESH,min1[0],min2[0]);
      tmpLayout[0]=max1[0]; tmpLayout[1]=max2[0];
      printf("(%f)-%d %d\n",getFitness(2,tmpLayout,sg[i])/DENOM_THRESH,max1[0],max2[0]);
    }

    printf("\n\nMultiFile results using pairwise algorithm:\n");
    for(i=0;i<32;i++) {
      for(j=0;j<numAxes;j++) printf("%1d",combo[i][j]);
      layout1 = comboMultiFile(numAxes,combo[i],sg,0);
      printf("\t(%f)-",getFitnessMultiFile(5,layout1,sg)/DENOM_THRESH);
      for(j=0;j<numAxes;j++) {
       printf(" %d",layout1[j]);
      }
      printf("\n");
      free(layout1);
    }

    printf("\n\nMultiFile results using average algorithm:\n");
    for(i=0;i<32;i++) {
      for(j=0;j<numAxes;j++) printf("%1d",combo[i][j]);
      layout1 = comboMultiFileAvg(numAxes,combo[i],sg);
      printf("\t(%f)-",getFitnessMultiFile(5,layout1,sg)/DENOM_THRESH);
      for(j=0;j<numAxes;j++) {
       printf(" %d",layout1[j]);
      }
      printf("\n");
      free(layout1);
    }
 
  }

  if(layoutOption == BRUTE_FORCE) {
    layout1 = bestByBruteForce(7,g);
    printf("  Global Optimum - ");
    printf("(%f)-",getFitness(7,layout1,g)/DENOM_THRESH);
    for(i=0;i<7;i++) {
       printf(" %d",layout1[i]);
    }
    printf("\n");

    /*int layout[15][7]=
      {{34, 0, 25, 1, 43, 6, 12}, {49, 34, 40, 50, 24, 41, 51}, {61, 59, 0, 1, 43, 44, 14},
           {58, 56, 35, 36, 11, 43, 59}, {3, 49, 4, 34, 2, 48, 6},
       {26, 91, 87, 25, 86, 1, 43}, {24, 101, 50, 111, 102, 40, 34}, {72, 0, 1, 43, 120, 104, 59},
           {59, 104, 120, 43, 72, 11, 36}, {3, 49, 4, 110, 6, 50, 12},
       {635, 1, 330, 396, 269, 208, 147}, {416, 477, 599, 474, 535, 413, 538}, {0, 1, 43, 120, 165, 181, 226},
           {429, 242, 490, 181, 714, 120, 104}, {537, 291, 17, 334, 416, 477, 1}};
     for(i=0;i<15;i++) {
        printf("%d - %f\n",i,getFitness(7,layout[i],g)/DENOM_THRESH);
     }*/
  }

  //fgets(temp,2,stdin);
	return 0;
}
