package net.sf.openrocket.file.openrocket.importt;
import java.util.HashMap;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.file.DocumentLoadingContext;
import net.sf.openrocket.file.simplesax.AbstractElementHandler;
import net.sf.openrocket.file.simplesax.ElementHandler;
import net.sf.openrocket.file.simplesax.PlainTextHandler;
import net.sf.openrocket.simulation.FlightDataBranch;
import net.sf.openrocket.simulation.FlightDataType;
import net.sf.openrocket.simulation.FlightEvent;
import net.sf.openrocket.simulation.FlightEvent.Type;
import net.sf.openrocket.simulation.customexpression.CustomExpression;
import net.sf.openrocket.unit.UnitGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class FlightDataBranchHandler extends AbstractElementHandler {
@SuppressWarnings("unused")
private final DocumentLoadingContext context;
private final FlightDataType[] types;
private final FlightDataBranch branch;
private static final Logger log = LoggerFactory.getLogger(FlightDataBranchHandler.class);
private final SingleSimulationHandler simHandler;
public FlightDataBranchHandler(String name, String typeList, SingleSimulationHandler simHandler, DocumentLoadingContext context) {
this.simHandler = simHandler;
this.context = context;
String[] split = typeList.split(",");
types = new FlightDataType[split.length];
for (int i = 0; i < split.length; i++) {
String typeName = split[i];
FlightDataType matching = findFlightDataType(typeName);
types[i] = matching;
//types[i] = FlightDataType.getType(typeName, matching.getSymbol(), matching.getUnitGroup());
}
// TODO: LOW: May throw an IllegalArgumentException
branch = new FlightDataBranch(name, types);
}
/**
* @param timeToOptimumAltitude
* @see net.sf.openrocket.simulation.FlightDataBranch#setTimeToOptimumAltitude(double)
*/
public void setTimeToOptimumAltitude(double timeToOptimumAltitude) {
branch.setTimeToOptimumAltitude(timeToOptimumAltitude);
}
/**
* @param optimumAltitude
* @see net.sf.openrocket.simulation.FlightDataBranch#setOptimumAltitude(double)
*/
public void setOptimumAltitude(double optimumAltitude) {
branch.setOptimumAltitude(optimumAltitude);
}
// Find the full flight data type given name only
// Note: this way of doing it requires that custom expressions always come before flight data in the file,
// not the nicest but this is always the case anyway.
private FlightDataType findFlightDataType(String name) {
// Kevins version with lookup by key. Not using right now
/*
if ( key != null ) {
for (FlightDataType t : FlightDataType.ALL_TYPES){
if (t.getKey().equals(key) ){
return t;
}
}
}
*/
// Look in built in types
for (FlightDataType t : FlightDataType.ALL_TYPES) {
if (t.getName().equals(name)) {
return t;
}
}
// Look in custom expressions
for (CustomExpression exp : simHandler.getDocument().getCustomExpressions()) {
if (exp.getName().equals(name)) {
return exp.getType();
}
}
log.warn("Could not find the flight data type '" + name + "' used in the XML file. Substituted type with unknown symbol and units.");
return FlightDataType.getType(name, "Unknown", UnitGroup.UNITS_NONE);
}
public FlightDataBranch getBranch() {
branch.immute();
return branch;
}
@Override
public ElementHandler openElement(String element, HashMap<String, String> attributes,
WarningSet warnings) {
if (element.equals("datapoint"))
return PlainTextHandler.INSTANCE;
if (element.equals("event"))
return PlainTextHandler.INSTANCE;
warnings.add("Unknown element '" + element + "' encountered, ignoring.");
return null;
}
@Override
public void closeElement(String element, HashMap<String, String> attributes,
String content, WarningSet warnings) {
if (element.equals("event")) {
double time;
FlightEvent.Type type;
try {
time = DocumentConfig.stringToDouble(attributes.get("time"));
} catch (NumberFormatException e) {
warnings.add("Illegal event specification, ignoring.");
return;
}
type = (Type) DocumentConfig.findEnum(attributes.get("type"), FlightEvent.Type.class);
if (type == null) {
warnings.add("Illegal event specification, ignoring.");
return;
}
branch.addEvent(new FlightEvent(type, time));
return;
}
if (!element.equals("datapoint")) {
warnings.add("Unknown element '" + element + "' encountered, ignoring.");
return;
}
// element == "datapoint"
// Check line format
String[] split = content.split(",");
if (split.length != types.length) {
warnings.add("Data point did not contain correct amount of values, ignoring point.");
return;
}
// Parse the doubles
double[] values = new double[split.length];
for (int i = 0; i < values.length; i++) {
try {
values[i] = DocumentConfig.stringToDouble(split[i]);
} catch (NumberFormatException e) {
warnings.add("Data point format error, ignoring point.");
return;
}
}
// Add point to branch
branch.addPoint();
for (int i = 0; i < types.length; i++) {
branch.setValue(types[i], values[i]);
}
}
}