package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; import java.io.IOException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import javafx.fxml.FXML; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.FlowPane; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; @Controller public class ArchiveOperationController { private static final Logger LOG = LoggerFactory.getLogger(ArchiveOperationController.class); @FXML private TextField txtSearch; @FXML private ImageView imvVehicleDetail; @FXML private Label lblStatus; @FXML private AnchorPane apMainDetails; @FXML private Label lblOperations; @FXML private Label lblCompleted; @FXML private Label lblCancelled; @FXML private AnchorPane backApMain; @FXML private AnchorPane backApDetails; @FXML private AnchorPane archiveOperationAP; @FXML private AnchorPane apDetails; @FXML private Label lblCodeHeader; @FXML private Label lblOpCode; @FXML private Label lblVehicles; @FXML private Label lblDate; @FXML private Label lblAddress; @FXML private FlowPane fpVehicles; private final OperationService operationService; @FXML private FlowPane archiveOperationFlowPane; private final CreateOperationController createOperationController; private Set list = new HashSet<>(); private final SpringFXMLLoader fxmlLoader; public ArchiveOperationController( OperationService operationService, CreateOperationController createOperationController, SpringFXMLLoader fxmlLoader) { this.operationService = operationService; this.createOperationController = createOperationController; this.fxmlLoader = fxmlLoader; } @FXML private void initialize() { update(); } public void update() { archiveOperationFlowPane.getChildren().clear(); list.clear(); try { list.addAll(operationService.list(EnumSet.of(Status.CANCELLED, Status.COMPLETED))); long cancelledAmount = 0; long completedAmount = 0; for (Operation operation : list) { if (operation.status() == Status.CANCELLED) cancelledAmount++; else completedAmount++; } lblCancelled.setText("storniert: " + cancelledAmount); lblCompleted.setText("abgeschlossen: " + completedAmount); lblOperations.setText("Einsätze: " + list.size()); } catch (ServiceException e) { LOG.error("ServiceException in update().", e); showServiceExceptionAlertAndWait("Die Einsätze konnten nicht geladen werden!"); ; } setFlowPane(list); } public void update(Set operations) { long cancelledAmount = 0; long completedAmount = 0; for (Operation operation : operations) { if (operation.status() == Status.CANCELLED) cancelledAmount++; else completedAmount++; } lblCancelled.setText("storniert: " + cancelledAmount); lblCompleted.setText("abgeschlossen: " + completedAmount); lblOperations.setText("Einsätze: " + operations.size()); setFlowPane(operations); } private void setFlowPane(Set operations) { try { archiveOperationFlowPane.getChildren().clear(); for (Operation operation : sortSet(operations)) { OperationInArchiveController opInAController = OperationInArchiveController.create(); opInAController.set(operation); opInAController .getRoot() .setOnMouseClicked( event -> { detailOperation = operation; backApMain.setVisible(false); apMainDetails.setVisible(false); backApDetails.setVisible(true); setOperation(); setDetailsVisible(true); imvVehicleDetail.setImage(new Image("/images/Vehicle.png")); }); archiveOperationFlowPane.getChildren().add(opInAController.getRoot()); } } catch (IOException e) { LOG.error("IOException in setFlowPane(). ", e); showServiceExceptionAlertAndWait("Die Elemente konnten nicht geladen werden!"); } } private Operation detailOperation; private List sortSet(Set operationsSet) { Operation[] array = operationsSet.toArray(new Operation[operationsSet.size()]); for (int i = array.length - 1; i > 0; i--) { for (int j = 0; j < i; j++) { LocalDateTime first = LocalDateTime.ofInstant( Objects.requireNonNull(array[j].created()), ZoneOffset.UTC); LocalDateTime second = LocalDateTime.ofInstant( Objects.requireNonNull(array[j + 1].created()), ZoneOffset.UTC); if (first.isBefore(second)) { Operation help = array[j]; array[j] = array[j + 1]; array[j + 1] = help; } } } return Arrays.asList(array); } private void setOperation() { lblCodeHeader.setText(detailOperation.opCode()); if (detailOperation.created() != null) { LocalDateTime dateTime = LocalDateTime.ofInstant( Objects.requireNonNull(detailOperation.created()), ZoneOffset.UTC); lblDate.setText( "am " + dateTime.getDayOfMonth() + "." + dateTime.getMonth().getValue() + "." + dateTime.getYear()); } else { lblDate.setText("---"); } lblStatus.setText( "Status: " + (detailOperation.status() == Status.CANCELLED ? "storniert" : "abgeschlossen")); lblOpCode.setText(detailOperation.opCode()); Collection elements = detailOperation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); String result = String.join(", ", elements); lblVehicles.setText(result); lblAddress.setText(detailOperation.destination()); fpVehicles.getChildren().clear(); try { for (Vehicle vehicle : detailOperation.vehicles()) { DetailArchiveOperationController controller = null; controller = DetailArchiveOperationController.create(fxmlLoader); controller.set(vehicle, detailOperation); fpVehicles.getChildren().add(controller.getRoot()); } } catch (IOException e) { LOG.error("IOException in setOperation(). ", e); showServiceExceptionAlertAndWait("Die Element konnte nicht geladen werden!"); } } private void setDetailsVisible(boolean b) { apDetails.setVisible(b); } public void backClicked() { LOG.debug("Hyperlink \"Zurück\" in archive detail view clicked."); fpVehicles.getChildren().clear(); setDetailsVisible(false); backApDetails.setVisible(false); apMainDetails.setVisible(true); backApMain.setVisible(true); } public void backToMain() { LOG.debug("Hyperlink \"Zurück\" in archive main view clicked."); this.setVisible(false); createOperationController.setVisible(true); } void setVisible(boolean b) { archiveOperationAP.setVisible(b); backApMain.setVisible(b); apMainDetails.setVisible(b); } @FXML public void searchInput() { LOG.debug("Search for operations in archive detail view started."); String text = txtSearch.getText(); Set chosenOperations = new HashSet<>(); if (emptyText(text)) update(); else { for (Operation operation : list) { if (checkEquality(operation, text)) chosenOperations.add(operation); } update(chosenOperations); } } private boolean emptyText(String text) { if (text == null) return true; text = text.replaceAll("\\s+", ""); return text.isEmpty(); } private boolean checkEquality(Operation operation, String text) { if (isEqual(text, operation.opCode()) || isEqual(text, operation.destination()) || isEqual(text, reformDateToString(operation.created()))) return true; for (Vehicle vehicle : operation.vehicles()) { if (isEqual(text, vehicle.name())) return true; } return false; } private String reformDateToString(Instant time) { LocalDateTime dateTime = LocalDateTime.ofInstant(Objects.requireNonNull(time), ZoneOffset.UTC); return "am " + dateTime.getDayOfMonth() + "." + dateTime.getMonth().getValue() + "." + dateTime.getYear(); } private boolean isEqual(String text, String realText) { for (int i = 0; (i + text.length()) < realText.length(); i++) { StringBuilder result = new StringBuilder(); for (int j = i; j < i + text.length(); j++) { result.append(realText.charAt(j)); } if ((text.toLowerCase()).equals(result.toString().toLowerCase())) return true; } return false; } }