/*
 * -------------------------------------------------------------------------
 *      $Id: BPanel.java,v 1.3 2005/12/30 16:46:52 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.
 *--------------------------------------------------------------------------
 */

/*
 * BPanel.java
 *
 * Created on September 13, 2004, 6:46 PM
 */

package com.imsl.demo.heatmaps;

import com.imsl.chart.*;
import java.util.*;
import java.io.*;
import java.awt.event.*;
import java.awt.Color;


public class BPanel extends javax.swing.JPanel implements MouseMotionListener {

    private Chart chart;
    private AxisXY axis;
    private HashMap map;
    private double[][] data0, data1, data2, plotData;
    private int[] rows0, cols0, rows1, cols1, rows2, cols2, plotRow, plotCol;
    private javax.swing.JFrame parentFrame;
    private final int xMin = 0;
    private final int xMax = 60;
    private final int yMin = 0;
    //private final int yMax = 1000;
    private final int yMax = 100;


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

        initComponents();
        setPreferredSize(new java.awt.Dimension(parent.getSize().width, (int)(0.85*parent.getSize().height)));

        setChart();
        jPanelChart.setPreferredSize(new java.awt.Dimension(parent.getSize().width, (int)(0.66*parent.getSize().height)));
        try {
            getData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        plotData = data0;
        update(0);
    }


    private void setChart() {
        chart = jPanelChart.getChart();
        axis = new AxisXY(chart);
        axis.setViewport(0.05,0.80,0.05,0.95);

        // Set axis ranges
        axis.getAxisX().setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
        axis.getAxisY().setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
        axis.getAxisX().setWindow(0.0, xMax-1);
        axis.getAxisY().setWindow(0.0, yMax-1);
        axis.getAxisX().getAxisTitle().setTitle("");
        axis.getAxisY().getAxisTitle().setTitle("");
        axis.getAxisX().setTextColor(Color.white);
        axis.getAxisY().setTextColor(Color.white);
        axis.getAxisX().setNumber(7);
        axis.getAxisX().setDensity(5);
        axis.getAxisY().setNumber(11);
        axis.getAxisY().setDensity(5);

        AxisXY axis2 = new AxisXY(chart);
        axis2.setViewport(0.05,0.80,0.05,0.95);
        axis2.getAxisX().setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
        axis2.getAxisY().setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
        axis2.getAxisX().setWindow(0.0, xMax-1);
        axis2.getAxisY().setWindow(0.0, yMax-1);
        axis2.getAxisX().getAxisTitle().setTitle("");
        axis2.getAxisY().getAxisTitle().setTitle("");
        axis2.getAxisX().setTextColor(Color.white);
        axis2.getAxisY().setTextColor(Color.white);
        axis2.getAxisX().setTickLength(-1);
        axis2.getAxisY().setTickLength(-1);
        axis2.getAxisX().setFontSize(0);
        axis2.getAxisY().setFontSize(0);
        axis2.getAxisX().setNumber(7);
        axis2.getAxisX().setDensity(5);
        axis2.getAxisY().setNumber(11);
        axis2.getAxisY().setDensity(5);
        axis2.setCross(xMax-1,yMax-1);

        // Add MouseMotionListener to the chart.
        jPanelChart.addMouseMotionListener(this);
    }


