/**
  Works like the main function of the program, it calls almost all other functions
*/
void run()
{
    char **files = get_files_list();

    read_matrix_from_file(files[1], 1);
    if (error_flag == 1)
        return;

    read_matrix_from_file(files[2], 2);
    if (error_flag == 1)
        return;

    post_read();
    if (error_flag == 1)
        return;

    calculate_without_threads();
    calculate_element_by_element();
    calculate_row_by_row();
    write_matrix_to_file(files[3]);
    print_statistics();
}
int main(int argc, char* argv[])
{
	int input[] = { 5, -1, 4, 12 };
	int input_size = 4;

	int input_sorted[] = { -4, 1, 22, 66, 89, 120, 238 };
	int input_sorted_size = 7;

	// 2. function pointers
	// direct invocation
	printf("Max is %d\n", max(input, input_size));
	// function pointer invocation
	int(*sortfunc)(int elements[], int size) = max;
	printf("Max (function pointer) %d\n", sortfunc(input, input_size));

	// 3. recursivity
	printf("recursive fibonacci(12) = %d\n", fibonacci_recursive(12));
	printf("iterative fibonacci(12) = %d\n", fibonacci_iterative(12));

	// 4. search
	// 4a. simple search 
	harness_search(input, input_size, 4, "search", search);
	harness_search(input, input_size, 2, "search", search);
	// 4b. binary search
	harness_search(input_sorted, input_sorted_size, 89, "search_binary", search_binary);
	harness_search(input_sorted, input_sorted_size, 500, "search_binary", search_binary);
	harness_search(input_sorted, input_sorted_size, -40, "search_binary", search_binary);
	harness_search(input_sorted, input_sorted_size, 140, "search_binary", search_binary);

	// 4. merge
	int to_sort[] = { 9, -1, 3, 11, 4, 99, 11, 0 };
	int to_sort_size = 8;

	printf("Performing merge sort\n");
	printf("- unsorted: ");
	print_array(to_sort, to_sort_size);
	sort_merge(to_sort, to_sort_size);
	printf("- sorted: ");
	print_array(to_sort, to_sort_size);

	// 5. file access
	int matrix[4][4] = {
		{ 1, 2, 3, 4 },
		{ 5, 6, 7, 8 },
		{ -1, -2, -3, -4 },
		{ 9, 78, 12, -1 }
	};
	write_matrix_to_file(matrix, "matrix.txt");
	int matrix_out[4][4];
	read_matrix_from_file(matrix_out, "matrix.txt");
	printf("Matrix read from file:\n");
	print_matrix(matrix_out);

	// 6/7. binary file access
	// delete 'db' before using
	unlink("students.dat");
	STUDENT student1;
	student1.an_studiu = 1;
	student1.grupa = 1014;
	student1.nume = "Salut";

	STUDENT student2;
	student2.an_studiu = 2;
	student2.grupa = 1084;
	student2.nume = "Pa";
	
	student_append(student1, "students.dat");
	student_append(student2, "students.dat");

	student_print_all("students.dat");

	// XX. bisection method
	// f(x) = x^3 - x - 2
	// f(1) = -2
	// f(2) = -4
	int res = bisection(1, 2, equation);
	printf("Bisected x to be %d\n", res);

	printf("GCD: %d\n", gcd(299792458, 6447287));

	return EXIT_SUCCESS;
}