/*
 * SimulationPanel.java
 *
 * Created on October 23, 2008, 2:38 PM
 */

package usda.weru.weps;

import com.klg.jclass.util.swing.JCPopupEvent;
import com.klg.jclass.util.swing.JCPopupListener;
import java.awt.event.ItemEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import javax.help.CSH;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import usda.weru.soil.IFC;
import usda.weru.util.ConfigData;
import usda.weru.util.ConvertedValue;
import usda.weru.util.Util;
import usda.weru.util.WepsTextField;

/**
 *
 * @author  Joseph Levin <joelevin@weru.ksu.edu>
 */
public class SimulationPanel extends JPanel implements PropertyChangeListener{
    private static final Logger LOGGER = Logger.getLogger(SimulationPanel.class);
    
    private boolean c_nrcsInstall = false;

    /** Creates new form SimulationPanel */
    public SimulationPanel() {
        initComponents();                        
        addHelp();
        
        waterField.setChecks(0, WepsTextField.CHECK_INCLUSIVE, 0, WepsTextField.CHECK_DISABLED);
        c_water.addPropertyChangeListener(ConvertedValue.PROP_VALUE, new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent evt) {                                
                firePropertyChange(RunFileData.WaterErosionLoss, null, c_water.toStringValue());   
                
            }
        });
        
        startDateField.getPopupEditor().addPopupListener(new JCPopupListener() {

            @Override
            public void commit(JCPopupEvent evt) {
                setStartDate(startDateField.getValue());
            }
        });
        
        endDateField.getPopupEditor().addPopupListener(new JCPopupListener() {

            @Override
            public void commit(JCPopupEvent evt) {
                setEndDate(endDateField.getValue());
            }
        });
               
        //addHelp();
        
        LOGGER.debug("Simulation panel initilized.");
    }

    /** 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() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        c_water = new ConvertedValue(Util.SIUnits, "kg/m^2");
        c_water.addDisplayUnits(Util.USUnits, "tn/ac");
        c_soilSlopeValue = new ConvertedValue(Util.SIUnits, "m/m");
        c_soilSlopeValue.addDisplayUnits(Util.USUnits, "ft/ft");
        c_soilRockFragmentsValue = new ConvertedValue(Util.SIUnits, "m^3/m^3");
        c_soilRockFragmentsValue.addDisplayUnits(Util.USUnits, "ft^3/ft^3");
        waterField = new usda.weru.util.WepsTextField();
        waterUnitLabel = new javax.swing.JLabel();
        modeLabel = new javax.swing.JLabel();
        cycleCountLabel = new javax.swing.JLabel();
        startDateLabel = new javax.swing.JLabel();
        endDateLabel = new javax.swing.JLabel();
        waterLabel = new javax.swing.JLabel();
        soilSlopeLabel = new javax.swing.JLabel();
        rockFragmentsLabel = new javax.swing.JLabel();
        soilSlopeUnitLabel = new javax.swing.JLabel();
        rockFragmentsUnitLabel = new javax.swing.JLabel();
        endDateField = new com.klg.jclass.swing.JCPopupCalendar();
        startDateField = new com.klg.jclass.swing.JCPopupCalendar();
        cycleCountField = new javax.swing.JSpinner();
        soilSlopeField = new usda.weru.weps.gui.ComboEditorField();
        rockFragmentsField = new usda.weru.weps.gui.ComboEditorField();
        modeField = new javax.swing.JComboBox();
        soilRockFragmentsValue = new usda.weru.util.WepsTextField();
        soilSlopeValue = new usda.weru.util.WepsTextField();
        soilSlopeLabel1 = new javax.swing.JLabel();
        soilSlopeLabel2 = new javax.swing.JLabel();
        rockFragmentsUnits1 = new javax.swing.JLabel();
        regionSlopeUnits1 = new javax.swing.JLabel();

        c_water.setOutputFormat("#0.0000");

        c_soilSlopeValue.setOutputFormat("#0.0000");

        c_soilRockFragmentsValue.setOutputFormat("#0.0000");

        waterField.setFormat("#0.00##");
        waterField.setFormatEdit("#0.000#");
        waterField.setPreferredSize(new java.awt.Dimension(100, 20));

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

        waterUnitLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, c_water, org.jdesktop.beansbinding.ELProperty.create("${displayUnits.abbreviation}"), waterUnitLabel, org.jdesktop.beansbinding.BeanProperty.create("text"));
        binding.setSourceUnreadableValue("units");
        bindingGroup.addBinding(binding);

        modeLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        modeLabel.setText("Run Mode");

        cycleCountLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        cycleCountLabel.setText("Cycle Count");

        startDateLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        startDateLabel.setText("Start Date");

        endDateLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        endDateLabel.setText("End Date");

        waterLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        waterLabel.setText("Water Erosion");

        soilSlopeLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        soilSlopeLabel.setText("Region Slope");

        rockFragmentsLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        rockFragmentsLabel.setText("Rock Fragments");

        soilSlopeUnitLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, soilSlopeField, org.jdesktop.beansbinding.ELProperty.create("${convertedValue.displayUnits.abbreviation}"), soilSlopeUnitLabel, org.jdesktop.beansbinding.BeanProperty.create("text"));
        bindingGroup.addBinding(binding);

        rockFragmentsUnitLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, rockFragmentsField, org.jdesktop.beansbinding.ELProperty.create("${convertedValue.displayUnits.abbreviation}"), rockFragmentsUnitLabel, org.jdesktop.beansbinding.BeanProperty.create("text"));
        bindingGroup.addBinding(binding);

        endDateField.setCalendarType(com.klg.jclass.swing.JCPopupCalendar.DATE);
        endDateField.setEditable(true);
        endDateField.setHidePopupOnDayTableClick(true);
        endDateField.setMinimumDate(new java.util.Date(-62135747999250l));
        endDateField.setPreferredSize(new java.awt.Dimension(89, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${endDate}"), endDateField, org.jdesktop.beansbinding.BeanProperty.create("value"));
        bindingGroup.addBinding(binding);

        startDateField.setCalendarType(com.klg.jclass.swing.JCPopupCalendar.DATE);
        startDateField.setEditable(true);
        startDateField.setHidePopupOnDayTableClick(true);
        startDateField.setMinimumDate(new java.util.Date(-62135747999250l));
        startDateField.setPreferredSize(new java.awt.Dimension(89, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${startDate}"), startDateField, org.jdesktop.beansbinding.BeanProperty.create("value"));
        bindingGroup.addBinding(binding);

        cycleCountField.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(50), Integer.valueOf(1), null, Integer.valueOf(1)));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${cycleCount}"), cycleCountField, org.jdesktop.beansbinding.BeanProperty.create("value"));
        bindingGroup.addBinding(binding);

        soilSlopeField.getConvertedValue().setBaseUnits("m/m");
        soilSlopeField.getConvertedValue().addDisplayUnits(Util.SIUnits, "m/m");
        soilSlopeField.getConvertedValue().addDisplayUnits(Util.USUnits, "ft/ft");
        String[] soilSlopeChoices = {"Override Soil Slope", "Use Soil Slope from Soils Database", "Level Basin, No Runoff", "Slope 0.001 (0.1%)", "Slope 0.01 (1%)", "Slope 0.02 (2%)", "Slope 0.03 (3%)", "Slope 0.05 (5%)", "Slope 0.10 (10%)"};
        double[] soilSlopeValues = {0, -1, -2, 0.001, 0.01, 0.02, 0.03, 0.05, 0.10};
        String[] soilSlopeDisplay = {null, "FROM SOIL DB", "BASIN", null, null, null,null,null, null};
        soilSlopeField.intilize(soilSlopeChoices, soilSlopeValues, soilSlopeDisplay, 0);
        soilSlopeField.setPreferredSize(new java.awt.Dimension(100, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${soilSlope}"), soilSlopeField, org.jdesktop.beansbinding.BeanProperty.create("value"));
        bindingGroup.addBinding(binding);

        rockFragmentsField.getConvertedValue().setBaseUnits("m^3/m^3");
        rockFragmentsField.getConvertedValue().addDisplayUnits(Util.SIUnits, "m^3/m^3");
        rockFragmentsField.getConvertedValue().addDisplayUnits(Util.USUnits, "ft^3/ft^3");
        String[] rockFragmentsChoices = {"Override Rock Fragments", "Use Rock Fragments from Soils Database"};
        double[] rockFragmentsValues = {0, -1};
        String[] rockFragmentsDisplay = {null, "FROM SOIL DB"};
        rockFragmentsField.intilize(rockFragmentsChoices, rockFragmentsValues, rockFragmentsDisplay, 0);
        rockFragmentsField.setPreferredSize(new java.awt.Dimension(100, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${rockFragments}"), rockFragmentsField, org.jdesktop.beansbinding.BeanProperty.create("value"));
        bindingGroup.addBinding(binding);

        modeField.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "NRCS", "Cycle", "Dates" }));
        modeField.setPreferredSize(new java.awt.Dimension(54, 20));
        modeField.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                modeFieldItemStateChanged(evt);
            }
        });

        soilRockFragmentsValue.setEditable(false);
        soilRockFragmentsValue.setDisabledTextColor(java.awt.SystemColor.textText);
        soilRockFragmentsValue.setFormat("#0.00##");
        soilRockFragmentsValue.setFormatEdit("#0.000#");
        soilRockFragmentsValue.setPreferredSize(new java.awt.Dimension(100, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ, c_soilRockFragmentsValue, org.jdesktop.beansbinding.ELProperty.create("${displayValue}"), soilRockFragmentsValue, org.jdesktop.beansbinding.BeanProperty.create("value"));
        bindingGroup.addBinding(binding);

        soilSlopeValue.setEditable(false);
        soilSlopeValue.setDisabledTextColor(java.awt.SystemColor.textText);
        soilSlopeValue.setFormat("#0.00##");
        soilSlopeValue.setFormatEdit("#0.000#");
        soilSlopeValue.setPreferredSize(new java.awt.Dimension(100, 20));

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ, c_soilSlopeValue, org.jdesktop.beansbinding.ELProperty.create("${displayValue}"), soilSlopeValue, org.jdesktop.beansbinding.BeanProperty.create("value"));
        bindingGroup.addBinding(binding);

        soilSlopeLabel1.setFont(soilSlopeLabel1.getFont().deriveFont(soilSlopeLabel1.getFont().getStyle() & ~java.awt.Font.BOLD));
        soilSlopeLabel1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        soilSlopeLabel1.setText("Soil DB Value");

        soilSlopeLabel2.setFont(soilSlopeLabel2.getFont().deriveFont(soilSlopeLabel2.getFont().getStyle() & ~java.awt.Font.BOLD));
        soilSlopeLabel2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        soilSlopeLabel2.setText("Soil DB Value");

        rockFragmentsUnits1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, rockFragmentsField, org.jdesktop.beansbinding.ELProperty.create("${convertedValue.displayUnits.abbreviation}"), rockFragmentsUnits1, org.jdesktop.beansbinding.BeanProperty.create("text"));
        binding.setSourceUnreadableValue("units");
        bindingGroup.addBinding(binding);

        regionSlopeUnits1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, soilSlopeField, org.jdesktop.beansbinding.ELProperty.create("${convertedValue.displayUnits.abbreviation}"), regionSlopeUnits1, org.jdesktop.beansbinding.BeanProperty.create("text"));
        binding.setSourceUnreadableValue("units");
        bindingGroup.addBinding(binding);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(soilSlopeLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)
                    .addComponent(cycleCountLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)
                    .addComponent(startDateLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)
                    .addComponent(endDateLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)
                    .addComponent(waterLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)
                    .addComponent(soilSlopeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)
                    .addComponent(soilSlopeLabel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)
                    .addComponent(rockFragmentsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)
                    .addComponent(modeLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(endDateField, javax.swing.GroupLayout.PREFERRED_SIZE, 128, Short.MAX_VALUE)
                    .addComponent(startDateField, javax.swing.GroupLayout.PREFERRED_SIZE, 128, Short.MAX_VALUE)
                    .addComponent(cycleCountField, javax.swing.GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE)
                    .addComponent(modeField, 0, 128, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(waterField, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(soilSlopeValue, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(soilSlopeField, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                .addGap(1, 1, 1)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(regionSlopeUnits1, 0, 23, Short.MAX_VALUE)
                            .addComponent(waterUnitLabel, javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(soilSlopeUnitLabel, javax.swing.GroupLayout.Alignment.TRAILING)))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(soilRockFragmentsValue, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE)
                            .addComponent(rockFragmentsField, javax.swing.GroupLayout.DEFAULT_SIZE, 101, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(rockFragmentsUnits1, 0, 23, Short.MAX_VALUE)
                            .addComponent(rockFragmentsUnitLabel))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(modeLabel)
                    .addComponent(modeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cycleCountLabel)
                    .addComponent(cycleCountField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(0, 0, 0)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(startDateLabel)
                    .addComponent(startDateField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(0, 0, 0)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(endDateLabel)
                    .addComponent(endDateField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(waterUnitLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(waterLabel)
                    .addComponent(waterField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(regionSlopeUnits1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(soilSlopeLabel)
                    .addComponent(soilSlopeField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(0, 0, 0)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(soilSlopeValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(soilSlopeLabel1)
                    .addComponent(soilSlopeUnitLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(rockFragmentsUnits1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(rockFragmentsLabel)
                    .addComponent(rockFragmentsField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(0, 0, 0)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(soilRockFragmentsValue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(soilSlopeLabel2)
                    .addComponent(rockFragmentsUnitLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

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

private void modeFieldItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_modeFieldItemStateChanged
        if (!holdFire && evt.getStateChange() == ItemEvent.SELECTED){                
        switch (modeField.getSelectedIndex()){
            case 0:
                firePropertyChange(RunFileData.RunTypeDisp, null, ConfigData.NRCS);
                break;
            case 1:
                firePropertyChange(RunFileData.RunTypeDisp, null, ConfigData.Cycle);
                break;
            case 2:
                firePropertyChange(RunFileData.RunTypeDisp, null, ConfigData.Dates);
                break;
            default:
                return;
        }
    }
}//GEN-LAST:event_modeFieldItemStateChanged


    // Variables declaration - do not modify//GEN-BEGIN:variables
    protected usda.weru.util.ConvertedValue c_soilRockFragmentsValue;
    protected usda.weru.util.ConvertedValue c_soilSlopeValue;
    protected usda.weru.util.ConvertedValue c_water;
    protected javax.swing.JSpinner cycleCountField;
    protected javax.swing.JLabel cycleCountLabel;
    protected com.klg.jclass.swing.JCPopupCalendar endDateField;
    protected javax.swing.JLabel endDateLabel;
    protected javax.swing.JComboBox modeField;
    protected javax.swing.JLabel modeLabel;
    protected javax.swing.JLabel regionSlopeUnits1;
    protected usda.weru.weps.gui.ComboEditorField rockFragmentsField;
    protected javax.swing.JLabel rockFragmentsLabel;
    protected javax.swing.JLabel rockFragmentsUnitLabel;
    protected javax.swing.JLabel rockFragmentsUnits1;
    protected usda.weru.util.WepsTextField soilRockFragmentsValue;
    protected usda.weru.weps.gui.ComboEditorField soilSlopeField;
    protected javax.swing.JLabel soilSlopeLabel;
    protected javax.swing.JLabel soilSlopeLabel1;
    protected javax.swing.JLabel soilSlopeLabel2;
    protected javax.swing.JLabel soilSlopeUnitLabel;
    protected usda.weru.util.WepsTextField soilSlopeValue;
    protected com.klg.jclass.swing.JCPopupCalendar startDateField;
    protected javax.swing.JLabel startDateLabel;
    protected usda.weru.util.WepsTextField waterField;
    protected javax.swing.JLabel waterLabel;
    protected javax.swing.JLabel waterUnitLabel;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        String property = evt.getPropertyName();
        String value = evt.getNewValue() != null ? evt.getNewValue().toString() : null;
        if (RunFileData.RunTypeDisp.equals(property)){
            updateMode(value);
        }
        else if (ConfigData.Units.equals(property)) {            
            c_water.setDisplaySystem(value);
            c_soilSlopeValue.setDisplaySystem(value);
            c_soilRockFragmentsValue.setDisplaySystem(value);
            
            
            soilSlopeField.getConvertedValue().setDisplaySystem(value);
            rockFragmentsField.getConvertedValue().setDisplaySystem(value);

        }
        else if (RunFileData.WaterErosionLoss.equals(property)) {
            double d = Double.parseDouble(value);
            if(d <= 0){
                LOGGER.warn("Invalid water erosion value: " + d);
                d = 0;
            }
            c_water.setValue(d);
        }
        else if (RunFileData.CycleCount.equals(property)){
            setCycleCount(Integer.valueOf(value), false);
        }
        else if (RunFileData.StartDate.equals(property)){
            setStartDate(parseDate(value), false);
        }
        else if (RunFileData.EndDate.equals(property)){
            setEndDate(parseDate(value), false);
        }
        else if (ConfigData.ReadonlySlope.equals(property)){
            if ("1".equals(value)){
                soilSlopeField.setReadonly(true);
            }
            else{
                soilSlopeField.setReadonly(false);
            }            
        }
        else if (ConfigData.ReadonlyRockFragments.equals(property)){
            if ("1".equals(value)){
                rockFragmentsField.setReadonly(true);
            }
            else{
                rockFragmentsField.setReadonly(false);
            }
        }
        else if (RunFileData.AverageSlope.equals(property)){
            setSoilSlope(Double.valueOf(value), false);
        }
        else if (RunFileData.SoilRockFragments.equals(property)){
            setRockFragments(Double.valueOf(value), false);
        }
        else if (ConfigData.CompatibilityNRCS.equals(property)){
            if ("1".equals(value)){
                updateCompatibility(true);
            }
            else{
                updateCompatibility(false);
            }
        }
        else if (RunFileData.SoilFile.equals(property)){
            updateSoilValues(value);
        }
    }

    private String c_lastSoilPath;
    //TODO: move into properly threaded gui/data contexts
    private void updateSoilValues(String path){
        if (path != null){
            if (!path.equals(c_lastSoilPath)){
                try {
                    IFC ifc = new IFC();
                    ifc.readIfc(path);
                    c_soilSlopeValue.setValue(ifc.surfaceSlope);
                    if(ifc.nsl > 0){
                        c_soilRockFragmentsValue.setValue(ifc.fractionRock[0]);
                    }
                    else{
                        //no layers
                        c_soilRockFragmentsValue.setValue(Double.NaN);
                    }

                }
                catch (IOException ex) {
                    LOGGER.warn("Error reading soil file: " + path);
                    c_soilRockFragmentsValue.setValue(Double.NaN);
                    c_soilSlopeValue.setValue(Double.NaN);
                }
            }
            //else nothing changed
        }
        else{
            c_soilRockFragmentsValue.setValue(Double.NaN);
            c_soilSlopeValue.setValue(Double.NaN);
        }
    }
    
    private void updateCompatibility(boolean c){
        if (c == c_nrcsInstall){
            //no change
            return;
        }
        c_nrcsInstall = c;        
        modeField.setEnabled(!c);
    }
    
    //methods for beans binding
    private int c_cycleCount;
    public int getCycleCount(){
        return c_cycleCount;
    }
    
    public void setCycleCount(int count){
        setCycleCount(count, true);
    }
    
    public void setCycleCount(int count, boolean fireRFD){
        int old = c_cycleCount;
        c_cycleCount = count;
        
        firePropertyChange("cycleCount", old, c_cycleCount);
        
        if (fireRFD){
            firePropertyChange(RunFileData.CycleCount, Integer.toString(old), Integer.toString(c_cycleCount));
        }
    }
    
    private DateFormat dateFormat(){
        return new SimpleDateFormat("dd MM yyyy");
    }
    
    private Date parseDate(String value){
        try{
            return dateFormat().parse(value);
        }
        catch(ParseException pe){
            LOGGER.warn("Error parsing date: " + value);
            return null;
        }
    }        
    
    private Date c_startDate;
    public Date getStartDate(){
        return c_startDate;
    }
    
    public void setStartDate(Date date){
        setStartDate(date, true);
    }
    
    public void setStartDate(Date date, boolean fireRFD){
        Date old = c_startDate;
        c_startDate = date;
        
        firePropertyChange("startDate", old, c_startDate);
        if (fireRFD){
            DateFormat format = dateFormat();
            firePropertyChange(RunFileData.StartDate, old != null ? format.format(old) : null, c_startDate != null ? format.format(c_startDate) : null);
        }
    }
    
    private Date c_endDate;
    public Date getEndDate(){
        return c_endDate;
    }
    
    public void setEndDate(Date date){
        setEndDate(date, true);
    }
    
    public void setEndDate(Date date, boolean fireRFD){
        Date old = c_endDate;
        c_endDate = date;
        
        firePropertyChange("endDate", old, c_endDate);
        if (fireRFD){
            DateFormat format = dateFormat();
            firePropertyChange(RunFileData.EndDate, old != null ? format.format(old) : null, c_endDate != null ? format.format(c_endDate) : null);
        }
    }
    
    private double c_soilSlope;
    public double getSoilSlope(){
        return c_soilSlope;
    }
    
    public void setSoilSlope(double slope){
        setSoilSlope(slope, true);
    }
    
    public void setSoilSlope(double slope, boolean fireRFD){
        double old = c_soilSlope;
        c_soilSlope = slope;

        regionSlopeUnits1.setVisible(c_soilSlope >= 0);
        firePropertyChange("soilSlope", old, c_soilSlope);
        if (fireRFD){
            firePropertyChange(RunFileData.AverageSlope, Double.toString(old), Double.toString(c_soilSlope));
        }
    }
    
    private double c_rockFragments2;
    public double getRockFragments(){
        return c_rockFragments2;
    }
    
    public void setRockFragments(double slope){
        setRockFragments(slope, true);
    }
    
    public void setRockFragments(double slope, boolean fireRFD){
        double old = c_rockFragments2;
        c_rockFragments2 = slope;

        rockFragmentsUnits1.setVisible(c_rockFragments2 >= 0);
        
        firePropertyChange("rockFragments", old, c_rockFragments2);
        if (fireRFD){
            firePropertyChange(RunFileData.SoilRockFragments, Double.toString(old), Double.toString(c_rockFragments2));
        }
    }
    private boolean holdFire = false;
    
    private void updateMode(String type){
        //holdFire = true;
        type = type != null ? type.trim().toLowerCase() : null;
        
        if (ConfigData.NRCS.toLowerCase().equals(type)){
            modeField.setSelectedItem("NRCS");
            startDateField.setVisible(false);
            startDateLabel.setVisible(false);
            
            endDateField.setVisible(false);
            endDateLabel.setVisible(false);
            
            cycleCountField.setVisible(false);
            cycleCountLabel.setVisible(false);
            
//            rockFragmentField.setVisible(true);
//            rockFragmentsLabel.setVisible(true);
//            rockFragmentsUnitLabel.setVisible(true);
            
            soilSlopeField.setVisible(true);
            soilSlopeLabel.setVisible(true);
            soilSlopeUnitLabel.setVisible(true);
            
            waterField.setVisible(true);
            waterLabel.setVisible(true);
            waterUnitLabel.setVisible(true);
            
        }
        else if (ConfigData.Cycle.toLowerCase().equals(type)){
            if(c_nrcsInstall){
                rejectMode();
                return;
            }
            modeField.setSelectedItem("Cycle");
            startDateField.setVisible(false);
            startDateLabel.setVisible(false);
            
            endDateField.setVisible(false);
            endDateLabel.setVisible(false);
            
            cycleCountField.setVisible(true);
            cycleCountLabel.setVisible(true);
            
//            rockFragmentField.setVisible(true);
//            rockFragmentsLabel.setVisible(true);
//            rockFragmentsUnitLabel.setVisible(true);
            
            soilSlopeField.setVisible(true);
            soilSlopeLabel.setVisible(true);
            soilSlopeUnitLabel.setVisible(true);
            
            waterField.setVisible(true);
            waterLabel.setVisible(true);
            waterUnitLabel.setVisible(true);            
        }
        else if(ConfigData.Dates.toLowerCase().equals(type)){
            if(c_nrcsInstall){
                rejectMode();
                return;
            }
            modeField.setSelectedItem("Dates");
            startDateField.setVisible(true);
            startDateLabel.setVisible(true);
            
            endDateField.setVisible(true);
            endDateLabel.setVisible(true);
            
            cycleCountField.setVisible(false);
            cycleCountLabel.setVisible(false);
            
//            rockFragmentField.setVisible(true);
//            rockFragmentsLabel.setVisible(true);
//            rockFragmentsUnitLabel.setVisible(true);
            
            soilSlopeField.setVisible(true);
            soilSlopeLabel.setVisible(true);
            soilSlopeUnitLabel.setVisible(true);
            
            waterField.setVisible(true);
            waterLabel.setVisible(true);
            waterUnitLabel.setVisible(true);
        }
        else{
            LOGGER.warn("Unknown run mode: " + type);
        }
        holdFire = false;
    }   
    
    private void rejectMode(){        
        firePropertyChange(RunFileData.RunTypeDisp, null, ConfigData.NRCS);
        JOptionPane.showMessageDialog(this, "This run was configured with an alternative run mode unavailable with an NRCS install.\nThe mode was changed to NRCS.", "Compatibility", JOptionPane.INFORMATION_MESSAGE);
    }
    
    private void addHelp(){
        CSH.setHelpIDString(startDateLabel, "simrunStartDate_html");
        CSH.setHelpIDString(startDateField, "simrunStartDate_html");
        CSH.setHelpIDString(endDateLabel, "simrunEndDate_html");
        CSH.setHelpIDString(endDateField, "simrunEndDate_html");
        CSH.setHelpIDString(cycleCountLabel, "simrunRotCyc_html");
        CSH.setHelpIDString(cycleCountField, "simrunRotCyc_html");
        CSH.setHelpIDString(modeLabel, "simrunNRCS_html");
        CSH.setHelpIDString(modeField, "simrunNRCS_html");
    }

}
