diff --git a/src/main/java/projekt/enigma/GuiController.java b/src/main/java/projekt/enigma/GuiController.java index 05b30eaefd2a1fd6fcaf3cbaad5ab471fc1c4238..0bacfd4f7d045c533bfc944e1c1fdec64062774d 100644 --- a/src/main/java/projekt/enigma/GuiController.java +++ b/src/main/java/projekt/enigma/GuiController.java @@ -22,120 +22,111 @@ import java.util.Arrays; public class GuiController { - //region Klassenvariablen - private final static String[] walzenNr = {"I", "II", "III", "IV", "V"}; - private final static String[] ringNr = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26"}; - private final static String[] position = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; - private String[] empfangeneNachricht; - private String textEingabe; - private String textCodiert; - private char chiffrierterBuchstabe; - private boolean resetDisplay; - private Codierer codierer; - private enum BUCHSTABE_LEUCHTET {AN, AUS} - - @FXML - private static ToggleButton[] tBtnPort; - //endregion - - //region GUI-Elemente - //deklariert die benötigten Buttons - @FXML - private Button btnA, btnB, btnC, btnD, btnE, btnF, btnG, btnH, btnI, btnJ, btnK, btnL, btnM, btnN, btnO, btnP, btnQ, - btnR, btnS, btnT, btnU, btnV, btnW, btnX, btnY, btnZ, btnSenden, btnEmpfangen, btnDelete, btnReset; - - //deklariert die benötigten Kreise - @FXML - private Circle circA, circB, circC, circD, circE, circF, circG, circH, circI, circJ, circK, circL, circM, circN, - circO, circP, circQ, circR, circS, circT, circU, circV, circW, circX, circY, circZ; - - //deklariert die benötigten Label - @FXML - private Label lblSpruchschluessel, lblKenngruppe; - - //deklariert die MenueButtons - @FXML - private MenuButton mBtnWalzPos1, mBtnWalzPos2, mBtnWalzPos3, mBtnNotchPos1, mBtnNotchPos2, mBtnNotchPos3, - mBtnStartPos1, mBtnStartPos2, mBtnStartPos3; - - //deklariert die benötigten Textfelder - @FXML - private TextField tfCodiert, tfKlartext; - - //deklariert benötigtes pane - @FXML - private Pane portPane0, portPane1, portPane2, portPane3, portPane4, portPane5, portPane6, portPane7, portPane8, portPane9; - - //deklariert benötigtes GridPane - @FXML - private GridPane mainGrid; - //endregion - - //region Init - /** - * Initialisiert die Elemente GUI und setzt deren Startwerte - */ - @FXML - void initialize() { - // Variablen setzen - textEingabe = ""; - textCodiert = ""; - resetDisplay = true; - - - //Einträge für Walzen - menu(mBtnWalzPos1, walzenNr); - menu(mBtnWalzPos2, walzenNr); - menu(mBtnWalzPos3, walzenNr); - - //Einträge für die Ringe - menu(mBtnNotchPos1, ringNr); - menu(mBtnNotchPos2, ringNr); - menu(mBtnNotchPos3, ringNr); - - //Einträge für die Startpositionen - menu(mBtnStartPos1, position); - menu(mBtnStartPos3, position); - menu(mBtnStartPos2, position); - - - myToggleButtons(); - } - - - /** - * Für das Steckbrett müssen zehn CheckComboBoxen erstellt werden. - * Hier wird die Funktion zum erstellen und Befüllen der Boxen, die Funktion zehn mal aufgerufen. - */ - private void generateSteckbrett() { - for (int i = 0; i <= 9; i++) { - this.createSteckbrettPort(i); - } - } - - /** - * Die Funktion createSteckbrettPort erstellt zehn CheckComboBoxen, holt sich die verfügbaren Buchstaben, - * die bereits gesteckten Kabel und weißt sie zu. - * Im Anschluss werden die CheckComboBoxen auf dem GridPane positioniert. - * - * @param port : int : Kabel Nummer (0-9) - */ - private void createSteckbrettPort(int port) { - // Holt die verfügbaren Buchstaben für diesen Port ab und erstellt ein char Array daraus - char[] verfuegbareBuchstaben = this.codierer.fetchVerfuegbareBuchstaben(port).toCharArray(); - - // Sortiert das Array nach dem Alphabet - Arrays.sort(verfuegbareBuchstaben); - - StringBuilder sb = new StringBuilder(); - - /* - * Die Buchstaben in die CheckComboBox laden und zusätzlich in einen String um später den - * Index des Buchstaben auslesen zu können - */ - for (char c : verfuegbareBuchstaben) { - sb.append(c); - } + //region Klassenvariablen + private final static String[] walzenNr = {"I", "II", "III", "IV", "V"}; + private final static String[] ringNr = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26"}; + private final static String[] position = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; + @FXML + private static ToggleButton[] tBtnPort; + private String[] empfangeneNachricht; + private String textEingabe; + private String textCodiert; + private char chiffrierterBuchstabe; + private boolean resetDisplay; + private Codierer codierer; + //region GUI-Elemente + //deklariert die benötigten Buttons + @FXML + private Button btnA, btnB, btnC, btnD, btnE, btnF, btnG, btnH, btnI, btnJ, btnK, btnL, btnM, btnN, btnO, btnP, btnQ, + btnR, btnS, btnT, btnU, btnV, btnW, btnX, btnY, btnZ, btnSenden, btnEmpfangen, btnDelete, btnReset; + //endregion + //deklariert die benötigten Kreise + @FXML + private Circle circA, circB, circC, circD, circE, circF, circG, circH, circI, circJ, circK, circL, circM, circN, + circO, circP, circQ, circR, circS, circT, circU, circV, circW, circX, circY, circZ; + //deklariert die benötigten Label + @FXML + private Label lblSpruchschluessel, lblKenngruppe; + //deklariert die MenueButtons + @FXML + private MenuButton mBtnWalzPos1, mBtnWalzPos2, mBtnWalzPos3, mBtnNotchPos1, mBtnNotchPos2, mBtnNotchPos3, + mBtnStartPos1, mBtnStartPos2, mBtnStartPos3; + //deklariert die benötigten Textfelder + @FXML + private TextField tfCodiert, tfKlartext; + //deklariert benötigtes pane + @FXML + private Pane portPane0, portPane1, portPane2, portPane3, portPane4, portPane5, portPane6, portPane7, portPane8, portPane9; + //deklariert benötigtes GridPane + @FXML + private GridPane mainGrid; + + /** + * Initialisiert die Elemente GUI und setzt deren Startwerte + */ + @FXML + void initialize() { + // Variablen setzen + textEingabe = ""; + textCodiert = ""; + resetDisplay = true; + + + //Einträge für Walzen + menu(mBtnWalzPos1, walzenNr); + menu(mBtnWalzPos2, walzenNr); + menu(mBtnWalzPos3, walzenNr); + + //Einträge für die Ringe + menu(mBtnNotchPos1, ringNr); + menu(mBtnNotchPos2, ringNr); + menu(mBtnNotchPos3, ringNr); + + //Einträge für die Startpositionen + menu(mBtnStartPos1, position); + menu(mBtnStartPos3, position); + menu(mBtnStartPos2, position); + + + myToggleButtons(); + } + //endregion + + //region Init + + /** + * Für das Steckbrett müssen zehn CheckComboBoxen erstellt werden. + * Hier wird die Funktion zum erstellen und Befüllen der Boxen, die Funktion zehn mal aufgerufen. + */ + private void generateSteckbrett() { + for (int i = 0; i <= 9; i++) { + this.createSteckbrettPort(i); + } + } + + /** + * Die Funktion createSteckbrettPort erstellt zehn CheckComboBoxen, holt sich die verfügbaren Buchstaben, + * die bereits gesteckten Kabel und weißt sie zu. + * Im Anschluss werden die CheckComboBoxen auf dem GridPane positioniert. + * + * @param port : int : Kabel Nummer (0-9) + */ + private void createSteckbrettPort(int port) { + // Holt die verfügbaren Buchstaben für diesen Port ab und erstellt ein char Array daraus + char[] verfuegbareBuchstaben = this.codierer.fetchVerfuegbareBuchstaben(port).toCharArray(); + + // Sortiert das Array nach dem Alphabet + Arrays.sort(verfuegbareBuchstaben); + + StringBuilder sb = new StringBuilder(); + + /* + * Die Buchstaben in die CheckComboBox laden und zusätzlich in einen String um später den + * Index des Buchstaben auslesen zu können + */ + for (char c : verfuegbareBuchstaben) { + sb.append(c); + } /* // ToggleButton erstellen tBtnPort[port] = new ToggleButton(); @@ -143,712 +134,810 @@ public class GuiController { mainGrid.add(tBtnPort[port], port + 1, 8); mainGrid.setMargin(tBtnPort[port], new Insets(0, 15, 0, 15));*/ - // Die Gesteckten Buchstaben in der CheckComboBox selektieren - //ccb.getCheckModel().check(sb.toString().indexOf(this.codierer.fetchSteckverbindungen()[port][0])); - //ccb.getCheckModel().check(sb.toString().indexOf(this.codierer.fetchSteckverbindungen()[port][1])); - } - - /** - * init Methode zur Erstellung der Einträge und Action Listener für die einzelnen Menüs - * - * @param button : Button für die die Einträge erstellt werden sollen - */ - private void menu(MenuButton button, String[] str) { - ArrayList<MenuItem> mItem = new ArrayList<>(); - - for (int i = 0; i < str.length; i++) { - //Eintrag aus str der Arraylist mi hinzufügen - mItem.add(new MenuItem(str[i])); - //MenuItem mi dem Button button hinzufügen - button.getItems().add(mItem.get(i)); - int finalI = i; - //Listener für die einzelnen Einträge - mItem.get(i).setOnAction(e -> setMenuBtnText(button, mItem.get(finalI))); - } - } - - /** - * TODO: Doku - * - * @param port : int : Port zu dem das Panel geändert werden soll - * @param status : aktivieren/deaktivieren - */ - private void switchPortVisible(int port, boolean status) { - switch (port) { - case 0: - portPane0.setVisible(status); - break; - case 1: - portPane1.setVisible(status); - break; - case 2: - portPane2.setVisible(status); - break; - case 3: - portPane3.setVisible(status); - break; - case 4: - portPane4.setVisible(status); - break; - case 5: - portPane5.setVisible(status); - break; - case 6: - portPane6.setVisible(status); - break; - case 7: - portPane7.setVisible(status); - break; - case 8: - portPane8.setVisible(status); - break; - case 9: - portPane9.setVisible(status); - break; - default: - - break; - } - } - - /** - * TODO: Doku - */ - private void myToggleButtons() { - final ToggleGroup cabelConnect = new ToggleGroup(); - tBtnPort = new ToggleButton[10]; - for (int i = 0; i < 10; i++) { - tBtnPort[i] = new ToggleButton(i + "Port"); - tBtnPort[i].setAlignment(Pos.CENTER_RIGHT); - tBtnPort[i].setToggleGroup(cabelConnect); - GridPane.setMargin(tBtnPort[i], new Insets(0, 15, 0, 15)); - mainGrid.add(tBtnPort[i], i + 1, 8); - - cabelConnect.selectedToggleProperty(). - addListener((observable, oldValue, newValue) -> { - //TODO - for (int j = 0; j < 10; j++) { - if (cabelConnect.getSelectedToggle() == tBtnPort[j]) { - switchPortVisible(j, true); - } else if (cabelConnect.getSelectedToggle() != tBtnPort[j]) { - switchPortVisible(j, false); - } - } - }); - } - } - //endregion - - //region EventHandler/Listener - /** - * Wird ausgelöst wenn der gedrückte Button losgelassen wird. - * Setzt die Hintergrundfarbe des Kreises mit dem chiffrierten Buchstaben auf grau, - * durch Aufruf der Methode leuchten. - * - * @param e => übergibt den zuletzt losgelassenen Button - */ - @FXML - void tasteRauf(MouseEvent e) { - if (e.getSource() == btnA) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnB) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnC) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnD) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnE) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnF) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnG) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnH) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnI) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnJ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnK) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnL) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnM) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnN) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnO) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnP) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnQ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnR) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnS) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnT) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnU) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnV) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnW) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnX) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnY) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - if (e.getSource() == btnZ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); - } - - /** - * Wird ausgelöst sobald eine Taste gedrückt wird (beim drücken der Taste) - * Auswertung welche Buchstaben-Taste gedrückt ist. - * Übergabe des entspechenden Buchstaben als Parameter der Methode setText welche den chiffrierten Buchstaben - * in der Klassen-Variablen chiffrierterBuchstabe ablegt. - * Setzt die Hintergrundfarbe des Kreises mit dem chiffrierten Buchstaben auf gelb - * - * @param e => übergibt den momentan gedrückten Buttons - */ - @FXML - void tasteRunter(MouseEvent e) { - if (e.getSource() == btnA) { - setText(btnA); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnB) { - setText(btnB); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnC) { - setText(btnC); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnD) { - setText(btnD); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnE) { - setText(btnE); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnF) { - setText(btnF); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnG) { - setText(btnG); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnH) { - setText(btnH); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnI) { - setText(btnI); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnJ) { - setText(btnJ); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnK) { - setText(btnK); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnL) { - setText(btnL); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnM) { - setText(btnM); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnN) { - setText(btnN); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnO) { - setText(btnO); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnP) { - setText(btnP); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnQ) { - setText(btnQ); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnR) { - setText(btnR); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnS) { - setText(btnS); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnT) { - setText(btnT); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnU) { - setText(btnU); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnV) { - setText(btnV); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnW) { - setText(btnW); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnX) { - setText(btnX); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnY) { - setText(btnY); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - if (e.getSource() == btnZ) { - setText(btnZ); - leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); - } - } - - /** - * Auswertung welcher Button (senden, empfangen oder löschen) gedrückt wurde. - * Funktionsaufruf entsprechend des gedrückten Button - * - * @param e => ActionEvent des auslösenden Button - */ - @FXML - private void gedrueckteTaste(ActionEvent e) { - if (e.getSource() == btnSenden) { - if (tfCodiert.getText().equals("")) { - new Fehler().showErrorDialog("warning", "Haben Sie heute nichts zu sagen?", - "Nutzung von militärischer Infrastruktur ohne Grund ist verboten."); - } else { - sendeFunkspruch(); - } - } - if (e.getSource() == btnEmpfangen) empfangeFunkspruch(); - if (e.getSource() == btnDelete) loeschen(); - if (e.getSource() == btnReset) { - codierer.resetHardware(); - this.resetDisplay = true; - this.lblSpruchschluessel.setText(""); - this.setzeTagesSchluessel(); - } - } - //endregion - - //region Methoden - /** - * Setzt die Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf gelb bzw. auf grau. - * - * @param leuchte => gibt an welcher Kreis (chiffrierter Buchstabe) den Hintergrund ändern soll - * @param shiningLetter => "AN" -> setzt Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf gelb - * "AUS" -> setzt Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf grau - */ - private void leuchten(Circle leuchte, BUCHSTABE_LEUCHTET shiningLetter) { - if (shiningLetter == BUCHSTABE_LEUCHTET.AN) leuchte.setStyle("-fx-fill: #FFA500"); - else if (shiningLetter == BUCHSTABE_LEUCHTET.AUS) { - leuchte.setStyle("-fx-background-color: grey"); - leuchte.setStyle("-fx-border-color: #000000"); - } - } - - /** - * Gibt den Buchstabenkreis entsprechend des chiffrierten Buchstabens zurück - * - * @param chiffLetter => chiffrierter Buchstabe - * @return => Kreis des chiffrierten Buchstabens (der leuchten soll) - */ - private Circle chiffCircle(char chiffLetter) { - switch (chiffLetter) { - case 'A': - return circA; - case 'B': - return circB; - case 'C': - return circC; - case 'D': - return circD; - case 'E': - return circE; - case 'F': - return circF; - case 'G': - return circG; - case 'H': - return circH; - case 'I': - return circI; - case 'J': - return circJ; - case 'K': - return circK; - case 'L': - return circL; - case 'M': - return circM; - case 'N': - return circN; - case 'O': - return circO; - case 'P': - return circP; - case 'Q': - return circQ; - case 'R': - return circR; - case 'S': - return circS; - case 'T': - return circT; - case 'U': - return circU; - case 'V': - return circV; - case 'W': - return circW; - case 'X': - return circX; - case 'Y': - return circY; - case 'Z': - return circZ; - } - return null; - } - - /** - * Methode zum setzen des menuButton Textes auf das ausgewählte MenuItem - * - * @param mBtn : MenuButton der Walze - * @param mItm : MenuItem - */ - private void setMenuBtnText(MenuButton mBtn, MenuItem mItm) { - if (mBtn.getId().equals(mBtnStartPos1.getId())) setzePosition(1, mItm.getText().charAt(0)); - if (mBtn.getId().equals(mBtnStartPos2.getId())) setzePosition(2, mItm.getText().charAt(0)); - if (mBtn.getId().equals(mBtnStartPos3.getId())) setzePosition(3, mItm.getText().charAt(0)); - if (mBtn.getId().equals(mBtnWalzPos1.getId())) setzeWalze(1, mItm.getText()); - if (mBtn.getId().equals(mBtnWalzPos2.getId())) setzeWalze(2, mItm.getText()); - if (mBtn.getId().equals(mBtnWalzPos3.getId())) setzeWalze(3, mItm.getText()); - if (mBtn.getId().equals(mBtnNotchPos1.getId())) - setzeRing(1, Integer.parseInt(mItm.getText()) - 1); - if (mBtn.getId().equals(mBtnNotchPos2.getId())) - setzeRing(2, Integer.parseInt(mItm.getText()) - 1); - if (mBtn.getId().equals(mBtnNotchPos3.getId())) - setzeRing(3, Integer.parseInt(mItm.getText()) - 1); - tfCodiert.setText(""); - tfKlartext.setText(""); - } - - /** - * Hier werden die TextFelder der ToggelButtons gesetzt, welche die Steckverbindungen darstellen, - * mit den Werten die von der Klasse Codierer zur Verfügung gestellt werden. - */ - private void setzeSteckverbindungen() { - - for (int i = 0; i <= 9; i++) { - tBtnPort[i].setText(codierer.fetchSteckverbindungen()[i][0] + "" - + codierer.fetchSteckverbindungen()[i][1]); - } - } - - /** - * Die Löschen Funktion löscht das letzte Zeichen im Klartext sowie im Codiert Feld, - * der Codierer wird aufgerufen um ebenfalls das letzte Zeichen zu löschen - */ - private void loeschen() { - if (textEingabe.length() == 0) { - tfKlartext.setText(""); - tfCodiert.setText(""); - } else { - textEingabe = textEingabe.substring(0, textEingabe.length() - 1); - textCodiert = textCodiert.substring(0, textCodiert.length() - 1); - tfKlartext.setText(textEingabe); - tfCodiert.setText(textCodiert); - codierer.letztesZeichenLoeschen(); - mBtnStartPos1.setText(String.valueOf(this.codierer.fetchWalzen()[0])); - mBtnStartPos2.setText(String.valueOf(this.codierer.fetchWalzen()[1])); - mBtnStartPos3.setText(String.valueOf(this.codierer.fetchWalzen()[2])); - } - } - - /** - * Holt Nachricht von Klasse Codierer und setzt den chiffrierten Text in das Textfeld tfCodiert, - * sowie den Klartext in das Textfeld tfKlartext. Setzt den Spruchschlüssel - */ - private void empfangeFunkspruch() { - progressDialogue("rx"); - - try { - if (this.empfangeneNachricht[2] != null && this.empfangeneNachricht[1] != null) { - setzeTagesSchluessel(); - tfKlartext.setText(this.empfangeneNachricht[2]); - tfCodiert.setText(this.empfangeneNachricht[1]); - resetDisplay = true; - - // Spruchschluessel in das Feld lblSpruchschluessel schreiben - lblSpruchschluessel.setText(codierer.empfangenerSpruchschluessel(this.empfangeneNachricht[2])); - } - } catch (NullPointerException ignored) { - new Fehler().showErrorDialog( - "warning", - "Keiner schreibt dir...", - "Es liegen keine neuen Nachrichten im Funkraum für Sie vor."); - } - } - - /** - * Senden der Nachricht mit Hilfe der Klasse Codierer - * Löscht die Textfelder tfKlartext und tfCodiert - */ - private void sendeFunkspruch() { - this.tfKlartext.setText(""); - this.tfCodiert.setText(""); - - progressDialogue("tx"); - } - - /** - * TODO - * - * @param strRxTx : String : RX oder TX - */ - private void progressDialogue(String strRxTx) { - Task copyWorker = createWorker(strRxTx); - - ProgressIndicator pi = new ProgressIndicator(); - pi.setProgress(-1); - - ProgressDialog dialog = new ProgressDialog(copyWorker); - dialog.initStyle(StageStyle.TRANSPARENT); - dialog.setTitle("Kommunikation zum Funkraum"); - if (strRxTx.equals("rx")) { - dialog.setContentText("Empfange Nachricht"); - } else if (strRxTx.equals("tx")) { - dialog.setContentText("Sende Nachricht"); - } - dialog.setHeaderText(null); - dialog.setGraphic(pi); - dialog.initStyle(StageStyle.UTILITY); - new Thread(copyWorker).start(); - dialog.showAndWait(); - } - - /** - * TODO - * - * @param strRxTx : String : RX oder TX - * @return boolean - */ - public Task createWorker(String strRxTx) { - return new Task() { - @Override - protected Object call() { - if (strRxTx.equals("rx")) { - empfangeneNachricht = codierer.empfangeNachricht(); - } else if (strRxTx.equals("tx")) { - try { - codierer.sendeNachricht(); - } catch (HttpException | IOException e) { - e.printStackTrace(); - } - } - - return true; - } - }; - } - - /** - * Schreibt Buchstaben des gedrückten Button in Textfeld tfKlartext. - * Übergabe des Buchstaben vom gedrückten Button an die Klasse Codierer - * Ablegen des chiffrierten Buchstaben in der char Variable chiffrierterBuchstabe - * Hinzufügen des chiffrierten Buchstaben in Textfeld tfCodiert - * Aktualisierung der Walzenstellung - * - * @param pressedButton : gedrückter Knopf - */ - private void setText(Button pressedButton) { - if (textEingabe.length() < 250) { - if (this.resetDisplay) { - this.tfCodiert.setText(""); - this.tfKlartext.setText(""); - this.lblSpruchschluessel.setText(""); - this.resetDisplay = false; - this.codierer.resetHardware(); - textCodiert = ""; - textEingabe = ""; - // Spruchschlüssel generieren und codieren - this.codierer.generateSpruchschluessel(); - // Spruchschluessel in das Feld lblSpruchschluessel schreiben - lblSpruchschluessel.setText(this.codierer.getSpruchschluessel()); - } - textEingabe += pressedButton.getText(); - chiffrierterBuchstabe = codierer.codiere(pressedButton.getText().charAt(0), true); - textCodiert += chiffrierterBuchstabe; - - tfKlartext.setText(textEingabe); - tfCodiert.setText(textCodiert); - - // Position der Walzen aktuallisieren - mBtnStartPos1.setText(String.valueOf(this.codierer.fetchWalzen()[0])); - mBtnStartPos2.setText(String.valueOf(this.codierer.fetchWalzen()[1])); - mBtnStartPos3.setText(String.valueOf(this.codierer.fetchWalzen()[2])); - } - } - - /** - * Setzt die Anzeige des entsprechende Gui-Element auf die entsprechende Walze - * ->d.h. welche Walze sitzt auf welcher Position - * - * @param walzeRoemischNr => gibt die Walzennummer an - * @param walzenPosition => gibt die Position der Walze - */ - private void setzeWalze(int walzenPosition, String walzeRoemischNr) { - int walzeNr = 0; - switch (walzeRoemischNr) { - case "I": - walzeNr = 0; - break; - case "II": - walzeNr = 1; - break; - case "III": - walzeNr = 2; - break; - case "IV": - walzeNr = 3; - break; - case "V": - walzeNr = 4; - break; - default: - break; - } - - switch (walzenPosition) { - case 1: - mBtnWalzPos1.setText(walzenNr[walzeNr]); - break; - case 2: - mBtnWalzPos2.setText(walzenNr[walzeNr]); - break; - case 3: - mBtnWalzPos3.setText(walzenNr[walzeNr]); - break; - default: - break; - } - } - - /** - * Setzt die Anzeige des entsprechende Gui-Element auf die entsprechende Walze - * -> d.h. welche Walze sitzt auf welcher Position - * - * @param walzenPosition => gibt die Position der Walze - * @param walzeNr => gibt die Walzennummer an - */ - private void setzeWalze(int walzenPosition, int walzeNr) { - switch (walzenPosition) { - case 1: - mBtnWalzPos1.setText(walzenNr[walzeNr - 1]); - //codierer.setWalze(walzeNr, walzenPosition) - break; - case 2: - mBtnWalzPos2.setText(walzenNr[walzeNr - 1]); - break; - case 3: - mBtnWalzPos3.setText(walzenNr[walzeNr - 1]); - break; - default: - break; - } - } - - /** - * Setzt den Notch (position)=> die Mitnahmeposition der Walze (walze) fest - * Mitnahmeposition meint => die nächste Walze wird bei erreichen dieser Position (notch) - * um eine Stelle versetzt - * - * @param ringStellung => gibt die walze an - * @param walzenPosition => gibt den notch der Walze (walze) an - */ - private void setzeRing(int walzenPosition, int ringStellung) { - switch (walzenPosition) { - case 1: - mBtnNotchPos1.setText(ringNr[ringStellung]); - break; - case 2: - mBtnNotchPos2.setText(ringNr[ringStellung]); - break; - case 3: - mBtnNotchPos3.setText(ringNr[ringStellung]); - break; - default: - break; - } - } - - /** - * Setzt die Startposition/ aktuelle Position der Walze - * - * @param walze => gibt die walze an - * @param buchstabe gibt den Startwert bzw die aktuelle Position der Walze (walze) an - */ - private void setzePosition(int walze, char buchstabe) { - switch (walze) { - case 1: - mBtnStartPos1.setText(String.valueOf(buchstabe)); - break; - case 2: - mBtnStartPos2.setText(buchstabe + ""); - break; - case 3: - mBtnStartPos3.setText(buchstabe + ""); - break; - default: - break; - } - } - - /** - * Setzt den aktuellen TagesSchluessel und zeigt diesen in der GUI an - */ - private void setzeTagesSchluessel() { - - // Umsprungpunkte anzeigen - mBtnNotchPos1.setText(String.valueOf(codierer.fetchRingstellung()[0])); - mBtnNotchPos2.setText(String.valueOf(codierer.fetchRingstellung()[1])); - mBtnNotchPos3.setText(String.valueOf(codierer.fetchRingstellung()[2])); - - // Walzennummern anzeigen - setzeWalze(1, codierer.fetchWalzenNr()[0]); - setzeWalze(2, codierer.fetchWalzenNr()[1]); - setzeWalze(3, codierer.fetchWalzenNr()[2]); - - // Position der Walzen anzeigen - mBtnStartPos1.setText(String.valueOf(codierer.fetchWalzen()[0])); - mBtnStartPos2.setText(String.valueOf(codierer.fetchWalzen()[1])); - mBtnStartPos3.setText(String.valueOf(codierer.fetchWalzen()[2])); - - // Steckbrett Felder setzen - setzeSteckverbindungen(); - - // Setzt das Steckbrett - generateSteckbrett(); - - // Felder zurück setzen - this.textCodiert = ""; - this.textEingabe = ""; - this.tfKlartext.setText(""); - this.tfCodiert.setText(""); - } - - /** - * TODO: Doku - * - * @param kenngruppe : String : Die Kenngruppe die gesetzt werden soll - */ - public void setKenngruppe(String kenngruppe) { - - // Initialisieren des Codierers und setzen der Kenngruppe - codierer = new Codierer(kenngruppe.toUpperCase()); - - this.codierer.resetHardware(); - - //Setzt die Kenngruppe in der GUI - lblKenngruppe.setText("Kenngruppe: " + this.codierer.getKenngruppe()); - - // Beim nächsten Tastendruck erstmal das Display löschen damit falschen Nachrichten geschickt werden. - resetDisplay = true; - - // Einstellungen aus dem Logbuch auslesen und setzen - setzeTagesSchluessel(); - setzeSteckverbindungen(); - } - //endregion + // Die Gesteckten Buchstaben in der CheckComboBox selektieren + //ccb.getCheckModel().check(sb.toString().indexOf(this.codierer.fetchSteckverbindungen()[port][0])); + //ccb.getCheckModel().check(sb.toString().indexOf(this.codierer.fetchSteckverbindungen()[port][1])); + } + + /** + * init Methode zur Erstellung der Einträge und Action Listener für die einzelnen Menüs + * + * @param button : Button für die die Einträge erstellt werden sollen + */ + private void menu(MenuButton button, String[] str) { + ArrayList<MenuItem> mItem = new ArrayList<>(); + + for (int i = 0; i < str.length; i++) { + //Eintrag aus str der Arraylist mi hinzufügen + mItem.add(new MenuItem(str[i])); + //MenuItem mi dem Button button hinzufügen + button.getItems().add(mItem.get(i)); + int finalI = i; + //Listener für die einzelnen Einträge + mItem.get(i).setOnAction(e -> setMenuBtnText(button, mItem.get(finalI))); + } + } + + /** + * TODO: Doku + * + * @param port : int : Port zu dem das Panel geändert werden soll + * @param status : aktivieren/deaktivieren + */ + private void switchPortVisible(int port, boolean status) { + switch (port) { + case 0: + portPane0.setVisible(status); + break; + case 1: + portPane1.setVisible(status); + break; + case 2: + portPane2.setVisible(status); + break; + case 3: + portPane3.setVisible(status); + break; + case 4: + portPane4.setVisible(status); + break; + case 5: + portPane5.setVisible(status); + break; + case 6: + portPane6.setVisible(status); + break; + case 7: + portPane7.setVisible(status); + break; + case 8: + portPane8.setVisible(status); + break; + case 9: + portPane9.setVisible(status); + break; + default: + + break; + } + } + + /** + * TODO: Doku + */ + private void myToggleButtons() { + final ToggleGroup cabelConnect = new ToggleGroup(); + tBtnPort = new ToggleButton[10]; + for (int i = 0; i < 10; i++) { + tBtnPort[i] = new ToggleButton(i + "Port"); + tBtnPort[i].setAlignment(Pos.CENTER_RIGHT); + tBtnPort[i].setToggleGroup(cabelConnect); + GridPane.setMargin(tBtnPort[i], new Insets(0, 15, 0, 15)); + mainGrid.add(tBtnPort[i], i + 1, 8); + + cabelConnect.selectedToggleProperty(). + addListener((observable, oldValue, newValue) -> { + //TODO + for (int j = 0; j < 10; j++) { + if (cabelConnect.getSelectedToggle() == tBtnPort[j]) { + switchPortVisible(j, true); + } else if (cabelConnect.getSelectedToggle() != tBtnPort[j]) { + switchPortVisible(j, false); + } + } + }); + } + } + + /** + * Wird ausgelöst wenn der gedrückte Button losgelassen wird. + * Setzt die Hintergrundfarbe des Kreises mit dem chiffrierten Buchstaben auf grau, + * durch Aufruf der Methode leuchten. + * + * @param e => übergibt den zuletzt losgelassenen Button + */ + @FXML + void tasteRauf(MouseEvent e) { + if (e.getSource() == btnA) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnB) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnC) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnD) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnE) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnF) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnG) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnH) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnI) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnJ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnK) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnL) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnM) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnN) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnO) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnP) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnQ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnR) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnS) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnT) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnU) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnV) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnW) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnX) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnY) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + if (e.getSource() == btnZ) leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AUS); + } + //endregion + + //region EventHandler/Listener + + /** + * Wird ausgelöst sobald eine Taste gedrückt wird (beim drücken der Taste) + * Auswertung welche Buchstaben-Taste gedrückt ist. + * Übergabe des entspechenden Buchstaben als Parameter der Methode setText welche den chiffrierten Buchstaben + * in der Klassen-Variablen chiffrierterBuchstabe ablegt. + * Setzt die Hintergrundfarbe des Kreises mit dem chiffrierten Buchstaben auf gelb + * + * @param e => übergibt den momentan gedrückten Buttons + */ + @FXML + void tasteRunter(MouseEvent e) { + if (e.getSource() == btnA) { + setText(btnA); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnB) { + setText(btnB); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnC) { + setText(btnC); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnD) { + setText(btnD); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnE) { + setText(btnE); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnF) { + setText(btnF); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnG) { + setText(btnG); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnH) { + setText(btnH); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnI) { + setText(btnI); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnJ) { + setText(btnJ); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnK) { + setText(btnK); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnL) { + setText(btnL); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnM) { + setText(btnM); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnN) { + setText(btnN); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnO) { + setText(btnO); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnP) { + setText(btnP); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnQ) { + setText(btnQ); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnR) { + setText(btnR); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnS) { + setText(btnS); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnT) { + setText(btnT); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnU) { + setText(btnU); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnV) { + setText(btnV); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnW) { + setText(btnW); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnX) { + setText(btnX); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnY) { + setText(btnY); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + if (e.getSource() == btnZ) { + setText(btnZ); + leuchten(chiffCircle(chiffrierterBuchstabe), BUCHSTABE_LEUCHTET.AN); + } + } + + /** + * Auswertung welcher Button (senden, empfangen oder löschen) gedrückt wurde. + * Funktionsaufruf entsprechend des gedrückten Button + * + * @param e => ActionEvent des auslösenden Button + */ + @FXML + private void gedrueckteTaste(ActionEvent e) { + if (e.getSource() == btnSenden) { + if (tfCodiert.getText().equals("")) { + new Fehler().showErrorDialog("warning", "Haben Sie heute nichts zu sagen?", + "Nutzung von militärischer Infrastruktur ohne Grund ist verboten."); + } else { + sendeFunkspruch(); + } + } + if (e.getSource() == btnEmpfangen) empfangeFunkspruch(); + if (e.getSource() == btnDelete) loeschen(); + if (e.getSource() == btnReset) { + codierer.resetHardware(); + this.resetDisplay = true; + this.lblSpruchschluessel.setText(""); + this.setzeTagesSchluessel(); + } + } + + /** + * Setzt die Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf gelb bzw. auf grau. + * + * @param leuchte => gibt an welcher Kreis (chiffrierter Buchstabe) den Hintergrund ändern soll + * @param shiningLetter => "AN" -> setzt Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf gelb + * "AUS" -> setzt Hintergrundfarbe des Kreises (chiffrierter Buchstabe) auf grau + */ + private void leuchten(Circle leuchte, BUCHSTABE_LEUCHTET shiningLetter) { + if (shiningLetter == BUCHSTABE_LEUCHTET.AN) leuchte.setStyle("-fx-fill: #FFA500"); + else if (shiningLetter == BUCHSTABE_LEUCHTET.AUS) { + leuchte.setStyle("-fx-background-color: grey"); + leuchte.setStyle("-fx-border-color: #000000"); + } + } + //endregion + + //region Methoden + + /** + * Gibt den Buchstabenkreis entsprechend des chiffrierten Buchstabens zurück + * + * @param chiffLetter => chiffrierter Buchstabe + * @return => Kreis des chiffrierten Buchstabens (der leuchten soll) + */ + private Circle chiffCircle(char chiffLetter) { + switch (chiffLetter) { + case 'A': + return circA; + case 'B': + return circB; + case 'C': + return circC; + case 'D': + return circD; + case 'E': + return circE; + case 'F': + return circF; + case 'G': + return circG; + case 'H': + return circH; + case 'I': + return circI; + case 'J': + return circJ; + case 'K': + return circK; + case 'L': + return circL; + case 'M': + return circM; + case 'N': + return circN; + case 'O': + return circO; + case 'P': + return circP; + case 'Q': + return circQ; + case 'R': + return circR; + case 'S': + return circS; + case 'T': + return circT; + case 'U': + return circU; + case 'V': + return circV; + case 'W': + return circW; + case 'X': + return circX; + case 'Y': + return circY; + case 'Z': + return circZ; + } + return null; + } + + /** + * Methode zum setzen des menuButton Textes auf das ausgewählte MenuItem + * + * @param mBtn : MenuButton der Walze + * @param mItm : MenuItem + */ + private void setMenuBtnText(MenuButton mBtn, MenuItem mItm) { + if (mBtn.getId().equals(mBtnStartPos1.getId())) { + setzePosition(1, mItm.getText().charAt(0)); + this.codierer.setzeWalzenPosition(0, mItm.getText().charAt(0)); + } + if (mBtn.getId().equals(mBtnStartPos2.getId())) { + setzePosition(2, mItm.getText().charAt(0)); + this.codierer.setzeWalzenPosition(1, mItm.getText().charAt(0)); + } + if (mBtn.getId().equals(mBtnStartPos3.getId())) { + setzePosition(3, mItm.getText().charAt(0)); + this.codierer.setzeWalzenPosition(2, mItm.getText().charAt(0)); + } + if (mBtn.getId().equals(mBtnWalzPos1.getId())) { + setzeWalze(1, mItm.getText()); + if (!mBtnWalzPos1.getText().equals(mBtnWalzPos2.getText()) && + !mBtnWalzPos1.getText().equals(mBtnWalzPos3.getText())) { + this.codierer.setzeWalzeNr(0, + convertRoemischToZahl(mItm.getText()) + 1, + mBtnNotchPos1.getText().charAt(0)); + } else { + setzeWalze(1, convertZahlToRoemisch(this.codierer.fetchWalzenNr(0))); + new Fehler().showErrorDialog("error", + "Walze nicht gefunden", + "Es scheint so das wir von jeder Walze nur eine da haben"); + } + } + if (mBtn.getId().equals(mBtnWalzPos2.getId())) { + setzeWalze(2, mItm.getText()); + if (!mBtnWalzPos1.getText().equals(mBtnWalzPos2.getText()) && + !mBtnWalzPos2.getText().equals(mBtnWalzPos3.getText())) { + this.codierer.setzeWalzeNr(1, + convertRoemischToZahl(mItm.getText()) + 1, + mBtnNotchPos2.getText().charAt(0)); + } else { + setzeWalze(2, convertZahlToRoemisch(this.codierer.fetchWalzenNr(1))); + new Fehler().showErrorDialog("error", + "Walze nicht gefunden", + "Es scheint so das wir von jeder Walze nur eine da haben"); + } + } + if (mBtn.getId().equals(mBtnWalzPos3.getId())) { + setzeWalze(3, mItm.getText()); + if (!mBtnWalzPos1.getText().equals(mBtnWalzPos3.getText()) && + !mBtnWalzPos2.getText().equals(mBtnWalzPos3.getText())) { + this.codierer.setzeWalzeNr(2, + convertRoemischToZahl(mItm.getText()) + 1, + mBtnNotchPos3.getText().charAt(0)); + } else { + setzeWalze(3, convertZahlToRoemisch(this.codierer.fetchWalzenNr(2))); + new Fehler().showErrorDialog("error", + "Walze nicht gefunden", + "Es scheint so das wir von jeder Walze nur eine da haben"); + } + } + if (mBtn.getId().equals(mBtnNotchPos1.getId())) { + setzeRing(1, Integer.parseInt(mItm.getText()) - 1); + this.codierer.setzeRing(0, Integer.parseInt(mItm.getText()) - 1); + } + if (mBtn.getId().equals(mBtnNotchPos2.getId())) { + setzeRing(2, Integer.parseInt(mItm.getText()) - 1); + this.codierer.setzeRing(1, Integer.parseInt(mItm.getText()) - 1); + } + if (mBtn.getId().equals(mBtnNotchPos3.getId())) { + setzeRing(3, Integer.parseInt(mItm.getText()) - 1); + this.codierer.setzeRing(2, Integer.parseInt(mItm.getText()) - 1); + } + tfCodiert.setText(""); + tfKlartext.setText(""); + } + + /** + * Hier werden die TextFelder der ToggelButtons gesetzt, welche die Steckverbindungen darstellen, + * mit den Werten die von der Klasse Codierer zur Verfügung gestellt werden. + */ + private void setzeSteckverbindungen() { + for (int i = 0; i <= 9; i++) { + tBtnPort[i].setText(codierer.fetchSteckverbindungen()[i][0] + "" + + codierer.fetchSteckverbindungen()[i][1]); + } + } + + /** + * Die Löschen Funktion löscht das letzte Zeichen im Klartext sowie im Codiert Feld, + * der Codierer wird aufgerufen um ebenfalls das letzte Zeichen zu löschen + */ + private void loeschen() { + if (textEingabe.length() == 0) { + tfKlartext.setText(""); + tfCodiert.setText(""); + } else { + textEingabe = textEingabe.substring(0, textEingabe.length() - 1); + textCodiert = textCodiert.substring(0, textCodiert.length() - 1); + tfKlartext.setText(textEingabe); + tfCodiert.setText(textCodiert); + codierer.letztesZeichenLoeschen(); + mBtnStartPos1.setText(String.valueOf(this.codierer.fetchWalzen()[0])); + mBtnStartPos2.setText(String.valueOf(this.codierer.fetchWalzen()[1])); + mBtnStartPos3.setText(String.valueOf(this.codierer.fetchWalzen()[2])); + } + } + + /** + * Holt Nachricht von Klasse Codierer und setzt den chiffrierten Text in das Textfeld tfCodiert, + * sowie den Klartext in das Textfeld tfKlartext. Setzt den Spruchschlüssel + */ + private void empfangeFunkspruch() { + progressDialogue("rx"); + + try { + if (this.empfangeneNachricht[2] != null && this.empfangeneNachricht[1] != null) { + setzeTagesSchluessel(); + tfKlartext.setText(this.empfangeneNachricht[2]); + tfCodiert.setText(this.empfangeneNachricht[1]); + resetDisplay = true; + + // Spruchschluessel in das Feld lblSpruchschluessel schreiben + lblSpruchschluessel.setText(codierer.empfangenerSpruchschluessel(this.empfangeneNachricht[2])); + } + } catch (NullPointerException ignored) { + new Fehler().showErrorDialog( + "warning", + "Keiner schreibt dir...", + "Es liegen keine neuen Nachrichten im Funkraum für Sie vor."); + } + } + + /** + * Senden der Nachricht mit Hilfe der Klasse Codierer + * Löscht die Textfelder tfKlartext und tfCodiert + */ + private void sendeFunkspruch() { + this.tfKlartext.setText(""); + this.tfCodiert.setText(""); + + progressDialogue("tx"); + } + + /** + * TODO + * + * @param strRxTx : String : RX oder TX + */ + private void progressDialogue(String strRxTx) { + Task copyWorker = createWorker(strRxTx); + + ProgressIndicator pi = new ProgressIndicator(); + pi.setProgress(-1); + + ProgressDialog dialog = new ProgressDialog(copyWorker); + dialog.initStyle(StageStyle.TRANSPARENT); + dialog.setTitle("Kommunikation zum Funkraum"); + if (strRxTx.equals("rx")) { + dialog.setContentText("Empfange Nachricht"); + } else if (strRxTx.equals("tx")) { + dialog.setContentText("Sende Nachricht"); + } + dialog.setHeaderText(null); + dialog.setGraphic(pi); + dialog.initStyle(StageStyle.UTILITY); + new Thread(copyWorker).start(); + dialog.showAndWait(); + } + + /** + * TODO + * + * @param strRxTx : String : RX oder TX + * @return boolean + */ + private Task createWorker(String strRxTx) { + return new Task() { + @Override + protected Object call() { + if (strRxTx.equals("rx")) { + empfangeneNachricht = codierer.empfangeNachricht(); + } else if (strRxTx.equals("tx")) { + try { + codierer.sendeNachricht(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return true; + } + }; + } + + /** + * Schreibt Buchstaben des gedrückten Button in Textfeld tfKlartext. + * Übergabe des Buchstaben vom gedrückten Button an die Klasse Codierer + * Ablegen des chiffrierten Buchstaben in der char Variable chiffrierterBuchstabe + * Hinzufügen des chiffrierten Buchstaben in Textfeld tfCodiert + * Aktualisierung der Walzenstellung + * + * @param pressedButton : gedrückter Knopf + */ + private void setText(Button pressedButton) { + if (textEingabe.length() < 250) { + if (this.resetDisplay) { + this.tfCodiert.setText(""); + this.tfKlartext.setText(""); + this.lblSpruchschluessel.setText(""); + this.resetDisplay = false; + this.codierer.resetHardware(); + textCodiert = ""; + textEingabe = ""; + // Spruchschlüssel generieren und codieren + this.codierer.generateSpruchschluessel(); + // Spruchschluessel in das Feld lblSpruchschluessel schreiben + lblSpruchschluessel.setText(this.codierer.getSpruchschluessel()); + } + textEingabe += pressedButton.getText(); + chiffrierterBuchstabe = codierer.codiere(pressedButton.getText().charAt(0), true); + textCodiert += chiffrierterBuchstabe; + + tfKlartext.setText(textEingabe); + tfCodiert.setText(textCodiert); + + // Position der Walzen aktuallisieren + mBtnStartPos1.setText(String.valueOf(this.codierer.fetchWalzen()[0])); + mBtnStartPos2.setText(String.valueOf(this.codierer.fetchWalzen()[1])); + mBtnStartPos3.setText(String.valueOf(this.codierer.fetchWalzen()[2])); + } + } + + /** + * Konvertiert eine rämische Zahl in eine arabische Zahl + * + * @param nummer : String : Römische Zahl + * @return int : arabische Zahl + */ + private int convertRoemischToZahl(String nummer) { + int result = 0; + + switch (nummer) { + case "I": + result = 0; + break; + case "II": + result = 1; + break; + case "III": + result = 2; + break; + case "IV": + result = 3; + break; + case "V": + result = 4; + break; + default: + break; + } + return result; + } + + /** + * Konvertiert eine arabische Zahl in eine rämische Zahl + * + * @param nummer : int : arabische Zahl + * @return String : römische Zahl + */ + private String convertZahlToRoemisch(int nummer) { + String result = ""; + + switch (nummer) { + case 0: + result = "I"; + break; + case 1: + result = "II"; + break; + case 2: + result = "III"; + break; + case 3: + result = "IV"; + break; + case 4: + result = "V"; + break; + default: + break; + } + return result; + } + + /** + * Setzt die Anzeige des entsprechende Gui-Element auf die entsprechende Walze + * ->d.h. welche Walze sitzt auf welcher Position + * + * @param walzeRoemischNr => gibt die Walzennummer an + * @param walzenPosition => gibt die Position der Walze + */ + private void setzeWalze(int walzenPosition, String walzeRoemischNr) { + switch (walzenPosition) { + case 1: + mBtnWalzPos1.setText(walzenNr[convertRoemischToZahl(walzeRoemischNr)]); + break; + case 2: + mBtnWalzPos2.setText(walzenNr[convertRoemischToZahl(walzeRoemischNr)]); + break; + case 3: + mBtnWalzPos3.setText(walzenNr[convertRoemischToZahl(walzeRoemischNr)]); + break; + default: + break; + } + } + + /** + * Setzt die Anzeige des entsprechende Gui-Element auf die entsprechende Walze + * -> d.h. welche Walze sitzt auf welcher Position + * + * @param walzenPosition => gibt die Position der Walze + * @param walzeNr => gibt die Walzennummer an + */ + private void setzeWalze(int walzenPosition, int walzeNr) { + switch (walzenPosition) { + case 1: + mBtnWalzPos1.setText(walzenNr[walzeNr - 1]); + //codierer.setWalze(walzeNr, walzenPosition) + break; + case 2: + mBtnWalzPos2.setText(walzenNr[walzeNr - 1]); + break; + case 3: + mBtnWalzPos3.setText(walzenNr[walzeNr - 1]); + break; + default: + break; + } + } + + /** + * Setzt den Notch (position)=> die Mitnahmeposition der Walze (walze) fest + * Mitnahmeposition meint => die nächste Walze wird bei erreichen dieser Position (notch) + * um eine Stelle versetzt + * + * @param ringStellung => gibt die walze an + * @param walzenPosition => gibt den notch der Walze (walze) an + */ + private void setzeRing(int walzenPosition, int ringStellung) { + switch (walzenPosition) { + case 1: + mBtnNotchPos1.setText(ringNr[ringStellung]); + break; + case 2: + mBtnNotchPos2.setText(ringNr[ringStellung]); + break; + case 3: + mBtnNotchPos3.setText(ringNr[ringStellung]); + break; + default: + break; + } + } + + /** + * Setzt die Startposition/ aktuelle Position der Walze + * + * @param walze => gibt die walze an + * @param buchstabe gibt den Startwert bzw die aktuelle Position der Walze (walze) an + */ + private void setzePosition(int walze, char buchstabe) { + switch (walze) { + case 1: + mBtnStartPos1.setText(String.valueOf(buchstabe)); + break; + case 2: + mBtnStartPos2.setText(buchstabe + ""); + break; + case 3: + mBtnStartPos3.setText(buchstabe + ""); + break; + default: + break; + } + } + + /** + * Setzt den aktuellen TagesSchluessel und zeigt diesen in der GUI an + */ + private void setzeTagesSchluessel() { + + // Umsprungpunkte anzeigen + mBtnNotchPos1.setText(String.valueOf(codierer.fetchRingstellung()[0])); + mBtnNotchPos2.setText(String.valueOf(codierer.fetchRingstellung()[1])); + mBtnNotchPos3.setText(String.valueOf(codierer.fetchRingstellung()[2])); + + // Walzennummern anzeigen + setzeWalze(1, codierer.fetchWalzenNr()[0]); + setzeWalze(2, codierer.fetchWalzenNr()[1]); + setzeWalze(3, codierer.fetchWalzenNr()[2]); + + // Position der Walzen anzeigen + mBtnStartPos1.setText(String.valueOf(codierer.fetchWalzen()[0])); + mBtnStartPos2.setText(String.valueOf(codierer.fetchWalzen()[1])); + mBtnStartPos3.setText(String.valueOf(codierer.fetchWalzen()[2])); + + // Steckbrett Felder setzen + setzeSteckverbindungen(); + + // Setzt das Steckbrett + generateSteckbrett(); + + // Felder zurück setzen + this.textCodiert = ""; + this.textEingabe = ""; + this.tfKlartext.setText(""); + this.tfCodiert.setText(""); + } + + /** + * TODO: Doku + * + * @param kenngruppe : String : Die Kenngruppe die gesetzt werden soll + */ + void setKenngruppe(String kenngruppe) { + + // Initialisieren des Codierers und setzen der Kenngruppe + codierer = new Codierer(kenngruppe.toUpperCase()); + + this.codierer.resetHardware(); + + //Setzt die Kenngruppe in der GUI + lblKenngruppe.setText("Kenngruppe: " + this.codierer.getKenngruppe()); + + // Beim nächsten Tastendruck erstmal das Display löschen damit falschen Nachrichten geschickt werden. + resetDisplay = true; + + // Einstellungen aus dem Logbuch auslesen und setzen + setzeTagesSchluessel(); + setzeSteckverbindungen(); + } + + private enum BUCHSTABE_LEUCHTET {AN, AUS} + //endregion } diff --git a/src/main/java/projekt/enigma/model/Codierer.java b/src/main/java/projekt/enigma/model/Codierer.java index b548415005700d404a7784efc93d14147fd41d0e..19211116ce17de7f8f90cc31a03b42c69a02cd5b 100644 --- a/src/main/java/projekt/enigma/model/Codierer.java +++ b/src/main/java/projekt/enigma/model/Codierer.java @@ -1,7 +1,5 @@ package projekt.enigma.model; -import org.apache.http.HttpException; - import java.io.IOException; import java.util.Calendar; import java.util.Random; @@ -14,503 +12,515 @@ import java.util.Random; */ public class Codierer { - //region Variablen - /** - * Der Klartext Spruchschlüssel zur codierung der Nachricht - */ - private String spruchschluessel; - - /** - * Der Spruchschlüssel, mit den Tageswerten aus dem Codebuch, codiert - */ - private String spruchschluesselCodiert; - - /** - * Die Kenngruppe für die versendeten Nachrichten gedacht sind. Diese ist relevant für den Webservice (Funkraum) - */ - private String kenngruppe; - - /** - * Die Nachricht, welche der Benutzer eingibt, wird als String nachricht gespeichert - * und im laufe der Benutzung ergänzt - */ - private String nachricht; - - /** - * Das Hardware Objekt. Hier werden alle Hardware relevanten Baugruppen gespeichert und verarbeitet. - */ - private Hardware hardware; - - /** - * Im Codebuch sind die Tageswerte zu finden. Über dieses Objekt kann darauf zugegriffen werden. - */ - private Codebuch codebuch; - //endregion - - //region Konstruktor - - /** - * Der Konstruktor des Codierers - * Hier werden die globalen Variablen auf ihre Standart Werte gesetzt sowie die Objekte Initialisiert. - */ - public Codierer(String kenngruppe) { - - this.nachricht = ""; - this.spruchschluessel = ""; - this.spruchschluesselCodiert = ""; - this.kenngruppe = kenngruppe; - - this.codebuch = new Codebuch(); - this.codebuch.fetchTagesschluessel(); - } - //endregion - - //region Funktionen & Methoden - //region Reset & Initialisieren - - /** - * Hier lesen wir den heutigen Eintrag aus dem Codebuch aus und erstellen ein Codebuch Objekt - * Nach dem Codebuch werden dann die Ringe auf die Walzen gesteckt und die Walzen anschließend - * in die Hardware gebaut. - * <br> - * Ein Reflektor wird definiert, jedoch keine Werte zugewisen, da wir nur einen besitzen und - * deshalb alle Einstellungen hierfür Statisch im Reflektor definiert haben. - * <br> - * Das Steck wird ebenfalls definiert und die notwendigen Kabel eingesteckt laut dem heutigen - * Codebuch Eintrag. - */ - private void initialisiereHardware() { - - this.nachricht = ""; - - // Das Steckbrett initialisieren - Steckbrett sb = new Steckbrett(); - char[][] verbinder = this.codebuch.getSteckverbindung(); - - // Für jedes Kabel eine Verbindung auf dem Steckbrett setzen - for (char[] kabel : verbinder) { - sb.setzeVertauschung(kabel[0], kabel[1]); - } - - // Die Hardware aus dem Koffer holen (initialisieren) - this.hardware = new Hardware(); - - // Den Ring an der Walze anbringen und die Walze dann in die Hardware einsetzen - this.hardware.setWalzen(0, this.codebuch.getWalzenlage()[0], this.codebuch.getRingstellung()[0]); - this.hardware.setWalzen(1, this.codebuch.getWalzenlage()[1], this.codebuch.getRingstellung()[1]); - this.hardware.setWalzen(2, this.codebuch.getWalzenlage()[2], this.codebuch.getRingstellung()[2]); - - // Der Hardware das gesetzte Steckbrett zuweisen - this.hardware.setSteckbrett(sb); - - // Ein Reflektor Objekt erstellen und der Hardware bekannt geben - this.hardware.setReflektor(new Reflektor()); - } - - /** - * Setzt die Enigma auf die Einstellungen des aktuellen Tages, aus dem Codebuch zurück. - */ - public void resetHardware() { - this.initialisiereHardware(); - } - - /** - * Leer das Nachrichten Objekt um eine neue Nachricht aufnehmen zu können - */ - public void resetNachricht() { - this.nachricht = ""; - } - //endregion - - //region Nachrichten handler - - /** - * Befehl die Nachricht an den Funker zu übergeben - * - * @throws IOException : Die Antwort konnte nicht gelesen werden - * @throws HttpException : Die Nachricht konnte nicht abgesendet werden - */ - public void sendeNachricht() throws IOException, HttpException { - String kopf = this.generateKopf(); - new Funkraum().sendeFunkspruch(new Morsecode().convertBuchstabeToMorsecode(kopf + this.nachricht), this.kenngruppe); - this.nachricht = ""; - this.resetHardware(); - } - - /** - * Gibt die letzte empfangene Nachricht zurück - * <br> - * String[0] Tag wann die Nachricht gesendet wurde - * String[1] = Die verschlüsselte Nachricht - * String[2] = Nachricht im Klartext - */ - public String[] empfangeNachricht() { - - // Alte Nachrichten Variable erstmal leeren - this.nachricht = ""; - // Morsecode Objekt initialisieren - Morsecode mc = new Morsecode(); - // Unser Nachrichten Array soll drei Einträge erhalten - String[] nachricht = new String[4]; - // Abrufen der letzten Nachricht, für unsere Kenngruppe, aus dem Funkraum - String[] codierteNachricht = new Funkraum().empfangeFunkspruch(this.kenngruppe); - - // Prüfen ob Nachrichtenlänge > 1 und die codierte Nachricht mehr als drei Felder (" ") hat - if (codierteNachricht[1] != null && codierteNachricht[1].split(" ").length > 3) { - // Den Tag der Nachricht speichern - nachricht[0] = codierteNachricht[0]; - // Die Nachricht von Morsecode in Buchstaben konvertieren - nachricht[1] = mc.convertMorsecodeToBuchstabe(codierteNachricht[1]); - // Die Enigma Nachricht (nachricht[1]) mittels der Tageseinstellungen (nachricht[0]) decodieren - nachricht[2] = this.decodiere(nachricht[1], Integer.parseInt(nachricht[0])); - // StringBuilder initialisieren - StringBuilder sb = new StringBuilder(); - - sb.append(nachricht[1], 0, 16); - for (int i = 17; i <= nachricht[1].length(); ) { - if ((i + 5) < nachricht[1].length()) { - sb.append(nachricht[1], i, i + 5).append(" "); - i += 5; - } else { - sb.append(nachricht[1].substring(i)); - break; - } - } - nachricht[1] = sb.toString(); - } - - return nachricht; - } - //endregion - - //region Generatoren - - /** - * Hier wird ein neuer Spruchschlüssel generiert. - * <p> - * Mit diesem werden die Walzen auf eine neue Startposition gestellt und dem Kopf, mit dem - * Tagesschlüssel codiert, hinzugefügt. - * <br> - * Hierfür wird mittels der Funktion "randomBuchstabe" ein zufälliger Buchstabe generiert, - * und geschaut ob dieser bereits in der globalen Variable (this.spruchschluessel) vorhanden ist. - * Wenn nicht, wird der Buchstabe dem Spruchschlüssel hinzugefügt. - * <br> - * Dies wir nun so lange gemacht bis der Spruchschlüssel eine länge von drei Zeichen hat. - */ - public void generateSpruchschluessel() { - - String klartext = ""; - - while (klartext.length() < 3) { - String temp = this.randomBuchstabe(); - if (!klartext.contains(temp)) { - klartext += temp; - } - } - - this.spruchschluessel = klartext; - this.spruchschluesselCodiert = this.codiere(klartext + klartext, false); - - // Walzen auf den Spruchschlüssel stellen - this.hardware.setzePosition(0, this.spruchschluessel.charAt(0)); - this.hardware.setzePosition(1, this.spruchschluessel.charAt(1)); - this.hardware.setzePosition(2, this.spruchschluessel.charAt(2)); - - // Die Kenngruppe codieren und in der Nachricht speichern - this.codiere(this.kenngruppe, true); - } - - /** - * Erstellen des Nachrichten Kopfes. - * Hierfür wird die aktuelle Uhrzeit ausgelesen, die Länge der Nachricht sowie der, mit den - * Tagescodes codierte, Spruchschlüssel. - */ - private String generateKopf() { - Calendar cal = Calendar.getInstance(); - - // Uhrzeit an den Kopf hängen - return String.format("%02d%02d", cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE)) + " " + - // Zeichen Anzahl der Nachricht - this.nachricht.length() + " " + - // Spruchschlüssel anhängen - this.spruchschluesselCodiert.substring(0, 3) + " " + this.spruchschluesselCodiert.substring(3, 6) + " "; - } - - /** - * Einen zufälligen Buchstaben aus dem Alphabet generieren. - * In der Funktion gibt es den String Alphabet, in welchem alle zulässigen Zeichen eingetragen sind. - * Aus diesem String wird nun zufällig ein Zeichen ausgewählt und zurück gegeben. - * - * @return String : ein zufällig generierter Buchstabe - */ - private String randomBuchstabe() { - return String.valueOf((char) ('A' + new Random().nextInt(26))); - } - //endregion - - //region setzte Funktionen - - /** - * Setzt den anzuzeigenden Buchstaben (buchstabe) auf der Walze (walzenPosition) und resetet anschließen das - * Nachrichten Objekt - * - * @param walzenPosition : int : Nummer der Walze - * @param buchstabe : char : Buchstabe der zugewiesen soll - */ - public void setzeWalze(int walzenPosition, char buchstabe) { - this.resetNachricht(); - this.hardware.setzePosition(walzenPosition, buchstabe); - } - - /** - * Setzt den Ring auf der Walze auf einen neuen Umstprungwert. - * - * @param walzenPosition : int : Walze auf die der Ring gesteckt wird - * @param umsprungPunkt : int : Buchstabe auf dem der Notch sitzt - */ - public void setzeRing(int walzenPosition, int umsprungPunkt) { - this.hardware.setzeRing(walzenPosition, umsprungPunkt); - } - - /** - * Setzt die Walze (walzeNr) in die Position (walzenPosition) der Enigma ein. - * Mit (ringstellung) gibt man die Position des Umsprungpunktes an. - * - * @param walzenPosition : int : Position der Walze in der Enigma (1-2-3) - * @param walzeNr : int : Nummer der Walze die eingesetzt wird - * @param ringstellung : int : Stellung des Ringes - */ - public void setzeWalzeNr(int walzenPosition, int walzeNr, int ringstellung) { - this.hardware.setzeWalzenNr(walzenPosition, walzeNr, ringstellung); - } - - /** - * Setzt das Kabel in beide Ports ein und fügt es dem Steckbrett Array hinzu. - * - * @param port : int : Kabel Nummer welches am Steckbrett eingesteckt wird - * @param verbindung : String : Verbindung welche die vertauschten Buchstaben angibt - * @return boolean : Wenn true, darf das Kabel gesteckt werden, wenn nicht, steckt da bereits schon eines - */ - public boolean setzeSteckbrett(int port, String verbindung) { - return this.hardware.getSteckbrett().setzeVertauschung(port, verbindung.charAt(0), verbindung.charAt(1)); - } - //endregion - - //region fetch Funktionen - - /** - * Gibt die Ringstellungen aus dem Codebuch zurück - * - * @return int[] : Array mit den Ringstellungen der drei eingesetzten Walzen - */ - public int[] fetchRingstellung() { - return this.codebuch.getRingstellung(); - } - - /** - * Gibt die Walzennummer aus dem Codebuch zurück - * - * @return int[] : Array mit den Nummern der drei eingesetzten Walzen - */ - public int[] fetchWalzenNr() { - return this.codebuch.getWalzenlage(); - } - - /** - * Gibt die Steckverbindungen aus dem Codebuch zurück - * - * @return char[][] : Array mit den gesteckten Verbindungen im Steckbrett - */ - public char[][] fetchSteckverbindungen() { - return this.codebuch.getSteckverbindung(); - } - - /** - * Gibt die aktuellen Buchstaben auf den Walzen zurück - * - * @return char[] : Walzen Array mit der aktuellen Position - */ - public char[] fetchWalzen() { - char[] walzen = new char[3]; - walzen[0] = this.hardware.getWalzen()[0].getPosition(); - walzen[1] = this.hardware.getWalzen()[1].getPosition(); - walzen[2] = this.hardware.getWalzen()[2].getPosition(); - - return walzen; - } - - /** - * Ueberprueft welche Buchstaben noch zur Vertauschung verfügbar sind - * - * @param port: Zahl zwischen 0-9: entspricht der Kabelnummer. - * @return String: liefert einen String mit den verfuegbaren Buchstaben zurueck. - */ - public String fetchVerfuegbareBuchstaben(int port) { - return this.hardware.getSteckbrett().fetchVerfuegbareBuchstaben(port); - } - //endregion - - //region codierer - - /** - * Hier wird ein einzelner Buchstabe verschlüsselt. - * Man muss hier ebenfalls mitgeben ob der codierte String in Codierer.nachricht gespeichert werden soll oder nicht. - * In der Regel ist dies der Fall. - * - * @param buchstabe : char : Der zu codierende Buchstabe - * @param save : boolean : Nachricht speichern oder nicht - * @return char : Der codierte Buchstabe - */ - public char codiere(char buchstabe, boolean save) { - - char codiert = this.hardware.codiere(buchstabe); - - if (save) { - this.nachricht += codiert; - } - - return codiert; - } - - /** - * Codiert den Übergebenen String. - * Man muss hier ebenfalls mitgeben ob der codierte String in Codierer.nachricht gespeichert werden soll oder nicht. - * In der Regel ist dies der Fall. - * - * @param klartext : String : Der zu codierende Text - * @param save : boolean : Nachricht speichern oder nicht - * @return String : Der codierte Text zusätzlich als Rückgabe - */ - public String codiere(String klartext, boolean save) { - - StringBuilder sb = new StringBuilder(); - - for (char buchstabe : klartext.toCharArray()) { - sb.append(this.codiere(buchstabe, save)); - } - - return sb.toString(); - } - - /** - * Diese Funktion erwartet als (codierteNachricht) eine korrekte Enigma Nachricht. - * Ihr muss auch der Tag der codierung mitgegeben werden. Dieser weiß dein Funker im Funkraum. - * In der Regel ist dies der Tag des Nachrichten empfangs. - * - * @param codierteNachricht : String : Enigma codierte Nachricht - * @param tag : int : Tag der Nachricht - * @return String : decodierte Nachricht - */ - private String decodiere(String codierteNachricht, int tag) { - - // Hardware reseten und Tageseinstellungen aus dem Codebuch laden - this.codebuch.fetchTagesschluessel(tag); - this.initialisiereHardware(); - - // Nachricht splitten mit whitespace als delimiter - String[] nachricht = codierteNachricht.split(" "); - StringBuilder sb = new StringBuilder(); - - // Uhrzeit - sb.append(nachricht[0]).append(" "); - - // Zeichen Anzahl der Nachricht - sb.append(nachricht[1]).append(" "); - - // Spruchschlüssel - String spruchschluessel = this.decodiereString(nachricht[2]); - - sb.append(spruchschluessel).append(" "); - sb.append(this.decodiereString(nachricht[3])).append(" "); - - // Walzen neu einstellen mit dem Spruchschlüssel - this.hardware.setzePosition(0, spruchschluessel.charAt(0)); - this.hardware.setzePosition(1, spruchschluessel.charAt(1)); - this.hardware.setzePosition(2, spruchschluessel.charAt(2)); - - // Nachricht decodieren - sb.append(this.decodiereString(nachricht[4])); - - return sb.toString(); - } - - /** - * Zerlegt den übergebenen String in einen char Array und decodiert jedes Zeichen. - * Der String wird dann decodiert zurück gegeben. - * - * @param nachricht : String : Der zu decodierende Text - * @return String : Der decodierte Text - */ - private String decodiereString(String nachricht) { - - StringBuilder sb = new StringBuilder(); - - for (char buchstabe : nachricht.toCharArray()) { - if (buchstabe > 0) { - sb.append(this.hardware.codiere(buchstabe)); - } - } - - return sb.toString(); - } - //endregion - - //region Sonstige - - /** - * Prüft ob der Port auf den das Kabel gesteckt werden soll, noch frei ist. - * <p> - * setSteckbrett ausführen mit beiden Buchstaben als String - * - * @param buchstabe : char : Der zuletzt eingegebene Buchstabe - * @return boolean : Wenn der Buchstabe nicht vorhanden ist, wird true zurückgegeben, ansonsten false - */ - public boolean pruefeSteckbrettPort(char buchstabe) { - return this.hardware.getSteckbrett().ueberpruefeVertauschungen(buchstabe); - } - - /** - * Ließt aus der empfangenen Nachricht den Spruchschlüssel aus und gibt ihn zurück. + //region Variablen + /** + * Der Klartext Spruchschlüssel zur codierung der Nachricht + */ + private String spruchschluessel; + + /** + * Der Spruchschlüssel, mit den Tageswerten aus dem Codebuch, codiert + */ + private String spruchschluesselCodiert; + + /** + * Die Kenngruppe für die versendeten Nachrichten gedacht sind. Diese ist relevant für den Webservice (Funkraum) + */ + private String kenngruppe; + + /** + * Die Nachricht, welche der Benutzer eingibt, wird als String nachricht gespeichert + * und im laufe der Benutzung ergänzt + */ + private String nachricht; + + /** + * Das Hardware Objekt. Hier werden alle Hardware relevanten Baugruppen gespeichert und verarbeitet. + */ + private Hardware hardware; + + /** + * Im Codebuch sind die Tageswerte zu finden. Über dieses Objekt kann darauf zugegriffen werden. + */ + private Codebuch codebuch; + //endregion + + //region Konstruktor + + /** + * Der Konstruktor des Codierers + * Hier werden die globalen Variablen auf ihre Standart Werte gesetzt sowie die Objekte Initialisiert. + */ + public Codierer(String kenngruppe) { + + this.nachricht = ""; + this.spruchschluessel = ""; + this.spruchschluesselCodiert = ""; + this.kenngruppe = kenngruppe; + + this.codebuch = new Codebuch(); + this.codebuch.fetchTagesschluessel(); + } + //endregion + + //region Funktionen & Methoden + //region Reset & Initialisieren + + /** + * Hier lesen wir den heutigen Eintrag aus dem Codebuch aus und erstellen ein Codebuch Objekt + * Nach dem Codebuch werden dann die Ringe auf die Walzen gesteckt und die Walzen anschließend + * in die Hardware gebaut. + * <br> + * Ein Reflektor wird definiert, jedoch keine Werte zugewisen, da wir nur einen besitzen und + * deshalb alle Einstellungen hierfür Statisch im Reflektor definiert haben. + * <br> + * Das Steck wird ebenfalls definiert und die notwendigen Kabel eingesteckt laut dem heutigen + * Codebuch Eintrag. + */ + private void initialisiereHardware() { + + this.nachricht = ""; + + // Das Steckbrett initialisieren + Steckbrett sb = new Steckbrett(); + char[][] verbinder = this.codebuch.getSteckverbindung(); + + // Für jedes Kabel eine Verbindung auf dem Steckbrett setzen + for (char[] kabel : verbinder) { + sb.setzeVertauschung(kabel[0], kabel[1]); + } + + // Die Hardware aus dem Koffer holen (initialisieren) + this.hardware = new Hardware(); + + // Den Ring an der Walze anbringen und die Walze dann in die Hardware einsetzen + this.hardware.setWalzen(0, this.codebuch.getWalzenlage()[0], this.codebuch.getRingstellung()[0]); + this.hardware.setWalzen(1, this.codebuch.getWalzenlage()[1], this.codebuch.getRingstellung()[1]); + this.hardware.setWalzen(2, this.codebuch.getWalzenlage()[2], this.codebuch.getRingstellung()[2]); + + // Der Hardware das gesetzte Steckbrett zuweisen + this.hardware.setSteckbrett(sb); + + // Ein Reflektor Objekt erstellen und der Hardware bekannt geben + this.hardware.setReflektor(new Reflektor()); + } + + /** + * Setzt die Enigma auf die Einstellungen des aktuellen Tages, aus dem Codebuch zurück. + */ + public void resetHardware() { + this.initialisiereHardware(); + } + + /** + * Leer das Nachrichten Objekt um eine neue Nachricht aufnehmen zu können + */ + private void resetNachricht() { + this.nachricht = ""; + } + //endregion + + //region Nachrichten handler + + /** + * Befehl die Nachricht an den Funker zu übergeben + * + * @throws IOException : Die Antwort konnte nicht gelesen werden + */ + public void sendeNachricht() throws IOException { + String kopf = this.generateKopf(); + new Funkraum().sendeFunkspruch(new Morsecode().convertBuchstabeToMorsecode(kopf + this.nachricht), this.kenngruppe); + this.nachricht = ""; + this.resetHardware(); + } + + /** + * Gibt die letzte empfangene Nachricht zurück + * <br> + * String[0] Tag wann die Nachricht gesendet wurde + * String[1] = Die verschlüsselte Nachricht + * String[2] = Nachricht im Klartext + */ + public String[] empfangeNachricht() { + + // Alte Nachrichten Variable erstmal leeren + this.nachricht = ""; + // Morsecode Objekt initialisieren + Morsecode mc = new Morsecode(); + // Unser Nachrichten Array soll drei Einträge erhalten + String[] nachricht = new String[3]; + // Abrufen der letzten Nachricht, für unsere Kenngruppe, aus dem Funkraum + String[] codierteNachricht = new Funkraum().empfangeFunkspruch(this.kenngruppe); + + // Prüfen ob Nachrichtenlänge > 1 und die codierte Nachricht mehr als drei Felder (" ") hat + if (codierteNachricht[1] != null && codierteNachricht[1].split(" ").length > 3) { + // Den Tag der Nachricht speichern + nachricht[0] = codierteNachricht[0]; + // Die Nachricht von Morsecode in Buchstaben konvertieren + nachricht[1] = mc.convertMorsecodeToBuchstabe(codierteNachricht[1]); + // Die Enigma Nachricht (nachricht[1]) mittels der Tageseinstellungen (nachricht[0]) decodieren + nachricht[2] = this.decodiere(nachricht[1], Integer.parseInt(nachricht[0])); + // StringBuilder initialisieren + StringBuilder sb = new StringBuilder(); + + sb.append(nachricht[1], 0, 16); + for (int i = 17; i <= nachricht[1].length(); ) { + if ((i + 5) < nachricht[1].length()) { + sb.append(nachricht[1], i, i + 5).append(" "); + i += 5; + } else { + sb.append(nachricht[1].substring(i)); + break; + } + } + nachricht[1] = sb.toString(); + } + + return nachricht; + } + //endregion + + //region Generatoren + + /** + * Hier wird ein neuer Spruchschlüssel generiert. + * <p> + * Mit diesem werden die Walzen auf eine neue Startposition gestellt und dem Kopf, mit dem + * Tagesschlüssel codiert, hinzugefügt. + * <br> + * Hierfür wird mittels der Funktion "randomBuchstabe" ein zufälliger Buchstabe generiert, + * und geschaut ob dieser bereits in der globalen Variable (this.spruchschluessel) vorhanden ist. + * Wenn nicht, wird der Buchstabe dem Spruchschlüssel hinzugefügt. + * <br> + * Dies wir nun so lange gemacht bis der Spruchschlüssel eine länge von drei Zeichen hat. + */ + public void generateSpruchschluessel() { + + String klartext = ""; + + while (klartext.length() < 3) { + String temp = this.randomBuchstabe(); + if (!klartext.contains(temp)) { + klartext += temp; + } + } + + this.spruchschluessel = klartext; + this.spruchschluesselCodiert = this.codiere(klartext + klartext, false); + + // Walzen auf den Spruchschlüssel stellen + this.hardware.setzePosition(0, this.spruchschluessel.charAt(0)); + this.hardware.setzePosition(1, this.spruchschluessel.charAt(1)); + this.hardware.setzePosition(2, this.spruchschluessel.charAt(2)); + + // Die Kenngruppe codieren und in der Nachricht speichern + this.codiere(this.kenngruppe, true); + } + + /** + * Erstellen des Nachrichten Kopfes. + * Hierfür wird die aktuelle Uhrzeit ausgelesen, die Länge der Nachricht sowie der, mit den + * Tagescodes codierte, Spruchschlüssel. + */ + private String generateKopf() { + Calendar cal = Calendar.getInstance(); + + // Uhrzeit an den Kopf hängen + return String.format("%02d%02d", cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE)) + " " + + // Zeichen Anzahl der Nachricht + this.nachricht.length() + " " + + // Spruchschlüssel anhängen + this.spruchschluesselCodiert.substring(0, 3) + " " + this.spruchschluesselCodiert.substring(3, 6) + " "; + } + + /** + * Einen zufälligen Buchstaben aus dem Alphabet generieren. + * In der Funktion gibt es den String Alphabet, in welchem alle zulässigen Zeichen eingetragen sind. + * Aus diesem String wird nun zufällig ein Zeichen ausgewählt und zurück gegeben. + * + * @return String : ein zufällig generierter Buchstabe + */ + private String randomBuchstabe() { + return String.valueOf((char) ('A' + new Random().nextInt(26))); + } + //endregion + + //region setzte Funktionen + + /** + * Setzt den Ring auf der Walze auf einen neuen Umstprungwert. + * + * @param walzenPosition : int : Walze auf die der Ring gesteckt wird + * @param umsprungPunkt : int : Buchstabe auf dem der Notch sitzt + */ + public void setzeRing(int walzenPosition, int umsprungPunkt) { + this.resetNachricht(); + this.hardware.setzeRing(walzenPosition, umsprungPunkt); + } + + /** + * Setzt die Walze (walzeNr) in die Position (walzenPosition) der Enigma ein. + * Mit (ringstellung) gibt man die Position des Umsprungpunktes an. + * + * @param walzenPosition : int : Position der Walze in der Enigma (1-2-3) + * @param walzeNr : int : Nummer der Walze die eingesetzt wird + * @param ringstellung : int : Stellung des Ringes + */ + public void setzeWalzeNr(int walzenPosition, int walzeNr, int ringstellung) { + this.resetNachricht(); + this.hardware.setzeWalzenNr(walzenPosition, walzeNr, ringstellung); + } + + /** + * Setzt das Kabel in beide Ports ein und fügt es dem Steckbrett Array hinzu. + * + * @param port : int : Kabel Nummer welches am Steckbrett eingesteckt wird + * @param verbindung : String : Verbindung welche die vertauschten Buchstaben angibt + * @return boolean : Wenn true, darf das Kabel gesteckt werden, wenn nicht, steckt da bereits schon eines + */ + public boolean setzeSteckbrett(int port, String verbindung) { + this.resetNachricht(); + return this.hardware.getSteckbrett().setzeVertauschung(port, verbindung.charAt(0), verbindung.charAt(1)); + } + + /** + * Setzt den anzuzeigenden Buchstaben (buchstabe) auf der Walze (walzenPosition) und resetet das + * Nachrichten Objekt + * + * @param walze : int : Nummer der Walze + * @param buchstabe : char : Buchstabe der zugewiesen soll + */ + public void setzeWalzenPosition(int walze, char buchstabe) { + this.resetNachricht(); + this.hardware.setzePosition(walze, buchstabe); + } + //endregion + + //region fetch Funktionen + + /** + * Gibt die Ringstellungen aus dem Codebuch zurück + * + * @return int[] : Array mit den Ringstellungen der drei eingesetzten Walzen + */ + public int[] fetchRingstellung() { + return this.codebuch.getRingstellung(); + } + + /** + * Gibt die Walzennummer aus dem Codebuch zurück + * + * @return int[] : Array mit den Nummern der drei eingesetzten Walzen + */ + public int[] fetchWalzenNr() { + return this.codebuch.getWalzenlage(); + } + + /** + * Gibt die Steckverbindungen aus dem Codebuch zurück + * + * @return char[][] : Array mit den gesteckten Verbindungen im Steckbrett + */ + public char[][] fetchSteckverbindungen() { + return this.codebuch.getSteckverbindung(); + } + + /** + * Gibt die aktuellen Buchstaben auf den Walzen zurück + * + * @return char[] : Walzen Array mit der aktuellen Position + */ + public char[] fetchWalzen() { + char[] walzen = new char[3]; + walzen[0] = this.hardware.getWalzen()[0].getPosition(); + walzen[1] = this.hardware.getWalzen()[1].getPosition(); + walzen[2] = this.hardware.getWalzen()[2].getPosition(); + + return walzen; + } + + /** + * Gibt die Walzennummer einer Walze auf Position (walzePos) zurück * - * @param empfangeneNachricht : String : Die empfangene Nachricht als String - * @return String : Der Spruchschlüssel mit welcher die Nachricht codiert wurde. + * @param walzePos : int : Position der Walze + * @return int : Nummer der eingesetzten Walze */ - public String empfangenerSpruchschluessel(String empfangeneNachricht) { - String[] nachricht = empfangeneNachricht.split(" "); - - return nachricht[2]; + public int fetchWalzenNr(int walzePos) { + return this.hardware.getWalzen()[walzePos].getWalzenNr(); } - /** - * Löscht das letzte Zeichen aus der Nachricht und dreht die Walzen eine Position zurück. - */ - public void letztesZeichenLoeschen() { - this.hardware.dreheWalzen(-1); - this.nachricht = this.nachricht.substring(0, this.nachricht.length() - 1); - } - //endregion - //endregion - - //region Getter - - /** - * Liest die Kenngruppe aus welche die Maschine gerade besitzt. Früher war dies eine eindeutige Nummer - * die einer Einheit zugewiesen war. Wir hinterlegen hier einen Benutzernamen. - * - * @return String : Kenngruppe - */ - public String getKenngruppe() { - return kenngruppe; - } - - /** - * Der Spruchschlüssel wird, zur internen Verwendung, auch im Klartext gespeichert. - * Wir brauchen diesen dann zum codieren der eigentlichen Nachricht. - * - * @return String : Der klartext Spruchschlüssel - */ - public String getSpruchschluessel() { - return this.spruchschluessel; - } - //endregion + /** + * Ueberprueft welche Buchstaben noch zur Vertauschung verfügbar sind + * + * @param port: Zahl zwischen 0-9: entspricht der Kabelnummer. + * @return String: liefert einen String mit den verfuegbaren Buchstaben zurueck. + */ + public String fetchVerfuegbareBuchstaben(int port) { + return this.hardware.getSteckbrett().fetchVerfuegbareBuchstaben(port); + } + //endregion + + //region codierer + + /** + * Hier wird ein einzelner Buchstabe verschlüsselt. + * Man muss hier ebenfalls mitgeben ob der codierte String in Codierer.nachricht gespeichert werden soll oder nicht. + * In der Regel ist dies der Fall. + * + * @param buchstabe : char : Der zu codierende Buchstabe + * @param save : boolean : Nachricht speichern oder nicht + * @return char : Der codierte Buchstabe + */ + public char codiere(char buchstabe, boolean save) { + + char codiert = this.hardware.codiere(buchstabe); + + if (save) { + this.nachricht += codiert; + } + + return codiert; + } + + /** + * Codiert den Übergebenen String. + * Man muss hier ebenfalls mitgeben ob der codierte String in Codierer.nachricht gespeichert werden soll oder nicht. + * In der Regel ist dies der Fall. + * + * @param klartext : String : Der zu codierende Text + * @param save : boolean : Nachricht speichern oder nicht + * @return String : Der codierte Text zusätzlich als Rückgabe + */ + public String codiere(String klartext, boolean save) { + + StringBuilder sb = new StringBuilder(); + + for (char buchstabe : klartext.toCharArray()) { + sb.append(this.codiere(buchstabe, save)); + } + + return sb.toString(); + } + + /** + * Diese Funktion erwartet als (codierteNachricht) eine korrekte Enigma Nachricht. + * Ihr muss auch der Tag der codierung mitgegeben werden. Dieser weiß dein Funker im Funkraum. + * In der Regel ist dies der Tag des Nachrichten empfangs. + * + * @param codierteNachricht : String : Enigma codierte Nachricht + * @param tag : int : Tag der Nachricht + * @return String : decodierte Nachricht + */ + private String decodiere(String codierteNachricht, int tag) { + + // Hardware reseten und Tageseinstellungen aus dem Codebuch laden + this.codebuch.fetchTagesschluessel(tag); + this.initialisiereHardware(); + + // Nachricht splitten mit whitespace als delimiter + String[] nachricht = codierteNachricht.split(" "); + StringBuilder sb = new StringBuilder(); + + // Uhrzeit + sb.append(nachricht[0]).append(" "); + + // Zeichen Anzahl der Nachricht + sb.append(nachricht[1]).append(" "); + + // Spruchschlüssel + String spruchschluessel = this.decodiereString(nachricht[2]); + + sb.append(spruchschluessel).append(" "); + sb.append(this.decodiereString(nachricht[3])).append(" "); + + // Walzen neu einstellen mit dem Spruchschlüssel + this.hardware.setzePosition(0, spruchschluessel.charAt(0)); + this.hardware.setzePosition(1, spruchschluessel.charAt(1)); + this.hardware.setzePosition(2, spruchschluessel.charAt(2)); + + // Nachricht decodieren + sb.append(this.decodiereString(nachricht[4])); + + return sb.toString(); + } + + /** + * Zerlegt den übergebenen String in einen char Array und decodiert jedes Zeichen. + * Der String wird dann decodiert zurück gegeben. + * + * @param nachricht : String : Der zu decodierende Text + * @return String : Der decodierte Text + */ + private String decodiereString(String nachricht) { + + StringBuilder sb = new StringBuilder(); + + for (char buchstabe : nachricht.toCharArray()) { + if (buchstabe > 0) { + sb.append(this.hardware.codiere(buchstabe)); + } + } + + return sb.toString(); + } + //endregion + + //region Sonstige + + /** + * Prüft ob der Port auf den das Kabel gesteckt werden soll, noch frei ist. + * <p> + * setSteckbrett ausführen mit beiden Buchstaben als String + * + * @param buchstabe : char : Der zuletzt eingegebene Buchstabe + * @return boolean : Wenn der Buchstabe nicht vorhanden ist, wird true zurückgegeben, ansonsten false + */ + public boolean pruefeSteckbrettPort(char buchstabe) { + return this.hardware.getSteckbrett().ueberpruefeVertauschungen(buchstabe); + } + + /** + * Ließt aus der empfangenen Nachricht den Spruchschlüssel aus und gibt ihn zurück. + * + * @param empfangeneNachricht : String : Die empfangene Nachricht als String + * @return String : Der Spruchschlüssel mit welcher die Nachricht codiert wurde. + */ + public String empfangenerSpruchschluessel(String empfangeneNachricht) { + String[] nachricht = empfangeneNachricht.split(" "); + + return nachricht[2]; + } + + /** + * Löscht das letzte Zeichen aus der Nachricht und dreht die Walzen eine Position zurück. + */ + public void letztesZeichenLoeschen() { + this.hardware.dreheWalzen(-1); + this.nachricht = this.nachricht.substring(0, this.nachricht.length() - 1); + } + //endregion + //endregion + + //region Getter + + /** + * Liest die Kenngruppe aus welche die Maschine gerade besitzt. Früher war dies eine eindeutige Nummer + * die einer Einheit zugewiesen war. Wir hinterlegen hier einen Benutzernamen. + * + * @return String : Kenngruppe + */ + public String getKenngruppe() { + return kenngruppe; + } + + /** + * Der Spruchschlüssel wird, zur internen Verwendung, auch im Klartext gespeichert. + * Wir brauchen diesen dann zum codieren der eigentlichen Nachricht. + * + * @return String : Der klartext Spruchschlüssel + */ + public String getSpruchschluessel() { + return this.spruchschluessel; + } + //endregion } diff --git a/src/main/java/projekt/enigma/model/Walze.java b/src/main/java/projekt/enigma/model/Walze.java index b064f6910f70aed6d735be95af321c65406ec622..eebb0ff1799d96dd6a301a0acb01b4fe3e8e22fd 100644 --- a/src/main/java/projekt/enigma/model/Walze.java +++ b/src/main/java/projekt/enigma/model/Walze.java @@ -70,7 +70,7 @@ public class Walze { * @param richtung : int : 1 dreht die Walze weiter und -1 dreht sie einen Schritt zurueck * @return checkRing : boolean : gibt true zurueck wenn der Umspringpunkt erreicht wurde */ - public boolean dreheWalze(int richtung) { + boolean dreheWalze(int richtung) { boolean checkRing = false; int korrekturFaktor = 0; @@ -108,7 +108,7 @@ public class Walze { * @param buchstabe : char : Buchstabe, der decodiert werden soll * @return char : decodierter Buchstabe */ - public char codiere2(char buchstabe) { + char codiere2(char buchstabe) { return this.alphabet.charAt((this.fetchWalze().indexOf(buchstabe) - this.turns + 260) % 26); } @@ -127,7 +127,7 @@ public class Walze { * * @param walzenNr : int : Walzennummer */ - public void setWalzenNr(int walzenNr) { + private void setWalzenNr(int walzenNr) { if ((walzenNr > 0) && (walzenNr < 6)) { this.walzenNr = walzenNr - 1; } else { @@ -144,7 +144,7 @@ public class Walze { * * @param ringstellung : int : Punkt an dem die Nachbarwalze umspringt */ - public void setRingstellung(int ringstellung) { + void setRingstellung(int ringstellung) { if ((ringstellung > 0) && (ringstellung <= 26)) { this.ringstellung = this.alphabet.charAt(ringstellung - 1); } else { @@ -158,7 +158,7 @@ public class Walze { * * @param buchstabe : Character : Einstellung der Walze */ - public void setPosition(Character buchstabe) { + void setPosition(Character buchstabe) { this.turns = alphabet.indexOf(buchstabe); } //endregion @@ -169,8 +169,12 @@ public class Walze { * * @return char : Ermittelte stelle im Alphabet, anhand der aktuellen Anzahl der Drehungen */ - public Character getPosition() { + Character getPosition() { return this.alphabet.charAt(turns % 26); } + + int getWalzenNr() { + return this.walzenNr; + } //endregion } \ No newline at end of file