/*
 * -------------------------------------------------------------------------
 *      $Id: ForecastPopulation.java,v 1.2 2003/09/12 20:43:22 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 com.imsl.stat.ARMA;
//import java.awt.Color;


/**
 *
 * @author  pate
 * @created October 23, 2002
 */
public class ForecastPopulation extends javax.swing.JDialog {

    private Data data, forecastData, upperLimit, lowerLimit;
    private JPanelChart jPanelChart;

    public ForecastPopulation(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        java.awt.Dimension parentSize = parent.getSize();
        java.awt.Point parentLoc = parent.getLocationOnScreen();
        parentLoc.x += parentSize.width/2.5;
        parentLoc.y += parentSize.height/2.5;
        setLocation(parentLoc.x, parentLoc.y);
        
        jPanelChart = new JPanelChart();
        int h = (int)((parentSize.height/2)*1.25);
        int w = (int)(h/0.8);
        jPanelChart.setPreferredSize(new java.awt.Dimension(w,h));
        getContentPane().add(jPanelChart);
        pack();
    }

    void draw(int gender, int category, double y[]) {
        // text used for chart labels
        String genderText = ((gender == 0) ? "Male" : "Female");
        String xlabels[] = {"1950", "1960", "1970", "1980", "1990", "2000", "2010"};
        String categories[] = {"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+"};

        // create a new XY chart
        Chart chart = jPanelChart.getChart();
        AxisXY axis = new AxisXY(chart);

        // Setup Chart Title
        chart.getChartTitle().setTitle("Projected " + genderText + " Population,  " + categories[category]);
        chart.getChartTitle().setFontStyle(1);

        //  Setup Y axis
        axis.getAxisY().getAxisTitle().setTitle("Population, Millions");
        axis.getAxisY().getAxisTitle().setFontStyle(1);
        axis.getAxisY().setWindow(0,15);

        // Setup X Axis
        axis.getAxisX().setWindow(0,60);
        axis.getAxisX().getAxisLabel().setLabels(xlabels);
        axis.getAxisX().getAxisTitle().setTitle("Year");
        axis.getAxisX().getAxisTitle().setFontStyle(1);

        axis.setAutoscaleInput(Axis.AUTOSCALE_OFF);

        // make local copy of population data
        double[] z = new double[y.length];
        for (int i = 0; i < y.length; i++) {
            z[i] = y[i];
        }

        // existing population data, 1950 to 2000
        Data data1 = new Data(axis, z);
        data1.setDataType(Data.DATA_TYPE_LINE);
        data1.setLineColor("blue");


        try {
            final int numYears = 7;  //project out 7 years

            // new arma forcast object
            ARMA arma = new ARMA(2, 1, z);
            arma.setRelativeError(0.5);
            arma.setMaxIterations(0);
            arma.compute();
            arma.setConfidence(0.50);
            arma.setBackwardOrigin(3);

            double[][] forecast = arma.forecast(numYears);
            double[] tmp = new double[numYears];
            double[] x1 = new double[numYears];

            // get the forecast data.
            for (int i = 0; i < numYears; i++) {
                tmp[i] = forecast[i][3];
                x1[i] = 50 + i;
            }

            // Draw upper and lower limits.
            double[] dev = arma.getDeviations();
            double[] ulimit = new double[dev.length];
            double[] llimit = new double[dev.length];
            double min = 3.0;

            // look for a new minumum reference point
            for (int i = 0; i < dev.length; i++) {
                ulimit[i] = tmp[i] + dev[i];
                llimit[i] = tmp[i] - dev[i];
                if (min > llimit[i]) min = llimit[i];
            }
            min = min - 1;

            // set the upper limit of the forecast
            upperLimit = new Data(axis, x1, ulimit);
            upperLimit.setTitle("Upper Limit");
            upperLimit.setDataType(Data.DATA_TYPE_LINE | Data.DATA_TYPE_FILL);
            upperLimit.setReference(min);
            upperLimit.setFillColor("yellow");
            upperLimit.setFillOutlineColor("yellow");

            // set the lower limit of the forecast
            lowerLimit = new Data(axis, x1, llimit);
            lowerLimit.setTitle("Lower Limit");
            lowerLimit.setDataType(Data.DATA_TYPE_LINE | Data.DATA_TYPE_FILL);
            lowerLimit.setReference(min);
            lowerLimit.setFillColor("white");
            lowerLimit.setFillOutlineColor("white");
        } catch (com.imsl.IMSLException e) {
            // all the ARMA exceptions extend IMSLException, so catch that
            System.out.println(e.getMessage());
            e.printStackTrace();
        } 
    }

    private void initComponents() {
        setTitle("Population Forcast");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                closeDialog(evt);
            }
        });
        pack();
    }

    private void closeDialog(java.awt.event.WindowEvent evt) {
        setVisible(false);
        dispose();
    }
}