/*
 * SortDialog.java
 *
 * 
 * Dialog that allows the user to select
 *  - column(s) to be sorted
 *  - column(s) to sort by
 */

package org.statcato.dialogs.data;

import org.statcato.spreadsheet.*;
import org.statcato.*;
import org.statcato.utils.OrderingFunctions;
import javax.swing.*;
import java.util.*;


/**
 * A dialog providing options to sort a set of columns by up to 
 * four columns.
 * 
 * @author  Margaret Yau
 * @version %I%, %G%
 * @since 1.0
 */
public class SortDialog extends StatcatoDialog {

    /** Creates new form SortDialog */
    public SortDialog(java.awt.Frame parent, boolean modal, Statcato app) {
        super(parent, modal);
        ParentSpreadsheet = app.getSpreadsheet();
        this.app = app;
        initComponents();

        // set up info displayed in sort dialog
        // set up radio button groups
        ButtonGroup group1 = new ButtonGroup();
        group1.add(AscendingRadioButton1);
        group1.add(DescendingRadioButton1);
        ButtonGroup group2 = new ButtonGroup();
        group2.add(AscendingRadioButton2);
        group2.add(DescendingRadioButton2);
        ButtonGroup group3 = new ButtonGroup();
        group3.add(AscendingRadioButton3);
        group3.add(DescendingRadioButton3);
        ButtonGroup group4 = new ButtonGroup();
        group4.add(AscendingRadioButton4);
        group4.add(DescendingRadioButton4);
        ButtonGroup storeGroup = new ButtonGroup();
        storeGroup.add(StoreOrgRadioButton);
        storeGroup.add(StoreSpecRadioButton);
        
        // default all radio buttons to unselected
        AscendingRadioButton1.setSelected(false);
        DescendingRadioButton1.setSelected(false);
        AscendingRadioButton2.setSelected(false);
        DescendingRadioButton2.setSelected(false);
        AscendingRadioButton3.setSelected(false);
        DescendingRadioButton3.setSelected(false);
        AscendingRadioButton4.setSelected(false);
        DescendingRadioButton4.setSelected(false);
               
        ParentSpreadsheet.populateComboBox(SortColumnsComboBox1);
        ParentSpreadsheet.populateComboBox(SortColumnsComboBox2);
        ParentSpreadsheet.populateComboBox(SortColumnsComboBox3);
        ParentSpreadsheet.populateComboBox(SortColumnsComboBox4);
        
        getRootPane().setDefaultButton(SortOKButton);
        setHelpFile("data-sort");
        name = "Sort";
        description = "For sorting a number of data columns by data up to four columns.";
        helpStrings.add("If a column contains only numbers, " +
                "the data will be sorted by their numerical values. " +
                "Otherwise, the data will be sorted as text in alphabetically order.");
    }
    
    /**
     * Updates elements on the dialog so that they have the most
     * current values.  Called by {@link #setVisible} to make
     * sure the dialog displays current values when made visible again.
     * 
     * @see #setVisible(boolean)
     */
    @Override
    public void updateElements() {
        updateComboBox(SortColumnsComboBox1);
        updateComboBox(SortColumnsComboBox2);
        updateComboBox(SortColumnsComboBox3);
        updateComboBox(SortColumnsComboBox4);
    }
    
