<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package usda.weru.weps.location;

import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import usda.weru.util.ConfigData;
import usda.weru.util.FireAllContext;
import usda.weru.util.LoadingContext;
import usda.weru.util.PropertyVetoRunnableException;
import usda.weru.util.ReportContext;
import usda.weru.weps.RunFileBean;
import usda.weru.weps.location.chooser.StationModeChooser;

/**
 *
 * @author Joseph Levin &lt;joelevin@weru.ksu.edu&gt;
 */
public class StationModeSelectionController implements VetoableChangeListener {

    private final RunFileBean c_bean;
    private final RunFileBean.StationType c_type;

    private StationModeSelectionController(RunFileBean bean, RunFileBean.StationType type) {
        c_bean = bean;
        c_type = type;

        switch (c_type) {
            case Cligen:
                c_bean.addVetoableChangeListener(RunFileBean.PROP_CLIGEN_STATION_MODE, this);
                break;
            case Windgen:
                c_bean.addVetoableChangeListener(RunFileBean.PROP_WINDGEN_STATION_MODE, this);
                break;
        }
    }

	/**
	 *
	 * @param bean
	 */
	public static void install(RunFileBean bean) {
        install(bean, RunFileBean.StationType.Cligen);
        install(bean, RunFileBean.StationType.Windgen);
    }

	/**
	 *
	 * @param bean
	 * @param type
	 */
	public static void install(RunFileBean bean, RunFileBean.StationType type) {
        new StationModeSelectionController(bean, type);
    }

    public void setStationMode(StationMode mode) {
        setStationMode (mode, false);
    }
    
    // Sometimes need to "force" mode to propagate through all of the setting
    // sequences. If new val matches the existing val, then some of the setting
    // is skipped. So for force, set first to null and then to new val, that way
    // new val NEVER matcheds existing val.
    //
    public void setStationMode(StationMode mode, boolean force) {
        switch (c_type) {
            case Cligen:
                if (force) {
                    // new mode == existing, then nothing happens
                    // if force, then set to null then to new so that the
                    // new goes through even if it happens to match existing.
                    c_bean.setCligenStationMode(null);
                }
                c_bean.setCligenStationMode(mode);
                break;
            case Windgen:
                if (force) {
                    // new mode == existing, then nothing happens
                    // if force, then set to null then to new so that the
                    // new goes through even if it happens to match existing.
                    c_bean.setWindgenStationMode(null);
                }
                c_bean.setWindgenStationMode(mode);
                break;
        }
    }

    private void validate(final StationMode[] allowed, final StationMode oldMode, final StationMode newMode, PropertyChangeEvent event) throws PropertyVetoException {
        if (FireAllContext.isInFireAll()) {
            //we work just fine with actuall listening.  Fire alls break this
            return;
        }
        if (!LoadingContext.isLoading()) {
            //let's assume that the application is right and we only care when loading a run file.
            return;
        }
        if(ReportContext.isInReport()){
            //We don't do any checks for reports.
            return;
        }
        if (newMode == null) {
            return;
        }
        for (StationMode mode : allowed) {
            if (mode == newMode) {
                //all is well
                return;
            }
        }

        

        //not allowed, handle the different selection types
        switch (allowed.length) {
            case 0:
                //really not good, no valid modes
                throw new PropertyVetoRunnableException("There is a configuration error. No valid " + c_type.getDisplayName() + " station modes are configured.", event) {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public void run() {
                        JOptionPane pane = new JOptionPane("There is a configuration error. No valid " + c_type.getDisplayName() + " station modes are configured.  You will not be able to run this simulation.  Please contact your system administrator.", JOptionPane.ERROR_MESSAGE) {
                            private static final long serialVersionUID = 1L;

                            @Override
                            public int getMaxCharactersPerLineCount() {
                                return 80;
                            }
                        };

                        JDialog dialog = pane.createDialog(c_type.getDisplayName() + " Station Mode");
                        dialog.setModal(true);
                        dialog.setVisible(true);
                        setStationMode(null);

                    }
                };

            case 1:
                //inform the user that the property is being changed.
                throw new PropertyVetoRunnableException(newMode.getDisplayName() + " is not an allowed " + c_type.getDisplayName() + " station mode.", event) {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public void run() {
                        if(ConfigData.getIntParm(ConfigData.invalidCligenDisplay, 1) == 1) {
                            JOptionPane pane = new JOptionPane("The WEPS simulation you are attempting to open uses an invalid " + c_type.getDisplayName() + " station mode for this configured version of WEPS. " + '"' + newMode.getDisplayName() + '"' + " mode is not allowed. \nAuto setting mode to " + '"' + allowed[0].getDisplayName() + '"' + ".", JOptionPane.WARNING_MESSAGE) {
                                private static final long serialVersionUID = 1L;

                                @Override
                                public int getMaxCharactersPerLineCount() {
                                    return 80;
                                }
                            };

                            JDialog dialog = pane.createDialog(c_type.getDisplayName() + " Station Mode");
                            dialog.setModal(true);
                            dialog.setVisible(true);
                        }
                        // set to the first and only allowed mode
                        // use "force" because the caller of this validate will fail
                        // since this is PropertyVeto. Since it fails, the bean will
                        // NOT get set to the current value.  Since the bean does NOT
                        // get set this time, the following call may happen to be
                        // setting the value to a new val that matches the existing mode
                        // and we want to "force" it to propagate through all of the setting
                        // sequences.
                        setStationMode(allowed[0], true);
                    }
                };

            default:
                //show the mode chooser
                throw new PropertyVetoRunnableException(newMode.getDisplayName() + " is not an allowed " + c_type.getDisplayName() + " station mode.", event) {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public void run() {
                        StationModeChooser smc = new StationModeChooser(allowedModes(), null);
                        smc.setLabelText("The simulation you are attempting to open uses an invalid " + c_type.getDisplayName() + " station mode. " + newMode.getDisplayName() + " is not allowed. Please select a valid station mode.");

                        JOptionPane pane = new JOptionPane(smc, JOptionPane.WARNING_MESSAGE);

                        final JDialog dialog = pane.createDialog(c_type.getDisplayName() + " Station Mode");
                        dialog.setModal(true);
                        //fork the pack to happen after the setVisible
                        EventQueue.invokeLater(new Runnable() {

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

                        // set to the first and only allowed mode
                        // use "force" because the caller of this validate will fail
                        // since this is PropertyVeto. Since it fails, the bean will
                        // NOT get set to the current value.  Since the bean does NOT
                        // get set this time, the following call may happen to be
                        // setting the value to a new val that matches the existing mode
                        // and we want to "force" it to propagate through all of the setting
                        // sequences.
                        setStationMode(smc.getSelectedStationMode(), true);

                    }
                };
        }




    }

	/**
	 *
	 * @param event
	 * @throws PropertyVetoException
	 */
	@Override
    public void vetoableChange(PropertyChangeEvent event) throws PropertyVetoException {

        StationMode oldMode = null;
        StationMode newMode = null;

        if (event.getOldValue() instanceof StationMode) {
            oldMode = (StationMode) event.getOldValue();
        }

        if (event.getNewValue() instanceof StationMode) {
            newMode = (StationMode) event.getNewValue();
        }

        validate(allowedModes(), oldMode, newMode, event);

    }

    private StationMode[] allowedModes() {
        switch (c_type) {
            case Cligen:
                return ConfigData.getDefault().getEnabledCligenStationModes();
            case Windgen:
                return ConfigData.getDefault().getEnabledWindgenStationModes();
            default:
                //stop here and just return an empty array
                return new StationMode[0];
        }
    }
}
</pre></body></html>