
// FieldStats.java
// Andrew Davison, Nov 2018, ad@fivedots.coe.psu.ac.th

/* This class collects and provides statistical data on the state 
 * of a field. It will create and maintain a counter 
 * for any class of object that is found within the field.
 * 
 * @author David J. Barnes and Michael Kolling
 * @version 2006.03.30

 The field now contains Animals, not Objects.
 */


import java.util.HashMap;


public class FieldStats
{
  private HashMap<Class, Counter> counters;
       // counters for each type of thing (fox, rabbit, etc.) in the simulation.
  private boolean countsValid; // are counters current?


  public FieldStats()
  { counters = new HashMap<Class, Counter>();
    countsValid = true;
  }


  public String getPopulationDetails(Field field)
  {
    if (!countsValid)
      generateCounts(field);

    StringBuffer buffer = new StringBuffer();
    for (Class key : counters.keySet()) {
      Counter info = counters.get(key);
      buffer.append(info.getName());
      buffer.append(": ");
      buffer.append(info.getCount());
      buffer.append(' ');
    }
    return buffer.toString();
  }  // end of getPopulationDetails()
    

  public void reset()
  // reset all counts to zero
  {
    countsValid = false;
    for (Class key : counters.keySet()) {
      Counter count = counters.get(key);
      count.reset();
    }
  }  // end of reset()


  public void incrementCount(Class animalClass)
  // increment the count for one class of animal
  {
    Counter count = counters.get(animalClass);
    if (count == null) {
      // We do not have a counter for this species yet. Create one.
      count = new Counter(animalClass.getName());
      counters.put(animalClass, count);
    }
    count.increment();
  }  // end of incrementCount()


  public void countFinished()
  // indicate that an animal count has been completed
  {  countsValid = true;  }


  public boolean isViable(Field field)
  /* Determine whether the simulation is still viable.
     i.e., should it continue to run. */
  {
    // How many counts are non-zero?
    int nonZero = 0;

    if (!countsValid)
      generateCounts(field);

    for (Class key : counters.keySet()) {
      Counter info = counters.get(key);
      if (info.getCount() > 0)
        nonZero++;
    }
    return (nonZero > 1);
  }  // end of isViable()
    

  private void generateCounts(Field field)
  /* Generate counts of the number of foxes and rabbits.
     These are not kept up to date as foxes and rabbits
     are placed in the field, but only when a request
     is made for the information. */
  {
    reset();
    for (int row = 0; row < field.getDepth(); row++) {
      for (int col = 0; col < field.getWidth(); col++) {
        Animal animal = field.getAnimalAt(row, col);   // was Object in v.1
        if (animal != null)
          incrementCount(animal.getClass());
      }
    }
    countsValid = true;
  }  // end of generateCounts()

}  // end of FieldStats class
