#include <stdio.h>
#include "Blossom.h"

//run like this: >Blossom -e blossom3228-2527 -w out3228.txt //indeed filenames at the cmd prompt ignored at this time

void LoadFile(int& node_num, int& edge_num, int*& edges, int*& weights, char* filename)
{
	int e = 0;
	char LINE[1000];
	FILE* fp = fopen(filename, "r");
	if (!fp) { printf("Can't open %s\n", filename); exit(1); }

	int format = -1; // 0: DIMACS format. node id's start from 1
	                 // 1: simpler format (without "p" and "e"). node id's start from 0

	edge_num = -1;
	while (fgets(LINE, sizeof(LINE)-1, fp))
	{
		if (LINE[0] == 'c') continue;
		if (format < 0)
		{
			if (LINE[0] == 'p')
			{
				format = 0;
				if (sscanf(LINE, "p edge %d %d\n", &node_num, &edge_num) != 2) { printf("%s: wrong format #1\n", filename); exit(1); }
			}
			else
			{
				format = 1;
				if (sscanf(LINE, "%d %d\n", &node_num, &edge_num) != 2) { printf("%s: wrong format #1\n", filename); exit(1); }
			}

			//////////////////////////////////////////////////////////////////////////////////
			if (node_num <= 0 || edge_num < 0) { printf("# of nodes and edges should be positive\n"); exit(1); }
			if (node_num & 1) { printf("# of nodes is odd: perfect matching cannot exist\n"); exit(1); }
			edges = new int[2*edge_num];
			weights = new int[edge_num];
			//////////////////////////////////////////////////////////////////////////////////
		}
		else
		{
			int i, j;
			char* ptr = LINE;
			if (format == 0) { if (LINE[0] != 'e') continue; ptr = &LINE[1]; }
			else             ptr = &LINE[0];

			int len;
			if (sscanf(ptr, "%d %d %d\n", &i, &j, &len) != 3) continue;
			if (format == 0) { i --; j --; }
			edges[2*e] = i;
			edges[2*e+1] = j;
			weights[e] = len;
			e ++;
		}
	}

	if (e != edge_num) { printf("%s: wrong format #3\n", filename); exit(1); }
	fclose(fp);
}

void LoadFileDouble(int& node_num, int& edge_num, int*& edges, double*& weights, char* filename)
{
	int e = 0;
	char LINE[1000];
	FILE* fp = fopen(filename, "r");
	if (!fp) { printf("Can't open %s\n", filename); exit(1); }

	int format = -1; // 0: DIMACS format. node id's start from 1
	                 // 1: simpler format (without "p" and "e"). node id's start from 0

	edge_num = -1;
	while (fgets(LINE, sizeof(LINE)-1, fp))
	{
		if (LINE[0] == 'c') continue;
		if (format < 0)
		{
			if (LINE[0] == 'p')
			{
				format = 0;
				if (sscanf(LINE, "p edge %d %d\n", &node_num, &edge_num) != 2) { printf("%s: wrong format #1\n", filename); exit(1); }
			}
			else
			{
				format = 1;
				if (sscanf(LINE, "%d %d\n", &node_num, &edge_num) != 2) { printf("%s: wrong format #1\n", filename); exit(1); }
			}

			//////////////////////////////////////////////////////////////////////////////////
			if (node_num <= 0 || edge_num < 0) { printf("# of nodes and edges should be positive\n"); exit(1); }
			if (node_num & 1) { printf("# of nodes is odd: perfect matching cannot exist\n"); exit(1); }
			edges = new int[2*edge_num];
			weights = new double[edge_num];
			//////////////////////////////////////////////////////////////////////////////////
		}
		else
		{
			int i, j;
			char* ptr = LINE;
			if (format == 0) { if (LINE[0] != 'e') continue; ptr = &LINE[1]; }
			else             ptr = &LINE[0];

			double len;
			if (sscanf(ptr, "%d %d %lf\n", &i, &j, &len) != 3) continue;
			if (format == 0) { i --; j --; }
			edges[2*e] = i;
			edges[2*e+1] = j;
			weights[e] = len;
			e ++;
		}
	}

	if (e != edge_num) { printf("%s: wrong format #3\n", filename); exit(1); }
	fclose(fp);
}

int main(int argc, char* argv[])
{
	char* filename = "blossom3228-2527";
	char* save_filename = "out3228.txt";
	int node_num, edge_num;
	int* edges;
	int* weights;
	double* weightsD;

	//LoadFile(node_num, edge_num, edges, weights, filename);
	LoadFileDouble(node_num, edge_num, edges, weightsD, filename);

	Blossom* blossom = new Blossom(save_filename);
	float cost = blossom->match(node_num, edge_num, edges, weightsD);
	printf("cost in main() = %.1f\n", cost);
	
	delete blossom; //no delete [] edges; and so on 'cos they're deleted in match()
	////// matching ends ////////

	return 0;
}


