/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package etomica.simulation.prototypes;

import etomica.action.BoxImposePbc;
import etomica.action.BoxInflate;
import etomica.action.activity.ActivityIntegrate;
import etomica.action.activity.Controller;
import etomica.atom.AtomType;
import etomica.box.Box;
import etomica.config.ConfigurationLattice;
import etomica.data.AccumulatorAverage;
import etomica.data.AccumulatorAverageCollapsing;
import etomica.data.DataPump;
import etomica.data.DataSourceCountSteps;
import etomica.data.meter.MeterPotentialEnergyFromIntegrator;
import etomica.data.types.DataDouble;
import etomica.data.types.DataGroup;
import etomica.integrator.IntegratorMC;
import etomica.integrator.mcmove.MCMoveAtom;
import etomica.lattice.LatticeCubicFcc;
import etomica.listener.IntegratorListenerAction;
import etomica.potential.P2SoftSphere;
import etomica.potential.P2SoftSphericalTruncated;
import etomica.potential.PotentialMaster;
import etomica.potential.PotentialMasterMonatomic;
import etomica.simulation.Simulation;
import etomica.space3d.Space3D;
import etomica.species.SpeciesSpheresMono;

/**
 * Simple hard-sphere Monte Carlo simulation in 2D.
 *
 * @author David Kofke
 */

public class SoftSphere3d extends Simulation {

    private static final long serialVersionUID = 1L;
    public IntegratorMC integrator;
    public MCMoveAtom mcMoveAtom;
    public SpeciesSpheresMono species, species2;
    public Box box;
    public P2SoftSphere potential;
    public PotentialMaster potentialMaster;
    public Controller controller;
    public DataSourceCountSteps meterCycles;


    public SoftSphere3d(double density, int exponent, double temperature) {
        super(Space3D.getInstance());
        potentialMaster = new PotentialMasterMonatomic(this);
        integrator = new IntegratorMC(this, potentialMaster);
        integrator.setTemperature(temperature);


        mcMoveAtom = new MCMoveAtom(random, potentialMaster, space);
        ActivityIntegrate activityIntegrate = new ActivityIntegrate(integrator);
        activityIntegrate.setMaxSteps(10000000);
        getController().addAction(activityIntegrate);

        species = new SpeciesSpheresMono(this, space);
        //species2 = new SpeciesSpheresMono(this);
        addSpecies(species);
        //getSpeciesManager().addSpecies(species2);
        box = new Box(space);
        addBox(box);
        box.setNMolecules(species, 108);
        BoxInflate inflater = new BoxInflate(box, space);
        inflater.setTargetDensity(density);
        inflater.actionPerformed();
        // box.setNMolecules(species2, 20);
        new ConfigurationLattice(new LatticeCubicFcc(space), space).initializeCoordinates(box);
        potential = new P2SoftSphere(space, 1, 1, exponent);
        P2SoftSphericalTruncated truncated = new P2SoftSphericalTruncated(space, potential, box.getBoundary().getBoxSize().getX(0) / 2);
        // System.out.println("Truncated radius is: " +truncated.getTruncationRadius());

        AtomType type1 = species.getLeafType();
        //AtomType type2 = species2.getLeafType();
        potentialMaster.addPotential(truncated, new AtomType[]{type1, type1});
        // potentialMaster.addPotential(potential, new AtomType[] {type1, type2});
        //potentialMaster.addPotential(potential, new AtomType[] {type2, type2});

        meterCycles = new DataSourceCountSteps(integrator);

        integrator.setBox(box);
        integrator.getMoveManager().addMCMove(mcMoveAtom);
        integrator.getEventManager().addListener(new IntegratorListenerAction(new BoxImposePbc(box, space)));

//	    LatticeRenderer.ColorSchemeCell colorSchemeCell = new LatticeRenderer.ColorSchemeCell();
//	    display.setColorScheme(colorSchemeCell);

//		elementCoordinator.go();
//	    etomica.lattice.BravaisLattice lattice = ((IteratorFactoryCell)this.getIteratorFactory()).getLattice(box);
//        colorSchemeCell.setLattice(lattice);
    }

    public static void main(String[] args) {

        double density = 1.338;
        int exponent = 12;
        double temperature = 0.1;


        if (args.length > 0) {
            density = Double.parseDouble(args[0]);
        }
        if (args.length > 1) {
            exponent = Integer.parseInt(args[1]);
        }
        if (args.length > 1) {
            temperature = Double.parseDouble(args[2]);
        }

        final SoftSphere3d sim = new SoftSphere3d(density, exponent, temperature);
        int numAtoms = 108;

        MeterPotentialEnergyFromIntegrator meterEnergy = new MeterPotentialEnergyFromIntegrator(sim.integrator);
        DataPump pump = new DataPump(meterEnergy, null);
        AccumulatorAverageCollapsing accumulator = new AccumulatorAverageCollapsing();

        accumulator.setPushInterval(1);
        pump.setDataSink(accumulator);
        sim.integrator.getEventManager().addListener(new IntegratorListenerAction(pump));

        sim.getController().actionPerformed();


        double temp = sim.integrator.getTemperature();
        double Cv = ((DataDouble) ((DataGroup) accumulator.getData()).getData(AccumulatorAverage.STANDARD_DEVIATION.index)).x;
        double energy = ((DataDouble) ((DataGroup) accumulator.getData()).getData(AccumulatorAverage.AVERAGE.index)).x;
        Cv /= temp;
        Cv *= Cv / numAtoms;
        System.out.println("Cv/k: " + Cv);
        System.out.println("System Energy: " + energy / numAtoms);

    }


}

@@ -363,51 +363,8 @@
 te;%0A
-import etomica.action.activity.Controller;%0A
 impo
@@ -1246,12 +1246,12 @@
 ple 
-hard
+soft
 -sph
@@ -1280,17 +1280,17 @@
 tion in 
-2
+3
 D.%0A *%0A *
@@ -1302,25 +1302,25 @@
 hor 
-David Kofke
+Tai Boon Tan
 %0A */%0A
-%0A
 publ
@@ -1367,61 +1367,8 @@
  %7B%0A%0A
-    private static final long serialVersionUID = 1L;%0A
     
@@ -1474,18 +1474,8 @@
 cies
-, species2
 ;%0A  
@@ -1575,42 +1575,8 @@
 er;%0A
-    public Controller controller;%0A
     
@@ -1617,16 +1617,79 @@
 ycles;%0A%0A
+    public SoftSphere3d() %7B%0A        this(1.338, 12, .1);%0A    %7D%0A
 %0A    pub
@@ -4544,19 +4544,50 @@
 Atoms = 
-108
+sim.box.getNMolecules(sim.species)
 ;%0A%0A     

clean up stuff (including javadoc), ensure there is a no-args contructor