/**
  * @param year year in question
  * @param crop crop in question
  * @param metTons tons produced
  */
 public final void setCropProduction(int year, EnumFood crop, double metTons) {
   if (metTons >= 0) {
     cropProduction[crop.ordinal()][year - START_YEAR] = metTons;
   } else {
     if (VERBOSE) {
       System.err.println("Invalid argument for Territory.setCropProduction method");
     }
   }
 }
 /**
  * @param year year in question
  * @param crop crop in question
  * @param value Income in $1,000
  */
 public final void setCropIncome(int year, EnumFood crop, double value) {
   if (value >= 0) {
     cropIncome[crop.ordinal()][year - START_YEAR] = value;
   } else {
     if (VERBOSE) {
       System.err.println("Invalid argument for Territory.setCropIncome method");
     }
   }
 }
  /**
   * Method for calculating & setting crop need
   *
   * @param crop EnumFood
   * @param tonsConsumed 2014 production + imports - exports
   * @param percentUndernourished 2014 % of population undernourished
   */
  public final void setCropNeedPerCapita(
      EnumFood crop, double tonsConsumed, double percentUndernourished) {
    for (AgriculturalUnit unit : entities) {
      unit.setCropNeedPerCapita(crop, tonsConsumed, percentUndernourished);
    }

    double population = getPopulation(START_YEAR);
    double tonPerPerson = tonsConsumed / (population - 0.5 * percentUndernourished * population);
    cropNeedPerCapita[crop.ordinal()] = tonPerPerson;
  }
  /**
   * Method for setting crop need when already known (e.g., when copying).
   *
   * @param crop EnumFood
   * @param tonPerPerson 2014 ton/person
   */
  public final void setCropNeedPerCapita(EnumFood crop, double tonPerPerson) {
    // Divide it up amongst the units.
    //
    double perUnit = tonPerPerson / entities.size();
    double remainder = tonPerPerson % (entities.size() * perUnit);
    for (AgriculturalUnit unit : entities) {
      unit.setCropNeedPerCapita(crop, perUnit + remainder);
      remainder = 0;
    }

    cropNeedPerCapita[crop.ordinal()] = tonPerPerson;
  }
  /**
   * @param year (passing year might be useful in the next milestone?)
   * @param crop
   * @param tonPerSqKilom yield for crop
   */
  public void setCropYield(int year, EnumFood crop, double tonPerSqKilom) {
    // Divide it up amongst the units.
    //
    double perUnit = tonPerSqKilom / entities.size();
    double remainder = tonPerSqKilom % (entities.size() * perUnit);
    for (AgriculturalUnit unit : entities) {
      unit.setCropYield(year, crop, perUnit + remainder);
      remainder = 0;
    }

    cropYield[crop.ordinal()] = tonPerSqKilom;
  }
 /**
  * Set crop land value; use this method when initializing
  *
  * @param year year in question
  * @param crop crop in question
  * @param kilomsq area to set
  */
 public final void setCropLand(int year, EnumFood crop, double kilomsq) {
   if (kilomsq >= 0 && kilomsq <= getArableLand(year)) {
     for (int i = 0; i < (YEARS_OF_SIM); i++) landCrop[crop.ordinal()][i] = kilomsq;
   } else {
     if (VERBOSE) {
       System.err.println(
           "Invalid argument for Territory.setCropLand method for country "
               + getName()
               + " crop "
               + crop);
     }
   }
 }
  /**
   * @param year year in question
   * @param crop crop in question
   * @param metTons tons imported
   */
  public void setCropImport(int year, EnumFood crop, double metTons) {
    if (metTons >= 0) {
      // Divide it up amongst the units.
      //
      double perUnit = metTons / entities.size();
      double remainder = metTons % (entities.size() * perUnit);
      for (AgriculturalUnit unit : entities) {
        unit.setCropImport(year, crop, perUnit + remainder);
        remainder = 0;
      }

      cropImport[crop.ordinal()][year - START_YEAR] = metTons;
    } else {
      if (VERBOSE) {
        System.err.println("Invalid argument for AgriculturalUnit.setCropImport method");
      }
    }
  }
  /**
   * Sets area to be planted with given crop in given year based on user input
   *
   * @param year year in question
   * @param crop crop in question
   * @param kilomsq number square km user wants to plant with that crop
   */
  public final void updateCropLand(int year, EnumFood crop, double kilomsq) {
    double unused = getArableLandUnused(year);
    double currCropLand = getCropLand(year, crop);
    double delta = kilomsq - currCropLand;
    double valueToSet;

    // if trying to decrease beyond 0, set to 0
    if ((currCropLand + delta) < 0) {
      valueToSet = 0;
    }
    // else if trying to increase by amount greater than available, set to current + available
    else if (delta > unused) {
      valueToSet = currCropLand + unused;
    }
    // else set to curr + delta
    else {
      valueToSet = currCropLand + delta;
    }
    for (int i = year - START_YEAR; i < YEARS_OF_SIM; i++) landCrop[crop.ordinal()][i] = valueToSet;
  }
  /**
   * The loader loads 2014 data. This function scales the data for 1981 given the scale factor.
   *
   * @param factor The scaling factor.
   */
  public void scaleInitialStatistics(double factor) {
    int index = 0; // The 0th index is the start year.

    population[index] *= factor;
    medianAge[index] *= factor;
    births[index] *= factor;
    mortality[index] *= factor;
    migration[index] *= factor;
    undernourished[index] *= factor;

    landTotal[index] *= factor;
    landArable[index] *= factor;

    for (int i = 0; i < EnumFood.values().length; i += 1) {
      cropYield[i] *= factor;
      cropNeedPerCapita[i] *= factor;
      cropProduction[i][index] *= factor;
      landCrop[i][index] *= factor;
    }

    for (int i = 0; i < EnumGrowMethod.values().length; i += 1) {
      cultivationMethod[i][index] *= factor;
    }
  }
 /**
  * Update % undernourished using formula in spec.
  *
  * @param year year to update
  */
 public final void updateUndernourished(int year) {
   double numUndernourished;
   double population = getPopulation(year);
   double[] netCropsAvail = new double[EnumFood.SIZE];
   int numCropsAvail = 0;
   for (EnumFood crop : EnumFood.values()) {
     double netAvail = getNetCropAvailable(year, crop);
     netCropsAvail[crop.ordinal()] = netAvail;
     if (netAvail >= 0) numCropsAvail++;
   }
   if (numCropsAvail == 5) {
     numUndernourished = 0;
   } else {
     double maxResult = 0;
     for (EnumFood crop : EnumFood.values()) {
       double need = getCropNeedPerCapita(crop);
       double result = (netCropsAvail[crop.ordinal()]) / (0.5 * need * population);
       if (result > maxResult) maxResult = result;
     }
     numUndernourished = Math.min(population, maxResult);
   }
   setUndernourished(year, numUndernourished / population);
 }
  /** Estimates the initial land used per food type, and the yield. */
  public void estimateInitialYield() {
    double income = 0.;
    double production = 0.;
    double land = 0.;
    for (EnumFood crop : EnumFood.values()) {
      land += landCrop[crop.ordinal()][0];
      production += cropProduction[crop.ordinal()][0];
      income += cropIncome[crop.ordinal()][0];
    }

    // If the total land is > 0 then this function has already been called.
    //
    if (land == 0.) {
      if (income == 0. && production == 0.) {
        Logger.getGlobal()
            .log(Level.INFO, "Territory {0} has no production or income. Faking it.", getName());

        // Assume they're getting $100 per acre.  Terrible guess, but it's just a
        // default for empty rows.
        //
        income = landTotal[0] / 10.; // $100 per acre / 1000.;
        double p = 1. / EnumFood.SIZE;
        for (int i = 0; i < EnumFood.SIZE; i += 1) cropIncome[i][0] = income * p;
      }

      if (production == 0.) {
        for (EnumFood crop : EnumFood.values()) {
          if (production == 0.) {
            // The current version of the CSV file doesn't have any production values.
            // Use the income values (if available) to estimate land per crop.
            //

            // Estimate production from the yield.
            //
            cropProduction[crop.ordinal()][0] =
                (cropIncome[crop.ordinal()][0] / income) * landTotal[0];
            production += cropProduction[crop.ordinal()][0];
          }
        }
      }

      for (EnumFood crop : EnumFood.values()) {
        cropYield[crop.ordinal()] = cropProduction[crop.ordinal()][0] / landTotal[0];

        // Use the crop production to estimate land per crop.
        //
        double p = cropProduction[crop.ordinal()][0] / production;

        // This is an initial naive estimate.  Per Joel there will eventually be a multiplier
        // applied that gives a more realistic estimate.
        //
        landCrop[crop.ordinal()][0] = landTotal[0] * p /* * multiplier[food] */;

        land += landCrop[crop.ordinal()][0];
      }
    }
  }
 /**
  * @param year (passing year might be useful in the next milestone?)
  * @param crop
  * @param tonPerSqKilom yield for crop
  */
 public final void setCropYield(int year, EnumFood crop, double tonPerSqKilom) {
   cropYield[crop.ordinal()] = tonPerSqKilom;
 }
 /**
  * Method for setting crop need when already known (e.g., when copying).
  *
  * @param crop EnumFood
  * @param tonPerPerson 2014 ton/person
  */
 public final void setCropNeedPerCapita(EnumFood crop, double tonPerPerson) {
   cropNeedPerCapita[crop.ordinal()] = tonPerPerson;
 }
 /**
  * Method for calculating & setting crop need
  *
  * @param crop EnumFood
  * @param tonsConsumed 2014 production + imports - exports
  * @param percentUndernourished 2014 % of population undernourished
  */
 public final void setCropNeedPerCapita(
     EnumFood crop, double tonsConsumed, double percentUndernourished) {
   double population = getPopulation(START_YEAR);
   double tonPerPerson = tonsConsumed / (population - 0.5 * percentUndernourished * population);
   cropNeedPerCapita[crop.ordinal()] = tonPerPerson;
 }
  /**
   * Copies initial data from another territory to this territory. This is primarily only done when
   * unifying XML and CSV data.
   *
   * @param fromTerritory The territory from which to copy data.
   */
  public void copyInitialValuesFrom(final Territory fromTerritory) {
    int index = 0;
    medianAge[index] = fromTerritory.medianAge[index];
    births[index] = fromTerritory.births[index];
    mortality[index] = fromTerritory.mortality[index];
    migration[index] = fromTerritory.migration[index];
    undernourished[index] = fromTerritory.undernourished[index];

    landTotal[index] = fromTerritory.landTotal[index];
    landArable[index] = fromTerritory.landArable[index];

    for (EnumFood food : EnumFood.values()) {
      cropYield[food.ordinal()] = fromTerritory.cropYield[food.ordinal()];
      cropNeedPerCapita[food.ordinal()] = fromTerritory.cropNeedPerCapita[food.ordinal()];
      cropIncome[food.ordinal()][index] = fromTerritory.cropIncome[food.ordinal()][index];
      cropProduction[food.ordinal()][index] = fromTerritory.cropProduction[food.ordinal()][index];
      landCrop[food.ordinal()][index] = fromTerritory.landCrop[food.ordinal()][index];
    }

    for (EnumGrowMethod method : EnumGrowMethod.values()) {
      cultivationMethod[method.ordinal()][index] =
          fromTerritory.cultivationMethod[method.ordinal()][index];
    }

    while (index < Constant.LAST_YEAR - Constant.FIRST_YEAR) {
      population[index] = fromTerritory.population[index];
      index += 1;
    }
  }