/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package vortex.gui;

import sandbox.dataIO.DatasetImporter;
import sandbox.dataIO.DatasetStub;
import sandbox.dataIO.ImportConfigObject;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import samusik.glasscmp.GlassDialog;
import samusik.objecttable.TableModelReorderHandler;
import sandbox.clustering.Dataset;
import vortex.util.Config;
import vortex.util.ConnectionManager;
import util.DefaultEntry;
import util.IO;
import util.logger;

/**
 *
 * @author Nikolay
 */
public class dlgImportDataset extends GlassDialog {

    private List<DatasetStub> stubs = new LinkedList<>();
    Entry<String, Color>[] options = new Entry[]{
        new DefaultEntry<>("Main", new Color(120, 194, 235)),
        new DefaultEntry<>("Cofounding", Color.YELLOW),
        new DefaultEntry<>("Skip", Color.GRAY),};

    public dlgImportDataset(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        
        jPanel2.setVisible(false);
        tab.setModel(new DefaultTableModel(new String[]{"#", "Option", "Short Name", "Long Name"}, 0) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return column == 3;
            }
        });
        tab.getColumnModel().getColumn(0).setPreferredWidth(50);
        tab.getColumnModel().getColumn(1).setPreferredWidth(50);
        tab.getColumnModel().getColumn(2).setPreferredWidth(200);
        tab.getColumnModel().getColumn(3).setPreferredWidth(1000);
        tab.getColumnModel().getColumn(0).setMaxWidth(50);
        tab.getColumnModel().getColumn(1).setMaxWidth(50);
        tab.getColumnModel().getColumn(2).setMaxWidth(200);
        // tab.getColumnModel().getColumn(2).setPreferredWidth(1000);
        tab.setTransferHandler(new TableModelReorderHandler());
        tab.setDragEnabled(true);
        tab.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int row = tab.rowAtPoint(e.getPoint());
                int col = tab.columnAtPoint(e.getPoint());
                if (col == 1 && row < tab.getRowCount()) {
                    int val = (Integer) ((DefaultTableModel) tab.getModel()).getValueAt(row, col);
                    if (e.getButton() == MouseEvent.BUTTON1) {
                        val++;
                        if (val == options.length) {
                            val = 0;
                        }
                    } else {
                        val--;
                        if (val == -1) {
                            val += options.length;
                        }
                    }

                    ((DefaultTableModel) tab.getModel()).setValueAt(val, row, col);
                }
            }
        });
        tab.getColumnModel().getColumn(1).setCellRenderer(new TableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                JLabel lbl = new JLabel() {
                    @Override
                    protected void paintComponent(Graphics g) {
                        g.setColor(this.getBackground());
                        g.fillRect(0, 0, this.getWidth(), this.getHeight());
                    }
                };
                lbl.setText("");
                int idx = (Integer) ((DefaultTableModel) tab.getModel()).getValueAt(row, column);
                lbl.setBackground(idx < options.length ? options[idx].getValue() : Color.GREEN);
                return lbl;
            }
        });

        tp.setEnabledAt(1, false);
        tp.setEnabledAt(2, false);
    }

    /**
     * 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.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        buttonGroup1 = new javax.swing.ButtonGroup();
        buttonGroup2 = new javax.swing.ButtonGroup();
        buttonGroup3 = new javax.swing.ButtonGroup();
        buttonGroup4 = new javax.swing.ButtonGroup();
        buttonGroup5 = new javax.swing.ButtonGroup();
        jPopupMenu1 = new javax.swing.JPopupMenu();
        pmiPaste = new javax.swing.JMenuItem();
        buttonGroup6 = new javax.swing.ButtonGroup();
        popImport = new javax.swing.JPopupMenu();
        pmiImport = new javax.swing.JMenuItem();
        tp = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        cmdSelectProfileTable = new samusik.glasscmp.GlassButton();
        scpColumns = new javax.swing.JScrollPane();
        tab = new javax.swing.JTable();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        glassButton2 = new samusik.glasscmp.GlassButton();
        jPanel6 = new javax.swing.JPanel();
        jLabel13 = new javax.swing.JLabel();
        jPanel3 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        rbTransfNone = new javax.swing.JRadioButton();
        rbPercentile = new javax.swing.JRadioButton();
        jLabel5 = new javax.swing.JLabel();
        jRadioButton4 = new javax.swing.JRadioButton();
        rbASINH = new javax.swing.JRadioButton();
        txtNoiseTheshold = new samusik.glasscmp.GlassEdit();
        jLabel10 = new javax.swing.JLabel();
        rbRescaleSeparately = new javax.swing.JRadioButton();
        jRadioButton8 = new javax.swing.JRadioButton();
        glassButton1 = new samusik.glasscmp.GlassButton();
        rbSD = new javax.swing.JRadioButton();
        rbDoubleASINH = new javax.swing.JRadioButton();
        jLabel12 = new javax.swing.JLabel();
        txtPercentile2 = new samusik.glasscmp.GlassEdit();
        jLabel14 = new javax.swing.JLabel();
        jLabel15 = new javax.swing.JLabel();
        txtScalingFactor = new samusik.glasscmp.GlassEdit();
        chkNoiseThreshold = new javax.swing.JCheckBox();
        jPanel5 = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();
        chkLimitRowNum = new javax.swing.JCheckBox();
        txtLimitRow = new samusik.glasscmp.GlassEdit();
        jLabel9 = new javax.swing.JLabel();
        cmdImport1 = new samusik.glasscmp.GlassButton();
        txtDatasetName = new samusik.glasscmp.GlassEdit();
        jLabel11 = new javax.swing.JLabel();
        chkEuclLen = new javax.swing.JCheckBox();
        txtEuclLen = new samusik.glasscmp.GlassEdit();
        jRadioButton1 = new javax.swing.JRadioButton();
        rbSeparateDs = new javax.swing.JRadioButton();

        pmiPaste.setText("Paste");
        pmiPaste.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pmiPasteActionPerformed(evt);
            }
        });
        jPopupMenu1.add(pmiPaste);

        pmiImport.setText("Import Short Column Names");
        pmiImport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pmiImportActionPerformed(evt);
            }
        });
        popImport.add(pmiImport);

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Import Dataset");
        getContentPane().setLayout(new java.awt.GridBagLayout());

        jPanel1.setLayout(new java.awt.GridBagLayout());

        cmdSelectProfileTable.setText("Select source file(s)");
        cmdSelectProfileTable.setMaximumSize(new java.awt.Dimension(150, 30));
        cmdSelectProfileTable.setMinimumSize(new java.awt.Dimension(150, 30));
        cmdSelectProfileTable.setPreferredSize(new java.awt.Dimension(150, 30));
        cmdSelectProfileTable.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdSelectProfileTableActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.ipadx = -9;
        jPanel1.add(cmdSelectProfileTable, gridBagConstraints);

        scpColumns.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                scpColumnsMouseReleased(evt);
            }
        });

        tab.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "#", "Type", "Short Name", "Long Name"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.Integer.class, java.lang.Integer.class, java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, true, true
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        tab.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                tabMouseReleased(evt);
            }
        });
        scpColumns.setViewportView(tab);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.ipadx = 851;
        gridBagConstraints.ipady = 341;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanel1.add(scpColumns, gridBagConstraints);

        jPanel2.setOpaque(false);
        jPanel2.setLayout(new java.awt.GridBagLayout());

        jLabel1.setText("Below are the columns that are common to all files. You reorder them by dragging, change long names and toggle between the following options:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 8);
        jPanel2.add(jLabel1, gridBagConstraints);

        jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/azure 16x16.png"))); // NOI18N
        jLabel3.setText("Feature variable - used for clustering");
        jLabel3.setToolTipText("This variable will be imported as a part of the main dataset. It will be taken into account for clustering and scoring.");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(6, 6, 6, 6);
        jPanel2.add(jLabel3, gridBagConstraints);

        jLabel4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/yellow 16x16.png"))); // NOI18N
        jLabel4.setText("Functional variable - does not affect clustering");
        jLabel4.setToolTipText("Functional variables are imported, but will NOT be taken into account for clustering and scoring. However, you will be able to analyse the behaviour of this variables across clusters");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(7, 7, 7, 7);
        jPanel2.add(jLabel4, gridBagConstraints);

        jLabel6.setIcon(new javax.swing.ImageIcon(getClass().getResource("/grey 16x16.png"))); // NOI18N
        jLabel6.setText("Skipped - will not be imported");
        jLabel6.setToolTipText("This column will be skipped");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(7, 7, 7, 7);
        jPanel2.add(jLabel6, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.ipadx = 138;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        jPanel1.add(jPanel2, gridBagConstraints);

        glassButton2.setText("Next");
        glassButton2.setMaximumSize(new java.awt.Dimension(60, 28));
        glassButton2.setMinimumSize(new java.awt.Dimension(60, 28));
        glassButton2.setPreferredSize(new java.awt.Dimension(60, 28));
        glassButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                glassButton2ActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 1, 2);
        jPanel1.add(glassButton2, gridBagConstraints);

        jPanel6.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 0, 51), 2));
        jPanel6.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jPanel6MouseReleased(evt);
            }
        });
        jPanel6.setLayout(new java.awt.GridBagLayout());

        jLabel13.setForeground(new java.awt.Color(255, 0, 51));
        jLabel13.setText("<html><b>Paste the panel here</b></html>");
        jLabel13.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jLabel13MouseReleased(evt);
            }
        });
        jPanel6.add(jLabel13, new java.awt.GridBagConstraints());

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanel1.add(jPanel6, gridBagConstraints);

        tp.addTab("1) Select files and parameters", jPanel1);

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

        jLabel2.setText("<html><b>Noise threshold</b><br>Sets the features that have absolute values below the theshold to zero. This may significantly reduce the infuence of noise on clustering.</html>");
        jLabel2.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        jLabel2.setAlignmentY(0.0F);
        jLabel2.setMinimumSize(new java.awt.Dimension(200, 100));
        jLabel2.setPreferredSize(new java.awt.Dimension(200, 100));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridheight = 2;
        jPanel3.add(jLabel2, gridBagConstraints);

        buttonGroup2.add(rbTransfNone);
        rbTransfNone.setText("none");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        jPanel3.add(rbTransfNone, gridBagConstraints);

        buttonGroup3.add(rbPercentile);
        rbPercentile.setText("percentile (0.0-100.0)");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        jPanel3.add(rbPercentile, gridBagConstraints);

        jLabel5.setText("<html><b>Normalization</b><br>Equalizes variance between different files, may help to remove the systematic differences in signal between samples</html>");
        jLabel5.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        jLabel5.setMinimumSize(new java.awt.Dimension(200, 100));
        jLabel5.setPreferredSize(new java.awt.Dimension(200, 100));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.gridheight = 2;
        jPanel3.add(jLabel5, gridBagConstraints);

        buttonGroup3.add(jRadioButton4);
        jRadioButton4.setSelected(true);
        jRadioButton4.setText("none");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        jPanel3.add(jRadioButton4, gridBagConstraints);

        buttonGroup2.add(rbASINH);
        rbASINH.setSelected(true);
        rbASINH.setText("arcsinh(x/f)");
        rbASINH.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                rbASINHActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        jPanel3.add(rbASINH, gridBagConstraints);

        txtNoiseTheshold.setText("1.0");
        txtNoiseTheshold.setMinimumSize(new java.awt.Dimension(50, 26));
        txtNoiseTheshold.setPreferredSize(new java.awt.Dimension(50, 26));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridheight = 2;
        jPanel3.add(txtNoiseTheshold, gridBagConstraints);

        jLabel10.setText("<html><b>Feature rescaling</b><br>Equalizes the variance of each of the feature variables, which in turn ensures that all the features  contribute equally to the clustering</html>");
        jLabel10.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        jLabel10.setMinimumSize(new java.awt.Dimension(200, 100));
        jLabel10.setPreferredSize(new java.awt.Dimension(200, 100));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.gridheight = 3;
        jPanel3.add(jLabel10, gridBagConstraints);

        buttonGroup5.add(rbRescaleSeparately);
        rbRescaleSeparately.setText("rescale each file separately");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 9;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        jPanel3.add(rbRescaleSeparately, gridBagConstraints);

        buttonGroup5.add(jRadioButton8);
        jRadioButton8.setSelected(true);
        jRadioButton8.setText("none");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        jPanel3.add(jRadioButton8, gridBagConstraints);

        glassButton1.setText("Next");
        glassButton1.setMaximumSize(new java.awt.Dimension(100, 28));
        glassButton1.setMinimumSize(new java.awt.Dimension(100, 28));
        glassButton1.setPreferredSize(new java.awt.Dimension(100, 28));
        glassButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                glassButton1ActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 10;
        gridBagConstraints.gridwidth = 4;
        jPanel3.add(glassButton1, gridBagConstraints);

        buttonGroup3.add(rbSD);
        rbSD.setText("standard deviation (SD)");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        jPanel3.add(rbSD, gridBagConstraints);

        buttonGroup2.add(rbDoubleASINH);
        rbDoubleASINH.setText("double arcsinh(x/f)");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        jPanel3.add(rbDoubleASINH, gridBagConstraints);

        jLabel12.setText("<html><b>Numerical transformation</b><br>Helps to bring non-normally distributed features (e.g. fold-changes, protein concentrations, intensities) to a normal scale.\n</html>");
        jLabel12.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        jLabel12.setAlignmentY(0.0F);
        jLabel12.setMinimumSize(new java.awt.Dimension(200, 100));
        jLabel12.setPreferredSize(new java.awt.Dimension(200, 100));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 3;
        jPanel3.add(jLabel12, gridBagConstraints);

        txtPercentile2.setText("99.0");
        txtPercentile2.setMinimumSize(new java.awt.Dimension(50, 26));
        txtPercentile2.setPreferredSize(new java.awt.Dimension(50, 26));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        jPanel3.add(txtPercentile2, gridBagConstraints);

        jLabel14.setText("f = ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        jPanel3.add(jLabel14, gridBagConstraints);

        jLabel15.setText("<html><b>Numerical transformation</b><br>Helps to bring non-normally distributed features (e.g. fold-changes, protein concentrations, intensities) to a normal scale.\n</html>");
        jLabel15.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        jLabel15.setAlignmentY(0.0F);
        jLabel15.setMinimumSize(new java.awt.Dimension(200, 100));
        jLabel15.setPreferredSize(new java.awt.Dimension(200, 100));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 3;
        jPanel3.add(jLabel15, gridBagConstraints);

        txtScalingFactor.setText("5.0");
        txtScalingFactor.setMinimumSize(new java.awt.Dimension(50, 26));
        txtScalingFactor.setPreferredSize(new java.awt.Dimension(50, 26));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 1;
        jPanel3.add(txtScalingFactor, gridBagConstraints);

        chkNoiseThreshold.setSelected(true);
        chkNoiseThreshold.setText("apply noise threshold of");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        jPanel3.add(chkNoiseThreshold, gridBagConstraints);

        tp.addTab("2) Transformation and Scaling", jPanel3);

        jPanel5.setLayout(new java.awt.GridBagLayout());

        jPanel4.setLayout(new java.awt.GridBagLayout());

        chkLimitRowNum.setText("Import max. ");
        chkLimitRowNum.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        jPanel4.add(chkLimitRowNum, gridBagConstraints);

        txtLimitRow.setText("1000");
        txtLimitRow.setMinimumSize(new java.awt.Dimension(50, 26));
        txtLimitRow.setPreferredSize(new java.awt.Dimension(50, 26));
        txtLimitRow.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtLimitRowActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 0, 0);
        jPanel4.add(txtLimitRow, gridBagConstraints);

        jLabel9.setText("rows  from each file after filtering");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 0, 0);
        jPanel4.add(jLabel9, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        jPanel5.add(jPanel4, gridBagConstraints);

        cmdImport1.setText("Finalize Import");
        cmdImport1.setMaximumSize(new java.awt.Dimension(150, 28));
        cmdImport1.setMinimumSize(new java.awt.Dimension(150, 28));
        cmdImport1.setPreferredSize(new java.awt.Dimension(150, 28));
        cmdImport1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdImport1ActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 10;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.insets = new java.awt.Insets(11, 0, 1, 0);
        jPanel5.add(cmdImport1, gridBagConstraints);

        txtDatasetName.setMinimumSize(new java.awt.Dimension(50, 26));
        txtDatasetName.setPreferredSize(new java.awt.Dimension(50, 26));
        txtDatasetName.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtDatasetNameActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 0, 0);
        jPanel5.add(txtDatasetName, gridBagConstraints);

        jLabel11.setText("Name of the new dataset: ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        jPanel5.add(jLabel11, gridBagConstraints);

        chkEuclLen.setText("Minimal Euclidean length of the profile:");
        chkEuclLen.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
        jPanel5.add(chkEuclLen, gridBagConstraints);

        txtEuclLen.setText("1.0");
        txtEuclLen.setMinimumSize(new java.awt.Dimension(50, 26));
        txtEuclLen.setPreferredSize(new java.awt.Dimension(50, 26));
        txtEuclLen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtEuclLenActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(0, 7, 5, 0);
        jPanel5.add(txtEuclLen, gridBagConstraints);

        buttonGroup6.add(jRadioButton1);
        jRadioButton1.setSelected(true);
        jRadioButton1.setText("Merge all files into one dataset");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 9;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        jPanel5.add(jRadioButton1, gridBagConstraints);

        buttonGroup6.add(rbSeparateDs);
        rbSeparateDs.setText("Create a seperate dataset for each file");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 9;
        jPanel5.add(rbSeparateDs, gridBagConstraints);

        tp.addTab("Row filtering", jPanel5);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        getContentPane().add(tp, gridBagConstraints);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cmdSelectProfileTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdSelectProfileTableActionPerformed
        HashMap<String, Integer> hm = new HashMap<>();
        JFileChooser fc = new JFileChooser();
        fc.setMultiSelectionEnabled(true);
        fc.setFileFilter(new FileNameExtensionFilter("Delimited text (CSV/TXT), Flow Cytomerty (FCS)", "csv", "txt", "fcs"));
        fc.setSelectedFile(Config.getFilePath("Import files"));

        if (fc.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) {
            return;
        }
        
        jPanel2.setVisible(true);
        
        if (fc.getSelectedFiles().length == 0) {
            return;
        }
        Config.putFilePath("Import files", fc.getSelectedFile());

        int cnt = ((DefaultTableModel) tab.getModel()).getRowCount();
        for (int i = 0; i < cnt; i++) {
            ((DefaultTableModel) tab.getModel()).removeRow(0);
        }

        stubs = new LinkedList<>();
        for (File f : fc.getSelectedFiles()) {
            if (txtDatasetName.getText().length() < 2) {
                txtDatasetName.setText(f.getName().substring(0, f.getName().length() - 4));
            }
            try {
                DatasetStub stub = (f.getName().toLowerCase().endsWith(".fcs")) ? DatasetStub.createFromFCS(f) : new vortex.util.DatasetStubTxtFJ(f);
                for (String s : stub.getShortColumnNames()) {
                    if (hm.get(s) == null) {
                        hm.put(s, new Integer(0));
                    }
                    hm.put(s, hm.get(s) + 1);
                }
                stubs.add(stub);
            } catch (Exception e) {
                JOptionPane.showMessageDialog(this, "File import failed, skipping: " + f.getName() + ", reason: \n" + e.toString());
                e.printStackTrace();
            }
        }
        if (stubs.isEmpty()) {
            return;
        }
        for (int i = 0; i < stubs.get(0).getShortColumnNames().length; i++) {
            String s = stubs.get(0).getShortColumnNames()[i];
            if (hm.get(s) >= stubs.size()) {
                ((DefaultTableModel) tab.getModel()).addRow(new Object[]{i, (s.equalsIgnoreCase("Time")||s.equalsIgnoreCase("beadDist")||s.equalsIgnoreCase("Cell_length")||s.startsWith("(Pt1")||s.startsWith("(Pd1")||s.startsWith("(Ir19")) ? 2 : 0, s, stubs.get(0).getLongColumnNames()[i]});
            }
        }
        
        if (tab.getRowCount() < 2) {
            JOptionPane.showMessageDialog(this, "Less than 2 columns that match across all files could be detected.\nCannot proceed - try selecting a different set of files");
        } else {
            tp.setEnabledAt(1, true);
        }

    }//GEN-LAST:event_cmdSelectProfileTableActionPerformed

    private String[] getFeatureColumns() {
        DefaultTableModel tm = ((DefaultTableModel) tab.getModel());
        ArrayList<String> al = new ArrayList<>();
        for (int i = 0; i < tm.getRowCount(); i++) {
            if (((int) tm.getValueAt(i, 1)) == 0) {
                al.add(((String) tm.getValueAt(i, 2)));
            }
        }
        return al.toArray(new String[al.size()]);
    }

    private String[] getSideColumns() {
        DefaultTableModel tm = ((DefaultTableModel) tab.getModel());
        ArrayList<String> al = new ArrayList<>();
        for (int i = 0; i < tm.getRowCount(); i++) {
            if (((int) tm.getValueAt(i, 1)) == 1) {
                al.add(((String) tm.getValueAt(i, 2)));
            }
        }
        return al.toArray(new String[al.size()]);
    }

    private double[] getFilteringArrayList() {
        return null;
    }

    private String[] getFilteringColumns() {
        return null;
    }

    private double[] getTargetRange() {
        return null;
    }

    private void txtLimitRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtLimitRowActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_txtLimitRowActionPerformed

    private void cmdImport1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdImport1ActionPerformed

        ImportConfigObject.RescaleType rescale = ImportConfigObject.RescaleType.NONE;
        if (rbPercentile.getModel().isSelected()) {
            rescale = ImportConfigObject.RescaleType.QUANTILE;
        }
        if (rbSD.getModel().isSelected()) {
            rescale = ImportConfigObject.RescaleType.SD;
        }
        try {
             if (txtDatasetName.getText().length() < 5) {
                    logger.showException(new IllegalStateException("Dataset name should be at least 5 characters long"));
                }
            for (String s : ConnectionManager.getStorageEngine().getAvailableDatasetNames()) {
               
                if (s.equals(txtDatasetName.getText())) {
                    logger.showException(new IllegalStateException("Dataset with this name already exists. Please choose a different name"));
                    return;
                }
            }
        } catch (SQLException e) {
            logger.showException(e);
        }

        ImportConfigObject o = new ImportConfigObject(txtDatasetName.getText(),
                getFeatureColumns(),
                getSideColumns(),
                rescale,
                rbTransfNone.getModel().isSelected() ? ImportConfigObject.TransformationType.NONE : (rbDoubleASINH.getModel().isSelected() ? ImportConfigObject.TransformationType.DOUBLE_ASINH : ImportConfigObject.TransformationType.ASINH),
                Double.parseDouble(txtScalingFactor.getText()),
                Double.parseDouble(txtPercentile2.getText()) / 100.0,
                rbRescaleSeparately.getModel().isSelected(),
                chkLimitRowNum.getModel().isSelected() ? Integer.parseInt(txtLimitRow.getText()) : -1,
                chkEuclLen.isSelected() ? Double.parseDouble(txtEuclLen.getText()) : 0, 
                chkNoiseThreshold.isSelected() ? Double.parseDouble(txtNoiseTheshold.getText()) : -1
        );

        if (rbSeparateDs.isSelected()) {
            try {
                for (DatasetStub stub : stubs) {
                    o.datasetName = stub.getFileName();
                    Dataset ds = DatasetImporter.importDataset(new DatasetStub[]{stub}, o);
                    ConnectionManager.getStorageEngine().saveDataset(ds, true);
                    Config.addDatasetIDsForLoading(ds.getName());
                }
            } catch (SQLException e) {
                logger.showException(e);
            }
        } else {
            try {
                Dataset ds = DatasetImporter.importDataset(stubs.toArray(new DatasetStub[stubs.size()]), o);
                ConnectionManager.getStorageEngine().saveDataset(ds, true);
                Config.addDatasetIDsForLoading(ds.getName());
                JOptionPane.showMessageDialog(this, "Import completed!");
            } catch (SQLException e) {
                logger.showException(e);
            }
        }

        this.setVisible(false);
    }//GEN-LAST:event_cmdImport1ActionPerformed

    private void glassButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_glassButton2ActionPerformed
        tp.setSelectedIndex(1);
    }//GEN-LAST:event_glassButton2ActionPerformed

    private void glassButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_glassButton1ActionPerformed
        tp.setEnabledAt(2, true);
        tp.setSelectedIndex(2);
    }//GEN-LAST:event_glassButton1ActionPerformed

    private void txtDatasetNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtDatasetNameActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_txtDatasetNameActionPerformed

    private void jPanel6MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanel6MouseReleased
        jPopupMenu1.show(jPanel6, evt.getX(), evt.getY());
    }//GEN-LAST:event_jPanel6MouseReleased

    private void jLabel13MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabel13MouseReleased
        jPopupMenu1.show(jLabel13, evt.getX(), evt.getY());
    }//GEN-LAST:event_jLabel13MouseReleased

    private void pmiPasteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pmiPasteActionPerformed
        try {
            Dataset.FeaturePanel fp = (Dataset.FeaturePanel) getToolkit().getSystemClipboard().getData(Dataset.FeaturePanel.panelFlavor);
            for (int i = 0; i < tab.getRowCount(); i++) {
                tab.setValueAt(2, i, 1);
            }

            for (String s : fp.featurePanel) {
                for (int i = 0; i < tab.getRowCount(); i++) {
                    String shortName = s.substring(s.indexOf(":")+1, s.length());
                    if (tab.getValueAt(i, 2).equals(shortName)) {
                        tab.setValueAt(0, i, 1);
                    }
                }
            }

            for (String s : fp.functionalPanel) {
                for (int i = 0; i < tab.getRowCount(); i++) {
                    String shortName = s.substring(s.indexOf(":")+1, s.length());
                    if (tab.getValueAt(i, 2).equals(shortName)) {
                        tab.setValueAt(1, i, 1);
                    }
                }
            }

        } catch (UnsupportedFlavorException | IOException e) {
           try {
            String fp = (String) getToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
            
            
            String [] lines = fp.split("\n");
            
            if(lines.length!=tab.getRowCount()+1){
                JOptionPane.showMessageDialog(null, "invalid length of the pasted text ("+lines.length + "), should be " + (tab.getRowCount()+1));
                return;
            }
            
            for (int i = 1; i < lines.length; i++) {
                String line = lines[i];
               
                int val = Integer.parseInt(line.split("\t")[1]);
               
                tab.setValueAt(Math.min(val,2), i-1, 1);
            }
            

        } catch (UnsupportedFlavorException | IOException ex) {
            logger.showException(ex);
        }
        }
        
        

    }//GEN-LAST:event_pmiPasteActionPerformed

    private void txtEuclLenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtEuclLenActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_txtEuclLenActionPerformed

    private void pmiImportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pmiImportActionPerformed
        File f = IO.chooseFileWithDialog("Import DS columns", "Tab/Comma-delimited", new String[]{"csv","txt"}, rootPaneCheckingEnabled);
        if(f!=null){
            try{
                int i = 0;
            for (String s : IO.getListOfStringsFromStream(new FileInputStream(f))) {
               
               String [] s2 = s.split("[\t,]+");
               if(s.startsWith("#")){
                   continue;
               }
                for (int j = 1; j < s2.length; j++) {
                    if(j==1){
                        tab.setValueAt(Integer.parseInt(s2[j]), i, j);
                    }else{
                        tab.setValueAt(s2[j], i, j);
                    }
                }
                i++;
            }
            }catch(FileNotFoundException e){
                logger.showException(e);
            }
        }
    }//GEN-LAST:event_pmiImportActionPerformed

    private void scpColumnsMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_scpColumnsMouseReleased
    }//GEN-LAST:event_scpColumnsMouseReleased

    private void tabMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tabMouseReleased
        if(evt.getButton()==MouseEvent.BUTTON3) {
            popImport.show(tab, evt.getX(), evt.getY());
        }
    }//GEN-LAST:event_tabMouseReleased

    private void rbASINHActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rbASINHActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_rbASINHActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.ButtonGroup buttonGroup2;
    private javax.swing.ButtonGroup buttonGroup3;
    private javax.swing.ButtonGroup buttonGroup4;
    private javax.swing.ButtonGroup buttonGroup5;
    private javax.swing.ButtonGroup buttonGroup6;
    private javax.swing.JCheckBox chkEuclLen;
    private javax.swing.JCheckBox chkLimitRowNum;
    private javax.swing.JCheckBox chkNoiseThreshold;
    private samusik.glasscmp.GlassButton cmdImport1;
    private samusik.glasscmp.GlassButton cmdSelectProfileTable;
    private samusik.glasscmp.GlassButton glassButton1;
    private samusik.glasscmp.GlassButton glassButton2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPopupMenu jPopupMenu1;
    private javax.swing.JRadioButton jRadioButton1;
    private javax.swing.JRadioButton jRadioButton4;
    private javax.swing.JRadioButton jRadioButton8;
    private javax.swing.JMenuItem pmiImport;
    private javax.swing.JMenuItem pmiPaste;
    private javax.swing.JPopupMenu popImport;
    private javax.swing.JRadioButton rbASINH;
    private javax.swing.JRadioButton rbDoubleASINH;
    private javax.swing.JRadioButton rbPercentile;
    private javax.swing.JRadioButton rbRescaleSeparately;
    private javax.swing.JRadioButton rbSD;
    private javax.swing.JRadioButton rbSeparateDs;
    private javax.swing.JRadioButton rbTransfNone;
    private javax.swing.JScrollPane scpColumns;
    private javax.swing.JTable tab;
    private javax.swing.JTabbedPane tp;
    private samusik.glasscmp.GlassEdit txtDatasetName;
    private samusik.glasscmp.GlassEdit txtEuclLen;
    private samusik.glasscmp.GlassEdit txtLimitRow;
    private samusik.glasscmp.GlassEdit txtNoiseTheshold;
    private samusik.glasscmp.GlassEdit txtPercentile2;
    private samusik.glasscmp.GlassEdit txtScalingFactor;
    // End of variables declaration//GEN-END:variables
}
