/*
 * -------------------------------------------------------------------------
 *      $Id: RDPanel.java,v 1.1 2004/09/03 16:22:19 estewart Exp $
 * -------------------------------------------------------------------------
 *      Copyright (c) 2004 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.stats;
import java.awt.*;
import com.imsl.chart.*;
import com.imsl.stat.Random;
import com.imsl.math.Cholesky;
import com.imsl.demo.gallery.Describe;


/**
 *
 * @author  Masayuki Saito
 * @created October 21, 2002
 */
public class RDPanel extends javax.swing.JPanel {

    private javax.swing.JFrame parentFrame;
    private JPanelChart jPanelChart;
    private Bar bar;
    private int randomK = 0;
    private int numPoints = 1000;
    private int numBins = 12;
    private final int numDist = 21;
    private javax.swing.JRadioButton rb[] = new javax.swing.JRadioButton[numDist];
    private String[] rname = new String[numDist];
    private boolean textUpdateFlag;


    /** Creates new form RandomGen */
    public RDPanel(javax.swing.JFrame parent) {
        this.parentFrame = parent;

        initComponents();
        setPreferredSize(new java.awt.Dimension(parent.getSize().width, (int)(0.85*parent.getSize().height)));
        rb[randomK].setSelected(true);
        jPanelChart.setPreferredSize(new java.awt.Dimension(parent.getSize().width, (int)(0.66*parent.getSize().height)));
        updateChart();
    }

    /*
    public void setVisible(boolean show) {
        super.setVisible(show);
    }
    */

