From 100da3849374608df227731068eae5373b03f5c9 Mon Sep 17 00:00:00 2001
From: Georg-Notebook <georg@dergeorg.at>
Date: Tue, 13 Apr 2021 14:16:07 +0200
Subject: [PATCH] Edit Log + Tour

---
 log/log4j/log.out                           |   1 +
 src/tourplaner/tourplaner.fxml              |  31 +--
 src/tourplaner/ui/AlertHelper.java          |  48 +++--
 src/tourplaner/ui/TourplanerController.java |  10 +
 src/tourplaner/viewmodels/ViewModel.java    | 206 ++++++++++++++++----
 5 files changed, 221 insertions(+), 75 deletions(-)

diff --git a/log/log4j/log.out b/log/log4j/log.out
index 1c58c9a..7a9854b 100644
--- a/log/log4j/log.out
+++ b/log/log4j/log.out
@@ -10,3 +10,4 @@
 2021-03-18 23:14:55 ERROR ViewModel -> DelTour:33 - Keine Tour ausgewählt!
 2021-03-19 11:56:22 ERROR ViewModel -> DelTour:33 - Keine Tour ausgewählt!
 2021-03-19 22:35:19 ERROR ViewModel -> DelTour:33 - Keine Tour ausgewählt!
+2021-03-19 23:23:36 ERROR ViewModel -> DelTour:33 - Keine Tour ausgewählt!
diff --git a/src/tourplaner/tourplaner.fxml b/src/tourplaner/tourplaner.fxml
index 6193249..d224ce0 100644
--- a/src/tourplaner/tourplaner.fxml
+++ b/src/tourplaner/tourplaner.fxml
@@ -32,26 +32,13 @@
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -->
 
-<?import javafx.geometry.Insets?>
-<?import javafx.scene.control.Button?>
-<?import javafx.scene.control.Label?>
-<?import javafx.scene.control.ListView?>
-<?import javafx.scene.control.Menu?>
-<?import javafx.scene.control.MenuBar?>
-<?import javafx.scene.control.MenuItem?>
-<?import javafx.scene.control.SplitPane?>
-<?import javafx.scene.control.Tab?>
-<?import javafx.scene.control.TabPane?>
-<?import javafx.scene.control.TableColumn?>
-<?import javafx.scene.control.TableView?>
-<?import javafx.scene.control.TextField?>
-<?import javafx.scene.layout.AnchorPane?>
-<?import javafx.scene.layout.HBox?>
-<?import javafx.scene.layout.VBox?>
-<?import javafx.scene.paint.Color?>
-<?import javafx.scene.text.Font?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.paint.*?>
+<?import javafx.scene.text.*?>
 
-<VBox prefHeight="600.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1" fx:controller="tourplaner.ui.TourplanerController">
+<VBox prefHeight="600.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="tourplaner.ui.TourplanerController">
   <children>
     <MenuBar VBox.vgrow="NEVER">
       <menus>
@@ -86,6 +73,7 @@
                   <Button fx:id="tourAdd" layoutX="58.0" mnemonicParsing="false" onAction="#addTour" text="+" />
                   <Label layoutX="14.0" layoutY="4.0" text="Tours" />
                   <Button fx:id="tourDel" layoutX="89.0" mnemonicParsing="false" onAction="#delTour" text="-" />
+                  <Button layoutX="117.0" mnemonicParsing="false" onAction="#editTourBtn" text="Edit" />
                </children></AnchorPane>
             <TextField fx:id="sucheInput" promptText="Suche..." />
             <Button fx:id="sucheButton" mnemonicParsing="false" onAction="#suche" text="Suchen" />
@@ -156,7 +144,7 @@
                            <children>
                               <AnchorPane prefWidth="676.0">
                                  <children>
-                                    <HBox id="HBox" alignment="CENTER_LEFT" prefWidth="702.0" spacing="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+                                    <HBox id="HBox" alignment="CENTER_LEFT" layoutY="2.0" prefWidth="702.0" spacing="5.0" AnchorPane.bottomAnchor="-2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="2.0">
                                        <children>
                                           <Label text="Logs:">
                                              <HBox.margin>
@@ -170,9 +158,10 @@
                                           </Button>
                                           <Button fx:id="logDel" mnemonicParsing="false" onAction="#delLog" prefWidth="21.0" text="-" textAlignment="CENTER">
                                              <HBox.margin>
