package no.ntnu.idatt1002.demo.controller; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.recipes.*; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Optional; import java.util.ResourceBundle; public class SuggestRecipesController implements Initializable { IngredientsAtHand ingredientsAtHand; RecipeRegister recipeRegister; @FXML private Button addToFridgeBtn; @FXML private Button removeBtn; @FXML private Button showAllBtn; @FXML private Button goBackBtn; @FXML private ListView<String> fridgeList; @FXML private GridPane recipeGrid; @FXML private Label missingList; @FXML private VBox recipeTile; private ObservableList<String> fridge; private ObservableList<Recipe> recipes; private final int NUMBER_OF_TILES = 4; private final ArrayList<VBox> currentRecipeTiles = new ArrayList<>(4); @FXML private void addIngredient(ActionEvent event) throws IOException { FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("/view/AddIngredient.fxml")); DialogPane addIngredientPane = loader.load(); Dialog<ButtonType> dialog = new Dialog<>(); dialog.setDialogPane(addIngredientPane); dialog.setTitle("Add ingredient to fridge"); Optional<ButtonType> clickedButton = dialog.showAndWait(); if (clickedButton.get() == ButtonType.APPLY) { // Refresh ingredientsAtHand. ingredientsAtHand = FileHandler.readIngredientsAtHand("Fridge"); //TODO: Duplicate code and assertion. assert ingredientsAtHand != null; fridge = FXCollections.observableArrayList(ingredientsAtHand.getIngredientsAtHand().stream().map(foodItem -> foodItem.label).toList()); fridgeList.setItems(fridge); setRecipeTiles(); }else if(clickedButton.get() == ButtonType.CANCEL) { } } @FXML private void removeFromFridge(ActionEvent event) throws IOException { String toRemove = fridgeList.getSelectionModel().getSelectedItem(); //TODO: If anything selected! ingredientsAtHand.removeIngredient(FoodItem.valueOf(toRemove.replace(" ", "_").toUpperCase())); FileHandler.writeIngredientsAtHand(ingredientsAtHand, "Fridge"); //TODO: Remove toUppercase solution above. //TODO: Consider factoring out to a update method. fridge = FXCollections.observableArrayList(ingredientsAtHand.getIngredientsAtHand().stream().map(foodItem -> foodItem.label).toList()); fridgeList.setItems(fridge); setRecipeTiles(); } private void setRecipeTiles() { // Ingredeints at hand and recipesRegister ArrayList<Recipe> recipes = recipeRegister.pickBestFits(NUMBER_OF_TILES, ingredientsAtHand); int i = 0; int j = 0; int counter = 0; for (Recipe r : recipes) { FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("/view/RecipeTile.fxml")); if (i > 1) { j++; i = 0; } try { VBox vBox = loader.load(); RecipeTileController recipeTileController = loader.getController(); recipeTileController.setData(r); if (currentRecipeTiles.size() < recipes.size()) { currentRecipeTiles.add(vBox); } else { recipeGrid.getChildren().remove(currentRecipeTiles.get(counter)); currentRecipeTiles.set(counter, vBox); } vBox.setOnMouseEntered(event -> { if(r.getMissingIngredients()==0) { missingList.setText(""); } else { missingList.setText("Missing: " + String.join(", ", r.getMissingList())); } }); vBox.setOnMouseExited(event -> { missingList.setText(""); }); recipeGrid.add(vBox, j, i); } catch (IOException e) { throw new RuntimeException(e); } i++; counter++; } } @FXML private void goBack(ActionEvent event) throws IOException { FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("/view/MainMenuNew.fxml")); Parent root = loader.load(); Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); } @FXML private void showAllRecipes(ActionEvent event) throws IOException { FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("/view/AllRecipes.fxml")); Parent root = loader.load(); Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); } @Override public void initialize(URL url, ResourceBundle resourceBundle) { // If no ingredients at hand file exsists, add one and let it be empty. //TODO ingredientsAtHand = FileHandler.readIngredientsAtHand("Fridge"); fridge = FXCollections.observableArrayList(ingredientsAtHand.getIngredientsAtHand().stream().map(foodItem -> foodItem.label).toList()); //List<String> fridgeLabels = fridge; fridgeList.setItems(fridge); recipeRegister = FileHandler.readRecipeRegister("Recipes"); recipes = FXCollections.observableArrayList(recipeRegister.getRecipes()); // Get the number from FX-grid available? setRecipeTiles(); } }