#include "mainbody.h"

int run_main_body(bool print_all, int n_runs, std::string ped_filename, std::string loc_filename, std::string fou_filename, GeneDrop* ui, bool* lock, bool* excep_flag)
{
    int i;
    int n_founders;	//Number of founder lines
    int n_gens;	//Number of generations in pedigree
    int n_loci;	//Number of markers being considered
    int seed;	//Seed for random number generator
    std::vector<locus> loci;	//Container for markers

    //Lock the thread
    *lock=true;

    //Mark exception flag incase there is a failure
    *excep_flag=true;

    //Read in the data about mapping distances between loci
    try
    {
        read_recom_fracs(&loci, &n_loci, loc_filename, ui);
    }
    catch(std::exception &e)
    {
        std::stringstream message;

        message<<"Reading in the loci data failed: "<<e.what();
        ui->print(message);
        *lock=false;
        *excep_flag=true;
        return 1;
    }
    catch(...)
    {
        ui->print("Reading in the loci data failed.");
        *lock=false;
        *excep_flag=true;
        return 1;
    }
    boost::this_thread::interruption_point();

    //Determine how many generations are included in the pedigree
    try
    {
        get_num_gens(&n_gens, ped_filename, ui);
    }
    catch(std::exception &e)
    {
        std::stringstream message;

        message<<"Determining the number of generations failed: "<<e.what();
        ui->print(message);
        *lock=false;
        *excep_flag=true;
        return 1;
    }
    catch(...)
    {
        ui->print("Determining the number of generations failed");
        *lock=false;
        *excep_flag=true;
        return 1;
    }
    boost::this_thread::interruption_point();

    //Work out how many founder lines there are
    try
    {
        get_num_founders(&n_founders, fou_filename, ui);
    }
    catch(std::exception &e)
    {
        std::stringstream message;

        message<<"Determing the number of founder lines failed: "<<e.what();
        ui->print(message);
        *lock=false;
        *excep_flag=true;
        return 1;
    }
    catch(...)
    {
        ui->print("Determining the number of founder lines failed");
        *lock=false;
        *excep_flag=true;
        return 1;
    }
    boost::this_thread::interruption_point();

    //Seed the random number generator
    if((seed=time(NULL))==-1)
    {
        ui->print("Determining the seed for the random number generator (using the system time) failed.");
        *lock=false;
        *excep_flag=true;
        return 1;
    }
    if(seed<=1)
    {
        seed++;
    }

    //Set up and seed boost random number generator
    boost::mt19937 mersenne;
    mersenne.seed(seed);
    boost::uniform_01<boost::mt19937> rng(mersenne);

    //Run simulations with parameters
    for(i=0; i<n_runs; i++)
    {
        std::stringstream message;

        message<<"Currently simulating run "<<i+1<<"/"<<n_runs<<".";
        ui->print(message);

        try
        {
            run_simulation(print_all, &rng, i, n_gens, loci, seed, n_runs, n_loci, &n_founders, ui, ped_filename, fou_filename);
        }
        catch(std::exception &e)
        {
            message<<"Running the simulation failed: "<<e.what();
            ui->print(message);
            *lock=false;
            *excep_flag=true;
            return 1;
        }
        catch(...)
        {
            ui->print("Running the simulation failed.");
            *lock=false;
            *excep_flag=true;
            return 1;
        }

        message<<"Run "<<i+1<<"/"<<n_runs<<" complete.";
        ui->print(message);
        ui->print(" ");
    }

    ui->print("\\O/ Jobs done \\O/");

    ui->print(" ");
    ui->print(" ");
    ui->print(" ");

    //Unlock the thread
    *lock=false;

    //Unmark exception flag if get to the end
    *excep_flag=false;

    return 0;
}
