/*
 * SoilSlopeField.java
 *
 * Created on October 27, 2008, 12:11 PM
 */
package usda.weru.weps.gui;

import java.awt.CardLayout;
import java.awt.event.ItemEvent;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import usda.weru.util.ConvertedValue;
import usda.weru.util.WepsTextField;

/**
 *
 * @author  Joseph Levin <joelevin@weru.ksu.edu>
 */
public class ComboEditorField extends javax.swing.JPanel {
    private static final long serialVersionUID = 1L;

    public static final String CARD_COMBO = "combo";
    public static final String CARD_READONLY = "readonly";
    public static final String CARD_EDITOR = "editor";
    public static final String PROP_VALUE = "value";
    public static final String PROP_READONLY = "readonly";
    private String[] c_choices;
    private double[] c_values;
    private String[] c_display;
    private int c_editIndex = 0;
    private boolean c_readonly;

    /** Creates new form SoilSlopeField */
    public ComboEditorField() {
        initComponents();

        

    }
    
    public void intilize(String[] choices, double[] values, String[] display, int editIndex) {
/**
                 * Note:  Assertions are not enabled.  These will be useless items
                 * unless assertions are enabled.  Thus, they will be commented out unless
                 * the user wishes to enable specific assertions (feed the virtual machine 
                 * the -ea argument).
                 */
//       assert choices.length == values.length : "Choices and values must be paired.";
/**
                 * Note:  Assertions are not enabled.  These will be useless items
                 * unless assertions are enabled.  Thus, they will be commented out unless
                 * the user wishes to enable specific assertions (feed the virtual machine 
                 * the -ea argument).
                 */
//        assert display.length == values.length : "Display and values must be paired.";
        
        c_choices = choices;
        c_values = values;
        c_display = display;
        
        c_editIndex = editIndex;
        
        editor.setCheckNumerics(true);
        editor.setChecks(0, WepsTextField.CHECK_INCLUSIVE, 1, WepsTextField.CHECK_INCLUSIVE);
        editor.setDefaults(0, null, WepsTextField.DEFAULT_LAST);
        editor.setFormat("#0.00#");
        editor.setFormatEdit("#0.000");
        
        combo.setModel(new DefaultComboBoxModel<String>(c_choices));
        showCard(CARD_COMBO);
        combo.setSelectedIndex(-1);
        if (c_choices.length < 8){
            combo.setMaximumRowCount(c_choices.length);
        }
        
    }
    
    private void showCard(String cardName) {
        ((CardLayout) getLayout()).show(this, cardName);
    }

    public void setValue(double value) {
        double old = c_value.getValue();
        c_value.setValue(value);
        
        updateText();
        firePropertyChange(PROP_VALUE, old, c_value.getValue());        
    }

    public double getValue() {
        return c_value.getValue();
    }
    
    public void setReadonly(boolean readonly) {
        boolean old = c_readonly;
        c_readonly = readonly;
        if (c_readonly) {
            showCard(CARD_READONLY);
        } else {
            showCard(CARD_COMBO);            
        }
        firePropertyChange(PROP_READONLY, old, readonly);
    }
    
    public boolean isReadonly() {
        return c_readonly;
    }

    public static void main(String[] args) {
        final JFrame frame = new JFrame("Testing");
        ComboEditorField field = new ComboEditorField();
        frame.add(field);
        frame.pack();

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                frame.setVisible(true);
            }
        });

    }
    
    public ConvertedValue getConvertedValue() {
        return c_value;
    }

    /** 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({"rawtypes", "unchecked"})
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        c_value = new usda.weru.util.ConvertedValue();
        combo = new usda.weru.util.WepsComboBox<String>();
        editor = new usda.weru.util.WepsTextField();
        readonly = new javax.swing.JTextField();

        c_value.setOutputFormat("#0.00#");

        setLayout(new java.awt.CardLayout());

        combo.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                comboItemStateChanged(evt);
            }
        });
        add(combo, "combo");

        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, c_value, org.jdesktop.beansbinding.ELProperty.create("${displayValue}"), editor, org.jdesktop.beansbinding.BeanProperty.create("value"));
        bindingGroup.addBinding(binding);

        editor.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editorActionPerformed(evt);
            }
        });
        editor.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                editorFocusLost(evt);
            }
        });
        add(editor, "editor");

        readonly.setEditable(false);
        add(readonly, "readonly");

        bindingGroup.bind();
    }// </editor-fold>//GEN-END:initComponents

private void comboItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboItemStateChanged
    if (evt.getStateChange() == ItemEvent.SELECTED) {
        int index = combo.getSelectedIndex();
        if (index < 0){
            return; //nothing selected
        }
        if (index == c_editIndex) {
            startEdit();
        } else {
            setValue(c_values[index]);
        }        
    }
}//GEN-LAST:event_comboItemStateChanged

private void editorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editorActionPerformed
    endEdit();
}//GEN-LAST:event_editorActionPerformed

private void editorFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_editorFocusLost
    endEdit();
}//GEN-LAST:event_editorFocusLost
    private double c_oldValue;

    private void startEdit() {
        c_oldValue = c_value.getValue();
        if (c_value.getDisplayValue() < 0) {
            editor.setValue(0);
        }
        showCard(CARD_EDITOR);        
        
        editor.requestFocusInWindow();
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                editor.selectAll();
            }
        });
    }

    private void endEdit() {
        showCard(CARD_COMBO);        
        updateText();
        firePropertyChange(PROP_VALUE, c_oldValue, c_value.getValue());
    }

    private void updateText() {
        String text;
        double value = c_value.getValue();
        for (int i = 0; i < c_values.length; i++){
            if (value == c_values[i]){
                //value matched, do we have a display overide?
                if (c_display[i] != null){
                    text = c_display[i];
                    combo.setText(text);
                    readonly.setText(text);
                    return;
                }
            }
        }
        
        text = c_value.toStringDisplayValue();
        combo.setText(text);
        readonly.setText(text);     
        
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    protected usda.weru.util.ConvertedValue c_value;
    protected usda.weru.util.WepsComboBox<String> combo;
    protected usda.weru.util.WepsTextField editor;
    protected javax.swing.JTextField readonly;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables
}
