package org.expasy.bprg;

/**
 *
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SpringLayout;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.AbstractTableModel;

import layout.SpringUtilities;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.expasy.minitools.util.FileUtils;

public class MainFrame extends JFrame {

    /**
     * Current version of the program
     */
    private String version = "MALDIPepQuant v3.1";

    /**
     * Logger
     */
    private static Logger log = Logger.getLogger(MainFrame.class);

    /**
     * FileChooser to choose folders and files throughout the program
     */
    private JFileChooser fc = new JFileChooser();

    ///////////////////////////////

    private JTextField tfError;
    
    private JTable tbLabels;

    private JTextField tfExcelFile;

    private JTextField tfPAFiles;
    
    private String tfPAFilter;

    private JCheckBox cbMOneDa;

    private JCheckBox cbMTwoDa;

    private ButtonGroup groupIntermPeaks;
    private JRadioButton rbIntermPeaksNo;
    private JRadioButton rbIntermPeaksYes;

    private PeptideLabelModel peptideLabelModel;



    /**
     * @throws HeadlessException
     */
    public MainFrame() throws HeadlessException {
        super();
        setTitle(version);
        setIconImage(null);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.createElements();

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int y = (screenSize.height - 550) / 2;
        int x = (screenSize.width - 500) / 2;
        this.setBounds(x, y, 500, 550);

        this.setVisible(true);

        log.info("\nMainFrame constructed and visible\n");

    }

    private void createElements() {
        //////////////////////////////MenuBar
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("?");
        menuBar.add(menu);

        JMenuItem menuItem = new JMenuItem("About "+version);
        menuItem.getAccessibleContext().setAccessibleDescription(
                "General informations on this program.");
        menuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                AboutFrame about = new AboutFrame(MainFrame.this.version);
                about.setVisible(true);
            }

        });
        menu.add(menuItem);
        setJMenuBar(menuBar);

        //////////////////////////////PANEL
        JPanel generalPanel = new JPanel(new BorderLayout());
        JPanel paramPanel = new JPanel();
        GridBagLayout gridBag = new GridBagLayout();
        paramPanel.setLayout(gridBag);
        GridBagConstraints constraints = new GridBagConstraints();

        /////////
        JLabel lbError = new JLabel("Error on peptide mass (Da) :");
        FileUtils.addConstraints(constraints, 0, 0, 2, 1, 0.50, 0.10, 10, 5,
                GridBagConstraints.NONE, GridBagConstraints.LINE_START);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(lbError, constraints);
        paramPanel.add(lbError);

        tfError = new JTextField("0.2");
        lbError.setLabelFor(tfError);
        FileUtils.addConstraints(constraints, 3, 0, 1, 1, 0.50, 0.10, 10, 5,
                GridBagConstraints.HORIZONTAL, GridBagConstraints.EAST);
        gridBag.setConstraints(tfError, constraints);
        paramPanel.add(tfError);

        /////////
        JLabel lbHeavyPept = new JLabel("Used labels :");
        lbHeavyPept.setBackground(Color.green);
        FileUtils.addConstraints(constraints, 0, 1, 2, 1, 0.50, 0.10, 10, 5,
                GridBagConstraints.NONE, GridBagConstraints.LINE_START);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(lbHeavyPept, constraints);
        paramPanel.add(lbHeavyPept);

        peptideLabelModel = new PeptideLabelModel(true);
        peptideLabelModel.addTableModelListener(new TableModelListener() {
            /* (non-Javadoc)
             * @see javax.swing.event.TableModelListener#tableChanged(javax.swing.event.TableModelEvent)
             */
            public void tableChanged(TableModelEvent e) {
                rbIntermPeaksYes.setEnabled(peptideLabelModel.getData().size() < 2);
                rbIntermPeaksNo.setEnabled(peptideLabelModel.getData().size() < 2);
                
            }
        });
        tbLabels = new JTable(peptideLabelModel);
        JScrollPane scrollPane = new JScrollPane(tbLabels);
        FileUtils.addConstraints(constraints, 2, 1, 2, 2, 0.50, 0.20, 10, 5,
                GridBagConstraints.BOTH, GridBagConstraints.CENTER);
        lbHeavyPept.setLabelFor(tbLabels);
        gridBag.setConstraints(scrollPane, constraints);
        paramPanel.add(scrollPane);

        /////////
        JButton bAdd = new JButton("Add...");
        bAdd.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                SmallForm sf = new SmallForm(MainFrame.this, "New Label");
                //Display the window.
                sf.pack();
                sf.setVisible(true);
            }

        });
        FileUtils.addConstraints(constraints, 0, 2, 1, 1, 0.25, 0.10, 10, 5,
                               GridBagConstraints.NONE, GridBagConstraints.EAST);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(bAdd, constraints);
        paramPanel.add(bAdd);
        
        JButton bRemove = new JButton("Remove");
        bRemove.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                int[] selection = tbLabels.getSelectedRows();
                if(selection.length == 0) {
                    JOptionPane.showMessageDialog(MainFrame.this,
                            "Empty selection!", 
                            "Selection error",
                            JOptionPane.WARNING_MESSAGE);
                    return;
                }
                
                String selectedElmts = "";
                for (int i : selection) {
                    selectedElmts += (peptideLabelModel.getData().get(i)+"\n");
                }
                int value = JOptionPane.showConfirmDialog(
                    MainFrame.this,
                    "Element(s) to remove:\n" +
                    selectedElmts+
                    "Are you sure?",
                    "Confirm deletion",
                    JOptionPane.YES_NO_OPTION);
                if (value == JOptionPane.YES_OPTION) {
                    for (int i =selection.length-1; i>=0; i--) {
                        peptideLabelModel.removeRow(selection[i]);
                    }
                    
                    
                }
            }

        });
        FileUtils.addConstraints(constraints, 1, 2, 1, 1, 0.25, 0.10, 10, 5,
                               GridBagConstraints.NONE, GridBagConstraints.EAST);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(bRemove, constraints);
        paramPanel.add(bRemove);

        /////////
        JLabel lbSelection = new JLabel("Select files for data treatment");
        FileUtils.addConstraints(constraints, 0, 3, 4, 1, 1.0, 0.10, 10, 5,
                               GridBagConstraints.NONE, GridBagConstraints.CENTER);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(lbSelection, constraints);
        paramPanel.add(lbSelection);

        ////////
        JPanel filePanel = createFilePanel();
        FileUtils.addConstraints(constraints, 0, 4, 4, 1, 1.0, 0.30, 10, 5,
                GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(filePanel, constraints);
        paramPanel.add(filePanel);

        ////////
        JLabel lbEchoPeaks = new JLabel("Find echo peaks at");
        FileUtils.addConstraints(constraints, 0, 5, 2, 1, 0.50, 0.10, 10, 5,
                               GridBagConstraints.NONE, GridBagConstraints.WEST);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(lbEchoPeaks, constraints);
        paramPanel.add(lbEchoPeaks);

        cbMOneDa = new JCheckBox("-1 Da");
        cbMOneDa.setSelected(true);
        cbMOneDa.addChangeListener(new ChangeListener(){

            public void stateChanged(ChangeEvent e) {
                cbMTwoDa.setEnabled(cbMOneDa.isSelected());
            }

        });
        FileUtils.addConstraints(constraints, 2, 5, 1, 1, 0.25, 0.10, 10, 5,
                               GridBagConstraints.NONE, GridBagConstraints.CENTER);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(cbMOneDa, constraints);
        paramPanel.add(cbMOneDa);

        cbMTwoDa = new JCheckBox("-2 Da");
        FileUtils.addConstraints(constraints, 3, 5, 1, 1, 0.25, 0.10, 10, 5,
                               GridBagConstraints.NONE, GridBagConstraints.WEST);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(cbMTwoDa, constraints);
        paramPanel.add(cbMTwoDa);

        ////////
        JLabel lbIntermPeaks = new JLabel("Find intermediary peaks");
        FileUtils.addConstraints(constraints, 0, 6, 2, 1, 0.50, 0.10, 10, 5,
                               GridBagConstraints.NONE, GridBagConstraints.WEST);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(lbIntermPeaks, constraints);
        paramPanel.add(lbIntermPeaks);

        rbIntermPeaksYes = new JRadioButton("Yes");
        rbIntermPeaksYes.setActionCommand("Yes");
        rbIntermPeaksYes.setSelected(true);
        rbIntermPeaksYes.setEnabled(peptideLabelModel.getData().size() < 2);
        FileUtils.addConstraints(constraints, 2, 6, 1, 1, 0.25, 0.10, 10, 5,
                                GridBagConstraints.NONE, GridBagConstraints.CENTER);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(rbIntermPeaksYes, constraints);
        paramPanel.add(rbIntermPeaksYes);

        rbIntermPeaksNo = new JRadioButton("No");
        rbIntermPeaksNo.setActionCommand("No");
        rbIntermPeaksNo.setEnabled(peptideLabelModel.getData().size() < 2);
        FileUtils.addConstraints(constraints, 3, 6, 1, 1, 0.25, 0.10, 10, 5,
                                GridBagConstraints.NONE, GridBagConstraints.WEST);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(rbIntermPeaksNo, constraints);
        paramPanel.add(rbIntermPeaksNo);

        groupIntermPeaks = new ButtonGroup();
        groupIntermPeaks.add(rbIntermPeaksYes);
        groupIntermPeaks.add(rbIntermPeaksNo);

        ////////
        JButton bStart = new JButton("Start...");
        bStart.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                try{
                    runSilacQuanti();
                }catch(Exception ex) {
                    JOptionPane.showMessageDialog(MainFrame.this, ex.getMessage(),
                            "Execution error", JOptionPane.ERROR_MESSAGE);
                    ex.printStackTrace();
                }
            }

        });
        FileUtils.addConstraints(constraints, 0, 7, 4, 1, 1.0, 0.10, 10, 5,
                               GridBagConstraints.NONE, GridBagConstraints.EAST);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(bStart, constraints);
        paramPanel.add(bStart);


        generalPanel.add(paramPanel,BorderLayout.CENTER);
        add(generalPanel);
    }

    /**
     *
     */
    protected void runSilacQuanti() {
        SilacQuantiParam params = new SilacQuantiParam();

        if(tfError.getText().equals("") || new Double(tfError.getText()).doubleValue()<0) {
            JOptionPane.showMessageDialog(this, "Error while checking Error : please enter a positive number.",
                    "Parameter error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        params.error = new Double(tfError.getText()).doubleValue();
        params.data = peptideLabelModel.getData();
        if(params.data.size() < 1) {
            JOptionPane.showMessageDialog(this, "Error while checking Label data :\n please provide at least one label.",
                    "Parameter error", JOptionPane.ERROR_MESSAGE);
            return;
        }
                
        params.findEchoPeaks =  (cbMOneDa.isSelected()? 1+(cbMTwoDa.isSelected()?1:0) : 0) ;//can't have -2Da alone
        params.findIntermPeaks = (this.rbIntermPeaksYes.isSelected() && params.data.size()==1);

        if(tfPAFiles.equals("")) {
            JOptionPane.showMessageDialog(this, "Error while checking Peak area files :\n please select one file containing peak areas\n (and put a # at the label position).",
                    "Parameter error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        params.paFolder = new File(tfPAFiles.getText());

        if(tfPAFilter==null) {
            JOptionPane.showMessageDialog(this, "Error while checking Peak area file name :\n please select one file containing peak areas\n (and put a # at the label position).",
                    "Parameter error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if(!tfPAFilter.contains("#")) {
            JOptionPane.showMessageDialog(this, "Error while checking Peak area file name :\n please put a # at the label position.",
                    "Parameter error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        params.paFilter = tfPAFilter.substring(0, tfPAFilter.indexOf("#"));

        //Parameters are ok, can run quantitation
        SilacQuanti sQuanti = new SilacQuanti();
        File excelFile = new File(tfExcelFile.getText());
        if(!excelFile.exists()) {
            JOptionPane.showMessageDialog(this, "Error while checking Excel file :\n file does not exist.",
                    "Parameter error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        sQuanti.quantifyAndWrite(excelFile, params);

    }

    /**
     * @return
     */
    private JPanel createFilePanel() {
        JPanel filePanel = new JPanel();
        filePanel.setBorder(BorderFactory.createEtchedBorder());
        filePanel.setPreferredSize(new Dimension(300, 200));
        GridBagLayout gridBag = new GridBagLayout();
        filePanel.setLayout(gridBag);
        GridBagConstraints constraints = new GridBagConstraints();

        //Browse Excel file
        JLabel lbExcelFile = new JLabel("Excel file :");
        FileUtils.addConstraints(constraints, 0, 0, 2, 1, 1.0, 0.25, 10, 5,
                               GridBagConstraints.NONE, GridBagConstraints.LINE_START);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(lbExcelFile, constraints);
        filePanel.add(lbExcelFile);

        tfExcelFile = new JTextField("");
        lbExcelFile.setLabelFor(tfExcelFile);
        FileUtils.addConstraints(constraints, 0, 1, 1, 1, 0.75, 0.25, 10, 5,
                                 GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER);
        gridBag.setConstraints(tfExcelFile, constraints);
        filePanel.add(tfExcelFile);

        JButton bBrowseExcel = new JButton("Browse");
        bBrowseExcel.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                FileFilter excelFileFilter = new ExcelFileFilter();
                fc.setFileFilter(excelFileFilter);
                int returnVal = fc.showOpenDialog(MainFrame.this);

                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File file = fc.getSelectedFile();
                    try {
                        MainFrame.this.tfExcelFile.setText(file.getCanonicalPath());
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }

                fc.resetChoosableFileFilters();
            }

        });
        FileUtils.addConstraints(constraints, 1, 1, 1, 1, 0.25, 0.25, 10, 5,
                                 GridBagConstraints.NONE, GridBagConstraints.CENTER);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(bBrowseExcel, constraints);
        filePanel.add(bBrowseExcel);

        //Browse Peak Areas
        JLabel lbPAFiles = new JLabel("Peak lists folder :");
        FileUtils.addConstraints(constraints, 0, 2, 2, 1, 1.0, 0.25, 10, 5,
                               GridBagConstraints.NONE, GridBagConstraints.LINE_START);
        gridBag.setConstraints(lbPAFiles, constraints);
        filePanel.add(lbPAFiles);

        tfPAFiles = new JTextField("");
        lbExcelFile.setLabelFor(tfPAFiles);
        FileUtils.addConstraints(constraints, 0, 3, 1, 1, 0.75, 0.25, 10, 5,
                                 GridBagConstraints.HORIZONTAL, GridBagConstraints.CENTER);
        gridBag.setConstraints(tfPAFiles, constraints);
        filePanel.add(tfPAFiles);

        JButton bBrowsePA = new JButton("Browse");
        bBrowsePA.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                int returnVal = fc.showOpenDialog(MainFrame.this);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File file = fc.getSelectedFile();
                    MainFrame.this.tfPAFiles.setText(file.getParent());
                    tfPAFilter = file.getName(); //Will contain the filter, like pmf_#_blabla.txt
                }
            }

        });
        FileUtils.addConstraints(constraints, 1, 3, 1, 1, 0.25, 0.25, 10, 5,
                                 GridBagConstraints.NONE, GridBagConstraints.CENTER);
        constraints.insets = new Insets(5, 10, 5, 10);
        gridBag.setConstraints(bBrowsePA, constraints);
        filePanel.add(bBrowsePA);
        return filePanel;
    }

    private class SmallForm extends JDialog{

        public SmallForm(JFrame mainframe, String title) {
            super(mainframe, title);
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

            // Create and populate the panel.
            JPanel pForm = new JPanel(new SpringLayout());
            pForm.setOpaque(true);

            JLabel llt = new JLabel("Label text: ", JLabel.TRAILING);
            pForm.add(llt);
            final JTextField textField = new JTextField("13C6/15N2-Lys", 10);
            llt.setLabelFor(textField);
            pForm.add(textField);

            JLabel lsh = new JLabel("Shift: ", JLabel.TRAILING);
            pForm.add(lsh);
            SpinnerModel spmodel = new SpinnerNumberModel(8, 1, null, 1); // initial,
                                                                            // min,
                                                                            // max,
                                                                            // step
            final JSpinner ssh = new JSpinner(spmodel);
            lsh.setLabelFor(ssh);
            pForm.add(ssh);

            JLabel laa = new JLabel("Amino acid: ", JLabel.TRAILING);
            pForm.add(laa);
            final JComboBox caa = new JComboBox(new Object[] { "A", "C", "D",
                    "E", "F", "G", "H", "I", "K", "L", "M", "N", "P", "Q", "R",
                    "S", "T", "V", "W", "Y" });
            caa.setSelectedIndex(8);
            laa.setLabelFor(caa);
            pForm.add(caa);

            // Lay out the panel.
            SpringUtilities.makeCompactGrid(pForm, 3, 2, // rows, cols
                    6, 6, // initX, initY
                    6, 6); // xPad, yPad
            pForm.setAlignmentX(0.5f);

            JPanel pMain = new JPanel();
            pMain.setLayout(new BoxLayout(pMain, BoxLayout.PAGE_AXIS));
            pMain.add(pForm);
            JButton okbutton = new JButton("OK");
            okbutton.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    if (textField.getText().equals(""))
                        return;

                    PeptideLabel newLabel = new PeptideLabel(textField
                            .getText(), (Integer) ssh.getValue(), caa
                            .getSelectedItem().toString());
                    peptideLabelModel.addData(newLabel);
                    
                    setVisible(false);
                    dispose();
                }

            });
            okbutton.setAlignmentX(0.5f);
            pMain.add(okbutton);
            pMain.setOpaque(true); // content panes must be opaque

            //Set up the content pane.
            setContentPane(pMain);
            
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            int y = (screenSize.height - 250) / 2;
            int x = (screenSize.width - 250) / 2;
            this.setBounds(x, y, 250, 250);
            


        }
    }

    
    private class ExcelFileFilter extends FileFilter {
        public boolean accept(File f) {
            if (f.isDirectory()) {
                return true;
            }

            String extension = getExtension(f);
            if (extension != null) {
                if (extension.equals("xls")) {
                        return true;
                } else {
                    return false;
                }
            }
            return false;
        }

        public String getDescription() {
            return "Microsoft Excel files (.xls)";
        }

        public String getExtension(File f) {
            String ext = null;
            String s = f.getName();
            int i = s.lastIndexOf('.');

            if (i > 0 &&  i < s.length() - 1) {
                ext = s.substring(i+1).toLowerCase();
            }
            return ext;
        }
    }

     /////////////////////////////////////////////////////

    /**
     * Starting main function.
     */
    public static void main(String[] args) {
        try {
            // Set System L&F
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (UnsupportedLookAndFeelException e) {
            try {
                // Set cross-platform Java L&F (also called "Metal")
                UIManager.setLookAndFeel(
                    UIManager.getCrossPlatformLookAndFeelClassName());
            }
            catch (UnsupportedLookAndFeelException e1) {
                e1.printStackTrace();
             }
             catch (ClassNotFoundException e1) {
                 e1.printStackTrace();
             }
             catch (InstantiationException e1) {
                 e1.printStackTrace();
             }
             catch (IllegalAccessException e1) {
                 e1.printStackTrace();
             }
        }
        catch (Exception e2) {
            e2.printStackTrace();
        }

        /* set properties file for log4J */
        PropertyConfigurator.configureAndWatch( Resources.log4j_properties_filepath, 60*1000 );

        new MainFrame();
    }

}

