csep-2025/client/src/main/java/client/scenes/nutrition/NutritionDetailsCtrl.java

141 lines
5.3 KiB
Java

package client.scenes.nutrition;
import client.Ingredient.IngredientViewModel;
import client.exception.IllegalInputFormatException;
import client.utils.LocaleAware;
import client.utils.LocaleManager;
import client.utils.server.ServerUtils;
import com.google.inject.Inject;
import commons.Ingredient;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.util.converter.NumberStringConverter;
import java.io.IOException;
import java.util.logging.Logger;
public class NutritionDetailsCtrl implements LocaleAware {
@FXML
public GridPane nutritionValueContainer;
private boolean visible;
private final LocaleManager manager;
private final ServerUtils server;
private final SimpleObjectProperty<IngredientViewModel> ingredient =
new SimpleObjectProperty<>(new IngredientViewModel());
private final Logger logger = Logger.getLogger(this.getClass().getName());
public Label ingredientName;
public Label fatInputLabel;
public Label proteinInputLabel;
public Label carbInputLabel;
public Label estimatedKcalLabel;
public Label usageLabel;
public TextField fatInputElement;
public TextField proteinInputElement;
public TextField carbInputElement;
@FXML
public VBox nutritionDetails;
@Inject
public NutritionDetailsCtrl(
LocaleManager manager,
ServerUtils server
) {
this.manager = manager;
this.server = server;
}
@Override
public void initializeComponents() {
Platform.runLater(() -> {
IngredientViewModel vm = this.ingredient.get();
this.ingredientName.textProperty().bind(vm.nameProperty());
this.fatInputElement.textProperty().bindBidirectional(vm.fatProperty(), new NumberStringConverter());
this.proteinInputElement.textProperty().bindBidirectional(vm.proteinProperty(), new NumberStringConverter());
this.carbInputElement.textProperty().bindBidirectional(vm.carbsProperty(), new NumberStringConverter());
this.estimatedKcalLabel.textProperty().bind(Bindings.createStringBinding(
() -> String.format(getLocaleString("app.kcal") + " %.1f kcal/100g", vm.getKcal()), vm.kcalProperty()
));
this.usageLabel.textProperty().bind(Bindings.createStringBinding(
() -> {
Long id = this.ingredient.get().toIngredient().getId();
logger.info("Fetching usage for ingredient ID: " + id);
return !id.equals(0L) ? String.format(
getLocaleString("app.label.usage.part") + " %d " + getLocaleString("app.word.recipe.n"),
server.getIngredientUsage(id)) : "";
},
this.ingredient.get().idProperty()
));
});
this.nutritionValueContainer.addEventHandler(KeyEvent.KEY_RELEASED, event -> {
if (event.getCode() != KeyCode.ENTER) {
return;
}
try {
Ingredient newIngredient = server.updateIngredient(updateIngredient());
Platform.runLater(() -> {
this.ingredient.get().updateFrom(newIngredient);
logger.info("Updated ingredient to " + newIngredient);
});
} catch (IllegalInputFormatException e) {
e.printStackTrace();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
}
@Override
public void updateText() {
}
public void setVisible(boolean isVisible) {
nutritionDetails.setVisible(isVisible);
}
public void toggleVisible() {
nutritionDetails.setVisible(!visible);
visible = !visible;
}
public void setItem(Ingredient ingredient) {
this.ingredient.get().updateFrom(ingredient);
setVisible(true);
}
private Ingredient updateIngredient() throws IllegalInputFormatException {
Ingredient current = this.ingredient.get().toIngredient();
try {
double f = Double.parseDouble(this.fatInputElement.getText());
double p = Double.parseDouble(this.proteinInputElement.getText());
double c = Double.parseDouble(this.carbInputElement.getText());
current.setCarbsPer100g(c);
current.setProteinPer100g(p);
current.setFatPer100g(f);
return current;
} catch (NumberFormatException e) {
throw new IllegalInputFormatException("Invalid F/P/C value");
}
}
@Override
public LocaleManager getLocaleManager() {
return manager;
}
public void handleNutritionSaveClick(ActionEvent actionEvent) throws IOException, InterruptedException {
Ingredient newIngredient = updateIngredient();
this.ingredient.get().updateFrom(server.updateIngredient(newIngredient));
}
}