package net.sf.openrocket.motor;
import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Compares two motors designations. The motors are ordered first
* by their motor class, second by their average thrust and lastly by any
* extra modifiers at the end of the designation.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class DesignationComparator implements Comparator<String> {
private static final Collator COLLATOR;
static {
COLLATOR = Collator.getInstance(Locale.US);
COLLATOR.setStrength(Collator.PRIMARY);
}
/*
* Regexp to parse the multitude of designations. Supported types:
*
* 1/4A4...
* 1/2A4...
* A4...
* 132G100...
* 132-G100...
*
* Capture groups:
* 1 = garbage (stuff before impulse class)
* 2 = divisor number for 1/2A, 1/4A etc, otherwise null
* 3 = impulse class letter
* 4 = average thrust
* 5 = stuff after thrust number
*/
private Pattern pattern =
Pattern.compile("^([0-9]+-?|1/([1-8]))?([a-zA-Z])([0-9,]+)(.*?)$");
@Override
public int compare(String o1, String o2) {
int value;
Matcher m1, m2;
m1 = pattern.matcher(o1);
m2 = pattern.matcher(o2);
if (m1.find() && m2.find()) {
String o1Class = m1.group(3);
int o1Thrust = Integer.parseInt(m1.group(4).replaceAll(",", ""));
String o1Extra = m1.group(5);
String o2Class = m2.group(3);
int o2Thrust = Integer.parseInt(m2.group(4).replaceAll(",", ""));
String o2Extra = m2.group(5);
// 1. Motor class
if (o1Class.equalsIgnoreCase("A") && o2Class.equalsIgnoreCase("A")) {
// 1/2A and 1/4A comparison
String sub1 = m1.group(2);
String sub2 = m2.group(2);
if (sub1 != null || sub2 != null) {
if (sub1 == null)
sub1 = "1";
if (sub2 == null)
sub2 = "1";
value = -COLLATOR.compare(sub1, sub2);
if (value != 0)
return value;
}
}
value = COLLATOR.compare(o1Class, o2Class);
if (value != 0)
return value;
// 2. Average thrust
if (o1Thrust != o2Thrust)
return o1Thrust - o2Thrust;
// 3. Extra modifier
return COLLATOR.compare(o1Extra, o2Extra);
} else {
// Not understandable designation, simply compare strings
return COLLATOR.compare(o1, o2);
}
}
}