// Path: src/worlds/planet/PlanetCell.java
// public class PlanetCell extends GeoCell {
// 
//   public static int area, length;
// 
//   static {
//     length = 1;
//     area = 1;
//   }
// 
//   public PlanetCell() {
//     this(0, 0);
//   }
// 
//   public PlanetCell(int x, int y) {
//     super(x, y);
//   }
// 
// }
// 
// Path: src/worlds/planet/Surface.java
// public abstract class Surface extends SurfaceMap<PlanetCell> {
// 
//   /**
//    * The number of years that pass for each step of erosion
//    */
//   public static long GEOUPDATE;
//   private long geologicalTimeStamp;
// 
//   /**
//    * The age of the planet in years
//    */
//   public static AtomicLong planetAge;
//   
//   /**
//    * The number of years that pass for each update to the geosphere
//    */
//   public static long timeStep;
// 
//   public final static int HEIGHTMAP = 0;
//   public final static int STRATAMAP = 1;
//   public final static int LANDOCEAN = 2;
// 
//   private static final int DEFAULT_THREAD_DELAY = 50;
// 
//   private final MinMaxHeightFactory mhFactory;
// 
//   static {
//     timeStep = 7125000;
//   }
// 
//   /**
//    * Constructs a new Surface with an empty map.
//    *
//    * @param totalSize The size of the surface
//    * @param threadsDelay The amount of time to delay each frame in milliseconds.
//    * @param threadCount The number of threads that will work on the map
//    */
//   public Surface(int totalSize, int threadsDelay, int threadCount) {
//     super(totalSize, DEFAULT_THREAD_DELAY);
//     setupThreads(threadCount, threadsDelay);
//     setupDefaultMap(threadCount);
//     mhFactory = new MinMaxHeightFactory(this);
//     produceTasks(mhFactory);
//     reset();
//   }
// 
//   /**
//    * Resets the surface to an empty map and resets the planet's age. This method
//    * should be calling the <code>buildMap()</code> method.
//    */
//   @Override
//   public final void reset() {
//     planetAge = new AtomicLong(0);
//     geologicalTimeStamp = 0;
//     pauseThreads();
//     buildMap();
//     addTaskToThreads(new SetParentThreads());
//     playThreads();
//   }
// 
//   public long getPlanetAge() {
//     return planetAge.get();
//   }
// 
//   public void updatePlanetAge() {
//     long curPlanetAge = planetAge.getAndAdd(timeStep);
//     if (curPlanetAge - geologicalTimeStamp > GEOUPDATE) {
//       geologicalTimeStamp = curPlanetAge;
//     }
//   }
// 
//   @Override
//   public PlanetCell generateCell(int x, int y) {
//     return new PlanetCell(x, y);
//   }
// 
//   public float getHighestHeight() {
//     return mhFactory.getHighestHeight();
//   }
// 
//   public float getLowestHeight() {
//     return mhFactory.getLowestHeight();
//   }
// 
// }


import java.util.HashSet;
import java.util.Set;
import worlds.planet.PlanetCell;
import worlds.planet.Surface;

package worlds.planet.geosphere;


/**
 *
 * @author Richard
 */
public class Layer {
  
  private RockType type;
  
  /**
   * The average averageDensity of the layer, this is based on an average for that type.
   * The units are in grams per liter.
   */
  private float averageDensity;
  
  private float averageErosionFactor;
  
  private float totalMass;
  
  private float specificHeat;
  
  /**
   * The temperature of this layer
   */
  private float temperature;
  
  private float granularity;
  
  private long depositTimeStamp;
  /**
   * An object reference of the layer below this Stratum.
   */
  private Layer bottom, top;
  
  /**
   * The list of materials that make up this Rock Layer. This forms layers 
   * such as granite, basalt, sandstones, or sediments eroded from these
   * rocks. 
   */
  private final Set<LayerMaterial> materials;
  
  public Layer() {
    this.materials = new HashSet<>();
    update();
  }
  
