KinderElektro/src/main/java/de/ph87/electro/circuit/part/Part.java

164 lines
4.2 KiB
Java

package de.ph87.electro.circuit.part;
import de.ph87.electro.circuit.part.node.Node;
import de.ph87.electro.circuit.part.node.NodeDto;
import de.ph87.electro.circuit.part.parts.*;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.List;
import java.util.*;
import static de.ph87.electro.CONFIG.P50;
import static de.ph87.electro.CONFIG.PART_BACK_COLOR;
import static java.lang.Math.round;
@Getter
@ToString(onlyExplicitlyIncluded = true)
public abstract class Part {
@NonNull
@ToString.Include
private final String uuid;
@NonNull
private final List<Node> nodes = new ArrayList<>();
@NonNull
protected Orientation orientation = Orientation.R0;
@NonNull
@Setter
@ToString.Include
private String name;
@NonNull
private Point position;
@NonNull
private AffineTransform transform = new AffineTransform();
protected Part(@NonNull final String name, @NonNull final Point position) {
this.uuid = UUID.randomUUID().toString();
this.name = name;
this.position = position;
updateTransform();
}
protected Part(@NonNull final PartDto dto) {
this.uuid = dto.getUuid();
this.name = dto.getName();
this.orientation = dto.getOrientation();
this.position = dto.getPosition();
updateTransform();
}
@NonNull
public static Part fromDto(@NonNull final PartDto abstractDto) {
return switch (abstractDto) {
case final BatteryDto dto -> new Battery(dto);
case final LightDto dto -> new Light(dto);
case final ConnectorSubDto dto -> new ConnectorSub(dto);
case final Switch1x1Dto dto -> new Switch1x1(dto);
case final Switch1x2Dto dto -> new Switch1x2(dto);
case final SwitchCrossDto dto -> new SwitchCross(dto);
case final PotiDto dto -> new Poti(dto);
case final VoltmeterDto dto -> new Voltmeter(dto);
case null, default -> throw new RuntimeException();
};
}
@NonNull
public abstract Point getSize();
public void setPosition(@NonNull final Point position) {
this.position = position;
updateTransform();
}
public void rotate() {
this.orientation = orientation.clockwise();
updateTransform();
}
@NonNull
private void updateTransform() {
transform = new AffineTransform();
transform.translate(position.x, position.y);
transform.rotate(orientation.getRadians(), P50, P50);
nodes.forEach(Node::positionChanged);
}
@NonNull
public Point transform(@NonNull final Point point) {
final Point2D result = transform.transform(point, new Point2D.Double());
return new Point((int) round(result.getX()), (int) round(result.getY()));
}
@NonNull
protected Node addNode(@NonNull final String name, final int x, final int y) {
return addNode(new Node(this, name, new Point(x, y)));
}
@NonNull
protected Node addNode(@NonNull final NodeDto dto, final int x, final int y) {
return addNode(new Node(this, dto, new Point(x, y)));
}
@NonNull
private Node addNode(@NonNull final Node node) {
nodes.add(node);
return node;
}
public final void draw(@NonNull final Graphics2D g) {
g.setColor(PART_BACK_COLOR);
g.fillRect(0, 0, getSize().x, getSize().y);
_render(g);
nodes.forEach(node -> node.draw(g));
_labels(g);
}
protected void _render(@NonNull final Graphics2D g) {
// -
}
protected void _labels(@NonNull final Graphics2D g) {
// -
}
public void action() {
// -
}
public void postCalculate() {
// -
}
@NonNull
public List<InnerConnection> getInnerConnections() {
return Collections.emptyList();
}
@NonNull
public Optional<Node> findNodeByUuid(@NonNull final String nodeUuid) {
return nodes.stream().filter(node -> node.getUuid().equals(nodeUuid)).findFirst();
}
@NonNull
public Optional<Node> findNodeByPosition(@NonNull final Point position) {
return nodes.stream().filter(node -> node.intersects(position)).findFirst();
}
public boolean intersects(@NonNull final Point point) {
return this.position.x <= point.x && point.x < this.position.x + this.getSize().x
&& this.position.y <= point.y && point.y < this.position.y + this.getSize().y;
}
}