
#include "gate.h"
#include "import.h"
#include "mapper.h"
#include "export_LUTs.h"
#include <list>
#include <map>
#include <set>
#include <time.h>

unsigned int Gate::c_id = 0;
unsigned int Gate::odstraneno = 0;

int main(int argc, char* argv[]) {	
	clock_t base_time_cl = clock();
	clock_t time_of_reading_circuits_cl;
	clock_t time_of_transforming_cl;
	clock_t time_of_counting_cl;
	clock_t time_of_printing_results_cl;	

	std::list<Gate*> inputs;
	std::list<Gate*> outputs;
	std::list<Gate*> inner_nodes;
	std::list<Lut*> luts;

	

	if (argc == 4) {
		Import import = Import(argv[1]);
		std::cout << "Reading circuit. ";
		import.read_circuit(inputs, outputs, inner_nodes); // bude prebirat 3 parametry....vstupni, vystupni a vnitrni uzly.... dojde ke zmenene
		std::cout << "Completed." << std::endl;
		time_of_reading_circuits_cl = clock();
	}
	else {
		std::cout << "Usei: mapper input_circuit.bench output_circuit.blif number_of_inputs_of_LUT";
		exit (-1);
	}

	int K = atoi(argv[3]);
	
	Mapper map (inputs, outputs, inner_nodes);
	std::cout << "Transforming into 2-bounded net. ";
	map.transform_to_K_bounded(2);
	std::cout << "Completed." <<std::endl;
	
	time_of_transforming_cl = clock();
	
	std::cout << "Counting of cuts.";
	map.map(luts, K);
	
	time_of_counting_cl = clock();
	std::cout << "	Completed." << std::endl;

	Export_LUTs exp (inputs,outputs,luts);
	
	time_of_printing_results_cl = clock();
	exp.export_LUTs (argv[2]);

	unsigned int depth = 0;
	for (std::list<Lut*>::iterator it = luts.begin(); it != luts.end(); ++it) {
		unsigned int x = (*it)->spoctiHloubku();
		if (x > depth)
			depth = x;
	}

	std::cout << std::endl << "Statistic: " << std::endl;
	std::cout << "Depth of critical path: " << depth << std::endl;
	std::cout << "Number of LUTs: " << luts.size() << std::endl <<std::endl;
	std::cout << "Time of reading circuits: " << (time_of_reading_circuits_cl - base_time_cl)<< " ms.\n";	
	std::cout << "Time of transforming into 2-bounding net: " << (time_of_transforming_cl - time_of_reading_circuits_cl)<< " ms.\n";	
	std::cout << "Time of counting of LUTs: " << (time_of_counting_cl - time_of_transforming_cl) << " ms.\n";	
	std::cout << "Time of writing results: " << (time_of_printing_results_cl - time_of_counting_cl) << " ms.\n";
	std::cout << "===============================================================\n";	
	std::cout << "Total time: " << (time_of_printing_results_cl - base_time_cl) << " ms." <<std::endl;
	
	for (std::list<Lut*>::iterator it = luts.begin(); it != luts.end(); ++it) {
		delete (*it);
	}

	for (std::list<Gate*>::iterator it = inputs.begin(); it != inputs.end(); ++it) 
		delete (*it);
	

	for (std::list<Gate*>::iterator it = inner_nodes.begin(); it != inner_nodes.end(); ++it) 		
		delete (*it);
	

	for (std::list<Gate*>::iterator it = outputs.begin(); it != outputs.end(); ++it) 		
		delete (*it);

	return 0;
};