  /**
   * Copy constructor
   * @param layer A Deep copy of this Layer and the Materials inside it.
   */
  public Layer(Layer layer) {
    this.bottom = layer.bottom;
    this.top = layer.top;
// Path: src/worlds/planet/PlanetCell.java
// public class PlanetCell extends GeoCell {
// 
//   public static int area, length;
// 
//   static {
//     length = 1;
//     area = 1;
//   }
// 
//   public PlanetCell() {
//     this(0, 0);
//   }
// 
//   public PlanetCell(int x, int y) {
//     super(x, y);
//   }
// 
// }
// 
// Path: src/worlds/planet/Surface.java
// public abstract class Surface extends SurfaceMap<PlanetCell> {
// 
//   /**
//    * The number of years that pass for each step of erosion
//    */
//   public static long GEOUPDATE;
//   private long geologicalTimeStamp;
// 
//   /**
//    * The age of the planet in years
//    */
//   public static AtomicLong planetAge;
//   
//   /**
//    * The number of years that pass for each update to the geosphere
//    */
//   public static long timeStep;
// 
//   public final static int HEIGHTMAP = 0;
//   public final static int STRATAMAP = 1;
//   public final static int LANDOCEAN = 2;
// 
//   private static final int DEFAULT_THREAD_DELAY = 50;
// 
//   private final MinMaxHeightFactory mhFactory;
// 
//   static {
//     timeStep = 7125000;
//   }
// 
//   /**
//    * Constructs a new Surface with an empty map.
//    *
//    * @param totalSize The size of the surface
//    * @param threadsDelay The amount of time to delay each frame in milliseconds.
//    * @param threadCount The number of threads that will work on the map
//    */
//   public Surface(int totalSize, int threadsDelay, int threadCount) {
//     super(totalSize, DEFAULT_THREAD_DELAY);
//     setupThreads(threadCount, threadsDelay);
//     setupDefaultMap(threadCount);
//     mhFactory = new MinMaxHeightFactory(this);
//     produceTasks(mhFactory);
//     reset();
//   }
// 
//   /**
//    * Resets the surface to an empty map and resets the planet's age. This method
//    * should be calling the <code>buildMap()</code> method.
//    */
//   @Override
//   public final void reset() {
//     planetAge = new AtomicLong(0);
//     geologicalTimeStamp = 0;
//     pauseThreads();
//     buildMap();
//     addTaskToThreads(new SetParentThreads());
//     playThreads();
//   }
// 
//   public long getPlanetAge() {
//     return planetAge.get();
//   }
// 
//   public void updatePlanetAge() {
//     long curPlanetAge = planetAge.getAndAdd(timeStep);
//     if (curPlanetAge - geologicalTimeStamp > GEOUPDATE) {
//       geologicalTimeStamp = curPlanetAge;
//     }
//   }
// 
//   @Override
//   public PlanetCell generateCell(int x, int y) {
//     return new PlanetCell(x, y);
//   }
// 
//   public float getHighestHeight() {
//     return mhFactory.getHighestHeight();
//   }
// 
//   public float getLowestHeight() {
//     return mhFactory.getLowestHeight();
//   }
// 
// }


// Path: src/worlds/planet/geosphere/Layer.java
import java.util.HashSet;
import java.util.Set;
import worlds.planet.PlanetCell;
import worlds.planet.Surface;


package worlds.planet.geosphere;


/**
 *
 * @author Richard
 */
public class Layer {
  
  private RockType type;
  
  /**
   * The average averageDensity of the layer, this is based on an average for that type.
   * The units are in grams per liter.
   */
  private float averageDensity;
  
  private float averageErosionFactor;
  
  private float totalMass;
  
  private float specificHeat;
  
  /**
   * The temperature of this layer
   */
  private float temperature;
  
  private float granularity;
  
  private long depositTimeStamp;
  /**
   * An object reference of the layer below this Stratum.
   */
  private Layer bottom, top;
  
  /**
   * The list of materials that make up this Rock Layer. This forms layers 
   * such as granite, basalt, sandstones, or sediments eroded from these
   * rocks. 
   */
  private final Set<LayerMaterial> materials;
  
  public Layer() {
    this.materials = new HashSet<>();
    update();
  }
  
  /**
   * Copy constructor
   * @param layer A Deep copy of this Layer and the Materials inside it.
   */
  public Layer(Layer layer) {
    this.bottom = layer.bottom;
    this.top = layer.top;
    this.materials = layer.copyMaterials();