    /** 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.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        SortOKButton = new javax.swing.JButton();
        SortCancelButton = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        SortColumnsComboBox1 = new javax.swing.JComboBox();
        SortColumnsComboBox4 = new javax.swing.JComboBox();
        jLabel2 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        AscendingRadioButton3 = new javax.swing.JRadioButton();
        AscendingRadioButton2 = new javax.swing.JRadioButton();
        DescendingRadioButton3 = new javax.swing.JRadioButton();
        DescendingRadioButton2 = new javax.swing.JRadioButton();
        jLabel3 = new javax.swing.JLabel();
        SortColumnsComboBox2 = new javax.swing.JComboBox();
        DescendingRadioButton1 = new javax.swing.JRadioButton();
        jLabel4 = new javax.swing.JLabel();
        DescendingRadioButton4 = new javax.swing.JRadioButton();
        SortColumnsComboBox3 = new javax.swing.JComboBox();
        AscendingRadioButton4 = new javax.swing.JRadioButton();
        AscendingRadioButton1 = new javax.swing.JRadioButton();
        jPanel2 = new javax.swing.JPanel();
        jLabel6 = new javax.swing.JLabel();
        InputTextField = new javax.swing.JTextField();
        StoreOrgRadioButton = new javax.swing.JRadioButton();
        jLabel7 = new javax.swing.JLabel();
        OutputTextField = new javax.swing.JTextField();
        StoreSpecRadioButton = new javax.swing.JRadioButton();
        jLabel8 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Sort");

        SortOKButton.setText("OK");
        SortOKButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SortOKButtonActionPerformed(evt);
            }
        });

        SortCancelButton.setText("Cancel");
        SortCancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SortCancelButtonActionPerformed(evt);
            }
        });

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Sort Order"));

        SortColumnsComboBox1.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                SortColumnsComboBox1ItemStateChanged(evt);
            }
        });

        SortColumnsComboBox4.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                SortColumnsComboBox4ItemStateChanged(evt);
            }
        });

        jLabel2.setText("Sort By Column: ");

        jLabel5.setText("Then By Column: ");

        AscendingRadioButton3.setText("Ascending");

        AscendingRadioButton2.setText("Ascending");

        DescendingRadioButton3.setText("Descending");

        DescendingRadioButton2.setText("Descending");

        jLabel3.setText("Then By Column: ");

        SortColumnsComboBox2.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                SortColumnsComboBox2ItemStateChanged(evt);
            }
        });

        DescendingRadioButton1.setText("Descending");

        jLabel4.setText("Then By Column: ");

        DescendingRadioButton4.setText("Descending");

        SortColumnsComboBox3.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                SortColumnsComboBox3ItemStateChanged(evt);
            }
        });

        AscendingRadioButton4.setText("Ascending");

        AscendingRadioButton1.setText("Ascending");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel2)
                    .addComponent(jLabel3)
                    .addComponent(jLabel4)
                    .addComponent(jLabel5))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(SortColumnsComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(SortColumnsComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(SortColumnsComboBox3, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(SortColumnsComboBox4, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(AscendingRadioButton1)
                    .addComponent(AscendingRadioButton2)
                    .addComponent(AscendingRadioButton3)
                    .addComponent(AscendingRadioButton4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(DescendingRadioButton2)
                    .addComponent(DescendingRadioButton1)
                    .addComponent(DescendingRadioButton3)
                    .addComponent(DescendingRadioButton4))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel2)
                    .addComponent(SortColumnsComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(AscendingRadioButton1)
                    .addComponent(DescendingRadioButton1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel3)
                    .addComponent(SortColumnsComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(AscendingRadioButton2)
                    .addComponent(DescendingRadioButton2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel4)
                    .addComponent(SortColumnsComboBox3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(AscendingRadioButton3)
                    .addComponent(DescendingRadioButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jLabel5)
                    .addComponent(SortColumnsComboBox4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(AscendingRadioButton4)
                    .addComponent(DescendingRadioButton4))
                .addContainerGap())
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Columns"));

        jLabel6.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel6.setText("Input Columns:");

        StoreOrgRadioButton.setSelected(true);
        StoreOrgRadioButton.setText("Store in original column(s)");
        StoreOrgRadioButton.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                StoreOrgRadioButtonStateChanged(evt);
            }
        });

        jLabel7.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel7.setText("Output Columns:");

        OutputTextField.setEnabled(false);

        StoreSpecRadioButton.setText("Store in these column(s):");
        StoreSpecRadioButton.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                StoreSpecRadioButtonStateChanged(evt);
            }
        });

        jLabel8.setText("<html>\n- Enter valid column names separated by space.<br>\nFor a continuous range of columns, separate using dash (e.g. C1-C30).<br>\n</html>\n");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(14, 14, 14)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel7)
                            .addGroup(jPanel2Layout.createSequentialGroup()
                                .addComponent(jLabel6)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(InputTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 229, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(StoreSpecRadioButton)
                            .addComponent(StoreOrgRadioButton)
                            .addGroup(jPanel2Layout.createSequentialGroup()
                                .addGap(21, 21, 21)
                                .addComponent(OutputTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 212, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jLabel8)))
                .addContainerGap(22, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(InputTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(jLabel7)
                .addGap(18, 18, 18)
                .addComponent(StoreOrgRadioButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(StoreSpecRadioButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(OutputTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel8)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addGroup(layout.createSequentialGroup()
                .addGap(128, 128, 128)
                .addComponent(SortOKButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(SortCancelButton)
                .addContainerGap(139, Short.MAX_VALUE))
        );

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {SortCancelButton, SortOKButton});

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 158, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(SortCancelButton)
                    .addComponent(SortOKButton))
                .addContainerGap())
        );

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

    
    private void SortColumnsComboBox1ItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_SortColumnsComboBox1ItemStateChanged
        // when a combobox has a selected column, set default value of order radio button
        if (SortColumnsComboBox1.getSelectedIndex() != 0) {
            AscendingRadioButton1.setSelected(true);
        }
    }//GEN-LAST:event_SortColumnsComboBox1ItemStateChanged

    private void SortColumnsComboBox2ItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_SortColumnsComboBox2ItemStateChanged
        // when a combobox has a selected column, set default value of order radio button
        if (SortColumnsComboBox2.getSelectedIndex() > 0) {
            if (SortColumnsComboBox1.getSelectedIndex() == 0) {
                AscendingRadioButton2.setSelected(false);
                SortColumnsComboBox2.setSelectedIndex(0);
                app.showErrorDialog("A Sort By Column must be selected first.");
            }
            else {
                AscendingRadioButton2.setSelected(true);
            }
        }
    }//GEN-LAST:event_SortColumnsComboBox2ItemStateChanged

    private void SortColumnsComboBox3ItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_SortColumnsComboBox3ItemStateChanged
        // when a combobox has a selected column, set default value of order radio button
        if (SortColumnsComboBox3.getSelectedIndex() > 0) {
            if (SortColumnsComboBox1.getSelectedIndex() == 0 ||
                    SortColumnsComboBox2.getSelectedIndex() == 0) {
                AscendingRadioButton3.setSelected(false);
                SortColumnsComboBox3.setSelectedIndex(0);
                app.showErrorDialog("A Sort By Column and a Then By Column must" +
                        " be selected.");
            }
            else
                AscendingRadioButton3.setSelected(true);
        }
        }//GEN-LAST:event_SortColumnsComboBox3ItemStateChanged

        private void SortColumnsComboBox4ItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_SortColumnsComboBox4ItemStateChanged
            // when a combobox has a selected column, set default value of order radio button
            if (SortColumnsComboBox4.getSelectedIndex() > 0) {
                if (SortColumnsComboBox1.getSelectedIndex() == 0 ||
                        SortColumnsComboBox2.getSelectedIndex() == 0 ||
                        SortColumnsComboBox3.getSelectedIndex() == 0) {
                    AscendingRadioButton4.setSelected(false);
                    SortColumnsComboBox4.setSelectedIndex(0);
                    app.showErrorDialog("A Sort By Column and two Then By Columns" +
                            " must be selected.");
                }
                else
                    AscendingRadioButton4.setSelected(true);
            }
        }//GEN-LAST:event_SortColumnsComboBox4ItemStateChanged

        private void SortOKButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SortOKButtonActionPerformed
            app.compoundEdit = new DialogEdit("sort");
            
            int[] inputColumnNumbers = 
                    ParentSpreadsheet.getColumnNumbersArrayFromString(InputTextField.getText());  
            int[] storeColumnNumbers = 
                    ParentSpreadsheet.getColumnNumbersArrayFromString(OutputTextField.getText());

            if (StoreSpecRadioButton.isSelected()) {
                if (inputColumnNumbers.length != storeColumnNumbers.length) {
                    app.showErrorDialog("The number of input columns must be the same as" +
                            " the number of columns for storing results.");
                    return;
                }
            }
            // get sort keys
            boolean ascending1 = false, ascending2 = false, 
                    ascending3 = false, ascending4 = false;
            Vector<Cell> byVec1 = null, byVec2 = null, byVec3 = null, byVec4 = null;
            
            // vectors of cell: [vec byVec1 byVec2 byVec3 byVec4]
            Vector<Vector<Cell>> vectors = new Vector<Vector<Cell>>();
            vectors.addElement(new Vector<Cell>());
            Vector<Boolean> orders = new Vector<Boolean>();
            orders.addElement(new Boolean(true));

            String sortKey1 = SortColumnsComboBox1.getSelectedItem().toString();
            int sortKeyColumn1 = ParentSpreadsheet.parseColumnNumber(sortKey1);
            if (sortKeyColumn1 != -1) {
                ascending1 = AscendingRadioButton1.isSelected();
                orders.addElement(new Boolean(ascending1));
                byVec1 = ParentSpreadsheet.getColumn(sortKeyColumn1);
                vectors.addElement(byVec1);
            }
            
            String sortKey2 = SortColumnsComboBox2.getSelectedItem().toString();
            int sortKeyColumn2 = ParentSpreadsheet.parseColumnNumber(sortKey2);
            if (sortKeyColumn2 != -1) {
                ascending2 = AscendingRadioButton2.isSelected();
                orders.addElement(new Boolean(ascending2));
                byVec2 = ParentSpreadsheet.getColumn(sortKeyColumn2);
                vectors.addElement(byVec2);
            }
            
            String sortKey3 = SortColumnsComboBox3.getSelectedItem().toString();
            int sortKeyColumn3 = ParentSpreadsheet.parseColumnNumber(sortKey3);
            if (sortKeyColumn3 != -1) {
                ascending3 = AscendingRadioButton3.isSelected();
                orders.addElement(new Boolean(ascending3));
                byVec3 = ParentSpreadsheet.getColumn(sortKeyColumn3);
                vectors.addElement(byVec3);
            }
            
            String sortKey4 = SortColumnsComboBox4.getSelectedItem().toString();
            int sortKeyColumn4 = ParentSpreadsheet.parseColumnNumber(sortKey4);
            if (sortKeyColumn4 != -1) {
                ascending4 = AscendingRadioButton4.isSelected();
                orders.addElement(new Boolean(ascending4));
                byVec4 = ParentSpreadsheet.getColumn(sortKeyColumn4);
                vectors.addElement(byVec4);
            }
            
            Vector<Vector<Cell>> sortedColumns = new Vector<Vector<Cell>>();
            
            for (int i = 0; i < inputColumnNumbers.length; ++i) {                
                Vector<Cell> vec = (Vector<Cell>) ParentSpreadsheet.getColumn(
                        inputColumnNumbers[i]);       
                vectors.setElementAt(vec, 0);
                Vector<Vector<Cell>> results = OrderingFunctions.sortVectors(
                        vectors, orders);
                sortedColumns.addElement(results.elementAt(0));
                
            }
            // store results in specified columns
            if (StoreSpecRadioButton.isSelected()) {
                for (int i = 0; i < inputColumnNumbers.length; ++i) {
                    ParentSpreadsheet.setCellColumn(storeColumnNumbers[i],
                            sortedColumns.elementAt(i));                
                }
            }
            // store results in original columns
            else {
                for (int i = 0; i < inputColumnNumbers.length; ++i) {
                    ParentSpreadsheet.setCellColumn(inputColumnNumbers[i],
                            sortedColumns.elementAt(i));                
                }                
            }
            
            app.addLogParagraph("Sort", "");

            app.compoundEdit.end();
            app.addCompoundEdit(app.compoundEdit);
        
            setVisible(false);
        }//GEN-LAST:event_SortOKButtonActionPerformed

        private void SortCancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SortCancelButtonActionPerformed
            // close dialog
            setVisible(false);
        }//GEN-LAST:event_SortCancelButtonActionPerformed

        private void StoreOrgRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_StoreOrgRadioButtonStateChanged
            if (StoreOrgRadioButton.isSelected()) {
                OutputTextField.setEnabled(false);
            }
        }//GEN-LAST:event_StoreOrgRadioButtonStateChanged

        private void StoreSpecRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_StoreSpecRadioButtonStateChanged
            if (StoreSpecRadioButton.isSelected()) {
                OutputTextField.setEnabled(true);
            }
        }//GEN-LAST:event_StoreSpecRadioButtonStateChanged



    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JRadioButton AscendingRadioButton1;
    private javax.swing.JRadioButton AscendingRadioButton2;
    private javax.swing.JRadioButton AscendingRadioButton3;
    private javax.swing.JRadioButton AscendingRadioButton4;
    private javax.swing.JRadioButton DescendingRadioButton1;
    private javax.swing.JRadioButton DescendingRadioButton2;
    private javax.swing.JRadioButton DescendingRadioButton3;
    private javax.swing.JRadioButton DescendingRadioButton4;
    private javax.swing.JTextField InputTextField;
    private javax.swing.JTextField OutputTextField;
    private javax.swing.JButton SortCancelButton;
    private javax.swing.JComboBox SortColumnsComboBox1;
    private javax.swing.JComboBox SortColumnsComboBox2;
    private javax.swing.JComboBox SortColumnsComboBox3;
    private javax.swing.JComboBox SortColumnsComboBox4;
    private javax.swing.JButton SortOKButton;
    private javax.swing.JRadioButton StoreOrgRadioButton;
    private javax.swing.JRadioButton StoreSpecRadioButton;
    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 jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    // End of variables declaration//GEN-END:variables
    
}