-                                                <Insets right="10.0" />
+                                                <Insets />
                                              </HBox.margin>
                                           </Button>
+                                          <Button mnemonicParsing="false" onAction="#editLogBtn" text="Edit" />
                                        </children>
                                        <padding>
                                           <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
diff --git a/src/tourplaner/ui/AlertHelper.java b/src/tourplaner/ui/AlertHelper.java
index 6b91c13..564e7ab 100644
--- a/src/tourplaner/ui/AlertHelper.java
+++ b/src/tourplaner/ui/AlertHelper.java
@@ -1,5 +1,6 @@
 package tourplaner.ui;
 
+import javafx.event.EventHandler;
 import javafx.scene.Scene;
 import javafx.scene.control.*;
 import javafx.scene.control.Label;
@@ -7,6 +8,7 @@ import javafx.scene.control.TextArea;
 import javafx.scene.image.Image;
 import javafx.scene.layout.*;
 import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
 import tourplaner.business.ConfigHelper;
 
 import java.io.PrintWriter;
@@ -113,10 +115,10 @@ public class AlertHelper {
      * @param msg Nachricht des Dialogs
      * @return Null bei keiner eingabe
      */
-    public static String inputText(String title, String header, String msg) {
+    public static String inputText(String title, String header, String msg, String content) {
         String returnStr = "";
         while (returnStr.isEmpty()) {
-            Optional<String> result = inputHelper(title, header, msg);
+            Optional<String> result = inputHelper(title, header, msg, content);
             AtomicReference<String> returnText = new AtomicReference<>("");
             result.ifPresent(returnText::set);
             returnStr = returnText.get();
@@ -136,11 +138,12 @@ public class AlertHelper {
      * @param msg Nachricht des Dialogs
      * @return Result des Inputs
      */
-    private static Optional<String> inputHelper(String title, String header, String msg){
-        TextInputDialog dialog = new TextInputDialog();
+    private static Optional<String> inputHelper(String title, String header, String msg, String content){
+        TextInputDialog dialog = new TextInputDialog(content);
         dialog.setTitle(title);
         dialog.setHeaderText(header);
         dialog.setContentText(msg);
+
         Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
         stage.getIcons().add(
                 new Image("file:"+ ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "start", "logo")));
@@ -149,48 +152,53 @@ public class AlertHelper {
 
     }
 
+
     /**
      * Positive Nummer eingabe. Wenn Convertierung zu int nicht klappt -> -1
      * @param title Title des Dialogs
      * @param header Header des Dialogs
      * @param msg Nachricht des Dialogs
-     * @return -1 bei error sonst ein Int
+     * @return -1.0 bei error sonst ein double
      */
-    public static int inputNumber(String title, String header, String msg) {
-        int returnInt = -2;
-        while (returnInt <= 0 ) {
-            Optional<String> result = inputHelper(title, header, msg);
-            AtomicReference<Integer> returnText = new AtomicReference<Integer>(-1);
+    public static double inputNumber(String title, String header, String msg, String content) {
+        double returnDouble = -2.0;
+        while (returnDouble < -1.0) {
+            Optional<String> result = inputHelper(title, header, msg, content);
+            AtomicReference<Double> returnText = new AtomicReference<Double>(-1.0);
             result.ifPresent(s -> {
                 try {
-                    int resultInt = Integer.parseInt(result.get());
-                    returnText.set(resultInt);
-                    if (resultInt < 0){
+                    double resultDouble = Double.parseDouble(result.get());
+//                    int resultInt = Integer.parseInt(result.get());
+                    returnText.set(resultDouble);
+                    if (resultDouble < 0){
                         AlertHelper.warn(title, ConfigHelper.getLangIniString("achtung"), ConfigHelper.getLangIniString("nurpositivezahlen"));
                     }
                 } catch (NumberFormatException e) {
                     AlertHelper.warn(title, ConfigHelper.getLangIniString("achtung"), ConfigHelper.getLangIniString("nurzahlen"));
-                    returnText.set(-1);
+                    returnText.set(-2.0);
                 }
 
             });
-            returnInt = returnText.get();
+            returnDouble = returnText.get();
         }
-
-        return returnInt;
+        return returnDouble;
     }
 
     /**
      * Date Picker Dialog, sobald ein Datum ausgewählt wurde, wird es automatisch bestätigt und der dialog geschlossen
-     * @param title Name des Dialogs
+     * @param content Aktuelles datum
      * @return Gewähltes datum
      */
-    public static LocalDate datePicker(String title){
-        final DatePicker datePicker = new DatePicker(LocalDate.now());
+    public static LocalDate datePicker(LocalDate content){
+        final DatePicker datePicker = new DatePicker(content);
         final Stage stage = new Stage();
         stage.getIcons().add(
                 new Image("file:"+ ConfigHelper.getIniString(ConfigHelper.getStandartConfig(), "start", "logo")));
         AtomicReference<LocalDate> selectedDate = new AtomicReference<>();
+        stage.setOnCloseRequest(ev -> {
+           stage.close();
+        });
+
         datePicker.setOnAction(event -> {
             LocalDate date = datePicker.getValue();
             System.out.println("Selected date: " + date);
diff --git a/src/tourplaner/ui/TourplanerController.java b/src/tourplaner/ui/TourplanerController.java
index 3065656..d993449 100644
--- a/src/tourplaner/ui/TourplanerController.java
+++ b/src/tourplaner/ui/TourplanerController.java
@@ -40,6 +40,16 @@ public class TourplanerController implements Initializable {
     public TableView<Log> logTableView;
     public TableColumn<Log, String> logDauerCol, logStreckeCol, logDatumCol;
 
+
+    @FXML
+    private void editTourBtn(){
+        this.viewModel.editTour();
+    }
+
+    @FXML
+    private void editLogBtn(){
+        this.viewModel.editLog();
+    }
     /**
      * Öffnet github im standart browser
      *
diff --git a/src/tourplaner/viewmodels/ViewModel.java b/src/tourplaner/viewmodels/ViewModel.java
index 47c0702..be4859b 100644
--- a/src/tourplaner/viewmodels/ViewModel.java
+++ b/src/tourplaner/viewmodels/ViewModel.java
@@ -2,7 +2,6 @@ package tourplaner.viewmodels;
 
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
-import javafx.fxml.FXML;
 import tourplaner.ui.AlertHelper;
 import tourplaner.business.ConfigHelper;
 import tourplaner.business.LogHelper;
@@ -15,6 +14,7 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.time.LocalDate;
 import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 
 public class ViewModel {
@@ -28,56 +28,53 @@ public class ViewModel {
     private Log selectedLog;
 
 
+
     /**
-     * Fügt einen Log eintrag zu einer Tour hinzu.
-     * Ist keine Tour ausgewählt, dann kommt eine Warnung an den User!
+     * Bearbeitet eine bereits bestehende Tour
      */
-    @FXML
-    public void addLog(){
+    public void editTour(){
         if (this.selectedTour == null){
             AlertHelper.warn(ConfigHelper.getLangIniString("achtung"),
                     ConfigHelper.getLangIniString("keinetourselected"),
                     ConfigHelper.getLangIniString("logtournotselectedmsg"));
         }else {
+            AtomicInteger index = new AtomicInteger(-1);
+            AtomicInteger aktIndex = new AtomicInteger(-1);
             this.tourData.forEach(s -> {
+                index.getAndIncrement();
                 if (s.getName().equals(this.selectedTour.getName())) {
-                    AtomicReference<String> newId = new AtomicReference<>();
-                    newId.set(UUID.randomUUID().toString());
-                    this.logData.forEach(ss -> {
-                        if (ss.getId().equals(newId.get())) {
-                            newId.set(UUID.randomUUID().toString());
-                        }
-                    });
-                    LocalDate neuesDatum = null;
-                    while (neuesDatum == null) {
-                        neuesDatum = AlertHelper.datePicker(ConfigHelper.getLangIniString("datum"));
-                    }
-                    double neueDauer = AlertHelper.inputNumber(ConfigHelper.getLangIniString("dauer"),
-                            ConfigHelper.getLangIniString("dauermsg"),
-                            ConfigHelper.getLangIniString("dauer") +
-                                    ConfigHelper.getLangIniString("doppelpunkt"));
-                    double neueStrecke = AlertHelper.inputNumber(ConfigHelper.getLangIniString("strecke"),
-                            ConfigHelper.getLangIniString("streckemsg"),
-                            ConfigHelper.getLangIniString("strecke") +
-                                    ConfigHelper.getLangIniString("doppelpunkt"));
-
-                    Log newLog = new Log(newId.get(), neueDauer + "", neuesDatum, neueStrecke);
-                    this.logData.add(newLog);
-                    s.addLog(newLog);
+                    aktIndex.set(index.intValue());
                 }
             });
+            if(aktIndex.intValue() != -1){
+                Tour tourToEdit = this.tourData.get(aktIndex.intValue());
+                this.tourData.removeIf(tour -> tour.getName().equals(this.selectedTour.getName()));
+                this.tourNamen.removeIf(tour -> tour.equals(this.selectedTour.getName()));
+                System.out.println(tourToEdit.getLogs());
+                tourNameInput(this.selectedTour.getName());
+                tourToEdit.setName(this.neueTourName);
+                tourStartInput(this.selectedTour.getStart());
+                tourToEdit.setStart(this.neueTourStart);
+                tourZielInput(this.selectedTour.getZiel());
+                tourToEdit.setZiel(this.neueTourZiel);
+                System.out.println(tourToEdit.getName());
+
+                this.tourData.add(new Tour(this.neueTourName, "TBD", "TBD", 0, this.neueTourStart, this.neueTourZiel));
+                this.tourNamen.add(this.neueTourName);
+//                this.tourData.add(tourToEdit);
+            }
         }
     }
 
-
     /**
-     * Fügt eine neue Tour hinzu
+     * Input des Tour Namen wird so lange durchgeführt, bis er korrekt ist. Das heißt:
+     * er darf nicht schon vorhanden sein und er darf nicht Null sein
      */
-    public void addTour(){
+    private void tourNameInput(String content){
         while(this.neueTourName == null) {
             this.neueTourName = AlertHelper.inputText(ConfigHelper.getLangIniString("tournametitle"),
                     ConfigHelper.getLangIniString("tournameheader"),
-                    ConfigHelper.getLangIniString("tournamemsg"));
+                    ConfigHelper.getLangIniString("tournamemsg"), content);
             if (getTour(this.neueTourName) != null) {
                 AlertHelper.warn(ConfigHelper.getLangIniString("achtung"),
                         ConfigHelper.getLangIniString("namevergebenheader"),
@@ -87,16 +84,40 @@ public class ViewModel {
                 this.neueTourName = null;
             }
         }
+    }
+
+    /**
+     * Input der Startpunkt der Tour
+     * Wird erst beendet wenn die eingabe erfolgreich war
+     */
+    private void tourStartInput(String content){
         while(this.neueTourStart == null){
             this.neueTourStart = AlertHelper.inputText(ConfigHelper.getLangIniString("startpunkttitle"),
                     ConfigHelper.getLangIniString("startpunktheader"),
-                    ConfigHelper.getLangIniString("startpunktmsg"));
+                    ConfigHelper.getLangIniString("startpunktmsg"), content);
         }
+    }
+
+    /**
+     * Input des Zielpunktes der Tour
+     * Wird erst beendet wenn die eingabe erfolgreich war
+     */
+    private void tourZielInput(String content){
         while(this.neueTourZiel == null){
             this.neueTourZiel = AlertHelper.inputText(ConfigHelper.getLangIniString("zielpunkttitle"),
                     ConfigHelper.getLangIniString("zielpunktheader"),
-                    ConfigHelper.getLangIniString("zielpunktmsg"));
+                    ConfigHelper.getLangIniString("zielpunktmsg"), content);
         }
+    }
+
+
+    /**
+     * Fügt eine neue Tour hinzu
+     */
+    public void addTour(){
+        tourNameInput("");
+        tourStartInput("");
+        tourZielInput("");
         if (getTour(this.neueTourName) == null) {
             tourData.add(new Tour(this.neueTourName, "TBD", "TBD", 0, this.neueTourStart, this.neueTourZiel));
             tourNamen.add(this.neueTourName);
@@ -106,6 +127,123 @@ public class ViewModel {
         this.neueTourName = null;
     }
 
+    private boolean keineTourSelected(){
+        if (this.selectedTour == null){
+            AlertHelper.warn(ConfigHelper.getLangIniString("achtung"),
+                    ConfigHelper.getLangIniString("keinetourselected"),
+                    ConfigHelper.getLangIniString("logtournotselectedmsg"));
+            return true;
+        }else {
+            return false;
+        }
+    }
+
+    /**
+     * Bearbeitet einen gewählten Log eintrag
+     */
+    public void editLog(){
+        AtomicReference<Tour> tourAkt = new AtomicReference<>();
+        AtomicReference<Log> logAkt = new AtomicReference<>();
+        this.tourData.forEach(tourd -> {
+            if(tourd.getName().equals(this.selectedTour.getName())) {
+                tourd.getLogs().forEach(log -> {
+                    if(this.selectedLog.getId().equals(log.getId())){
+                        logAkt.set(log);
+                        tourAkt.set(tourd);
+                    }
+                });
+            }
+        });
+        double dauer = dauerInput(this.selectedLog.getDauer());
+        double strecke = -1;
+        LocalDate datum = null;
+        if (dauer >= 0) {
+            strecke = streckeInput(this.selectedLog.getStrecke() + "");
+            if (strecke >= 0) {
+                datum = dateInput(this.selectedLog.getDatum());
+                if(datum != null){
+                    Log newLog = new Log(this.selectedLog.getId(), dauer + "", datum,strecke);
+                    this.logData.removeIf(ld -> ld.getId().equals(this.selectedLog.getId()));
+                    this.logData.add(newLog);
+                    tourAkt.get().delLog(this.selectedLog.getId());
+                    tourAkt.get().addLog(newLog);
+                    this.tourData.removeIf(td -> td.getName().equals(this.selectedTour.getName()));
+                    this.tourData.add(tourAkt.get());
+                }
+            }
+        }
+    }
+
+    /**
+     * Eingabe der Strecke bis diese Korrekt ist
+     * @return Korrekte eingegebene Strecke
+     */
+    private double streckeInput(String content){
+        return AlertHelper.inputNumber(ConfigHelper.getLangIniString("strecke"),
+                ConfigHelper.getLangIniString("streckemsg"),
+                ConfigHelper.getLangIniString("strecke") +
+                        ConfigHelper.getLangIniString("doppelpunkt"), content);
+    }
+
+    /**
+     * Eingabe der Dauer bis sie korrekt ist
+     * @return Die eingegebene Dauer
+     */
+    private double dauerInput(String content){
+        return AlertHelper.inputNumber(ConfigHelper.getLangIniString("dauer"),
+                ConfigHelper.getLangIniString("dauermsg"),
+                ConfigHelper.getLangIniString("dauer") +
+                        ConfigHelper.getLangIniString("doppelpunkt"), content);
+    }
+
+    /**
+     * Datum eingabe bis diese Korrekt ist
+     * @return Das eingegebene korekte Datum
+     */
+    private LocalDate dateInput(LocalDate date){
+        LocalDate neuesDatum = null;
+        neuesDatum = AlertHelper.datePicker(date);
+        System.out.println(neuesDatum);
+        return neuesDatum;
+    }
+
+    /**
+     * Fügt einen Log eintrag zu einer Tour hinzu.
+     * Ist keine Tour ausgewählt, dann kommt eine Warnung an den User!
+     */
+    public void addLog(){
+        if (!keineTourSelected()){
+            this.tourData.forEach(s -> {
+                if (s.getName().equals(this.selectedTour.getName())) {
+                    AtomicReference<String> newId = new AtomicReference<>();
+                    newId.set(UUID.randomUUID().toString());
+                    this.logData.forEach(ss -> {
+                        if (ss.getId().equals(newId.get())) {
+                            newId.set(UUID.randomUUID().toString());
+                        }
+                    });
+                    double dauer = dauerInput("");
+                    double strecke;
+                    LocalDate date = null;
+                    if(dauer >= 0) {
+                        strecke = streckeInput("");
+                        if (strecke >= 0.0) {
+                            date = dateInput(LocalDate.now());
+                                if (date != null){
+                                    Log newLog = new Log(newId.get(), dauer + "", date, strecke);
+                                    this.logData.add(newLog);
+                                    s.addLog(newLog);
+                                }
+                        }
+                    }
+                }
+            });
+        }
+    }
+
+
+
+
     /**
      * Entfernt ein Log anhand des selectierten Logs
      */