class PeptideLabel {
    
    public String label;
    public Integer shift;
    public String aminoacid;
    
    public static String[] columnNames = {"Label",
            "Shift",
            "Amino acid"};
    
    /**
     * @param string
     * @param integer
     * @param string2
     */
    public PeptideLabel(String label, Integer shift, String aminoacid) {
        this.label = label;
        this.shift = shift;
        this.aminoacid = aminoacid;
    }

    public String toString() {
        return "Label : "+label+"; Shift : "+shift.intValue()+"; Target a.a. : "+aminoacid;
        }

}

class PeptideLabelModel extends AbstractTableModel {
    private String[] columnNames = PeptideLabel.columnNames;
    private ArrayList<PeptideLabel> data;

    /**
     * 
     */
    public PeptideLabelModel(boolean setDefaultValues) {
        super();
        data = new ArrayList<PeptideLabel>(5);
        if(setDefaultValues) {
            data.add(new PeptideLabel("13C-Leu", new Integer(6), "L"));
//            data.add(new PeptideLabel("13C6/15N2-Lys", new Integer(8), "K"));
        }
    }

    public ArrayList<PeptideLabel> getData() {
        return data;
    }
    public void addData(PeptideLabel newLabel) {
        data.add(newLabel);
        fireTableRowsInserted(data.size()-1, data.size()-1);
    }
    
    ////////////////////////////////////////
    
    public int getColumnCount() {
        return columnNames.length;
    }

    public int getRowCount() {
        return data.size();
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col) {
        switch (col) {
        case 0:
            return data.get(row).label;
        case 1:
            return data.get(row).shift;
        case 2:
            return data.get(row).aminoacid;
        default:
            return null;
        }
    }

    @SuppressWarnings("unchecked")
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    /*
     */
    public void setValueAt(Object value, int row, int col) {
        switch (col) {
        case 0:
            data.get(row).label = (String) value;
            break;
        case 1:
            data.get(row).shift = (Integer) value;
            break;
        case 2:
            data.get(row).aminoacid = (String) value;
            break;
        default:
            return;
        }
        fireTableCellUpdated(row, col);
    }
    
    public void removeRow(int row) {
        data.remove(row);
        fireTableRowsDeleted(row, row);        
    }
}

