package net.sf.openrocket.rocketcomponent; import java.util.EventObject; import java.util.List; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.simulation.FlightEvent; import net.sf.openrocket.startup.Application; import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.util.ArrayList; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.Pair; import net.sf.openrocket.util.StateChangeListener; public class DeploymentConfiguration implements FlightConfigurableParameter<DeploymentConfiguration> { public static enum DeployEvent { LAUNCH(trans.get("RecoveryDevice.DeployEvent.LAUNCH")) { @Override public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) { return e.getType() == FlightEvent.Type.LAUNCH; } }, EJECTION(trans.get("RecoveryDevice.DeployEvent.EJECTION")) { @Override public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) { if (e.getType() != FlightEvent.Type.EJECTION_CHARGE) return false; RocketComponent charge = e.getSource(); return charge.getStageNumber() == source.getStageNumber(); } }, APOGEE(trans.get("RecoveryDevice.DeployEvent.APOGEE")) { @Override public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) { return e.getType() == FlightEvent.Type.APOGEE; } }, ALTITUDE(trans.get("RecoveryDevice.DeployEvent.ALTITUDE")) { @SuppressWarnings("unchecked") @Override public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) { if (e.getType() != FlightEvent.Type.ALTITUDE) return false; double alt = config.deployAltitude; Pair<Double, Double> altitude = (Pair<Double, Double>) e.getData(); return (altitude.getU() >= alt) && (altitude.getV() <= alt); } }, LOWER_STAGE_SEPARATION(trans.get("RecoveryDevice.DeployEvent.LOWER_STAGE_SEPARATION")) { @Override public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) { if (e.getType() != FlightEvent.Type.STAGE_SEPARATION) return false; int separation = e.getSource().getStageNumber(); int current = source.getStageNumber(); return (current + 1 == separation); } }, NEVER(trans.get("RecoveryDevice.DeployEvent.NEVER")) { @Override public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) { return false; } }; private final String description; DeployEvent(String description) { this.description = description; } public abstract boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source); @Override public String toString() { return description; } } private static final Translator trans = Application.getTranslator(); private final List<StateChangeListener> listeners = new ArrayList<StateChangeListener>(); private DeployEvent deployEvent = DeployEvent.EJECTION; private double deployAltitude = 200; private double deployDelay = 0; public boolean isActivationEvent(FlightEvent e, RocketComponent source) { return deployEvent.isActivationEvent(this, e, source); } public DeployEvent getDeployEvent() { return deployEvent; } public void setDeployEvent(DeployEvent deployEvent) { if (this.deployEvent == deployEvent) { return; } if (deployEvent == null) { throw new NullPointerException("deployEvent is null"); } this.deployEvent = deployEvent; fireChangeEvent(); } public double getDeployAltitude() { return deployAltitude; } public void setDeployAltitude(double deployAltitude) { if (MathUtil.equals(this.deployAltitude, deployAltitude)) { return; } this.deployAltitude = deployAltitude; fireChangeEvent(); } public double getDeployDelay() { return deployDelay; } public void setDeployDelay(double deployDelay) { if (MathUtil.equals(this.deployDelay, deployDelay)) { return; } this.deployDelay = deployDelay; fireChangeEvent(); } @Override public String toString() { String description = deployEvent.toString(); if (deployDelay > 0) { description += " + " + deployDelay + "s"; } if (deployEvent == DeployEvent.ALTITUDE && deployAltitude != 0) { description += " " + UnitGroup.UNITS_DISTANCE.toString(deployAltitude); } return description; } @Override public void addChangeListener(StateChangeListener listener) { listeners.add(listener); } @Override public void removeChangeListener(StateChangeListener listener) { listeners.remove(listener); } private void fireChangeEvent() { EventObject event = new EventObject(this); Object[] list = listeners.toArray(); for (Object l : list) { ((StateChangeListener) l).stateChanged(event); } } @Override public DeploymentConfiguration clone() { DeploymentConfiguration that = new DeploymentConfiguration(); that.deployAltitude = this.deployAltitude; that.deployDelay = this.deployDelay; that.deployEvent = this.deployEvent; return that; } }