/*
 * RankDialog.java
 *
 * Created on April 16, 2008, 3:52 PM
 */

package org.statcato.dialogs.data;

import org.statcato.*;
import org.statcato.spreadsheet.*;
import org.statcato.utils.HelperFunctions;
import java.util.*;

/**
 * A dialog for ranking data values in the Datasheet.
 * 
 * @author  Margaret Yau
 * @version %I%, %G%
 * @since 1.0
 */
public class RankDialog extends StatcatoDialog {
  
    /** Creates new form RankDialog */
    public RankDialog(java.awt.Frame parent, boolean modal, Statcato app) {
        super(parent, modal);
        this.app = app;
        ParentSpreadsheet = app.getSpreadsheet();
        initComponents();
        
        ParentSpreadsheet.populateComboBox(InputComboBox);
        
        getRootPane().setDefaultButton(OKButton);
        setHelpFile("data-rank");
        name = "Rank Data";
        description = "For assigning ranks to numerical values in a column.";
        helpStrings.add("Select the column containing data to be ranked " +
                "and enter the column or variable name for storing ranks.");
    }
    
    /**
     * 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(InputComboBox);
    }
    
    /** 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() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        InputComboBox = new javax.swing.JComboBox();
        OKButton = new javax.swing.JButton();
        CancelButton = new javax.swing.JButton();
        StoreTextField = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Rank Data");

        jLabel1.setText("Rank data in:");
        jLabel1.setToolTipText("");

        jLabel2.setText("Store Ranks in:");

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

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

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2))
                        .addGap(26, 26, 26)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(StoreTextField)
                            .addComponent(InputComboBox, 0, 115, Short.MAX_VALUE)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(62, 62, 62)
                        .addComponent(OKButton)
                        .addGap(18, 18, 18)
                        .addComponent(CancelButton)))
                .addContainerGap(53, Short.MAX_VALUE))
        );

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

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(22, 22, 22)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(InputComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(StoreTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(34, 34, 34)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(OKButton)
                    .addComponent(CancelButton))
                .addContainerGap(24, Short.MAX_VALUE))
        );

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

    @SuppressWarnings("unchecked")
    private void OKButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OKButtonActionPerformed
        app.compoundEdit = new DialogEdit("rank");
        
        // get input and output column numbers
        String input = InputComboBox.getSelectedItem().toString();
        int inputColumn = ParentSpreadsheet.parseColumnNumber(input);
        
        Vector<Cell> CellColumnVector;
        Vector<Double> ColumnVector;
        CellColumnVector = ParentSpreadsheet.getColumn(inputColumn);
        ColumnVector = HelperFunctions.ConvertInputVectorToDoubles(CellColumnVector);
        if (ColumnVector == null) {
            app.showErrorDialog("Invalid input column " + input +
                    ": all data must be numbers.");
            return;
        }
        
        int storeColumnNum;
        String StoreColumn = StoreTextField.getText();
        // check if Column is valid
        storeColumnNum = ParentSpreadsheet.getColumnNumber(StoreColumn);
        if (storeColumnNum == -1) { // invalid column
            app.showErrorDialog("Enter a valid column name (e.g. C1) or a valid variable name to store the results.");
            return;
        }
        
        Vector<Cell> Cells = (Vector<Cell>) CellColumnVector.clone();

        // sort the vector column cells
        Collections.sort(Cells, new CellComparator());
        
        // compute ranks based on sorted order
        double[] rankArray = new double[Cells.size()];
        Vector<String> rankVector = new Vector<String>(Cells.size());
        double sum = 0, rank;
        int start = 0, end = 0, i;
        // initialize vector
        for (i = 0; i < Cells.size(); ++i)
            rankVector.addElement("");
        i = 0;
        while (i < Cells.size()) {
            start = i;
            end = i;
            // loop over repeated numbers
            while ((end < Cells.size() - 1) && (Cells.elementAt(end).getNumValue() != null) &&
                    (Cells.elementAt(end+1).getNumValue() != null) &&
                    ((Cell)Cells.elementAt(end)).getNumValue().doubleValue() ==
                    ((Cell)Cells.elementAt(end+1)).getNumValue().doubleValue()) {
                end++;
            }

            // start = index of first repeated value, end = index of last repeated value
            sum = 0;
            for (int j = start; j <= end; ++j) {
                sum += j + 1;
            }
            rank = sum / (end - start + 1);
            for (int j = start; j <= end; ++j) {
                rankArray[j] = rank;
            }
            
            i = end+1;
        }
        
        // construct ranks in the order of the column cells
        for (i = 0; i < Cells.size(); ++i) {
            Cell cell = Cells.elementAt(i);
            if (cell.getNumValue() != null) 
                rankVector.setElementAt(rankArray[i] + "", cell.getRow()-1);
        }
        ParentSpreadsheet.setColumn(storeColumnNum, rankVector);
        
        app.addLogParagraph("Rank " + input + "-> store in " + StoreColumn, 
                "");

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

    private void CancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CancelButtonActionPerformed
        setVisible(false);
    }//GEN-LAST:event_CancelButtonActionPerformed
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton CancelButton;
    private javax.swing.JComboBox InputComboBox;
    private javax.swing.JButton OKButton;
    private javax.swing.JTextField StoreTextField;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    // End of variables declaration//GEN-END:variables
    
}
