package housing;

import java.util.Iterator;

import org.apache.commons.math3.random.MersenneTwister;

public class Demographics {

	//------------------//
	//----- Fields -----//
	//------------------//

    private Config	            config; // Private field to receive the Model's configuration parameters object
    private MersenneTwister     rand; // Private field to receive the Model's random number generator
    private Geography           geography;
    private int                 totalPopulation;

    //------------------------//
    //----- Constructors -----//
    //------------------------//

    /**
     * Initialises the demographics with a reference to the whole geography of regions
     *
     * @param geography Geography of region where the demographic processes occur
     */
    public Demographics(Config config, MersenneTwister rand, Geography geography) {
        this.config = config;
        this.rand = rand;
        this.geography = geography;
    }

    //-------------------//
    //----- Methods -----//
    //-------------------//

    /**
     * Sets initial values for all relevant variables
     */
    public void init() { totalPopulation = 0; }


    /**
	 * Adds newly "born" households to the model and removes households that "die". In particular, households are added
     * to each region in proportion to the region's target population, which is a measure of the availability of
     * employment opportunities (number of jobs) in that region. Furthermore, households get permanently assigned this
     * region as their job region.
	 */
	public void step() {
	    // For each region...
        for (Region region: geography.getRegions()) {
            // Birth: Add new households at a rate compatible with the age at birth distribution, the probability of
            // death dependent on age, and the target population
            int nBirths = (int) (region.getTargetPopulation() * data.Demographics.getBirthRate() + rand.nextDouble());
            // Finally, add the households, with random ages drawn from the corresponding distribution
            while(nBirths-- > 0) {
                region.households.add(new Household(config, rand,
                        data.Demographics.pdfHouseholdAgeAtBirth.nextDouble(rand), geography, region));
                totalPopulation++;
            }
            // Death: Kill households with a probability dependent on their age and organise inheritance
            double pDeath;
            Iterator<Household> iterator = region.households.iterator();
            while(iterator.hasNext()) {
                Household h = iterator.next();
                pDeath = data.Demographics.probDeathGivenAge(h.getAge())/config.constants.MONTHS_IN_YEAR;
                if (rand.nextDouble() < pDeath) {
                    iterator.remove();
                    totalPopulation--;
                    // Inheritance
                    // TODO: This imposes inheritance within the same region, which is the job region of the dead household!!!
                    h.transferAllWealthTo(region.households.get(rand.nextInt(region.households.size())));
                }
            }
        }
	}

    //----- Getter/setter methods -----//

    public int getTotalPopulation() { return totalPopulation; }
}

@@ -2927,101 +2927,636 @@
     
-// TODO: This imposes inheritance within the same region, which is the job region of the dead
+h.transferAllWealthTo(findRandomHousehold());%0A                %7D%0A            %7D%0A        %7D%0A%09%7D%0A%0A    /**%0A     * Choose a random household within the whole geography of regions, i.e., a random household from a random region%0A     * with the probability of choosing a region being proportional to its population%0A     */%0A    private Household findRandomHousehold() %7B%0A        // Draw a random integer from 0 to (totalPopulation - 1)%0A        int randInt = rand.nextInt(totalPopulation);%0A        // Set counter to zero%0A        int counter = 0;%0A        // First, iterate over the regions to find the chosen one (the one containing the chosen
  hou
@@ -3565,11 +3565,9 @@
 hold
-!!!
+)
 %0A   
@@ -3575,149 +3575,709 @@
     
-            h.transferAllWealthTo(region.households.get(rand.nextInt(region.households.size())));%0A                %7D%0A            %7D%0A        %7D%0A%09
+Iterator%3CRegion%3E regionIterator = geography.getRegions().iterator();%0A        Region region = regionIterator.next();%0A        while (counter + region.households.size() %3C randInt) %7B%0A            counter += region.households.size();%0A            region = regionIterator.next();%0A        %7D%0A        // Then, iterate over the households of that region until the chosen one is found%0A        Iterator%3CHousehold%3E householdIterator = region.households.iterator();%0A        Household household = householdIterator.next();%0A        for (int i = 1; i %3C (randInt - counter); i++) %7B // Start at 1, since first household has already been called%0A            householdIterator.next();%0A        %7D%0A        return household;%0A    
 %7D%0A%0A 

Implement whole geography inheritance