#ifndef _JRN_AXISLAYOUT_H_
#define _JRN_AXISLAYOUT_H_

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <limits.h>

#include "globals.h"
#include "layout.h"

#define SWAP(a,b) { register int t=(a);(a)=(b);(b)=t; }

#ifdef __cplusplus
extern "C" {
#endif

//------------------------------------------------------------------------
// Creates a layout of axes that's near optimal by picking out the
// highest-valued pair and then greedily creating a layout which optimizes
// the total edge weight of consecutive axes connected to the last.
// O(|V|^2 + |V|*(k-2))
//------------------------------------------------------------------------
int* bestByGreedy(int numAxes, graph* g);

//------------------------------------------------------------------------
// Creates a layout of axes that's near optimal by picking out the
// highest-valued pairs and then creating a layout which optimizes
// the total edge weight of consecutive axes.
// O(k|V|^2 + k!)
//------------------------------------------------------------------------
int* bestByPairs(int numAxes, graph* g);

//------------------------------------------------------------------------
// Gets the requested number of variables which make up pairs with
// the highest or lowest edge weight
//------------------------------------------------------------------------
int getBestPairs(int numAxes, graph* g, int** targetX, int** targetY, int allowRepeats);
int getWorstPairs(int numAxes, graph* g, int** targetX, int** targetY, int allowRepeats);

//------------------------------------------------------------------------
// Tell the sum of weights for a given layout
//------------------------------------------------------------------------
int getFitness(int numAxes, int* layout, graph* g);
int getFitnessMultiFile(int numAxes, int* layout, graph** sg);

//------------------------------------------------------------------------
// Creates a layout of axes by brute-force searching all possible axis
// combinations.
// O( (n choose k) * k!) = O( n!/(n-k)! )
//------------------------------------------------------------------------
int* bestByBruteForce(int numAxes, graph* g);

//------------------------------------------------------------------------
// Creates a layout of axes by taking an integer array which denotes
// whether the axes should contain high or low (within percentage) values
// in all supplied graphs.
//------------------------------------------------------------------------
int* comboMultiFile(int numAxes, int* combo, graph** sg, int allowRepeats);
int* comboMultiFileAvg(int numAxes, int* combo, graph** sg);


//Combination n choose k
int choose(int n, int k);
//int QuickPerm(int num, int* list);

#ifdef __cplusplus
}
#endif

#endif
