/*
 * 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.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.FileNotFoundException;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;

import javax.help.CSH;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; 
import usda.weru.mcrew.DisplayCalendar;
import usda.weru.mcrew.JulianCalendar;
import usda.weru.soil.IFC;
import usda.weru.util.ConfigData;
import usda.weru.util.ConvertedValue;
import usda.weru.util.Util;

/**
 *
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public class SimulationPanel extends JPanel implements PropertyChangeListener {

    private static final long serialVersionUID = 1L;

    private static final Logger LOGGER = LogManager.getLogger(SimulationPanel.class);

    private boolean c_nrcsInstall = false;
    private String measurementUnits = Util.SIUnits;

    DateFormat df = new SimpleDateFormat("MMMM dd, yyyy");
    private simCalendarSelector simCalStart;
    private simCalendarSelector simCalEnd;

    //variables for setting condition for preventing run with unordered dates
    //this is used in the weps.java file for preventing the error
    private static boolean datesUnordered = false;

    public static boolean getDatesUnordered() {
        return datesUnordered;
    }

    private static void setDatesUnordered(boolean dateDisjoint) {
        SimulationPanel.datesUnordered = dateDisjoint;
    }

    /**
     * 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() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                firePropertyChange(RunFileData.WaterErosionLoss, null, c_water.toStringValue());

            }
        });

        //do not allow text box editing
        //this may prevent user input errors
        startDateText.setEditable(false);
        endDateText.setEditable(false);

        simCalStart = new simCalendarSelector(false);
        startDateField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                simCalStart.calendarPopOut();
            }
        });
        startDateField.setVisible(true);

        simCalEnd = new simCalendarSelector(true);
        endDateField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                simCalEnd.calendarPopOut();
            }
        });
        endDateField.setVisible(true);
        
//        RunFileData
//        firePropertyChange(RunFileData.AverageSlopeField,null,c_soilSlopeValue.getValue());
        //addHelp();
        LOGGER.debug("Simulation panel initilized.");
        String mode = ConfigData.getDefault().getData(ConfigData.DefaultRunMode);
        System.err.println("Mode: " + mode);
        switch(mode) {
            case "dates":
                firePropertyChange(RunFileData.RunTypeDisp, null, ConfigData.Dates);
                break;
            case "NRCS":
                firePropertyChange(RunFileData.RunTypeDisp, null, ConfigData.NRCS);
                break;
            case "cycle":
                firePropertyChange(RunFileData.RunTypeDisp, null, ConfigData.Cycle);
                break;
            default:
                System.out.println("WARNING: Unknown mode selected.");
                break;
        }
        updateMode(mode);
    }

    /**
     * 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() {

        c_water = new ConvertedValue(Util.SIUnits, "kg/m^2/yr");
 c_water.addDisplayUnits(Util.USUnits, "t/ac/yr");
        c_soilSlopeValue = new ConvertedValue(Util.SIUnits, "m/m");
        c_soilSlopeValue.addDisplayUnits(Util.USUnits, "ft/ft");
        c_soilRockFragmentsValue = new ConvertedValue(Util.SIUnits, "m^2/m^2");
        c_soilRockFragmentsValue.addDisplayUnits(Util.USUnits, "ft^2/ft^2");
        jLayeredPane1 = new javax.swing.JLayeredPane();
        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();
        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();
        startDateText = new javax.swing.JTextField();
        endDateText = new javax.swing.JTextField();
        startDateField = new javax.swing.JButton();
        endDateField = new javax.swing.JButton();

        c_water.setOutputFormat("#0.0000");

        c_soilSlopeValue.setOutputFormat("#0.0000");

        c_soilRockFragmentsValue.setOutputFormat("#0.0000");

        javax.swing.GroupLayout jLayeredPane1Layout = new javax.swing.GroupLayout(jLayeredPane1);
        jLayeredPane1.setLayout(jLayeredPane1Layout);
        jLayeredPane1Layout.setHorizontalGroup(
            jLayeredPane1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );
        jLayeredPane1Layout.setVerticalGroup(
            jLayeredPane1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );

        waterField.setToolTipText("");
        waterField.setFormat("#0.00#");
        waterField.setFormatEdit("#0.0000");
        waterField.setInputVerifier(new DoubleInputVerifier());
        waterField.setPreferredSize(new java.awt.Dimension(100, 20));
        waterField.setInputVerifier(new DoubleInputVerifier());
        waterField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                waterFieldFocusLost(evt);
            }
        });
        waterField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                waterFieldActionPerformed(evt);
            }
        });

        waterUnitLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

        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.LEFT);
        soilSlopeLabel.setText("Region Slope");

        rockFragmentsLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        rockFragmentsLabel.setText("Rock Fragments");

        soilSlopeUnitLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

        rockFragmentsUnitLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

        cycleCountField.setModel(new javax.swing.SpinnerNumberModel(50, 1, null, 1));

        soilSlopeField.getConvertedValue().setBaseUnits("m/m");
        soilSlopeField.getConvertedValue().addDisplayUnits(Util.SIUnits, "m/m");
        soilSlopeField.getConvertedValue().addDisplayUnits(Util.USUnits, "ft/ft");
        String[] soilSlopeChoices = {"Override Soil Slope", "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, "Use value from Soil DB", "BASIN", null, null, null,null,null, null};
        soilSlopeField.intilize(soilSlopeChoices, soilSlopeValues, soilSlopeDisplay, 0);
        soilSlopeField.setValue(-1);
        soilSlopeField.setPreferredSize(new java.awt.Dimension(100, 20));
        soilSlopeField.setInputVerifier(new PercentageInputVerifier());
        soilSlopeField.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                soilSlopeFieldPropertyChange(evt);
            }
        });

        rockFragmentsField.getConvertedValue().setBaseUnits("m^2/m^2");
        rockFragmentsField.getConvertedValue().addDisplayUnits(Util.SIUnits, "m^2/m^2");
        rockFragmentsField.getConvertedValue().addDisplayUnits(Util.USUnits, "ft^2/ft^2");
        String[] rockFragmentsChoices = {"Override Rock Fragments", "Rock Fragments from Soils Database"};
        double[] rockFragmentsValues = {0, -1};
        String[] rockFragmentsDisplay = {null, "Use value from Soil DB"};
        rockFragmentsField.intilize(rockFragmentsChoices, rockFragmentsValues, rockFragmentsDisplay, 0);
        rockFragmentsField.setValue(-1);
        rockFragmentsField.setPreferredSize(new java.awt.Dimension(100, 20));
        rockFragmentsField.setInputVerifier(new PercentageInputVerifier());
        rockFragmentsField.addContainerListener(new java.awt.event.ContainerAdapter() {
            public void componentAdded(java.awt.event.ContainerEvent evt) {
                rockFragmentsFieldComponentAdded(evt);
            }
        });
        rockFragmentsField.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                rockFragmentsFieldPropertyChange(evt);
            }
        });

        modeField.setModel(new javax.swing.DefaultComboBoxModel<String>(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.setEnabled(false);
        soilRockFragmentsValue.setFormat("#0.00##");
        soilRockFragmentsValue.setFormatEdit("#0.000#");
        soilRockFragmentsValue.setPreferredSize(new java.awt.Dimension(100, 20));

        soilSlopeValue.setEditable(false);
        soilSlopeValue.setDisabledTextColor(java.awt.SystemColor.textText);
        soilSlopeValue.setEnabled(false);
        soilSlopeValue.setFormat("#0.00##");
        soilSlopeValue.setFormatEdit("#0.000#");
        soilSlopeValue.setPreferredSize(new java.awt.Dimension(100, 20));

        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);

        regionSlopeUnits1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

        startDateText.setText("Jan 1, 0001");
        startDateText.setPreferredSize(new java.awt.Dimension(59, 21));
        startDateText.setRequestFocusEnabled(false);

        endDateText.setText("Dec 31, 0001");
        endDateText.setPreferredSize(new java.awt.Dimension(59, 21));
        endDateText.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                endDateTextActionPerformed(evt);
            }
        });

        startDateField.setIcon(new javax.swing.ImageIcon(getClass().getResource("/usda/weru/resources/calpng2.png"))); // NOI18N
        startDateField.setToolTipText("<html>\n<b>Start Date Calendar icon (only displays when \"Dates\" Run Mode is selected)</b>\n<p>The Start Date calendar icon provides a convenient graphical means to select the \"Start Date\" of the simulation run when in \"Dates\" Run mode.</p>");
        startDateField.setPreferredSize(new java.awt.Dimension(27, 20));

        endDateField.setIcon(new javax.swing.ImageIcon(getClass().getResource("/usda/weru/resources/calpng2.png"))); // NOI18N
        endDateField.setToolTipText("<html>\n<b>End Date Calendar icon (only displays when \"Dates\" Run Mode is selected)</b>\n<p>The End Date calendar icon provides a convenient graphical means to select the \"End Date\" of the simulation run when in \"Dates\" Run mode.</p>");
        endDateField.setPreferredSize(new java.awt.Dimension(27, 20));

        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)
                    .addComponent(rockFragmentsLabel)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(waterLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(soilSlopeLabel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(cycleCountLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(startDateLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(endDateLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(modeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(soilSlopeLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(soilSlopeLabel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(soilSlopeValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(soilSlopeField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(soilSlopeUnitLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(regionSlopeUnits1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                    .addComponent(cycleCountField)
                    .addComponent(modeField, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(startDateText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(endDateText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(startDateField, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(endDateField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(waterField, javax.swing.GroupLayout.DEFAULT_SIZE, 229, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(waterUnitLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(rockFragmentsField, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(soilRockFragmentsValue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .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(rockFragmentsUnitLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                .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(1, 1, 1)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(startDateLabel)
                    .addComponent(startDateText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(startDateField, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(endDateText, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(endDateLabel))
                    .addComponent(endDateField, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(waterUnitLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .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.LEADING)
                    .addComponent(soilSlopeUnitLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .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)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 16, Short.MAX_VALUE)
                .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, 21, Short.MAX_VALUE))
                .addGap(0, 0, 0)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(rockFragmentsUnitLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .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)))
                .addContainerGap(20, Short.MAX_VALUE))
        );
    }// </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

    private void endDateTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_endDateTextActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_endDateTextActionPerformed

    private void waterFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_waterFieldActionPerformed

        if(measurementUnits.equals(Util.SIUnits)){
            setCWaterUnits(false);
        c_water.setValue(waterField.getValue());//.setValue(waterField.getValue());     
            setCWaterUnits(true);
        }else{
            c_water.setDisplayValue(waterField.getValue());

        }
        
        firePropertyChange(RunFileData.WaterErosionLoss, null, c_water.toStringValue());
//        setCWaterUnits(true);
        
    }//GEN-LAST:event_waterFieldActionPerformed

    private void waterFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_waterFieldFocusLost
        if(measurementUnits.equals(Util.SIUnits)){
            setCWaterUnits(false);
            c_water.setValue(waterField.getValue());//.setValue(waterField.getValue());     
            setCWaterUnits(true);
        }else{
            c_water.setDisplayValue(waterField.getValue());
        }
       
        firePropertyChange(RunFileData.WaterErosionLoss, null, c_water.toStringValue());

    }//GEN-LAST:event_waterFieldFocusLost

    private void soilSlopeFieldPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_soilSlopeFieldPropertyChange
        
        c_soilSlopeValue.setValue(soilSlopeField.getValue());//.setDisplayUnits(soilSlopeField.getValue());
        firePropertyChange(RunFileData.AverageSlope, null, c_soilSlopeValue.toStringValue());


    }//GEN-LAST:event_soilSlopeFieldPropertyChange

    private void rockFragmentsFieldPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_rockFragmentsFieldPropertyChange
        c_soilRockFragmentsValue.setValue(rockFragmentsField.getValue());//.setDisplayUnits(soilSlopeField.getValue());
        firePropertyChange(RunFileData.SoilRockFragments, null, c_soilRockFragmentsValue.toStringValue());
//        c_soilRockFragmentsValue.setDisplayValue(rockFragmentsField.getValue());
//        setRockFragments(c_soilRockFragmentsValue.getValue());
//        setso;
    }//GEN-LAST:event_rockFragmentsFieldPropertyChange

    private void rockFragmentsFieldComponentAdded(java.awt.event.ContainerEvent evt) {//GEN-FIRST:event_rockFragmentsFieldComponentAdded
        // TODO add your handling code here:
    }//GEN-LAST:event_rockFragmentsFieldComponentAdded

    /**
     * This method is invoked whenever the orientation text field of the simulation 
     * region panel gets a value entered/modified or even just gets focused and then
     * loses focus to some other component in the containenr or a different container.
     * @param event
     */
    public void JTF_waterField_focusLost(java.awt.event.FocusEvent event) {

    }

    // 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 javax.swing.JButton endDateField;
    protected javax.swing.JLabel endDateLabel;
    protected javax.swing.JTextField endDateText;
    protected javax.swing.JLayeredPane jLayeredPane1;
    protected javax.swing.JComboBox<String> 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 javax.swing.JButton startDateField;
    protected javax.swing.JLabel startDateLabel;
    protected javax.swing.JTextField startDateText;
    //
    protected usda.weru.util.WepsTextField waterField;
    protected javax.swing.JLabel waterLabel;
    protected javax.swing.JLabel waterUnitLabel;
    // 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;
        switch (property) {
            case RunFileData.RunTypeDisp:
                String configMode = ConfigData.getDefault().getData(ConfigData.DefaultRunMode).toLowerCase();
                if(value.toLowerCase().equals(configMode)) {
                    updateMode(value);
                } else if(!Weps.isNRCSMode) {
                    JOptionPane.showMessageDialog(null,
                        "The default simulation mode is different from the current run's simulation mode.\nIgnoring the default simulation mode.",
                        "Simulation Mode Mismatch",
                        JOptionPane.WARNING_MESSAGE);
                    updateMode(value);
                } else {
                    JOptionPane.showMessageDialog(null,
                        "The default simulation mode is different from the current run's simulation mode.\nIgnoring the default simulation mode.",
                        "Simulation Mode Mismatch",
                        JOptionPane.WARNING_MESSAGE);
                    updateMode("nrcs");
                    int nrcsCycleCount = ConfigData.getIntParm(ConfigData.NRCSRunLen, 50);
                    setCycleCount(nrcsCycleCount, true);
                }
                break;
            case ConfigData.Units:
//                waterFieldFocusLost(null);
                measurementUnits = value;
                String beforeUnits = c_water.getDisplayUnits().getName();
                updateLabelsUnits();
//                c_water.setDisplaySystem(value);
                updateWaterLabelValue();
                updateFragmentsLabel();
                updateSoilSlopeLabel();
//                c_soilRockFragmentsValue.setDisplaySystem(value);
//                c_soilSlopeValue.setDisplaySystem(value);
                if(!beforeUnits.equals(c_water.getDisplayUnits().getName())){
                    if(measurementUnits.equals(Util.SIUnits)){
                        setCWaterUnits(true);
                    }else{
                        setCWaterUnits(false);
                    }
//                    c_water.setDisplaySystem(measurementUnits);
                    c_water.setValue(c_water.getValue());
                    setCWaterUnits(true);
                    waterField.setValue(c_water.getDisplayValue());
                    
                }
//                c_water
//                rockFragmentsUnits1.setText(c_soilRockFragmentsValue.getDisplayUnits().getAbbreviation());
//                rockFragmentsUnitLabel.setText(c_soilRockFragmentsValue.getDisplayUnits().getAbbreviation());
//                regionSlopeUnits1.setText(c_soilSlopeValue.getDisplayUnits().getAbbreviation());
//                soilSlopeUnitLabel.setText(c_soilSlopeValue.getDisplayUnits().getAbbreviation());
//                c_soilSlopeValue.setDisplaySystem(value);
//                c_soilRockFragmentsValue.setDisplaySystem(value);
                
                soilSlopeField.getConvertedValue().setDisplaySystem(value);
                rockFragmentsField.getConvertedValue().setDisplaySystem(value);
                break;
            case RunFileData.WaterErosionLoss:
                double d = Double.parseDouble(value);
                if (d < 0.0) {
                    LOGGER.warn("Invalid water erosion value: " + d);
                    d = 0.0;
                    //    waterField.setInputVerifier(new DoubleInputVerifier());
                }
                setCWaterUnits(false);
                c_water.setValue(d);
                setCWaterUnits(true);
                waterField.setValue(c_water.getDisplayValue());
                
                break;
            case RunFileData.CycleCount:
                setCycleCount(Integer.valueOf(value), false);
                break;
            case RunFileData.StartDate:
                setStartDate(parseDate(value), false);
                break;
            case RunFileData.EndDate:
                setEndDate(parseDate(value), false);
                break;
            case ConfigData.ReadonlySlope:
                if ("1".equals(value)) {
                    soilSlopeField.setValue(-1); //From Soil DB
                    soilSlopeField.setReadonly(true);
                } else {
                    soilSlopeField.setReadonly(false);
                }
                break;
            case ConfigData.ReadonlyRockFragments:
                if ("1".equals(value)) {
                    rockFragmentsField.setValue(-1);
                    rockFragmentsField.setReadonly(true);
                } else {
                    rockFragmentsField.setReadonly(false);
                }
                break;
//            case RunFileData.AverageSlopeField:
//                if(value == null || value.equals("null")){
//                    soilSlopeField.setValue(Double.valueOf("-1"));
//                }else{
//                    soilSlopeField.setValue(Double.valueOf(value));
//                }
//                break;
            case RunFileData.AverageSlope:
                if(value.trim().startsWith("-1")/*Double.valueOf(value)== -1.0*/){c_soilSlopeValue.setValue(-1);}
                if(value.trim().startsWith("-2"))/*Double.valueOf(value)== -2.0)*/{c_soilSlopeValue.setValue(-2);}
                if(Double.valueOf(value)>0){c_soilSlopeValue.setValue(Double.valueOf(value));}
//                c_soilSlopeValue.setValue(Double.valueOf(value));
                soilSlopeField.setValue(c_soilSlopeValue.getDisplayValue());
//                setSoilSlope(Double.valueOf(value));
                break;
//            case RunFileData.SoilRockFragmentsField:
//                if(value == null || value.equals("null")){
//                    rockFragmentsField.setValue(Double.valueOf("-1"));
//                }else{
//                    rockFragmentsField.setValue(Double.valueOf(value));
//                }
//                break;
            case RunFileData.SoilRockFragments:
                if(value.trim().startsWith("-1")){c_soilRockFragmentsValue.setValue(-1);}else{
                    c_soilRockFragmentsValue.setValue(Double.valueOf(value));
                }
                
                rockFragmentsField.setValue(c_soilRockFragmentsValue.getDisplayValue());
                break;
            case ConfigData.CompatibilityNRCS:
                if ("1".equals(value)) {
                    updateCompatibility(true);
                } else {
                    updateCompatibility(false);
                }
                break;
            case RunFileData.SoilFile:
                updateSoilValues(value);
                break;
        }
    }

    private String c_lastSoilPath;

    //TODO: move into properly threaded gui/data contexts
    public void updateSoilValues(String path) {
       
        if (path != null && !path.equals("")) {
            if (!path.equals(c_lastSoilPath)) {
                try {
                    IFC ifc = new IFC();
                    ifc.readIfc(path);
                    c_soilSlopeValue.setValue(ifc.surfaceSlope);
                    if (ifc.nsl > 0) {
//                        c_soilSlopeValue.setValue(ifc.surfaceSlope);
//                            
//                        setSoilSlope(ifc.surfaceSlope);
                        c_soilRockFragmentsValue.setValue(ifc.fractionRock[0]);
//                        setRockFragments(ifc.fractionRock[0]);
//                        
                    } else {
                        //no layers
                        c_soilRockFragmentsValue.setValue(-1.0);
                    }
//                    firePropertyChange(path, holdFire, c_water);

                } catch (FileNotFoundException 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);
            soilSlopeValue.setValue(Double.NaN);
            soilRockFragmentsValue.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 void setCWaterUnits(boolean setDefault){
        if(setDefault){
            c_water.setBaseUnits("kg/m^2/yr");
            return;
        }
        if(measurementUnits.equals(Util.USUnits) ){
            
            c_water.setBaseUnits("t/ac/yr");
        }else{
            c_water.setBaseUnits("kg/m^2/yr");
        }
    }
    private Date c_startDate;

    public Date getStartDate() {
        return c_startDate;
    }

    public void setStartDate(Date date, boolean pcflag) {
        setStartDate(date, pcflag, false);
    }

    public void setStartDate(Date date, boolean fireRFD, boolean check_message) {
        //System.out.println("[setStartDate] " + date);
        Date old = c_startDate;
        c_startDate = date;
        startDateText.setText(df.format(c_startDate));

        if (c_startDate != null && c_endDate != null) {
            checkStartDate(check_message);
        }

        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);
        }
    }

    /*
    *this method checks if the start date appears after end date
    *check_message is only true if the user selected the dates to be processed
    *the static functions accessing and setting datesUnordered is used 
        in setting a new run. if the condition is set a new run can not be 
        performed. 
     */
    public void checkStartDate(boolean check_message) {
        if (c_startDate.compareTo(c_endDate) == 1) {
            if (check_message) {
                //System.out.println("startDate appears after endDate");
                JOptionPane.showMessageDialog(null, "Start Date set past End Date."
                        + "\nPlease Adjust so Start Date is set before End Date.", "Start Date Entry Warning", JOptionPane.WARNING_MESSAGE);
                setDatesUnordered(true);
                //System.out.println(getDatesUnordered());
            }
        } else {
            setDatesUnordered(false);
            //System.out.println(getDatesUnordered());
        }
    }

    private Date c_endDate;

    public Date getEndDate() {
        return c_endDate;
    }

    public void setEndDate(Date date, boolean pcflag) {
        setEndDate(date, pcflag, false);
    }

    public void setEndDate(Date date, boolean fireRFD, boolean check_message) {
        //System.out.println("[setEndDate] " + date);
        Date old = c_endDate;
        c_endDate = date;
        endDateText.setText(df.format(c_endDate));

        if (c_endDate != null && c_startDate != null) {
            checkEndDate(check_message);
        }

        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);
        }
    }

    /*
    *this method checks if the end date appears before start date
    *check_message is only true if the user selected the dates to be processed
    *the static functions accessing and setting datesUnordered is used 
        in setting a new run. if the condition is set a new run can not be 
        performed. 
     */
    public void checkEndDate(boolean check_message) {
        if (c_endDate.compareTo(c_startDate) == -1) {
            //dates disjoint
            //set disjoint field 
            if (check_message) {
                //System.out.println("endDate appears before startDate");
                JOptionPane.showMessageDialog(null, "End Date set before Start Date."
                        + "\nPlease Adjust so End Date is set after Start Date.", "End Date Entry Warning", JOptionPane.WARNING_MESSAGE);
                setDatesUnordered(true);
                //System.out.println(getDatesUnordered());
            }
        } else {
            setDatesUnordered(false);
            //System.out.println(getDatesUnordered());
        }
    }
    
    private void updateLabelsUnits(){
        c_water.setDisplaySystem(measurementUnits);
        c_soilRockFragmentsValue.setDisplaySystem(measurementUnits);
        c_soilSlopeValue.setDisplaySystem(measurementUnits);
        
    }

    private void updateWaterLabelValue(){
        waterUnitLabel.setText(c_water.getDisplayUnits().getAbbreviation());
    }
    
    private void updateFragmentsLabel(){
//        rockFragmentsUnits1.setText(c_soilRockFragmentsValue.getDisplayUnits().getAbbreviation());
        rockFragmentsUnitLabel.setText(c_soilRockFragmentsValue.getDisplayUnits().getAbbreviation());
    }
    
    private void updateSoilSlopeLabel(){
//        regionSlopeUnits1.setText(c_soilSlopeValue.getDisplayUnits().getAbbreviation());
        soilSlopeUnitLabel.setText(c_soilSlopeValue.getDisplayUnits().getAbbreviation());
    }
    
    private double c_soilSlope;
    
    public void setSoilSlopeValue(double newSlope) {
        soilSlopeValue.setText("" + newSlope);
    }
    
    public void setRockFragValue(double newFrag) {
        soilRockFragmentsValue.setText("" + newFrag);
    }
    
    public double getSoilSlope() {
        return c_soilSlope;
    }

    public void setSoilSlope(double slope) {
        setSoilSlope(slope, true);
    }
    private double originalSlope;
    private boolean changeTheWepsData = true;
    
    protected void setOriginalSlope(double slope){ originalSlope = slope;}
    protected double getOriginalSlope(){ return originalSlope;}
    
    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) {
//            if(c_soilSlope >0.0){
//                firePropertyChange(RunFileData.AverageSlopeField,Double.toString(old), Double.toString(c_soilSlope));
//            }
            if(changeTheWepsData && c_soilSlope >0.0){
                originalSlope = c_soilSlope;
                changeTheWepsData = false;
            }
            String newString = Double.toString(c_soilSlope);
            String oldString = Double.toHexString(old);
            System.out.println(old + "  " + c_soilSlope);
            if(Double.toString(c_soilSlope).trim().startsWith("-1")){
                newString = "-1";
            }else if(Double.toString(c_soilSlope).trim().startsWith("-2")){
                newString = "-2";
            }
            if(Double.toString(old).trim().startsWith("-1")){
                oldString = "-1";
            }else if(Double.toString(old).trim().startsWith("-2")){
                oldString = "-2";
            }
            System.out.println(oldString + " " + newString);
//            String oldString = Double.toString(old).trim().startsWith("-1") ? "-1" : Double.toString(old);
//            String newString = Double.toString(c_soilSlope).trim().startsWith("-1") ? "-1" : Double.toString(c_soilSlope);
            firePropertyChange(RunFileData.AverageSlope, oldString, newString);
            
//            firePropertyChange(RunFileData.AverageSlope, old, Double.toString(c_soilSlope));
            soilSlopeField.setValue(Double.valueOf(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.0);
        firePropertyChange("rockFragments", old, c_rockFragments2);
        if (fireRFD) {
//            if(c_rockFragments2 >=0.0){
                firePropertyChange(RunFileData.SoilRockFragments,Double.toString(old), Double.toString(c_rockFragments2));
//            }
            String oldString = Double.toString(old).trim().startsWith("-1") ? "-1" : Double.toString(old);
            String newString = Double.toString(c_rockFragments2).trim().startsWith("-1") ? "-1" : Double.toString(c_rockFragments2);
            firePropertyChange(RunFileData.SoilRockFragments, oldString, newString);
        }
    }
    private boolean holdFire = false;

    private void updateMode(String type) {
        //holdFire = true;
        type = type != null ? type.trim().toLowerCase() : null;
        System.out.println("Run type: " + type);
        if (ConfigData.NRCS.toLowerCase().equals(type)) {
            this.setNRCS();
        } else if (ConfigData.Cycle.toLowerCase().equals(type)) {
            if (c_nrcsInstall) {
                rejectMode();
                return;
            }
            this.setCYCLE();
        } else if (ConfigData.Dates.toLowerCase().equals(type)) {
            if (c_nrcsInstall) {
                rejectMode();
                return;
            }
            this.setDATES();
        } else {
            LOGGER.warn("Unknown run mode: " + type);
        }
        holdFire = false;
    }

    //set fields visible when nrcs option is selected
    private void setNRCS() {
        modeField.setSelectedItem("NRCS");
        startDateField.setVisible(false);
        startDateLabel.setVisible(false);
        startDateText.setVisible(false);

        endDateField.setVisible(false);
        endDateLabel.setVisible(false);
        endDateText.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);
    }

    //set fields visible when cycle is selected
    private void setCYCLE() {
        modeField.setSelectedItem("Cycle");
        startDateField.setVisible(false);
        startDateLabel.setVisible(false);
        startDateText.setVisible(false);

        endDateField.setVisible(false);
        endDateLabel.setVisible(false);
        endDateText.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);
    }

    //set fields visible when date option is selected
    private void setDATES() {
        modeField.setSelectedItem("Dates");
        startDateField.setVisible(true);
        startDateLabel.setVisible(true);
        startDateText.setVisible(true);

        endDateField.setVisible(true);
        endDateLabel.setVisible(true);
        endDateText.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);
    }

    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(this, "simrunPanel_html");
        CSH.setHelpIDString(startDateLabel, "simrunDates_html");
        CSH.setHelpIDString(startDateField, "simrunCalendar_html");
        CSH.setHelpIDString(endDateLabel, "simrunDates_html");
        CSH.setHelpIDString(endDateField, "simrunCalendar_html");
        CSH.setHelpIDString(cycleCountLabel, "simrunRotCyc_html");
        CSH.setHelpIDString(cycleCountField, "simrunRotCyc_html");
        CSH.setHelpIDString(modeLabel, "simrunModes_html");
        CSH.setHelpIDString(modeField, "simrunModes_html");
        CSH.setHelpIDString(waterLabel, "waterErosion_html");
        CSH.setHelpIDString(waterField, "waterErosion_html");
        CSH.setHelpIDString(soilSlopeLabel, "regionSlope_html");
        CSH.setHelpIDString(soilSlopeField, "regionSlope_html");
        CSH.setHelpIDString(soilSlopeLabel1, "regionSlope_html");
        CSH.setHelpIDString(soilSlopeValue, "regionSlope_html");
        CSH.setHelpIDString(rockFragmentsLabel, "rockFragments_html");
        CSH.setHelpIDString(rockFragmentsField, "rockFragments_html");
        CSH.setHelpIDString(soilSlopeLabel2, "rockFragments_html");
        CSH.setHelpIDString(soilRockFragmentsValue, "rockFragments_html");
        //CSH.setHelpIDString(startDateField, "simrunCalendar_html");
        //CSH.setHelpIDString(endDateField, "simrunCalendar_html");
    }

    private class simCalendarSelector { //extends JButton?

        //date value associated with calendar
        Date dateSelected;
        //option for chaning start/end
        boolean selected;

        public Date getDate() {
            return dateSelected;
        }

        public void setDate(Date dObj) {
            dateSelected = dObj;
        }

        //option determine where start date or end date will be 
        //will be set by call to setnewcalendardate
        public simCalendarSelector(boolean option) {
            selected = option;
        }

        //display calander to allow user to select a date and
        //reset start/end date field
        public void calendarPopOut() {
            // Create a new calendar panel.
            JulianCalendar jd = null;
            Calendar calendar = Calendar.getInstance();
            if (selected) {
                calendar.setTime(c_endDate);
            } else {
                calendar.setTime(c_startDate);
            }
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH);
            int day = calendar.get(Calendar.DAY_OF_MONTH);
            jd = new JulianCalendar(year, month, day);
            //jd = new JulianCalendar();
            DisplayCalendar dc = new DisplayCalendar(Util.getParentJFrame(SimulationPanel.this), jd, "sim");
            dc.setVisible(true);

            if (dc.getResult() == DisplayCalendar.OK_OPTION && dc.curDate != null) {
                dateSelected = dc.curDate.getTime();
                if (selected) {
                    setEndDate(dateSelected, true, true);
                } else {
                    setStartDate(dateSelected, true, true);
                }
            }
        }
    }
}