    // clear and load data sets determined by the menu selection
    public void getData() throws IOException, java.text.ParseException {
        rows0 = new int[yMax];
        cols0 = new int[xMax];
        data0 = new double[xMax][yMax];
        rows1 = new int[yMax];
        cols1 = new int[xMax];
        data1 = new double[xMax][yMax];
        rows2 = new int[yMax];
        cols2 = new int[xMax];
        data2 = new double[xMax][yMax];

        // read first data set
        InputStream is = getClass().getResourceAsStream("simu1.csv");
        Reader fr = new InputStreamReader(is);
        LineNumberReader lnr = new LineNumberReader(fr);
        int lineNum = 0;

        while (true) {
            String line = lnr.readLine();
            if (line == null)  break;
            lineNum++;
            StringTokenizer st = new StringTokenizer(line,",");
            if (lineNum == 1) {
               int holder = Integer.valueOf(st.nextToken()).intValue();
               for (int i=0; i<xMax; i++) {
                  cols0[i] = Integer.valueOf(st.nextToken()).intValue();
               }
            } else {
               rows0[yMax+3-lineNum-2] = Integer.valueOf(st.nextToken()).intValue();
               for (int i=0; i<xMax; i++) {
                  data0[i][yMax+3-lineNum-2] = Double.valueOf(st.nextToken()).doubleValue();
               }
            }
        }

        // read second data set
        is = getClass().getResourceAsStream("simu1_cluster1.csv");
        fr = new InputStreamReader(is);
        lnr = new LineNumberReader(fr);
        lineNum = 0;

        while (true) {
            String line = lnr.readLine();
            if (line == null)  break;
            lineNum++;
            StringTokenizer st = new StringTokenizer(line,",");
            if (lineNum == 1) {
               int holder = Integer.valueOf(st.nextToken()).intValue();
               for (int i=0; i<xMax; i++) {
                  cols1[i] = Integer.valueOf(st.nextToken()).intValue();
               }
            } else {
               rows1[yMax-lineNum+1] = Integer.valueOf(st.nextToken()).intValue();
               for (int i=0; i<xMax; i++) {
                  data1[i][yMax-lineNum+1] = Double.valueOf(st.nextToken()).doubleValue();
               }
            }
        }

        // read third data set
        is = getClass().getResourceAsStream("simu1_cluster2.csv");
        fr = new InputStreamReader(is);
        lnr = new LineNumberReader(fr);
        lineNum = 0;

        while (true) {
            String line = lnr.readLine();
            if (line == null)  break;
            lineNum++;
            StringTokenizer st = new StringTokenizer(line,",");
            if (lineNum == 1) {
               int holder = Integer.valueOf(st.nextToken()).intValue();
               for (int i=0; i<xMax; i++) {
                  cols2[i] = Integer.valueOf(st.nextToken()).intValue();
               }
            } else {
               rows2[yMax-lineNum+1] = Integer.valueOf(st.nextToken()).intValue();
               for (int i=0; i<xMax; i++) {
                  data2[i][yMax-lineNum+1] = Double.valueOf(st.nextToken()).doubleValue();
               }
            }
        }
    }


    // Draw the graph
    private void drawGraph() {
        Heatmap heatmap = new Heatmap(axis, 0, xMax-1, 0, yMax-1, -12.0, 12.0, plotData, new MavaColormap());
        heatmap.getHeatmapLegend().setPaint(true);
        heatmap.getHeatmapLegend().setTextFormat("##");
        heatmap.getHeatmapLegend().setTitle("Value");
    }


    // Print the details for the current mouse location
    private void getDetails(int xLoc, int yLoc) {
        StringBuffer sb = new StringBuffer("\tValue = "+plotData[xLoc][yLoc]+"\n");
        sb.append("\tCurrent location = ( "+(xLoc+1)+" , "+(yMax-yLoc)+" )\n");
        sb.append("\tOriginal location = ( "+plotCol[xLoc]+" , "+plotRow[yLoc]+" )\n");
        displayText.setText(sb.toString());
    }


    // Redraw the chart based on radio button selection.
    public void update(int dataSet) {
        if (dataSet == 0) {
            plotData = data0;
            plotRow = rows0;
            plotCol = cols0;
            jRadioButton1.setSelected(false);
            jRadioButton2.setSelected(false);
        }
        if (dataSet == 1) {
            plotData = data1;
            plotRow = rows1;
            plotCol = cols1;
            jRadioButton0.setSelected(false);
            jRadioButton2.setSelected(false);
        }
        if (dataSet == 2) {
            plotData = data2;
            plotRow = rows2;
            plotCol = cols2;
            jRadioButton0.setSelected(false);
            jRadioButton1.setSelected(false);
        }
        drawGraph();
        repaint();
    }