    private void initComponents() {
        jPanel1 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jTextField1 = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jTextField2 = new javax.swing.JTextField();
        jPanel3 = new javax.swing.JPanel();
        set_rname();
        for (int i=0; i<numDist ;i++){
            rb[i] = new javax.swing.JRadioButton(rname[i]);
            jPanel3.add(rb[i]);
            rb[i].addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    String eventname = new String(evt.getActionCommand());
                    methodActionPerformed(eventname);
                }
            });
        }
        jPanel4 = new javax.swing.JPanel();
        jTextArea1 = new javax.swing.JTextArea();
        jPanelChart = new com.imsl.chart.JPanelChart();

        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.X_AXIS));

        jPanel1.setLayout(new java.awt.BorderLayout());
        jPanel1.setMaximumSize(new java.awt.Dimension(300, 500));
        jPanel1.setPreferredSize(new java.awt.Dimension(300, 500));
        jPanel2.setLayout(new java.awt.GridLayout(2, 2));

        jPanel2.setMaximumSize(new java.awt.Dimension(400, 40));
        jPanel2.setMinimumSize(new java.awt.Dimension(0, 0));
        jPanel2.setPreferredSize(new java.awt.Dimension(300, 40));
        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel1.setText("Number of Samples: ");
        jLabel1.setMaximumSize(new java.awt.Dimension(100, 20));
        jLabel1.setMinimumSize(new java.awt.Dimension(25, 10));
        jLabel1.setPreferredSize(new java.awt.Dimension(100, 20));
        jPanel2.add(jLabel1);

        jTextField1.setText(String.valueOf(numPoints));
        jTextField1.setMaximumSize(new java.awt.Dimension(50, 20));
        jTextField1.setMinimumSize(new java.awt.Dimension(0, 0));
        jTextField1.setPreferredSize(new java.awt.Dimension(50, 20));
        jTextField1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField1ActionPerformed(evt);
            }
        });
        jPanel2.add(jTextField1);

        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel2.setText("Number of bins: ");
        jLabel2.setMaximumSize(new java.awt.Dimension(100, 20));
        jLabel2.setPreferredSize(new java.awt.Dimension(100, 20));
        jPanel2.add(jLabel2);

        jTextField2.setText(String.valueOf(numBins));
        jTextField2.setMaximumSize(new java.awt.Dimension(50, 20));
        jTextField2.setPreferredSize(new java.awt.Dimension(50, 20));
        jTextField2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField2ActionPerformed(evt);
            }
        });
        jPanel2.add(jTextField2);

        jPanel1.add(jPanel2, java.awt.BorderLayout.NORTH);

        jPanel3.setLayout(new java.awt.GridLayout(11, 2));
        jPanel3.setMaximumSize(new java.awt.Dimension(400, 250));
        jPanel3.setPreferredSize(new java.awt.Dimension(300, 400));
        jPanel1.add(jPanel3, java.awt.BorderLayout.CENTER);

        jPanel4.setLayout(new java.awt.GridLayout(1, 0));
        jPanel4.setMaximumSize(new java.awt.Dimension(400, 150));
        jPanel4.setPreferredSize(new java.awt.Dimension(300, 150));
        jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Summary"));
        jTextArea1.setEditable(false);
        jTextArea1.setMaximumSize(new java.awt.Dimension(300, 150));
        jTextArea1.setMinimumSize(new java.awt.Dimension(0, 0));
        jTextArea1.setPreferredSize(new java.awt.Dimension(300, 150));
        jPanel4.add(jTextArea1);

        jPanel1.add(jPanel4, java.awt.BorderLayout.SOUTH);
        add(jPanel1);

        jPanelChart.setPreferredSize(new java.awt.Dimension(500, 500));
        add(jPanelChart);
    }

    private void jTextField1FocusLost(java.awt.event.FocusEvent evt) {
        jTextField1.postActionEvent();
    }

    private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {
        numPoints = new Integer(jTextField1.getText().trim()).intValue();
        if (!textUpdateFlag)
            updateChart();
    }

    private void jTextField2ActionPerformed(java.awt.event.ActionEvent evt) {
        numBins = new Integer(jTextField2.getText().trim()).intValue();
        if (!textUpdateFlag)
            updateChart();
    }

    private void methodActionPerformed(String eventname) {
        textUpdateFlag = true;
        //jTextField1.postActionEvent();
        jTextField2.postActionEvent();
        textUpdateFlag = false;
        for(int i=0; i<numDist; i++){
            if(!eventname.equals(rname[i]))
                rb[i].setSelected(false);
            else {
                rb[i].setSelected(true);
                randomK = i;
            }
        }
        updateChart();
    }

    private void updateChart() {
        jPanelChart.setChart(new Chart());
        Chart chart = jPanelChart.getChart();
        String output = setup(chart, numPoints, numBins);
        repaint();
        jTextArea1.setText(output);
    }

    // ++++++++++ setup method ++++++++++ //
    // ++  Create Histgram bar graph   ++ //
    // ++++++++++++++++++++++++++++++++++ //
    private String setup(Chart chart, int numPoints, int numBins) {
        bar = null;
        AxisXY axis = new AxisXY(chart);
        double v[] =  new double[numPoints];

        //  Generate some random data
        Random r = new Random();
        String x[] = new String[numBins];
        double y[] = new double[numBins];

        // -- Calc. Histgram data : y --
        for (int kitem = 0; kitem < numBins; kitem++) y[kitem]=0;

        double maxv = -10000;
        double minv = 10000;
        if (randomK != 20) {
            v = new double[numPoints];
            for (int i = 0; i < numPoints; i++) { // -- Max/Min value --
                v[i] = randomValue(r);
                if (maxv < v[i]) maxv=v[i];
                if (minv > v[i]) minv=v[i];
            }
        } else {
            double a[][] = {{ 1, -3,  2},{-3, 10, -5},{ 2, -5,  6}};
            try {
                Cholesky matrix = new Cholesky(a);
                int k = 3;
                v = r.nextMultivariateNormal(k, matrix);
                for (int i = 0; i < v.length; i++) {
                    if (v[i] < minv) minv=v[i];
                    if (v[i] > maxv) maxv=v[i];
                }
            } catch (Exception e) {
                javax.swing.JOptionPane.showMessageDialog(this, e.getMessage(),
                    "Exception", javax.swing.JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
            }
        }

        double wx = (maxv-minv)/numBins;
        for (int kitem = 0; kitem < v.length; kitem++) {
            int i;
            if (maxv == v[kitem]){
                i = numBins-1;
            } else {
                i = (int) ((v[kitem]-minv)/wx);
            }
            y[i] = y[i] + 1;
        }

        //  Create an instance of a Bar Chart
        bar = new Bar(axis, y);

        chart.getChartTitle().setTitle(rname[randomK]+" Random Distribution");
        chart.getChartTitle().setFontStyle(java.awt.Font.BOLD);
        bar.setFillOutlineType(Bar.FILL_TYPE_SOLID);
        bar.getBarSet(0).setFillColor(Color.red);

        // Setup the X axis for a labeled bar chart.
        String spacer = " : ";
        String labels[] = new String[numBins];
        java.text.DecimalFormat df = new java.text.DecimalFormat();
        if (randomK != 15) {
            df.applyPattern("##0.00");
        } else {    // special format for logNormal
            df.applyPattern("0.0000");
        }
        labels[0] = String.valueOf(df.format(minv)) + spacer + String.valueOf(df.format(minv+wx));
        for (int i = 1; i < numBins-1; i++) {
            labels[i] = String.valueOf(df.format(minv + i*wx)) + spacer + String.valueOf(df.format(minv + (i+1)*wx));
        }
        labels[numBins-1] = String.valueOf(df.format(maxv-wx)) + spacer + String.valueOf(df.format(maxv));

        bar.setLabels(labels, Data.BAR_TYPE_VERTICAL);
        axis.getAxisX().getAxisLabel().setTextAngle(90);
        //axis.getAxisY().getAxisTitle().setTitle("Number\n");
        axis.setViewport(0.12,0.95,0.1,0.8);
        if (randomK != 20) {
            axis.getAxisY().setTextFormat(new java.text.DecimalFormat("###0"));
        } else {
            axis.getAxisY().setTextFormat(new java.text.DecimalFormat("#0.0"));
        }

        // +++++ Print Random Name, Sample No. MAX, MIN +++++
        StringBuffer sb = new StringBuffer();
        sb.append("Random Distribution: "+rname[randomK]+"\n");
        if (randomK != 20) {
            sb.append("   # Samples: "+numPoints+"\n");
            sb.append("   # Bins: "+numBins+"\n");
        } else {
            sb.append("   Matrix: a[ ][ ] = {{ 1, -3,  2},{-3, 10, -5},{ 2, -5,  6}}\n");
        }
        sb.append("   Max Value: "+maxv+"\n");
        sb.append("   Min Value: "+minv+"\n");
        return sb.toString();
    }

    // ++++++++++ randomValue ++++++++++ //
    // ++  Create next Random value   ++ //
    // +++++++++++++++++++++++++++++++++ //
    double randomValue(Random r) {
        double nr = 0.0;
        if (randomK == 0) nr = r.nextDouble();
        if (randomK == 1) nr = r.nextBeta(1.0d, 0.5d);
        if (randomK == 2) nr = r.nextNormal();
        if (randomK == 3) nr = r.nextNormalAR();
        if (randomK == 4) nr = r.nextBinomial(5, 0.5d);
        if (randomK == 5) nr = r.nextCauchy();
        if (randomK == 6) nr = r.nextChiSquared(5);
        if (randomK == 7) nr = r.nextGamma(0.5);
        if (randomK == 8) nr = r.nextGeometric(0.5);
        if (randomK == 9) nr = r.nextHypergeometric(5, 5, 11);
        if (randomK == 10) nr = r.nextLogarithmic(0.5d);
        if (randomK == 11) nr = r.nextNegativeBinomial(0.5d, 0.5d);
        if (randomK == 12) nr = r.nextPoisson(10d);
        if (randomK == 13) nr = r.nextExponential();
        if (randomK == 14) nr = r.nextExponentialMix(30d, 10d, 0.5d);
        if (randomK == 15) nr = r.nextLogNormal(0d, .001d);
        if (randomK == 16) nr = r.nextTriangular();
        if (randomK == 17) nr = r.nextStudentsT(5.0d);
        if (randomK == 18) nr = r.nextVonMises(1.0e-7d);
        if (randomK == 19) nr = r.nextWeibull(5d);
        return nr;
    }

    // ++++++++++ set_rname method ++++++++++ //
    // ++  Set 21 Random names.            ++ //
    // ++++++++++++++++++++++++++++++++++++++ //
    public void set_rname(){
        rname[0]  = "Standard Pseudo";
        rname[1]  = "Beta";
        rname[2]  = "Normal";
        rname[3]  = "NormalAR";
        rname[4]  = "Binomial";
        rname[5]  = "Cauchy";
        rname[6]  = "ChiSquare";
        rname[7]  = "Gamma";
        rname[8]  = "Geometric";
        rname[9]  = "Hypergeometric";
        rname[10] = "Logarithmic";
        rname[11] = "NegativeBinomial";
        rname[12] = "Poisson";
        rname[13] = "Exponential";
        rname[14] = "ExponentialMix";
        rname[15] = "LogNormal";
        rname[16] = "Triangular";
        rname[17] = "StudentT";
        rname[18] = "VonMises";
        rname[19] = "Weibull";
        rname[20] = "MultivariateNormal";
    }


    // Variables declaration - do not modify
    private javax.swing.JPanel jPanel4;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JTextField jTextField2;
    private javax.swing.JTextField jTextField1;
    // End of variables declaration
}