/*
 * -------------------------------------------------------------------------
 *      $Id: Population.java,v 1.3 2004/05/26 18:24:57 estewart Exp $
 * -------------------------------------------------------------------------
 *      Copyright (c) 1999 Visual Numerics Inc. All Rights Reserved.
 *
 *      This software is confidential information which is proprietary to
 *      and a trade secret of Visual Numerics, Inc.  Use, duplication or
 *      disclosure is subject to the terms of an appropriate license
 *      agreement.
 *
 *      VISUAL NUMERICS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
 *      SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
 *      BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
 *      FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. VISUAL
 *      NUMERICS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 *      AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
 *      ITS DERIVATIVES.
 *--------------------------------------------------------------------------
 */

package com.imsl.demo.Population;
import com.imsl.chart.*;
import javax.swing.*;
import com.imsl.demo.gallery.Describe;


/**
 *
 * @author  pate
 * @created October 23, 2002
 */
public class Population extends JFrameChart implements
    javax.swing.event.ChangeListener, java.awt.event.MouseListener, PickListener, Runnable  {

    final int nItems = 17;
    final int nYears = 51;
    int currentBar = 0;
    boolean loopAnimate = false;
    boolean stopRequested = false;

    final double populationData[][][] = new double[2][nYears][nItems];
    final double maleData[][][] = new double[1][1][nItems];
    final double femaleData[][][] = new double[1][1][nItems];

    Chart chart = getChart();
    AxisXY axis = new AxisXY(chart);

    private JSlider yearSlider;
    private JButton animButton;
    private JTextField yearField;
    private ChartNode node;
    private java.awt.event.ActionListener startAnimateListener, stopAnimateListener;


    public Population(boolean exitOnClose) {
        if (!exitOnClose) {
            // remove WindowListeners
            Object l[] = getListeners(java.awt.event.WindowListener.class);
            for (int k = 0;  k < l.length;  k++) {
                removeWindowListener((java.awt.event.WindowListener)l[k]);
            }
        }

        Describe des = new Describe(this, "/com/imsl/demo/Population/Population.html");
        des.show();
        java.awt.Dimension dess = des.getSize();

        java.awt.Dimension ss = getToolkit().getScreenSize();
        int h = Math.min(ss.width/2, ss.height-dess.height-32);
        int w = (int)(h/0.8);
        setSize(w, h);
        setLocation(ss.width-dess.width, dess.height);
        setTitle("Demographics");

        // Setup the vertical axis for a labeled bar chart.
        String xlabels[] = {"0-4", "5-9", "10-14", "15-19",
            "20-24", "25-29", "30-34", "35-39", "40-44",
            "45-49", "50-54", "55-59", "60-64", "65-69",
            "70-74", "75-79", "80+"};
        String ylabels[] = {"12", "8", "4", "0", "4", "8", "12"};

        // Create components for use in control panel.
        java.awt.Container cp = getContentPane();

        startAnimateListener = new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startAnimation();
            }
        };
        stopAnimateListener = new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                stopAnimation();
            }
        };
        animButton = new JButton("Animate");
        animButton.addActionListener(startAnimateListener);

        JButton forecast = new JButton("Forecast");
        forecast.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                forecast();
            }
        });

        yearSlider = new JSlider(1950, 2000, 1950);
        yearSlider.setPaintTicks(true);
        yearSlider.setPaintLabels(true);
        yearSlider.setMajorTickSpacing(10);
        yearSlider.setMinorTickSpacing(1);
        yearSlider.setSnapToTicks(true);
        yearSlider.addMouseListener(this);
        yearSlider.addChangeListener(this);

        yearField = new JTextField("0", 3);
        yearField.setEditable(false);

        // checkbox sets the boolean loopAnimate
        final JCheckBox loop = new JCheckBox("Loop Animation", false);
        loop.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                loopAnimate = loop.isSelected();
            }
        });

        JPanel buttonPanel = new JPanel();
        ((java.awt.FlowLayout)buttonPanel.getLayout()).setAlignment(java.awt.FlowLayout.LEADING);
        buttonPanel.add(animButton);
        buttonPanel.add(loop);
        buttonPanel.add(yearSlider);
        buttonPanel.add(yearField);
        buttonPanel.add(forecast);
        cp.add(buttonPanel, java.awt.BorderLayout.NORTH);

        // Setup the Bar Chart Title and legend
        chart.getChartTitle().setFontStyle(1);
        chart.getLegend().setPaint(true);

        // Change background to gradient for effects
        chart.getBackground().setFillType(ChartNode.FILL_TYPE_GRADIENT);
        chart.getBackground().setGradient("yellow", "yellow", "lightYellow", "lightYellow");

        // build database, get initial data from 1950
        buildData();
        updateGraph(1950);
        yearField.setText(Integer.toString(1950));

        //  Create male bars
        Bar bar1 = new Bar(axis, maleData);
        bar1.getBarSet(0,0).setFillColor("blue");
        bar1.getBarSet(0,0).setTitle("Male");
        bar1.setLabels(xlabels, Data.BAR_TYPE_HORIZONTAL);
        bar1.setBarWidth(1.0);
        bar1.addPickListener(this);

        //  Create female bars
        Bar bar2 = new Bar(axis, femaleData);
        bar2.getBarSet(0,0).setFillColor("magenta");
        bar2.getBarSet(0,0).setTitle("Female");
        bar2.setLabels(xlabels, Data.BAR_TYPE_HORIZONTAL);
        bar2.setBarWidth(1.0);
        bar2.addPickListener(this);

        // enumerate the bars so we can set refer to them later
        for (int i = 0;  i < nItems;  i++) {
            bar1.getBarSet(0,0).getBarItem(i).setAttribute("barNumber", new Integer(100+i));;
            bar2.getBarSet(0,0).getBarItem(i).setAttribute("barNumber", new Integer(200+i));;
        }

        // Add the mouse listener
        getPanel().addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent event) {
                getChart().pick(event);
            }
        });

        //  Setup X axis
        axis.getAxisX().setWindow(-12,12);
        axis.setAutoscaleInput(Axis.AUTOSCALE_OFF);
        axis.getAxisX().getAxisLabel().setLabels(ylabels);
        axis.getAxisX().getAxisTitle().setTitle("Millions");
        axis.getAxisX().getAxisTitle().setFontStyle(1);

        //  Setup Y axis
        axis.getAxisY().getAxisTitle().setTitle("Age");
        axis.getAxisY().getAxisTitle().setFontStyle(1);
    }


    // update the graph based on given year
    public void updateGraph(int year) {
        getYearData(year);
        chart.getChartTitle().setTitle("U.S. Age Distribution,  " + year);
        repaint();
    }

    // Implement ActionListeners
    public void forecast() {
        if (currentBar > 0) {
            int gender = barGender(currentBar);
            int category = barCategory(currentBar);
            double[] categoryData = getCategoryData(gender, category);

            ForecastPopulation forecastGraph = new ForecastPopulation(this, false);
            forecastGraph.draw(gender, category, categoryData);
            forecastGraph.show();
        } else {
            String message = "Please select a bar in the figure to choose\n" +
                "which population segment to forcast.";
            JOptionPane.showMessageDialog(this, message, "Population Forcast", JOptionPane.WARNING_MESSAGE);
        }
    }

    public void startAnimation() {
        animButton.setText("   Stop    ");
        animButton.removeActionListener(startAnimateListener);
        animButton.addActionListener(stopAnimateListener);
        stopRequested = false;
        yearSlider.setEnabled(false);

        Thread newThread = new Thread(this);
        newThread.setDaemon(true);
        newThread.start();
    }

    public void stopAnimation() {
        stopRequested = true;
    }


    // Event Handlers
    public void stateChanged(javax.swing.event.ChangeEvent event) {
        yearField.setText(Integer.toString(yearSlider.getValue()));
        updateGraph(yearSlider.getValue());
    }

    public void pickPerformed(PickEvent event) {
        // repaint old node before selecting new node
        if (currentBar > 0) {
            String color = ((currentBar < 200) ? "blue" : "magenta");
            node.setFillColor(color);
        }

        // set node to selected bar and color it green
        node = event.getNode();
        node.setFillColor("green");

        // get code for current bar
        currentBar = node.getIntegerAttribute("barNumber", 0);
        repaint();
    }

    // Implement MouseListeners
    public void mouseClicked(java.awt.event.MouseEvent event) {  }
    public void mousePressed(java.awt.event.MouseEvent event) {  }
    public void mouseReleased(java.awt.event.MouseEvent event) {  }
    public void mouseEntered(java.awt.event.MouseEvent event) {  }
    public void mouseExited(java.awt.event.MouseEvent event) {  }
    public void mouseDragged(java.awt.event.MouseEvent event) {  }
    public void mouseMoved(java.awt.event.MouseEvent event) {  }


    // runnable method for the animation thread
    public void run() {
        do {
            for (int i = 0; i < nYears; i++) {
                yearSlider.setValue(1950 + i);
                updateGraph(1950 + i);
                if (stopRequested) break;
                try {
                    Thread.sleep(250);
                } catch (Exception ex) {
                }
            }
        } while (loopAnimate && !stopRequested);
        animButton.setText("Animate");
        animButton.removeActionListener(stopAnimateListener);
        animButton.addActionListener(startAnimateListener);
        yearSlider.setEnabled(true);
    }

    // keep the paint methods synchronized between threads
    synchronized public void paint(java.awt.Graphics g) {
        super.paint(g);
    }

    // retrieve the category of the selected bar
    private int barCategory(int bar) {
        return ((bar < 200) ? bar-100 : bar-200);
    }

    // retrieve the gender of the selected bar
    private int barGender(int bar) {
        return ((bar < 200) ? 0 : 1);
    }

    // retrieve a subset of data for analysis
    //private void getCategoryData(int gender, int category) {
    private double[] getCategoryData(int gender, int category) {
        double[] categoryData = new double[nYears-1];
        for (int i = 0; i < nYears-1; i++) {
            categoryData[i] = populationData[gender][i][category];
        }
        return categoryData;
    }

    // retrieve a year's worth of data for displaying
    private void getYearData(int year) {
        for (int i = 0; i < nItems; i++) {
            maleData[0][0][i] = populationData[0][year-1950][i] * -1;
            femaleData[0][0][i] = populationData[1][year-1950][i];
        }
    }

    // main
    public static void main(String args[]) {
        boolean exitOnClose = true;
        if (args.length > 0 && args[0].equals("-noexit")) {
            exitOnClose = false;
        }
        new Population(exitOnClose).show();
    }


    /* Official data from the U.S. Census Bureau. The data
     * would normally reside in a database but has been
     * placed in this class for ease of use in this demo.
     * first element:  0 = male data, 1 = female data
     * second element:  0 - 16 = categories
     */
    private void buildData() {
        populationData[0][0] = new double[] {8.362000, 6.811000, 5.707000, 5.381000,
        5.794000, 6.071000, 5.733000, 5.585000, 5.121000, 4.566000, 4.149000,
        3.656000, 3.058000, 2.447000, 1.644000, 1.005000, 0.761000};
        populationData[1][0] = new double[] {8.048000, 6.564000, 5.506000, 5.294000,
        5.886000, 6.291000, 5.942000, 5.762000, 5.169000, 4.576000, 4.162000,
        3.637000, 3.045000, 2.602000, 1.800000, 1.150000, 0.989000};
        populationData[0][1] = new double[] {8.831000, 6.961000, 5.850000, 5.317000,
        5.753000, 6.047000, 5.842000, 5.643000, 5.192000, 4.643000, 4.170000,
        3.719000, 3.109000, 2.509000, 1.689000, 1.042000, 0.786000};
        populationData[1][1] = new double[] {8.503000, 6.707000, 5.650000, 5.240000,
        5.800000, 6.248000, 6.053000, 5.819000, 5.260000, 4.670000, 4.194000,
        3.730000, 3.127000, 2.680000, 1.864000, 1.203000, 1.031000};
        populationData[0][2] = new double[] {8.817000, 7.545000, 6.090000, 5.300000,
        5.658000, 6.000000, 5.947000, 5.699000, 5.268000, 4.744000, 4.184000,
        3.754000, 3.173000, 2.564000, 1.741000, 1.075000, 0.812000};
        populationData[1][2] = new double[] {8.495000, 7.266000, 5.872000, 5.235000,
        5.692000, 6.187000, 6.167000, 5.873000, 5.353000, 4.790000, 4.217000,
        3.793000, 3.229000, 2.747000, 1.938000, 1.251000, 1.076000};
        populationData[0][3] = new double[] {8.980000, 7.809000, 6.453000, 5.376000,
        5.516000, 5.984000, 5.988000, 5.745000, 5.338000, 4.833000, 4.227000,
        3.767000, 3.234000, 2.620000, 1.796000, 1.107000, 0.840000};
        populationData[1][3] = new double[] {8.658000, 7.523000, 6.218000, 5.307000,
        5.547000, 6.148000, 6.221000, 5.919000, 5.443000, 4.902000, 4.266000,
        3.833000, 3.331000, 2.817000, 2.015000, 1.297000, 1.124000};
        populationData[0][4] = new double[] {9.192000, 8.165000, 6.716000, 5.484000,
        5.407000, 5.918000, 6.064000, 5.779000, 5.399000, 4.931000, 4.282000,
        3.796000, 3.284000, 2.676000, 1.865000, 1.140000, 0.874000};
        populationData[1][4] = new double[] {8.866000, 7.866000, 6.475000, 5.410000,
        5.425000, 6.064000, 6.294000, 5.961000, 5.522000, 5.019000, 4.327000,
        3.882000, 3.420000, 2.890000, 2.106000, 1.345000, 1.179000};
        populationData[0][5] = new double[] {9.449000, 8.529000, 6.944000, 5.558000,
        5.351000, 5.857000, 6.110000, 5.834000, 5.459000, 5.028000, 4.335000,
        3.841000, 3.330000, 2.722000, 1.931000, 1.174000, 0.911000};
        populationData[1][5] = new double[] {9.117000, 8.220000, 6.694000, 5.482000,
        5.363000, 5.977000, 6.337000, 6.023000, 5.596000, 5.131000, 4.390000,
        3.947000, 3.504000, 2.958000,  2.195000, 1.395000, 1.238000};
        populationData[0][6] = new double[] {9.671000, 8.986000, 7.085000, 5.713000,
        5.299000, 5.815000, 6.090000, 5.931000, 5.523000, 5.104000, 4.406000,
        3.886000, 3.373000, 2.760000, 1.991000, 1.205000, 0.941000};
        populationData[1][6] = new double[] {9.333000, 8.667000, 6.833000, 5.628000,
        5.317000, 5.907000, 6.309000, 6.132000, 5.672000, 5.220000, 4.476000,
        4.008000, 3.584000, 3.025000, 2.277000, 1.446000, 1.293000};
        populationData[0][7] = new double[] {9.918000, 8.968000, 7.658000, 5.955000,
        5.291000, 5.728000, 6.047000, 6.025000, 5.584000, 5.184000, 4.500000,
        3.926000, 3.390000, 2.813000, 2.046000, 1.244000, 0.971000};
        populationData[1][7] = new double[] {9.575000, 8.656000, 7.387000, 5.843000,
        5.312000, 5.812000, 6.257000, 6.243000, 5.744000, 5.309000, 4.586000,
        4.061000, 3.635000, 3.112000, 2.350000, 1.507000, 1.346000};
        populationData[0][8] = new double[] {10.117000, 9.126000, 7.910000, 6.316000,
        5.372000, 5.593000, 6.035000, 6.055000, 5.636000, 5.259000, 4.581000,
        3.994000, 3.384000, 2.859000,  2.098000, 1.279000, 0.991000};
        populationData[1][8] = new double[] {9.770000, 8.815000, 7.636000, 6.186000,
        5.384000, 5.679000, 6.231000, 6.296000, 5.810000, 5.397000, 4.689000,
        4.142000, 3.662000, 3.196000, 2.423000, 1.567000, 1.392000};
        populationData[0][9] = new double[] {10.260000, 9.329000, 8.249000, 6.583000,
        5.486000, 5.484000, 5.967000, 6.113000, 5.674000, 5.323000, 4.670000,
        4.074000, 3.394000, 2.895000, 2.153000, 1.328000, 1.016000};
        populationData[1][9] = new double[] {9.916000, 9.015000, 7.971000, 6.436000,
        5.483000, 5.563000, 6.155000, 6.365000, 5.871000, 5.473000, 4.796000,
        4.236000, 3.698000, 3.268000, 2.502000, 1.642000, 1.444000};
        populationData[0][10] = new double[] {10.339000, 9.565000, 8.602000, 6.803000,
        5.569000, 5.423000, 5.904000, 6.140000, 5.732000, 5.379000, 4.763000,
        4.145000, 3.414000, 2.936000, 2.197000, 1.370000, 1.039000};
        populationData[1][10] = new double[] {10.002000, 9.245000, 8.323000, 6.640000,
        5.566000, 5.512000, 6.079000, 6.403000, 5.946000, 5.535000, 4.901000,
        4.326000, 3.741000, 3.344000, 2.577000, 1.711000, 1.502000};
        populationData[0][11] = new double[] {10.432000, 9.763000, 9.065000, 6.964000,
        5.744000, 5.393000, 5.837000, 6.140000, 5.809000, 5.414000, 4.857000,
        4.220000, 3.431000, 2.953000, 2.241000, 1.405000, 1.073000};
        populationData[1][11] = new double[] {10.090000, 9.433000, 8.771000, 6.795000,
        5.739000, 5.476000, 5.985000, 6.400000, 6.043000, 5.586000, 5.019000,
        4.427000, 3.770000, 3.407000, 2.668000, 1.773000, 1.569000};
        populationData[0][12] = new double[] {10.405000, 9.990000, 9.045000, 7.573000,
        5.985000, 5.389000, 5.760000, 6.111000, 5.893000, 5.441000, 4.932000,
        4.315000, 3.455000, 2.955000, 2.283000, 1.433000, 1.098000};
        populationData[1][12] = new double[] {10.063000, 9.651000, 8.749000, 7.377000,
        5.975000, 5.469000, 5.877000, 6.363000, 6.152000, 5.631000, 5.119000,
        4.555000, 3.805000, 3.456000, 2.763000, 1.833000, 1.635000};
        populationData[0][13] = new double[] {10.343000, 10.172000, 9.217000, 7.861000,
        6.367000, 5.441000, 5.668000, 6.056000, 5.975000, 5.467000, 4.993000,
        4.415000, 3.483000, 2.951000, 2.316000, 1.454000, 1.124000};
        populationData[1][13] = new double[] {9.998000, 9.824000, 8.911000, 7.648000,
        6.346000, 5.533000, 5.768000, 6.297000, 6.256000, 5.684000, 5.203000,
        4.691000, 3.847000, 3.493000, 2.850000, 1.888000, 1.701000};
        populationData[0][14] = new double[] {10.262000, 10.294000, 9.433000, 8.241000,
        6.649000, 5.531000, 5.570000, 5.983000, 6.034000, 5.502000, 5.050000,
        4.508000, 3.525000, 2.957000, 2.339000, 1.480000, 1.160000};
        populationData[1][14] = new double[] { 9.902000, 9.942000, 9.114000, 8.009000,
        6.619000, 5.637000, 5.659000, 6.213000, 6.332000, 5.748000, 5.281000,
        4.817000, 3.907000, 3.535000, 2.928000, 1.949000, 1.779000};
        populationData[0][15] = new double[] {10.090000, 10.366000, 9.692000, 8.640000,
        6.899000, 5.612000, 5.518000, 5.899000, 6.058000, 5.553000, 5.101000,
        4.583000, 3.583000, 2.972000, 2.349000, 1.500000, 1.193000};
        populationData[1][15] = new double[] {9.734000, 10.012000, 9.357000, 8.386000,
        6.847000, 5.728000, 5.607000, 6.122000, 6.368000, 5.828000, 5.358000,
        4.922000, 3.989000, 3.578000, 2.987000, 2.012000, 1.860000};
        populationData[0][16] = new double[] {9.780000, 10.468000,  9.913000,  9.118000,
        7.056000, 5.772000, 5.485000, 5.816000, 6.056000, 5.619000, 5.150000,
        4.644000, 3.660000, 2.989000, 2.346000, 1.522000, 1.224000};
        populationData[1][16] = new double[] {9.428000, 10.105000, 9.565000, 8.844000,
        6.994000, 5.889000, 5.579000, 6.030000, 6.373000, 5.925000, 5.431000,
        5.009000, 4.095000, 3.623000, 3.032000, 2.077000, 1.941000};
        populationData[0][17] = new double[] {9.452000, 10.449000, 10.163000, 9.110000,
        7.665000, 5.988000, 5.477000, 5.729000, 6.028000, 5.702000, 5.194000,
        4.689000, 3.758000, 3.013000, 2.338000, 1.548000, 1.260000};
        populationData[1][17] = new double[] {9.111000, 10.085000, 9.800000, 8.838000,
        7.583000, 6.105000, 5.586000, 5.934000, 6.347000, 6.038000, 5.505000,
        5.077000, 4.229000, 3.670000, 3.062000, 2.149000, 2.032000};
        populationData[0][18] = new double[] {9.125000, 10.390000, 10.367000, 9.289000,
        7.937000, 6.345000, 5.531000, 5.630000, 5.976000, 5.783000, 5.241000,
        4.723000, 3.865000, 3.042000, 2.324000, 1.566000, 1.290000};
        populationData[1][18] = new double[] {8.788000, 10.024000, 9.990000, 9.014000,
        7.849000, 6.455000, 5.659000, 5.830000, 6.294000, 6.148000, 5.585000,
        5.128000, 4.372000, 3.727000, 3.085000, 2.214000, 2.116000};
        populationData[0][19] = new double[] {8.854000, 10.310000, 10.513000,  9.520000,
        8.290000, 6.594000, 5.622000, 5.526000, 5.909000, 5.842000, 5.299000,
        4.749000, 3.963000, 3.080000, 2.316000, 1.576000, 1.323000};
        populationData[1][19] = new double[] {8.522000, 9.933000, 10.128000, 9.236000,
        8.190000, 6.697000, 5.768000, 5.725000, 6.223000, 6.230000, 5.676000,
        5.174000, 4.504000, 3.800000, 3.105000, 2.268000, 2.211000};
        populationData[0][20] = new double[] {8.751000, 10.152000, 10.622000, 9.816000,
        8.655000, 6.821000, 5.716000, 5.475000, 5.847000, 5.873000, 5.380000,
        4.781000, 4.052000, 3.139000, 2.322000, 1.573000, 1.379000};
        populationData[1][20] = new double[] {8.415000, 9.768000, 10.230000, 9.517000,
        8.547000, 6.915000, 5.872000, 5.680000, 6.148000, 6.277000, 5.786000,
        5.225000, 4.624000, 3.887000, 3.145000, 2.298000, 2.363000};
        populationData[0][21] = new double[] {8.796000, 9.886000, 10.749000, 10.048000,
        9.130000, 6.980000, 5.880000, 5.454000, 5.796000, 5.862000, 5.477000,
        4.816000, 4.134000, 3.204000, 2.333000, 1.607000, 1.415000};
        populationData[1][21] = new double[] {8.448000, 9.510000, 10.346000, 9.741000,
        9.029000, 7.062000, 6.036000, 5.666000, 6.062000, 6.280000, 5.900000,
        5.274000, 4.739000, 3.965000, 3.181000, 2.380000, 2.476000};
        populationData[0][22] = new double[] {8.728000, 9.606000, 10.752000, 10.308000,
        9.130000, 7.588000, 6.115000, 5.470000, 5.730000, 5.809000, 5.605000,
        4.838000, 4.213000, 3.298000, 2.329000, 1.619000, 1.453000};
        populationData[1][22] = new double[] {8.374000, 9.241000, 10.347000, 9.988000,
        9.023000, 7.653000, 6.269000, 5.689000, 5.971000, 6.223000, 6.048000,
        5.316000, 4.844000, 4.106000, 3.189000, 2.433000, 2.593000};
        populationData[0][23] = new double[] {8.601000, 9.318000, 10.720000, 10.525000,
        9.320000, 7.867000, 6.500000, 5.526000, 5.655000, 5.782000, 5.689000,
        4.868000, 4.275000, 3.390000, 2.365000, 1.609000, 1.496000};
        populationData[1][23] = new double[] {8.250000, 8.961000, 10.310000, 10.194000,
        9.202000, 7.920000, 6.652000, 5.744000, 5.885000, 6.179000, 6.158000,
        5.361000, 4.924000, 4.245000, 3.246000, 2.456000, 2.716000};
        populationData[0][24] = new double[] {8.422000, 9.075000, 10.668000, 10.691000,
        9.554000, 8.237000, 6.775000, 5.612000, 5.580000, 5.735000, 5.738000,
        4.930000, 4.336000, 3.481000, 2.409000, 1.617000, 1.533000};
        populationData[1][24] = new double[] {8.065000, 8.730000, 10.243000, 10.351000,
        9.421000, 8.284000, 6.930000, 5.836000, 5.797000, 6.114000, 6.222000,
        5.456000, 4.991000, 4.383000, 3.302000, 2.509000, 2.828000};
        populationData[0][25] = new double[] {8.240000, 8.972000, 10.534000, 10.817000,
        9.839000, 8.617000, 7.018000, 5.702000, 5.497000, 5.712000, 5.737000,
        5.048000, 4.368000, 3.596000, 2.441000, 1.653000, 1.575000};
        populationData[1][25] = new double[] {7.881000, 8.623000, 10.112000, 10.468000,
        9.688000, 8.663000, 7.173000, 5.931000, 5.700000, 6.072000, 6.235000,
        5.598000, 5.031000, 4.536000, 3.344000, 2.593000, 2.958000};
        populationData[0][26] = new double[] {7.981000, 9.017000, 10.251000, 10.949000,
        10.071000, 9.113000, 7.167000, 5.853000, 5.477000, 5.658000, 5.728000,
        5.159000, 4.415000, 3.675000, 2.500000, 1.682000, 1.614000};
        populationData[1][26] = new double[] {7.636000, 8.655000, 9.837000, 10.585000,
        9.915000, 9.162000, 7.318000, 6.075000, 5.689000, 5.994000, 6.242000,
        5.725000, 5.087000, 4.643000, 3.419000, 2.663000, 3.082000};
        populationData[0][27] = new double[] {7.959000, 8.949000, 9.954000, 10.956000,
        10.332000, 9.115000, 7.791000, 6.071000, 5.496000, 5.591000, 5.679000,
        5.301000, 4.451000, 3.754000, 2.591000, 1.702000, 1.644000};
        populationData[1][27] = new double[] {7.605000, 8.581000, 9.550000, 10.585000,
        10.167000, 9.162000, 7.929000, 6.283000, 5.713000, 5.910000, 6.191000,
        5.891000, 5.137000, 4.736000, 3.557000, 2.713000, 3.195000};
        populationData[0][28] = new double[] {8.049000, 8.835000, 9.657000, 10.938000,
        10.557000, 9.319000, 8.073000, 6.446000, 5.560000, 5.519000, 5.659000,
        5.403000, 4.495000, 3.818000, 2.678000, 1.763000, 1.655000};
        populationData[1][28] = new double[] {7.686000, 8.465000, 9.262000, 10.558000,
        10.389000, 9.364000, 8.207000, 6.651000, 5.780000, 5.838000, 6.156000,
        6.023000, 5.192000, 4.807000, 3.692000, 2.808000, 3.281000};
        populationData[0][29] = new double[] {8.216000, 8.661000, 9.414000, 10.900000,
        10.736000, 9.571000, 8.444000, 6.717000, 5.657000, 5.451000, 5.623000,
        5.472000, 4.569000, 3.882000, 2.766000, 1.825000, 1.680000};
        populationData[1][29] = new double[] {7.847000, 8.286000, 9.031000, 10.502000,
        10.560000, 9.606000, 8.581000, 6.919000, 5.884000, 5.766000, 6.102000,
        6.110000, 5.297000, 4.863000, 3.827000, 2.898000, 3.392000};
        populationData[0][30] = new double[] {8.414215, 8.491414, 9.313212, 10.779171,
        10.884885, 9.888501, 8.836010, 6.960677, 5.757209, 5.376515, 5.617519,
        5.478072, 4.697364, 3.915788, 2.871581, 1.862070, 1.714857};
        populationData[1][30] = new double[] {8.036969, 8.110939, 8.923123, 10.386201,
        10.705064, 9.903993, 8.974414, 7.159824, 5.989589, 5.676899, 6.078434,
        6.133480, 5.445314, 4.893691, 3.969654, 2.967762, 3.512053};
        populationData[0][31] = new double[] {8.640091, 8.214465, 9.351660, 10.493433,
        11.040091, 10.143266, 9.331832, 7.102531, 5.907763, 5.352933, 5.579466,
        5.443662, 4.806605, 3.956185, 2.933039, 1.910802, 1.748033};
        populationData[1][31] = new double[] {8.252628, 7.845656, 8.948747, 10.101917,
        10.829376, 10.131649, 9.466490, 7.305586, 6.138503, 5.636996, 6.016346,
        6.110944, 5.552804, 4.941798, 4.058848, 3.047369, 3.624723};
        populationData[0][32] = new double[] {8.809415, 8.166741, 9.277340, 10.200211,
        11.070925, 10.427713, 9.329779, 7.703554, 6.125915, 5.373554, 5.501560,
        5.398874, 4.908898, 4.005224, 2.997531, 1.964327, 1.790885};
        populationData[1][32] = new double[] {8.418414, 7.791204, 8.867238, 9.813546,
        10.830981, 10.387932, 9.451713, 7.908793, 6.357026, 5.643228, 5.913462,
        6.063895, 5.658443, 4.998249, 4.146896, 3.132799, 3.751570};
        populationData[0][33] = new double[] {8.973478, 8.218065, 9.138622, 9.908576,
        11.056813, 10.666922, 9.513838, 7.980066, 6.468917, 5.472658, 5.382327,
        5.405538, 4.947309, 4.067787, 3.058328, 2.019085, 1.834180};
        populationData[1][33] = new double[] {8.573405, 7.835186, 8.729904, 9.518336,
        10.786989, 10.592563, 9.623470, 8.185917, 6.701199, 5.733733, 5.773436,
        6.051614, 5.707653, 5.058962, 4.228359, 3.218083, 3.875889};
        populationData[0][34] = new double[] {9.050297, 8.363255, 8.930143, 9.678046,
        11.026807, 10.844351, 9.741530, 8.356864, 6.710547, 5.588178, 5.293784,
        5.367850, 5.014370, 4.113185, 3.112160, 2.073012, 1.877758};
        populationData[1][34] = new double[] {8.644608, 7.974670, 8.520132, 9.290100,
        10.710601, 10.739917, 9.834020, 8.562241, 6.945762, 5.846395, 5.664116,
        5.983914, 5.788287, 5.101201, 4.300043, 3.301001, 3.999147};
        populationData[0][35] = new double[] {9.126958, 8.528140, 8.718569, 9.585293,
        10.912881, 10.965046, 10.013407, 8.729107, 6.937423, 5.678197, 5.245636,
        5.327031, 5.057207, 4.180380, 3.158447, 2.128936, 1.924527};
        populationData[1][35] = new double[] {8.714663, 8.136717, 8.308864, 9.177385,
        10.565605, 10.839335, 10.088517, 8.928573, 7.171484, 5.933617, 5.609279,
        5.901870, 5.849300, 5.162825, 4.357008, 3.381925, 4.122131};
        populationData[0][36] = new double[] {9.189589, 8.750561, 8.435189, 9.644906,
        10.658702, 11.080705, 10.246079, 9.233936, 7.094819, 5.815150, 5.217610,
        5.293338, 5.026472, 4.278956, 3.195926, 2.185351, 1.976823};
        populationData[1][36] = new double[] {8.772912, 8.347837, 8.039045, 9.210441,
        10.283548, 10.937418, 10.305626, 9.429255, 7.322751, 6.068274, 5.564678,
        5.841923, 5.832394, 5.264966, 4.397411, 3.460330, 4.247834};
        populationData[0][37] = new double[] {9.236547, 8.918362, 8.389502, 9.596943,
        10.389956, 11.067752, 10.503680, 9.247458, 7.697842, 6.023807, 5.235365,
        5.224129, 4.989804, 4.370425, 3.244251, 2.244467, 2.035647};
        populationData[1][37] = new double[] {8.815658, 8.511896, 7.987344, 9.143601,
        9.995382, 10.913798, 10.554243, 9.421919, 7.931691, 6.276185, 5.567513,
        5.744187, 5.792803, 5.364771, 4.447233, 3.537606, 4.381766};
        populationData[0][38] = new double[] {9.309388, 9.088479, 8.452764, 9.501460,
        10.134044, 11.014526, 10.713901, 9.441696, 7.992844, 6.353193, 5.335272,
        5.113353, 5.000971, 4.405910, 3.303980, 2.300186, 2.087785};
        populationData[1][38] = new double[] {8.886032, 8.670823, 8.043473, 9.033245,
        9.711802, 10.853887, 10.755639, 9.604194, 8.218782, 6.607699, 5.660683,
        5.609321, 5.790336, 5.415275, 4.501140, 3.607698, 4.501633};
        populationData[0][39] = new double[] {9.468861, 9.170405, 8.605825, 9.326737,
        9.945692, 10.932107, 10.858833, 9.682308, 8.383086, 6.584616, 5.444419,
        5.030815, 4.972318, 4.465976, 3.357796, 2.354936, 2.154315};
        populationData[1][39] = new double[] {9.039197, 8.746388, 8.191011, 8.845013,
        9.496061, 10.757872, 10.899536, 9.827059, 8.601851, 6.843100, 5.768681,
        5.503177, 5.734973, 5.496260, 4.544070, 3.672328, 4.636075};
        populationData[0][40] = new double[] {9.646499, 9.244877, 8.808488, 9.143540,
        9.894904, 10.764146, 10.977243, 9.954810, 8.803732, 6.784650, 5.522246,
        5.004168, 4.947562, 4.512419, 3.423152, 2.411549, 2.217721};
        populationData[1][40] = new double[] {9.203978, 8.814475, 8.387337, 8.655642,
        9.409081, 10.592882, 11.017141, 10.082326, 9.015303, 7.044649, 5.848000,
        5.469622, 5.671164, 5.563913, 4.599197, 3.734807, 4.776569};
        populationData[0][41] = new double[] {9.833318, 9.361344, 9.098526, 8.893639,
        9.942153, 10.615614, 11.197075, 10.257111, 9.282219, 6.934010, 5.684731,
        4.999356, 4.958438, 4.499209, 3.542359, 2.480453, 2.288976};
        populationData[1][41] = new double[] {9.384293, 8.923940, 8.660223, 8.413021,
        9.473584, 10.421441, 11.178902, 10.371547,  9.494776, 7.201925, 6.008457,
        5.444825, 5.645715, 5.540430, 4.713909, 3.801711, 4.945273};
        populationData[0][42] = new double[] {9.997886, 9.438873, 9.349905, 8.875641,
        9.882820, 10.388481, 11.301217, 10.562539, 9.294474, 7.573867, 5.904189,
        5.045006, 4.912970, 4.488343, 3.656960, 2.540116, 2.366685};
        populationData[1][42] = new double[] {9.545403, 8.997747, 8.899001, 8.392975,
        9.435178, 10.196411, 11.248989, 10.660793,  9.515910, 7.844957, 6.232738,
        5.477284, 5.564994, 5.508462, 4.833974, 3.860078, 5.099323};
        populationData[0][43] = new double[] {10.106027, 9.548069, 9.593132, 8.992572,
        9.761408, 10.166519, 11.354300, 10.838152, 9.485754, 7.866684, 6.259076,
        5.155252, 4.835958, 4.526531, 3.736668, 2.587283, 2.452454};
        populationData[1][43] = new double[] {9.642496, 9.103407, 9.130360, 8.500488,
        9.345350, 9.978858, 11.278759, 10.922494, 9.714260, 8.151046, 6.592552,
        5.581640, 5.456118, 5.517781, 4.911782, 3.898463, 5.263659};
        populationData[0][44] = new double[] {10.132420, 9.742203, 9.734847, 9.200557,
        9.579000, 10.000632, 11.368516, 11.044977,  9.732486, 8.248082, 6.510261,
        5.289598, 4.779273, 4.527200, 3.801831, 2.642538, 2.534838};
        populationData[1][44] = new double[] {9.667418, 9.287954, 9.267266, 8.693722,
        9.185169, 9.813721, 11.269825, 11.119548, 9.963900, 8.545367, 6.851860,
        5.719228, 5.369799, 5.480255, 4.978883, 3.946494, 5.406005};
        populationData[0][45] = new double[] {9.991196, 9.772973, 9.655691, 9.367561,
        9.216512, 9.494994, 10.899846, 11.120968, 10.024667, 8.569578, 6.629663,
        5.315259, 4.723321, 4.505369, 3.838512, 2.729003, 2.660887};
        populationData[1][45] = new double[] {9.537989, 9.319412, 9.193726, 8.845072,
        8.851982, 9.466608, 10.974838, 11.210098, 10.248489, 8.891180, 7.011828,
        5.770350, 5.322324, 5.419823, 4.991968, 3.970695, 5.501264};
        populationData[0][46] = new double[] {9.946558, 10.169920, 9.955805, 9.735924,
        9.182504, 10.068661, 11.059698, 11.379927, 10.271464, 9.145329,
        6.917803, 5.525535, 4.775075, 4.551119, 3.842915, 2.798891, 2.718823};
        populationData[1][46] = new double[] {9.491911, 9.696261, 9.477733, 9.198281,
        8.788146, 9.874903, 10.935015, 11.431910, 10.501236, 9.465018, 7.269406,
        5.953339, 5.331303, 5.411202, 5.014252, 4.100005, 5.681519};
        populationData[0][47] = new double[] {9.859333, 10.369863, 10.040011, 9.981055,
        9.198327, 10.090682, 10.812886, 11.442800, 10.556042, 9.179319, 7.566180,
        5.734078, 4.825014, 4.513530, 3.838541, 2.889826, 2.805174};
        populationData[1][47] = new double[] {9.407516, 9.890198, 9.558468, 9.431007,
        8.800448, 9.891272, 10.686093, 11.487379, 10.774354, 9.505342, 7.921135,
        6.168128, 5.364993, 5.333405, 4.990951, 4.202725, 5.795685};
        populationData[0][48] = new double[] {9.812280, 10.505394, 10.153507, 10.207605,
        9.334233, 10.045474, 10.570912, 11.454846, 10.812158, 9.391829, 7.875167,
        6.072569, 4.941850, 4.445965, 3.881845, 2.954397, 2.895344};
        populationData[1][48] = new double[] {9.368860, 10.012337, 9.667272, 9.646589,
        8.920699, 9.836584, 10.434330, 11.495030, 11.013924, 9.718821, 8.237645,
        6.512883, 5.475285, 5.226620, 5.008621, 4.270018, 5.914395};
        populationData[0][49] = new double[] {9.800730, 10.555678, 10.356345, 10.332977,
        9.559507, 9.935647, 10.402583, 11.439475, 11.009166, 9.667935, 8.277454,
        6.317578, 5.077517, 4.397248, 3.891873, 3.009129, 2.991279};
        populationData[1][49] = new double[] {9.359191, 10.056607, 9.856848, 9.766445,
        9.114919, 9.705121, 10.250299, 11.474129, 11.194971, 9.987765, 8.644237,
        6.764078, 5.612888, 5.140272, 4.982430, 4.329465, 6.032927};
        populationData[0][50] = new double[] {9.638841, 10.121917, 10.196117, 10.237197,
        9.502290, 8.926215, 9.720964, 11.104940, 11.230903, 9.780182, 8.399166,
        6.397563, 5.045734, 4.333794, 3.876268, 3.102951, 3.159852};
        populationData[1][50] = new double[] {9.226600, 9.659274, 9.712006, 9.672207,
        9.097582, 8.992754, 9.903564, 11.209009, 11.401585, 10.125843, 8.866969,
        6.926612, 5.631346, 5.101957, 4.876838, 4.318818, 6.064815};
    }
}