/*
 * Main.java
 *
 */

package com.imsl.demo.SeriesAnalysis;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.awt.Color;
import com.imsl.chart.*;
import com.imsl.demo.gallery.Describe;

/**
 *
 * @author  bmiller
 * @created November 18, 2002
 */
public class SeriesAnalysis extends javax.swing.JFrame {

    private ArrayList data;
    private ArrayList params;
    private Chart chart;
    private boolean useSingleY = false;
    private final Function functionList[];
    private final static Color colorList[] = {Color.blue, Color.magenta,
        Color.black, Color.red, Color.gray, Color.green, Color.yellow,
        Color.darkGray, Color.cyan, Color.orange, Color.pink, Color.white};

    /** Creates new SeriesAnalysis */
    public SeriesAnalysis(boolean exitOnClose) {
        if (!exitOnClose) {
            // remove the WindowListener, installed by JFrame, that
            // exits the application when the window is closed.
            Object l[] = getListeners(java.awt.event.WindowListener.class);
            for (int k = 0;  k < l.length;  k++) {
                removeWindowListener((java.awt.event.WindowListener)l[k]);
            }
        }

        functionList = Binding.getFunctions();
        initComponents();
        chart = new Chart();
        jPanelChart.setChart(chart);
        chart.getBackground().setFillColor(new Color(205,205,205));
        jMenuItemOpen.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.ActionEvent.CTRL_MASK));
        for (int k=0; k<functionList.length; k++) {
            javax.swing.JMenuItem m = new javax.swing.JMenuItem(functionList[k].text);
            m.setMnemonic(functionList[k].mnemonic);
            final String name = functionList[k].fullname;
            m.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    analyze(name);
                }
            });
            jMenuAnalyze.add(m);
        }

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

        java.awt.Dimension ss = getToolkit().getScreenSize();
        int h = Math.min(ss.width/2, ss.height-ds.height-32);
        int w = (int)(h/0.65);
        setSize(w, h);
        setLocation(ss.width-ds.width, ds.height);
        setup("flight_test.csv");
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        jPanel1 = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jList = new javax.swing.JList();
        jPanel3 = new javax.swing.JPanel();
        jButtonDraw = new javax.swing.JButton();
        jCheckBoxY = new javax.swing.JCheckBox();
        jPanel2 = new javax.swing.JPanel();
        jPanelChart = new com.imsl.chart.JPanelChart();
        jMenuBar = new javax.swing.JMenuBar();
        jMenuFile = new javax.swing.JMenu();
        jMenuItemOpen = new javax.swing.JMenuItem();
        jMenuItemReadFlight = new javax.swing.JMenuItem();
        jMenuItemReadTurb = new javax.swing.JMenuItem();
        jMenuCopy = new javax.swing.JMenuItem();
        jSeparator = new javax.swing.JSeparator();
        jMenuItemExit = new javax.swing.JMenuItem();
        jMenuAnalyze = new javax.swing.JMenu();
        jMenuHelp = new javax.swing.JMenu();
        jMenuItemAbout = new javax.swing.JMenuItem();

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

        setTitle("Time Series Analysis");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS));

        jPanel1.setPreferredSize(new java.awt.Dimension(100, 600));
        jPanel4.setLayout(new java.awt.BorderLayout());

        jPanel4.setMaximumSize(new java.awt.Dimension(200, 1000));
        jScrollPane1.setToolTipText("Use Shift and Control keys to make multiple selections");
        jScrollPane1.setMaximumSize(new java.awt.Dimension(200, 1000));
        jScrollPane1.setPreferredSize(new java.awt.Dimension(150, 350));
        jList.setToolTipText("Use Shift and Control keys to make multiple selections");
        jList.setFixedCellHeight(18);
        jList.setMaximumSize(new java.awt.Dimension(200, 1000));
        jList.setPreferredSize(new java.awt.Dimension(150, 350));
        jList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jListMouseClicked(evt);
            }
        });

        jScrollPane1.setViewportView(jList);

        jPanel4.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jPanel1.add(jPanel4);

        jPanel3.setLayout(new java.awt.BorderLayout());

        jPanel3.setMaximumSize(new java.awt.Dimension(150, 150));
        jPanel3.setMinimumSize(new java.awt.Dimension(0, 0));
        jPanel3.setPreferredSize(new java.awt.Dimension(150, 150));
        jButtonDraw.setText("<html><center>Draw<br>Chart</center></html>");
        jButtonDraw.setToolTipText("Update the chart");
        jButtonDraw.setMaximumSize(new java.awt.Dimension(200, 75));
        jButtonDraw.setMinimumSize(new java.awt.Dimension(81, 26));
        jButtonDraw.setPreferredSize(new java.awt.Dimension(150, 75));
        jButtonDraw.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonDrawActionPerformed(evt);
            }
        });

        jPanel3.add(jButtonDraw, java.awt.BorderLayout.CENTER);

        jCheckBoxY.setText("<html><center>Use Single<br>Y Axis</center></html>"
        );
        jCheckBoxY.setToolTipText("Set Y axis method");
        jCheckBoxY.setMaximumSize(new java.awt.Dimension(150, 50));
        jCheckBoxY.setPreferredSize(new java.awt.Dimension(150, 50));
        jCheckBoxY.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBoxYActionPerformed(evt);
            }
        });

        jPanel3.add(jCheckBoxY, java.awt.BorderLayout.SOUTH);

        jPanel1.add(jPanel3);

        getContentPane().add(jPanel1);

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

        jPanel2.setMaximumSize(new java.awt.Dimension(1500, 975));
        jPanel2.setMinimumSize(new java.awt.Dimension(0, 0));
        jPanel2.setPreferredSize(new java.awt.Dimension(700, 455));
        jPanelChart.setPreferredSize(new java.awt.Dimension(700, 600));
        jPanel2.add(jPanelChart);

        getContentPane().add(jPanel2);

        jMenuFile.setMnemonic('F');
        jMenuFile.setText("File");
        jMenuFile.setToolTipText("Open a csv file or Exit");
        jMenuItemOpen.setMnemonic('O');
        jMenuItemOpen.setText("Open...");
        jMenuItemOpen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/imsl/demo/SeriesAnalysis/Open16.gif")));
        jMenuItemOpen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemOpenActionPerformed(evt);
            }
        });

        jMenuFile.add(jMenuItemOpen);

        jMenuItemReadFlight.setText("Load Flight Data");
        jMenuItemReadFlight.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemReadFlightActionPerformed(evt);
            }
        });

        jMenuFile.add(jMenuItemReadFlight);

        jMenuItemReadTurb.setText("Load Turbulence Data");
        jMenuItemReadTurb.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemReadTurbActionPerformed(evt);
            }
        });

        jMenuFile.add(jMenuItemReadTurb);

        jMenuCopy.setText("Copy");
        jMenuCopy.setToolTipText("Copy image to clipboard");
        jMenuCopy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuCopyActionPerformed(evt);
            }
        });

        jMenuFile.add(jMenuCopy);

        jMenuFile.add(jSeparator);

        jMenuItemExit.setMnemonic('x');
        jMenuItemExit.setText("Exit");
        jMenuItemExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemExitActionPerformed(evt);
            }
        });

        jMenuFile.add(jMenuItemExit);

        jMenuBar.add(jMenuFile);

        jMenuAnalyze.setMnemonic('A');
        jMenuAnalyze.setText("Analyze");
        jMenuAnalyze.setToolTipText("Choose an analysis method");
        jMenuBar.add(jMenuAnalyze);

        jMenuHelp.setMnemonic('H');
        jMenuHelp.setText("Help");
        jMenuHelp.setToolTipText("Get help");
        jMenuItemAbout.setMnemonic('A');
        jMenuItemAbout.setText("About");
        jMenuItemAbout.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/imsl/demo/SeriesAnalysis/Help16.gif")));
        jMenuItemAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemAboutActionPerformed(evt);
            }
        });

        jMenuHelp.add(jMenuItemAbout);

        jMenuBar.add(jMenuHelp);

        setJMenuBar(jMenuBar);

        pack();
    }//GEN-END:initComponents

    private void jMenuCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuCopyActionPerformed
        // File -> Copy
        java.awt.datatransfer.Clipboard clip = getToolkit().getSystemClipboard();
        java.awt.Dimension sz = chart.getScreenSize();
        
        /* create and Image from the chart */
        java.awt.Image image = chart.getComponent().createImage((int)sz.getWidth(), (int)sz.getHeight());
        chart.paintChart(image.getGraphics());
        ImageSelection selection = new ImageSelection(image);
        
        /* This method could use a BufferedImage instead */
        //java.awt.image.BufferedImage bi = new java.awt.image.BufferedImage((int)sz.getWidth(), (int)sz.getHeight(), java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE);
        //chart.paintChart(bi.getGraphics());
        //ImageSelection selection = new ImageSelection(bi);
        
        clip.setContents(selection, null);
    }//GEN-LAST:event_jMenuCopyActionPerformed

    private void jCheckBoxYActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxYActionPerformed
        useSingleY = !useSingleY;
        draw();
    }//GEN-LAST:event_jCheckBoxYActionPerformed

    private void jMenuItemReadTurbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemReadTurbActionPerformed
        // File -> Load turbulence data
        setup("turbulence.csv");
        draw();
    }//GEN-LAST:event_jMenuItemReadTurbActionPerformed

    private void jMenuItemReadFlightActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemReadFlightActionPerformed
        // File -> Load flight test data
        setup("flight_test.csv");
        draw();
    }//GEN-LAST:event_jMenuItemReadFlightActionPerformed

    private void jMenuItemOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemOpenActionPerformed
        // File -> Open
        javax.swing.JFileChooser fileChooser = new javax.swing.JFileChooser();
        fileChooser.setFileSelectionMode(javax.swing.JFileChooser.FILES_AND_DIRECTORIES);
        fileChooser.setCurrentDirectory(new java.io.File("."));
        CSVFileFilter filter = new CSVFileFilter();
        fileChooser.setFileFilter(filter);

        int result = fileChooser.showOpenDialog(this);
        if (result == javax.swing.JFileChooser.CANCEL_OPTION) return;

        java.io.File file = fileChooser.getSelectedFile();
        String fileName = file.getPath();
        if (fileName == null || fileName.equals("")) {
            javax.swing.JOptionPane.showMessageDialog(this,"Invalid File Name","Invalid File Name",javax.swing.JOptionPane.ERROR_MESSAGE);
        } else {
            try {
                readData(new java.io.BufferedReader(new java.io.FileReader(file)));
                updateList();
            } catch (Exception e) {
                javax.swing.JOptionPane.showMessageDialog(this, e.getMessage(), "Exception", javax.swing.JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
            }
        }
    }//GEN-LAST:event_jMenuItemOpenActionPerformed

    private void jListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jListMouseClicked
        if (evt.getClickCount() == 2) {
            draw();
        }
    }//GEN-LAST:event_jListMouseClicked

    private void jMenuItemAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemAboutActionPerformed
        // Help -> About
        String about = "This demonstration extends javax.swing.JFrame instead \n" +
                       "of com.imsl.chart.JFrameChart like most of the other \n" +
                       "demos. Therefore, you do not have access to the standard \n" +
                       "About menus that JFrameChart provides. However, that \n" +
                       "functionality is easily duplicated, as it is here.";
        javax.swing.JOptionPane.showMessageDialog(this, about, "About", javax.swing.JOptionPane.INFORMATION_MESSAGE);
    }//GEN-LAST:event_jMenuItemAboutActionPerformed

    private void jButtonDrawActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDrawActionPerformed
        draw();
    }//GEN-LAST:event_jButtonDrawActionPerformed

    private void jMenuItemExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemExitActionPerformed
        // File -> Exit
        System.exit(0);
    }//GEN-LAST:event_jMenuItemExitActionPerformed

    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
        setVisible(false);
        dispose();
    }//GEN-LAST:event_exitForm

    private void draw() {
        jPanelChart.setChart(new Chart());
        chart = jPanelChart.getChart();
        chart.getBackground().setFillColor(new Color(205,205,205));
        if (jList.isSelectionEmpty() == false) {
            chart.getChartTitle().setTitle("Magnitude vs. Sample Index");
            chart.getChartTitle().setFontStyle(java.awt.Font.BOLD);
            chart.getLegend().setPaint(true);
            chart.getLegend().setViewport(0.85,0.98,0.05,0.25);
            chart.getLegend().setFillOutlineColor(Color.black);
            chart.getLegend().setTitle("Legend");
            if (useSingleY) {
                drawSingle(chart);
            } else {
                drawMulti(chart);
            }
        }
        jPanelChart.repaint();
    }

    private double[] computeX(int num) {
        double[] xx = new double[num];
        for (int k=0; k<num; k++) {
            xx[k] = k;
        }
        return xx;
    }

    private void drawSingle(Chart chart) {
        int[] index = jList.getSelectedIndices();
        AxisXY axis = new AxisXY(chart);
        axis.setViewport(0.1, 0.85, 0.1, 0.9);

        double globalMin = 1e28;
        double globalMax = -1e28;
        for (int i=0; i<index.length; i++) {
            int n = ((double[])data.get(index[i])).length;
            double x[] = computeX(n);
            double y[] = new double[n];
            y = (double[])data.get(index[i]);
            Color color = nextColor(i);

            Data selectData = new Data(axis, x, y);
            String t = (String) params.get(index[i]);
            int ix = t.indexOf("_");
            if (ix != -1) {
                t = t.substring(0,ix) + "\n " + t.substring(ix);
            }
            selectData.setTitle(t);
            selectData.setDataType(Data.DATA_TYPE_LINE);
            selectData.setLineColor(color);
            double ymin = y[getMinimumIndex(y)];
            double ymax = y[getMaximumIndex(y)];
            globalMin = Math.min(globalMin, ymin);
            globalMax = Math.max(globalMax, ymax);
        }
        axis.getAxisX().getAxisLabel().setTextFormat(new java.text.DecimalFormat("####"));
        axis.getAxisY().setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
        axis.getAxisY().setWindow(globalMin,globalMax);
        axis.getAxisY().getAxisLabel().setTextFormat(new java.text.DecimalFormat("0.00"));
    }

    private void drawMulti(Chart chart) {
        int[] index = jList.getSelectedIndices();
        for (int i = 0; i < index.length; i++) {
            createLine(chart, index[i], i, index.length);
        }
    }

    private void createLine(Chart chart, int index, int c, int num) {
        int n = ((double[]) data.get(index)).length;
        double tCross = 0.0;
        double x[] = new double[n];
        double y[] = new double[n];
        x = computeX(n);
        y = (double[]) data.get(index);
        Color color = nextColor(c);
        AxisXY axis = new AxisXY(chart);
        Data selectData = new Data(axis, x, y);
        double x0 = 0.1 + Math.sqrt(num-1)*0.17;
        axis.setViewport(x0, 0.85, 0.1, 0.9);
        axis.getAxisY().setTextColor(color);
        selectData.setDataType(Data.DATA_TYPE_LINE);
        selectData.setLineColor(color);
        tCross = (double) c * (x[n-1] * -.20);
        double ymin = y[getMinimumIndex(y)];
        double ymax = y[getMaximumIndex(y)];
        double buffer = (ymax-ymin)*.05;
        axis.setCross(tCross, ymin-buffer);
        axis.getAxisX().getAxisLabel().setTextFormat(new java.text.DecimalFormat("####"));
        axis.getAxisY().setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
        axis.getAxisY().setWindow(ymin-buffer,ymax+buffer);
        axis.getAxisY().getAxisLabel().setTextFormat(new java.text.DecimalFormat("0.00"));
        
        // only draw the X axis once
        if (c != 0) {
            axis.getAxisX().setPaint(false);
        }
        
        // add title to axis
        //axis.getAxisY().getAxisUnit().setTitle((String) params.get(index));
        // add title in legend
        //selectData.setTitle((String) params.get(index));
        // add title, but split new lines on the _ character
        String t = (String) params.get(index);
        int ix = t.indexOf("_");
        if (ix != -1) {
            t = t.substring(0,ix) + "\n " + t.substring(ix);
        }
        selectData.setTitle(t);
    }

    /** This method takes the name of a class to be used to analyze the data.
     *  The class itself exists in the package com.imsl.demo.SeriesAnalysis.Lib
     *  Since reflection isn't everyday Java knowledge, here is what's going on:
     *
     *  a) a Class is created (classMain) from the String parameter. This is a
     *  fully qualified name like com.imsl.demo.SeriesAnalysis.Lib.Abs
     *
     *  b) a Cunstructor is created with a Class[] parameter of the type required
     *  by the class we're instantiating (a JFrame here)
     *
     *  c) an Object is created using this Constructor. So far, we've executed
     *  this line of code:  Abs o = new Abs(this);
     *
     *  d) next we make two method calls by creating a Method, which takes
     *  a String name parameter and a Class[] containing the parameters to pass.
     *  And then the method is invoked for the Object just instantiated. These
     *  lines are equivalent to:  o.setData(params,data);  o.show();
     *
     *  This code block can throw ClassNotFoundException, NoSuchMethodException,
     *  InstantiationException, and IllegalAccessException exceptions. Instead
     *  of treating each, we'll just report them.
     */
    private void analyze(String main) {
        try {
            Class classMain = Class.forName(main);
            java.lang.reflect.Constructor co = classMain.getConstructor(new Class[] {javax.swing.JFrame.class});
            Object o = co.newInstance(new Object[] {this});
            java.lang.reflect.Method methodSetData = classMain.getMethod("setData", new Class[]{ArrayList.class, ArrayList.class});
            methodSetData.invoke(o, new Object[]{params, data});
            java.lang.reflect.Method methodShow = classMain.getMethod("show", (Class[])null);
            methodShow.invoke(o, new Object[]{});
        } catch (Exception e) {
            String name = e.toString().substring(10,e.toString().indexOf(':'));
            javax.swing.JOptionPane.showMessageDialog(this, e.getMessage(), name, javax.swing.JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        }
    }

    /** This method is called by analysis functions to update the main list
     * of parameters when a new vector as been added by the function.
     */
    public void updateList() {
        jList.setVisibleRowCount(params.size());
        jList.setPreferredSize(jList.getPreferredScrollableViewportSize());
        jList.setListData(params.toArray());
    }

    public void setData(ArrayList dataList) {
        this.data = dataList;
    }

    public void setParams(ArrayList paramList) {
        this.params = paramList;
    }

    private int getMinimumIndex(double[] array){
        int j = 0;
        for (int i = 0; i < array.length; i++) {
            if (array[i] < array[j]) j = i;
        }
        return j;
    }

    private int getMaximumIndex(double[] array){
        int j = 0;
        for (int i = 0; i < array.length; i++) {
            if (array[i] > array[j]) j = i;
        }
        return j;
    }
    
    private void setup(String fileName) {
        // Read the file
        try {
            java.io.InputStream is = getClass().getResourceAsStream(fileName);
            readData(new java.io.BufferedReader(new java.io.InputStreamReader(is)));
        } catch (Exception e) {
            javax.swing.JOptionPane.showMessageDialog(this, e.getMessage(), "Exception", javax.swing.JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        }

        // set up the user interface
        updateList();
}

    private void readData(java.io.BufferedReader in) throws java.io.IOException, java.text.ParseException {
        // Read a csv file
        String line;
        ArrayList tmpArrayList = null;
        double[] tmpArray;
        
        if ((line = in.readLine()) != null) {
            StringTokenizer st = new StringTokenizer(line, ",");
            params = new ArrayList();
            while (st.hasMoreTokens()) {
                params.add((String) st.nextToken().trim());
            }

            data = new ArrayList(params.size());
            for (int i = 0; i < params.size(); i++) {
                data.add(new ArrayList());
            }

            while((line = in.readLine()) != null) {
                StringTokenizer datalistSt = new StringTokenizer(line, ",");
                for (int i = 0; i < params.size(); i++) {
                    tmpArrayList = (ArrayList)data.get(i);
                    tmpArrayList.add(new Double(datalistSt.nextToken()));
                    data.set(i,(ArrayList)tmpArrayList);
                }
            }

            for (int i = 0; i < params.size(); i++) {
                tmpArrayList = (ArrayList)data.get(i);
                tmpArrayList.trimToSize();
                tmpArray = new double[tmpArrayList.size()];
                for (int j = 0; j < tmpArray.length; j++) {
                    tmpArray[j]= ((Double)tmpArrayList.get(j)).doubleValue();
                }
                data.set(i,tmpArray);
            }
        }
        in.close();
    }

    private Color nextColor(int i) {
        Color c = colorList[i%colorList.length];
        return c;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        boolean exitOnClose = true;
        if (args.length > 0  && args[0].equals("-noexit")) {
            exitOnClose = false;
        }
        new SeriesAnalysis(exitOnClose).show();
    }

    class CSVFileFilter extends javax.swing.filechooser.FileFilter {
        public boolean accept(java.io.File f) {
            boolean b = false;
            if (f.getName().toLowerCase().endsWith(".csv") || f.isDirectory()) {
                b = true;
            }
            return b;
        }

        public String getDescription() {
            return "Comma Separated Values (.csv)";
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonDraw;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JSeparator jSeparator;
    private javax.swing.JMenuItem jMenuItemAbout;
    private javax.swing.JMenuItem jMenuItemReadTurb;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JMenu jMenuAnalyze;
    private com.imsl.chart.JPanelChart jPanelChart;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JMenuItem jMenuItemOpen;
    private javax.swing.JMenuBar jMenuBar;
    private javax.swing.JCheckBox jCheckBoxY;
    private javax.swing.JList jList;
    private javax.swing.JMenu jMenuFile;
    private javax.swing.JMenu jMenuHelp;
    private javax.swing.JMenuItem jMenuCopy;
    private javax.swing.JMenuItem jMenuItemReadFlight;
    private javax.swing.JMenuItem jMenuItemExit;
    // End of variables declaration//GEN-END:variables

    class ImageSelection implements java.awt.datatransfer.Transferable {
        public ImageSelection(java.awt.Image image) {
            theImage = image;
        }
        public java.awt.datatransfer.DataFlavor[] getTransferDataFlavors() {
            return new java.awt.datatransfer.DataFlavor[] {
                java.awt.datatransfer.DataFlavor.imageFlavor
            };
        }
        public boolean isDataFlavorSupported(java.awt.datatransfer.DataFlavor flavor) {
            return flavor.equals(java.awt.datatransfer.DataFlavor.imageFlavor);
        }
        public Object getTransferData(java.awt.datatransfer.DataFlavor flavor) throws java.awt.datatransfer.UnsupportedFlavorException {
            if (flavor.equals(java.awt.datatransfer.DataFlavor.imageFlavor)) {
                return theImage;
            } else {
                throw new java.awt.datatransfer.UnsupportedFlavorException(flavor);
            }
        }
        private java.awt.Image theImage;
    }           
}