You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
8.9 KiB
288 lines
8.9 KiB
package de.srsoftware.web4rail.moving; |
|
|
|
import java.io.BufferedReader; |
|
import java.io.BufferedWriter; |
|
import java.io.FileReader; |
|
import java.io.FileWriter; |
|
import java.io.IOException; |
|
import java.util.HashMap; |
|
import java.util.HashSet; |
|
import java.util.List; |
|
import java.util.Map; |
|
import java.util.TreeSet; |
|
import java.util.stream.Collectors; |
|
|
|
import org.json.JSONObject; |
|
import org.slf4j.Logger; |
|
import org.slf4j.LoggerFactory; |
|
|
|
import de.keawe.tools.translations.Translation; |
|
import de.srsoftware.tools.Tag; |
|
import de.srsoftware.web4rail.Application; |
|
import de.srsoftware.web4rail.BaseClass; |
|
import de.srsoftware.web4rail.Plan; |
|
import de.srsoftware.web4rail.Window; |
|
import de.srsoftware.web4rail.tags.Button; |
|
import de.srsoftware.web4rail.tags.Fieldset; |
|
import de.srsoftware.web4rail.tags.Form; |
|
import de.srsoftware.web4rail.tags.Input; |
|
import de.srsoftware.web4rail.tags.Label; |
|
import de.srsoftware.web4rail.tags.Table; |
|
|
|
public class Car extends BaseClass implements Comparable<Car>{ |
|
protected static final Logger LOG = LoggerFactory.getLogger(Car.class); |
|
|
|
public static final String NAME = "name"; |
|
public static boolean FORWARD = true; |
|
public static boolean REVERSE = false; |
|
private static final String LENGTH = "length"; |
|
private static final String STOCK_ID = "stock-id"; |
|
private static final String TAGS = "tags"; |
|
private static final String MAX_SPEED = "max_speed"; |
|
private static final String MAX_SPEED_REVERSE = "max_speed_reverse"; |
|
protected HashSet<String> tags = new HashSet<String>(); |
|
|
|
private String name; |
|
public int length; |
|
protected String stockId = ""; |
|
private Train train; |
|
protected int maxSpeedForward = 0; |
|
protected int maxSpeedReverse = 0; |
|
protected boolean orientation = FORWARD; |
|
|
|
public Car(String name) { |
|
this(name,null); |
|
} |
|
|
|
public Car(String name, Id id) { |
|
this.name = name; |
|
this.id = id; |
|
register(); |
|
} |
|
|
|
public static Object action(HashMap<String, String> params,Plan plan) throws IOException { |
|
String id = params.get(ID); |
|
Car car = id == null ? null : Car.get(new Id(id)); |
|
|
|
switch (params.get(ACTION)) { |
|
case ACTION_ADD: |
|
if (isSet(car)) { |
|
car.clone(); |
|
} else new Car(params.get(Car.NAME)).parent(plan); |
|
return Car.manager(); |
|
case ACTION_MOVE: |
|
return car.moveUp(); |
|
case ACTION_PROPS: |
|
return car == null ? Car.manager() : car.properties(); |
|
case ACTION_TURN: |
|
return car.turn(); |
|
case ACTION_UPDATE: |
|
return car.update(params); |
|
} |
|
if (car instanceof Locomotive) return Locomotive.action(params,plan); |
|
return t("Unknown action: {}",params.get(ACTION)); |
|
} |
|
|
|
public Car clone() { |
|
Car clone = new Car(name); |
|
clone.maxSpeedForward = maxSpeedForward; |
|
clone.length = length; |
|
clone.tags = new HashSet<String>(tags); |
|
clone.notes = notes; |
|
clone.parent(parent()); |
|
clone.register(); |
|
return clone; |
|
} |
|
|
|
private Button cloneButton() { |
|
return new Button(t("copy"),Map.of(REALM,REALM_CAR,ID,id(),ACTION,ACTION_ADD)); |
|
} |
|
|
|
@Override |
|
public int compareTo(Car o) { |
|
return (stockId+":"+name).compareTo(o.stockId+":"+o.name); |
|
} |
|
|
|
public JSONObject json() { |
|
JSONObject json = super.json(); |
|
json.put(NAME, name); |
|
json.put(LENGTH, length); |
|
if (maxSpeedForward != 0) json.put(MAX_SPEED, maxSpeedForward); |
|
if (maxSpeedReverse != 0) json.put(MAX_SPEED_REVERSE, maxSpeedReverse); |
|
json.put(STOCK_ID, stockId); |
|
if (!tags.isEmpty()) json.put(TAGS, tags); |
|
return json; |
|
} |
|
|
|
/** |
|
* If arguments are given, the first is taken as content, the second as tag type. |
|
* If no content is supplied, name is set as content. |
|
* If no type is supplied, "span" is preset. |
|
* @param args |
|
* @return |
|
*/ |
|
public Tag link(String...args) { |
|
String tx = args.length<1 ? name()+NBSP : args[0]; |
|
String type = args.length<2 ? "span" : args[1]; |
|
return link(type, tx); |
|
} |
|
|
|
public static void loadAll(String filename, Plan plan) throws IOException { |
|
BufferedReader file = new BufferedReader(new FileReader(filename, UTF8)); |
|
String line = file.readLine(); |
|
while (line != null) { |
|
JSONObject json = new JSONObject(line); |
|
String name = json.getString(Car.NAME); |
|
Id id = Id.from(json); |
|
Car car = json.has(Locomotive.LOCOMOTIVE) ? new Locomotive(name, id) : new Car(name,id); |
|
car.load(json).parent(plan); |
|
|
|
line = file.readLine(); |
|
} |
|
file.close(); |
|
} |
|
|
|
public Car load(JSONObject json) { |
|
super.load(json); |
|
if (json.has(LENGTH)) length = json.getInt(LENGTH); |
|
if (json.has(MAX_SPEED)) { |
|
maxSpeedForward = json.getInt(MAX_SPEED); |
|
maxSpeedReverse = maxSpeedForward; |
|
} |
|
if (json.has(MAX_SPEED_REVERSE)) maxSpeedReverse = json.getInt(MAX_SPEED_REVERSE); |
|
if (json.has(STOCK_ID)) stockId = json.getString(STOCK_ID); |
|
if (json.has(TAGS)) json.getJSONArray(TAGS).forEach(elem -> { tags.add(elem.toString()); }); |
|
return this; |
|
} |
|
|
|
public static Object manager() { |
|
Window win = new Window("car-manager", t("Car manager")); |
|
new Tag("h4").content(t("known cars")).addTo(win); |
|
new Tag("p").content(t("Click on a name to edit the entry.")).addTo(win); |
|
|
|
Table table = new Table().addHead(t("Stock ID"),t("Name"),t("Max. Speed",speedUnit),t("Length"),t("Train"),t("Tags"),t("Actions")); |
|
List<Car> cars = BaseClass.listElements(Car.class) |
|
.stream() |
|
.filter(car -> !(car instanceof Locomotive)) |
|
.sorted((c1,c2)->{ |
|
try { |
|
return Integer.parseInt(c1.stockId)-Integer.parseInt(c2.stockId); |
|
} catch (NumberFormatException nfe) { |
|
return c1.stockId.compareTo(c2.stockId); |
|
} |
|
|
|
}).collect(Collectors.toList()); |
|
for (Car car : cars) { |
|
String maxSpeed = (car.maxSpeedForward == 0 ? "–":""+car.maxSpeedForward)+NBSP; |
|
if (car.maxSpeedReverse != car.maxSpeedForward) maxSpeed += "("+car.maxSpeedReverse+")"+NBSP; |
|
|
|
table.addRow( |
|
car.stockId, |
|
car.link(), |
|
maxSpeed+speedUnit, |
|
car.length+NBSP+lengthUnit, |
|
isSet(car.train) ? car.train.link("span", car.train) : "", |
|
String.join(", ", car.tags()), |
|
car.cloneButton()); |
|
} |
|
table.addTo(win); |
|
|
|
Form form = new Form("add-car-form"); |
|
new Input(ACTION, ACTION_ADD).hideIn(form); |
|
new Input(REALM,REALM_CAR).hideIn(form); |
|
Fieldset fieldset = new Fieldset(t("add new car")); |
|
new Input(Locomotive.NAME, t("new car")).addTo(new Label(t("Name:")+NBSP)).addTo(fieldset); |
|
new Button(t("Apply"),form).addTo(fieldset); |
|
fieldset.addTo(form).addTo(win); |
|
return win; |
|
} |
|
|
|
public int maxSpeed() { |
|
return orientation == FORWARD ? maxSpeedForward : maxSpeedReverse; |
|
} |
|
|
|
protected Window moveUp() { |
|
if (!isSet(train())) return properties(); |
|
return train().moveUp(this); |
|
} |
|
|
|
String name(){ |
|
return name; |
|
} |
|
|
|
@Override |
|
protected Window properties(List<Fieldset> preForm, FormInput formInputs, List<Fieldset> postForm) { |
|
formInputs.add(t("Name"),new Input(NAME,name)); |
|
formInputs.add(t("Stock ID"),new Input(STOCK_ID,stockId)); |
|
formInputs.add(t("Length"),new Input(LENGTH,length).attr("type", "number").addTo(new Tag("span")).content(NBSP+lengthUnit)); |
|
formInputs.add(t("Tags"), new Input(TAGS,String.join(", ", tags))); |
|
Tag div = new Tag("div"); |
|
new Input(MAX_SPEED, maxSpeedForward).numeric().addTo(new Tag("p")).content(NBSP+speedUnit+NBSP+t("forward")).addTo(div); |
|
new Input(MAX_SPEED_REVERSE, maxSpeedReverse).numeric().addTo(new Tag("p")).content(NBSP+speedUnit+NBSP+t("reverse")).addTo(div); |
|
formInputs.add(t("Maximum Speed"),div); |
|
|
|
Fieldset fieldset = new Fieldset(t("Train")); |
|
if (train != null) train.link().addTo(fieldset); |
|
|
|
postForm.add(fieldset); |
|
|
|
return super.properties(preForm,formInputs,postForm); |
|
} |
|
|
|
@Override |
|
protected void removeChild(BaseClass child) { |
|
if (child == train) train = null; |
|
super.removeChild(child); |
|
} |
|
|
|
|
|
public static void saveAll(String filename) throws IOException { |
|
BufferedWriter file = new BufferedWriter(new FileWriter(filename)); |
|
for (Car car : BaseClass.listElements(Car.class)) file.write(car.json()+"\n"); |
|
file.close(); |
|
} |
|
|
|
protected static String t(String txt, Object...fills) { |
|
return Translation.get(Application.class, txt, fills); |
|
} |
|
|
|
public TreeSet<String> tags() { |
|
return new TreeSet<String>(tags); |
|
} |
|
|
|
@Override |
|
public String toString() { |
|
return name; |
|
} |
|
|
|
public Train train() { |
|
return train; |
|
} |
|
|
|
public void train(Train train) { |
|
this.train = train; |
|
} |
|
|
|
protected Window update(HashMap<String, String> params) { |
|
super.update(params); |
|
if (params.containsKey(NAME)) name = params.get(NAME).trim(); |
|
if (params.containsKey(LENGTH)) length = Integer.parseInt(params.get(LENGTH)); |
|
if (params.containsKey(MAX_SPEED)) maxSpeedForward = Integer.parseInt(params.get(MAX_SPEED)); |
|
if (params.containsKey(MAX_SPEED_REVERSE)) maxSpeedReverse = Integer.parseInt(params.get(MAX_SPEED_REVERSE)); |
|
if (params.containsKey(STOCK_ID)) stockId = params.get(STOCK_ID); |
|
if (params.containsKey(TAGS)) { |
|
String[] parts = params.get(TAGS).replace(",", " ").split(" "); |
|
tags.clear(); |
|
for (String tag : parts) { |
|
tag = tag.trim(); |
|
if (!tag.isEmpty()) tags.add(tag); |
|
} |
|
} |
|
return properties(); |
|
} |
|
|
|
public String turn() { |
|
orientation = !orientation; |
|
return t("Reversed {}.",this); |
|
} |
|
}
|
|
|