/**
   * prints out either the shopping List or the Overview of the items in stock depending on the type
   *
   * @param type
   */
  public void printOut(PrintOutType type) {

    boolean output = false;
    String fileToPrint = "";

    switch (type) {
      case OVERVIEW:
        output = SaveToFile.printOut(new ArrayList<ItemBox>(items), type, false);
        fileToPrint = "Overview.txt";
        break;
      case SHOPPING:
        ArrayList<ItemBox> temp = new ArrayList<>();

        // adds every Item which has an amount of 0 to the shopping list
        for (ItemBox item : items) {
          if (item.getAmount() == 0) {
            temp.add(item);
          }
        }
        output = SaveToFile.printOut(temp, type, false);
        fileToPrint = "Shopping.txt";
        break;
    }

    if (output) {
      log.debug(type.name() + " Successfully Saved PrintFile");
      File file = new File(System.getProperty("user.home") + "/Desktop/" + fileToPrint);

      if (file != null) {
        boolean printOut = Printing.printFile(file);

        if (printOut) {
          log.debug("Successfully printed File");
          Alert alert =
              Alerter.getAlert(AlertType.INFORMATION, "Print", null, "Successfully printed.");
          alert.showAndWait();
        } else {
          log.debug("File was saved but could not be printed");
          Alert alert =
              Alerter.getAlert(
                  AlertType.INFORMATION,
                  "Print Failed",
                  null,
                  "File saved but could not be printed.");
          alert.showAndWait();
        }
      }

    } else {
      Alert alert =
          Alerter.getAlert(
              AlertType.INFORMATION, "Error", null, "File could not be saved and printed.");
      alert.showAndWait();
      log.debug(type.name() + "PrintFile could NOT be saved and printed");
    }
  }
  /**
   * if the barcode hasn't already got a name on outpan.com the item will be listed online with the
   * passed name
   *
   * @param gtin
   * @param name
   */
  private void listNewItem(String gtin, String name) {
    try {
      URL url =
          new URL(
              "https://api.outpan.com/v2/products/"
                  + gtin
                  + "/name"
                  + "?apikey=e13a9fb0bda8684d72bc3dba1b16ae1e");

      HttpsURLConnection httpCon = (HttpsURLConnection) url.openConnection();
      httpCon.setDoOutput(true);
      httpCon.setRequestMethod("POST");

      // replaces umlauts, ß, ", ' and /
      name = IllegalStringReplacer.replaceIllegalChars(name);

      String content = "name=" + name;
      DataOutputStream out = new DataOutputStream(httpCon.getOutputStream());

      out.writeBytes(content);
      out.flush();

      log.debug(httpCon.getResponseCode() + " - " + httpCon.getResponseMessage());
      out.close();

      if (httpCon.getResponseCode() == 200) {
        Alert alert =
            Alerter.getAlert(AlertType.INFORMATION, "Item Added", null, "Item is now listed.");
        alert.showAndWait();
        log.info("Item '" + name + "' now listed");

        addItem(gtin);
      } else {
        log.debug("Item could not be listed");
        Alert alert =
            Alerter.getAlert(
                AlertType.WARNING,
                "Item not Added",
                null,
                "Item could not be listed, please try again.");
        alert.showAndWait();
      }

    } catch (MalformedURLException e) {
      log.error("MalformedURLException: " + e.getMessage());
    } catch (IOException e) {
      log.error("IOException: " + e.getMessage());
    }
  }
  /** Sets up the behaviour of the Items int the menubar */
  private void setupMenuItems() {
    aboutMenu.setOnAction(
        event -> {
          AnchorPane root;
          try {
            root = FXMLLoader.load(getClass().getResource("about.fxml"));

            Stage stage = new Stage();
            stage.setScene(new Scene(root));
            stage.setTitle("About");
            stage.show();
          } catch (Exception e) {
            log.error("Error loading About Window - " + e.getMessage());
          }
        });

    exitMenu.setOnAction(
        event -> {
          Platform.runLater(
              new Runnable() {
                @Override
                public void run() {
                  Platform.exit();
                  log.debug("Window closed");
                }
              });
        });

    loadMenu.setOnAction(event -> loadFile(true));

    saveMenu.setOnAction(event -> Main.serializeItems());

    groupByMenu.setOnAction(
        event -> {
          Optional<String> sortOption =
              Alerter.getChoiceDialog("Sorting", null, "Select how you want to group: ");
          sortOption.ifPresent(letter -> groupItems(letter));
        });

    updateAllMenu.setOnAction(
        event -> {
          new Thread(
                  new Task<Void>() {
                    @Override
                    protected Void call() throws Exception {
                      log.debug("UpdateAll Thread Triggered");

                      itemsMap.forEach(
                          (a, b) -> {
                            updateItem(b);
                          });

                      updateList();
                      Main.serializeItems();

                      log.debug("UpdateAll Thread terminated successfully");
                      return null;
                    }
                  })
              .start();
        });

    updateMenu.setOnAction(
        event -> {
          if (!listView.getSelectionModel().isEmpty()) {
            ItemBox itemBox = listView.getSelectionModel().getSelectedItem();
            updateItem(itemBox);
          } else {
            Alert alert =
                Alerter.getAlert(
                    AlertType.INFORMATION,
                    "No Item selected",
                    null,
                    "Please select the Item you want to update!");
            alert.showAndWait();
            log.debug("Info Popup triggered, No item selected");
          }
        });

    deleteMenu.setOnAction(
        event -> {
          ItemBox rem = itemsMap.remove(listView.getSelectionModel().getSelectedItem().getGtin());
          log.info("Item: " + rem.getName() + " removed");
          updateList();
        });

    repeatMenu.setOnAction(
        event -> {
          if (lastCommand != null) {
            String[] props = lastCommand.split(" ");
            log.info("Repeat called with: " + lastCommand);

            switch (props[0]) {
              case "ADD":
                addItem(props[1]);
                break;
              case "RM":
                removeItem(props[1]);
                break;
            }
          }
        });

    printMenu.setOnAction(
        event -> {
          printOut(PrintOutType.OVERVIEW);
        });

    printShoppingMenu.setOnAction(
        event -> {
          printOut(PrintOutType.SHOPPING);
        });
  }