#include "common.h"
#include "io/io.h"
#include "modules/modules.h"

void print_compile_time_settings();
void preamble(int, char**);

int main(int argc, char *argv[])
{
    preamble(argc, argv);
    int filestart,fileend,fileskip;

    filestart = 103;
    fileend = 120;
    fileskip = 1;

    setup();
    
    Snap.Time = read_input(filestart);
    printf("Input... read\n");

    Assert(Snap.Time < Param.EndTime, "First snapshot later than EndTime "
			"%g <> %g", Snap.Time, Param.EndTime);

    //sortP_global();    
    //printf("First sorting... done\n");

    Init_spectrum();
    printf("Spectrum... initialized");
    
    start_timing(CPU_MAIN);

    for (int ifile=filestart+1; ifile<fileend+1; ifile+=fileskip) { 

        Shift_Particle_Data();
        printf("Shift... done\n");
            
        Snap.Time = read_input(ifile);
        printf("New input... read\n");
    
        if (Snap.Time > Param.EndTime)
            break; // End program 

        //sortP_global();    
        //printf("New sorting... done\n");
        
	calc_timesteps(); 
        printf("Timestep... calculated\n");

        solver();
        printf("solver... done\n");
        
	write_spectra();
        printf("Write... done\n");
    }
    
    rprintf("\nEnd of Simulation reached \n\n");

    stop_timing(CPU_MAIN);

    finish_timing();

    MPI_Finalize();

    return EXIT_SUCCESS;
}

void preamble(int argc, char *argv[])
{
	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask.Rank);
	MPI_Comm_size(MPI_COMM_WORLD, &ThisTask.NTask);

	#pragma omp parallel
    {

#ifdef _OPENMP
    Omp.ThreadID = omp_get_thread_num();
    Omp.NThreads = omp_get_num_threads();
#else
    Omp.ThreadID = 0;
    Omp.NThreads = 1;
#endif
    
	}

  	rprintf("\n*** This is P-Fkp, a parallel Fokker Planck Solver ***\n");
	
	#pragma omp parallel
	rprintf("\nRunning on <%d> nodes  and <%d> threads per node\n\n", 
				ThisTask.NTask, Omp.NThreads);

    print_compile_time_settings();

    if ( !(argc == 2 || argc == 4) && !ThisTask.Rank) {
        printf("\nUsage   : ./P-Fkp $PARAMETERFILE [Flag] [SnapNum]\n"
            "Flag    : 1 = Resume, 2 = Convert Spectrum File\n"
            "SnapNum : Snapshot number to restart/convert from\n");

        Assert(0, "Program Call incomplete");
    }

    init_timing();

    read_param_file(argv[1]);

    if (argc == 4) {
        
        Param.Flag_Start = atoi(argv[2]);

        Snap.SnapNum = atoi(argv[3]);

        sprintf(Param.Input_File, "snap_%03d", Snap.SnapNum);

        if (Param.Flag_Start == 1)
            rprintf("\nResuming simulation at Snapshot %d \n",Snap.SnapNum);
        else if (Param.Flag_Start == 2)
            rprintf("\nConverting Spectrum File No: %d \n",Snap.SnapNum);
    }

    return ;
}
