
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

/**
 * Class that can be used toward the completion of CE 530 Assignment 7.
 * Everything is set up to read a file config.dat having xyz coordinates to be analyzed, and given with the assignment.
 * Resulting g(r) will be written to a file rdf.dat, having two columns with values of r and g(r), respectively.
 * The config.dat file should be placed in the same directory as the Assignment7.class file.
 * The rdf.dat file will be written to this directory.
 * 
 * Everything is in place to do the input/output processing.  You need just to code the g(r) calculation
 * algorithm in the location highlighted in the code.
 *
 */

public class Assignment7 {
      
    // This main method sets up parameters and calls the required static methods of this class to perform the calculations.
    // Upon completion, the computed g(r) will be in a file "rdf.dat" in the same directory as the config.dat file 
    public static void main(String[] args) {

        int n = 6000;//number of atoms
        double L = 20;//length of the cubic box
        double[][] xyz;//coordinates of the atoms, as read from file; first index (0 to n-1) is atom number, second index (0 to 2) indicates x, y, or z
        double dr = 1./16.; //spacing of r values in output g(r); it is good to make this a power of 1/2
        String pathName = "";//this should point to directory where config.dat file is located; it is not needed if config.dat is in same directory as Assignment7.class

        xyz = Assignment7.readConfig(pathName+"config.dat", n);
        double[] g = Assignment7.calculateRDF(n, xyz, L, dr);
        Assignment7.writeRDF(pathName+"rdf.dat",dr, g);
     
    }

    /**
     * Computes and returns the radial distribution function given the input parameters:
     * @param n - number of atoms in the configuration
     * @param xyz - array of atoms' x, y, and z coordinates; xyz[i][j] gives coordinate for atom i, with j = 0,1,2 for x, y, z, respectively.
     * @param L - edge length of the cubic box containing the atoms
     * @param dr - spacing of the r values for the returned g(r) function
     * @param nBin - number of bins (each corresponding to an r value) in the returned g(r) function
     * @return an array containing the g(r) values
     */
    public static double[] calculateRDF(int n, double[][] xyz, double L, double dr) {
        
        double rMax = L/2;  //maximum tabulated value is half the box length
        int nBin = (int)(rMax/dr); // number of bins in tabulation of g
        double[] g = new double[nBin];
 
//  ********************************************************
//  *****FILL IN HERE THE CODE NEEDED TO COMPUTE G(R) ******
//  ********************************************************
     
        return g;
    }
    
    //**************  Remainder is utility I/O methods **********************
    
    public static double[][] readConfig(String fileName, int n) {
        double xyz[][] = new double[n][3];
        try {
            File file = new File(fileName);
            Scanner scanner = new Scanner(file);
            int i = 0;
            while (scanner.hasNext()) {
                xyz[i][0] = scanner.nextDouble();
                xyz[i][1] = scanner.nextDouble();
                xyz[i][2] = scanner.nextDouble();
                i++;
            }
            scanner.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } 
        return xyz;
    }

    
    public static void writeRDF(String fileName, double dr, double[] g) {
        try {
            File file = new File(fileName);
            if (!file.exists()) {
                file.createNewFile();
            }
 
            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            for(int i=0; i<g.length; i++) {
//                System.out.println((i+0.5)*dr+"\t"+g[i]);
                bw.write((i+0.5)*dr+"\t"+g[i]+"\n");
            }
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }
}
