package de.ph87.electro.circuit.part; import de.ph87.electro.circuit.ShortCircuit; import de.ph87.electro.circuit.dto.*; import de.ph87.electro.circuit.part.impl.*; import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.awt.*; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import java.util.UUID; import static de.ph87.electro.CONFIG.PART_BACKGROUND; import static de.ph87.electro.CONFIG.RASTER; import static java.lang.Math.round; @Getter @Setter @ToString(onlyExplicitlyIncluded = true) public abstract class Part { @ToString.Include private final String uuid; @ToString.Include protected String name; protected int x; protected int y; protected Orientation orientation = Orientation.R0; protected final List junctions = new ArrayList<>(); protected Part(final String name, final int x, final int y) { this.uuid = UUID.randomUUID().toString(); this.name = name; this.x = x; this.y = y; } protected Part(final PartDto dto) { this.uuid = dto.getUuid(); this.name = dto.getName(); this.x = dto.getX(); this.y = dto.getY(); this.orientation = dto.getOrientation(); } public void link(final List junctions) { junctions.forEach(junction -> junction.link(junctions)); } public void reset() { junctions.forEach(Junction::reset); } public void paint(final Graphics2D g) { rect(g, 0, 0, 1, 1, null, null, PART_BACKGROUND); _paint(g); junctions.forEach(junction -> junction.paint(g)); } public void clockwise() { orientation = orientation.clockwise(); junctions.forEach(Junction::rotate); } public void line(final Graphics2D g, final Junction common0, final Junction output0, final Color color, final BasicStroke stroke) { line(g, common0.getX(), common0.getY(), output0.getX(), output0.getY(), color, stroke); } public void line(final Graphics2D g, final double x0, final double y0, final double x1, final double y1, final Color color, final Stroke stroke) { final int _x0 = (int) round((x + x0) * RASTER); final int _y0 = (int) round((y + y0) * RASTER); final int _x1 = (int) round((x + x1) * RASTER); final int _y1 = (int) round((y + y1) * RASTER); if (color != null) { g.setColor(color); } if (stroke != null) { g.setStroke(stroke); } g.drawLine(_x0, _y0, _x1, _y1); } public void rect(final Graphics2D g, final double x, final double y, final double w, final double h, final Color border, final Stroke stroke, final Color fill) { final int _x = (int) round((this.x + x) * RASTER); final int _y = (int) round((this.y + y) * RASTER); final int _w = (int) round(w * RASTER); final int _h = (int) round(h * RASTER); if (fill != null) { g.setColor(fill); g.fillRect(_x, _y, _w, _h); } if (border != null && stroke != null) { g.setColor(border); g.setStroke(stroke); g.drawRect(_x, _y, _w, _h); } } public void img(final Graphics2D g, final BufferedImage img, final double x, final double y) { final int _x = (int) round((this.x + x) * RASTER); final int _y = (int) round((this.y + y) * RASTER); g.drawImage(img, _x, _y, null); } public void circle(final Graphics2D g, final double x, final double y, final double radius, final Color border, final Stroke stroke, final Color fill) { final int _x = (int) round((this.x + x - radius) * RASTER); final int _y = (int) round((this.y + y - radius) * RASTER); final int diameter = (int) round(radius * RASTER * 2); if (fill != null) { g.setColor(fill); g.fillArc(_x, _y, diameter, diameter, 0, 360); } if (border != null && stroke != null) { g.setColor(border); g.setStroke(stroke); g.drawArc(_x, _y, diameter, diameter, 0, 360); } } public abstract void click(); public abstract void propagate(final Junction source) throws ShortCircuit; protected abstract void _paint(final Graphics2D g); public static Part of(final PartDto abstractDto) { return switch (abstractDto) { case final PartBatteryDto dto -> new PartBattery(dto); case final PartLightDto dto -> new PartLight(dto); case final PartSwitch1x1Dto dto -> new PartSwitch1x1(dto); case final PartSwitch1x2Dto dto -> new PartSwitch1x2(dto); case final PartSwitchCrossDto dto -> new PartSwitchCross(dto); case null, default -> throw new RuntimeException(); }; } public abstract Part duplicate(final int x, final int y); }