    private void initComponents() {
        jPanelTop = new javax.swing.JPanel();
        jPanelLeft = new javax.swing.JPanel();
        jPanelRight = new javax.swing.JPanel();
        jRadioButton0 = new javax.swing.JRadioButton();
        jRadioButton1 = new javax.swing.JRadioButton();
        jRadioButton2 = new javax.swing.JRadioButton();
        jLabelSelect = new javax.swing.JLabel();
        displayText = new javax.swing.JTextArea(6, 20);
        jPanelChart = new com.imsl.chart.JPanelChart();

        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));
        setPreferredSize(new java.awt.Dimension(500, 600));

        jPanelTop.setLayout(new javax.swing.BoxLayout(jPanelTop, javax.swing.BoxLayout.X_AXIS));
        jPanelLeft.setLayout(new javax.swing.BoxLayout(jPanelLeft, javax.swing.BoxLayout.Y_AXIS));

        jLabelSelect.setText("  Select Data Set:    ");
        jPanelLeft.add(jLabelSelect);

        jRadioButton0.setText("Original Data");
        jRadioButton0.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                update(0);
            }
        });
        jRadioButton0.setSelected(true);
        jPanelLeft.add(jRadioButton0);

        jRadioButton1.setText("One pass");
        jRadioButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                update(1);
            }
        });
        jPanelLeft.add(jRadioButton1);

        jRadioButton2.setText("Two Passes");
        jRadioButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                update(2);
            }
        });
        jPanelLeft.add(jRadioButton2);

        displayText.setEditable(false);
        displayText.setText("\tMove the mouse over the heat map for details.");
        displayText.setPreferredSize(new java.awt.Dimension(500, 16));
        displayText.setBackground(jPanelRight.getBackground());
        jPanelRight.add(displayText);

        jPanelTop.add(jPanelLeft);
        jPanelTop.add(jPanelRight);
        add(jPanelTop);


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


    // Implement MouseMotionListener
    public void mouseMoved(MouseEvent e) {
        double user[] = {0,0};
        axis.mapDeviceToUser(e.getX(), e.getY(), user);
        if ((user[0] < xMin) || (user[0] > xMax) ||
            (user[1] < yMin) || (user[1] > yMax)) {

            displayText.setText("\tMove the mouse over the heat map for details.");
            return;
        }

        getDetails((int)user[0],(int)user[1]);
    }

    public void mouseDragged(MouseEvent e) {
    }


    // Variables declaration
    private javax.swing.JLabel jLabelSelect;
    private javax.swing.JRadioButton jRadioButton0;
    private javax.swing.JRadioButton jRadioButton1;
    private javax.swing.JRadioButton jRadioButton2;
    private com.imsl.chart.JPanelChart jPanelChart;
    private javax.swing.JTextArea displayText;
    private javax.swing.JPanel jPanelTop;
    private javax.swing.JPanel jPanelLeft;
    private javax.swing.JPanel jPanelRight;
    // End of variables declaration

    private class MavaColormap implements com.imsl.chart.Colormap {
        int[] c = new int[] {10157607,10092070,10092070,10026534,10026534,10026534,9960998,9960998,9895462,9895462,9895462,9829926,9829926,9764390,9764390,9764390,9698854,9698854,9633318,9633318,9633318,9567782,9567782,9502246,9502246,
                             9502502,9436709,9371172,9305635,9305634,9240097,9174561,9108768,9108767,9043230,8977693,8912157,8912156,8846619,8780826,8780825,8715289,8649752,8584215,8584214,8518421,8452885,8387348,8387347,8321810,
                             8256273,8256273,8124944,8059152,7993359,7927567,7861774,7795982,7730189,7664397,7533068,7467276,7401483,7335691,7269898,7204106,7138313,7072521,6941192,6875400,6809607,6743815,6678022,6612230,6546437,
                             6480645,6415109,6283013,6151173,6084869,5953029,5886725,5754885,5688325,5556485,5490181,5358341,5292037,5160197,5093894,4961798,4829958,4763654,4631814,4565510,4433670,4367110,4235270,4168966,4037126,
                             3970822,3838982,3772679,3640070,3507718,3375366,3242758,3110406,2978054,2845446,2713094,2580742,2448134,2315782,2183430,2051078,1852934,1786118,1653766,1521158,1388806,1256454,1123846,991494,859142,726534,
                             594182,461830,329478,656902,984582,1377799,1705479,2098695,2426376,2754056,3147272,3474953,3868169,4195849,4523530,4916746,5244427,5637643,5965323,6293004,6686220,7013900,7407117,7734797,8062477,8455694,
                             8783374,9176591,9241870,9372942,9504014,9569550,9700622,9831694,9962766,10028302,10159374,10290446,10421518,10487054,10618126,10748941,10814477,10945549,11076621,11207693,11273229,11404301,11535373,
                             11666445,11731981,11863053,11994125,12125197,12124940,12190476,12256012,12321548,12387084,12452620,12518156,12583692,12649228,12714764,12780300,12845836,12845580,12911116,12976652,13042188,13107724,
                             13173260,13238796,13304332,13369868,13435404,13500940,13566476,13632012,13697548,13828620,13894156,14025229,14156301,14221837,14352910,14418446,14549518,14680591,14746127,14877199,15008272,15073808,
                             15204880,15270416,15401489,15532561,15598097,15729170,15794706,15925778,16056851,16122387,16253459,16384532,16384533,16384534,16384791,16384792,16385049,16385050,16450843,16450844,16450845,16451102,
                             16451103,16451360,16516897,16517154,16517155,16517412,16517413,16517414,16583207,16583208,16583465,16583466,16583723,16583724,16649517};

        public java.awt.Color color(double t) {
            int i = (int)(t*255);
            return new java.awt.Color(c[i]);
        }
    }
}