/*
 * root.c
 *
 *  Created on: Nov 23, 2009
 *      Author: brian
 */
#include <stdio.h>
#include <mpi.h>
#include "constants.h"
#include "root.h"

int root(int size)
{

	printf("Argos Version Started");

	char message[BUFFSIZE];
	int i, gen;
	MPI_Status stat;
	MPI_Status stat2;
	int cont;
	int converged = 0;
	int conv_t = -1;
	FILE* conv_data;


//Discover if migration (Random or directed) or mutation gradients are enabled (at compile time)
	int migrate = 0;
	int dirmig = 0;
	int mutgrad = 0;

#ifdef MIGRATE
	migrate = 1;
#endif
#ifdef DIRMIG
	dirmig = 1;
#endif
#ifdef MUTGRAD
	mutgrad = 1;
#endif


	double s_max;

	//printf("Size: %d\n", size);

    if (checkSize(size) != 0)
    {
    	printf("Error.  Size must equal 1 + LANDSCAPE_WIDTH * LANDSCAPE_HEIGHT (%d). Terminating.\n", 1 + LANDSCAPE_WIDTH * LANDSCAPE_HEIGHT);
    	MPI_Finalize();
    	return -1;
    }

    for (gen = 0; gen < 3000; gen++)
    {
		for (i = 1; i < size; i++)
		{
			MPI_Recv(message, BUFFSIZE, MPI_CHAR, i, STATUS_TAG, MPI_COMM_WORLD, &stat);
			MPI_Recv(&s_max, 1, MPI_DOUBLE, i, BEST_TAG, MPI_COMM_WORLD, &stat2);
			cont = 0;
			MPI_Send(&cont, 1, MPI_INT, i, CONTINUE_TAG, MPI_COMM_WORLD);

			if (s_max > 16.5)
			{
				printf("!!!FOUND!!!");
				converged = 1;
			}

			printf("%s", message);
		}

		if (converged == 1)
		{
			conv_t = gen;
			break;
		}
    }

    //Tell the child processes to terminate the genetic algorithm
    cont = -1;
    for (i = 1; i < size; i++)
    {
    	MPI_Send(&cont, 1, MPI_INT, i, CONTINUE_TAG, MPI_COMM_WORLD);
    }


	//Add data to the convergence log
	conv_data = fopen("conv_data.txt", "a");
	if (conv_data == NULL)
	{
		printf("Couldn't open convergence log for appending!\n");
		return 13;
	}

	//Write data to the file
	fprintf(conv_data, "%d, %d, %d, %d\n", conv_t, migrate, dirmig, mutgrad);

	//Close the file
	fclose(conv_data);
}

int checkSize(int s)
{
    //Check that there is the correct number of processes
    //For the LANDSCAPE_WIDTH and LANDSCAPE_HEIGHT defined
    //in constants.h
    if (s != (1 + LANDSCAPE_WIDTH * LANDSCAPE_HEIGHT))
    {
    	return -1;
    }

    return 0;
}
