package de.calette.mephisto3.ui.weather;
import callete.api.Callete;
import callete.api.services.impl.resources.SlideShowImpl;
import callete.api.services.resources.SlideShow;
import callete.api.services.weather.Weather;
import de.calette.mephisto3.control.ServiceController;
import de.calette.mephisto3.control.ServiceState;
import de.calette.mephisto3.ui.ControllablePanel;
import de.calette.mephisto3.ui.ServiceScroller;
import de.calette.mephisto3.util.ComponentUtil;
import de.calette.mephisto3.util.Executor;
import de.calette.mephisto3.util.SlideshowPanel;
import de.calette.mephisto3.util.TransitionUtil;
import javafx.animation.ParallelTransition;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
/**
*/
public class WeatherPanel extends ControllablePanel {
private final static Logger LOG = LoggerFactory.getLogger(WeatherPanel.class);
private SlideshowPanel slideshowPanel = new SlideshowPanel();
private ServiceScroller scroller = new ServiceScroller();
private List<WeatherForecastPanel> forecastPanels = new ArrayList<>();
private Weather activeWeather;
private static Map<String, SlideShow> cachedSlideShows = new HashMap<>();
private ImageView weatherIconView;
private Label cityLabel;
private Text degreeLabel;
private Text tempLabel;
private HBox busyIndicator;
public WeatherPanel() {
for(Weather w : Callete.getWeatherService().getWeather()) {
getSlideShow(w.getCity());
}
}
@Override
public void pushed(ServiceState serviceState) {
ServiceController.getInstance().fireControlEvent(KeyCode.UP);
}
@Override
public void showPanel() {
if(busyIndicator == null) {
buildUI();
}
busyIndicator.setOpacity(1);
super.showPanel();
scroller.showScroller();
activeWeather = (Weather) ServiceController.getInstance().getServiceState().getSelection();
cityLabel.getStyleClass().clear();
cityLabel.getStyleClass().addAll("label", "weather-city");
cityLabel.setText(activeWeather.getCity());
Executor.run(new Runnable() {
@Override
public void run() {
String city = activeWeather.getCity();
SlideShow slideShow = getSlideShow(city);
slideshowPanel.setSlideShow(slideShow);
Platform.runLater(new Runnable() {
@Override
public void run() {
cityLabel.getStyleClass().clear();
cityLabel.getStyleClass().addAll("label", "weather-city-active");
slideshowPanel.startSlideShow();
busyIndicator.setOpacity(0);
}
});
}
});
}
@Override
public void hidePanel() {
super.hidePanel();
scroller.hideScroller();
slideshowPanel.stopSlideShow();
}
@Override
protected void serviceStateChanged(ServiceState serviceState) {
this.activeWeather = (Weather) serviceState.getSelection();
final Image image = new Image(WeatherConditionMapper.getWeatherForecastIcon(activeWeather), 55, 55, false, true);
String city = activeWeather.getCity();
SlideShow slideShow = getSlideShow(city);
slideshowPanel.setSlideShow(slideShow);
slideshowPanel.startSlideShow();
ParallelTransition transition = new ParallelTransition(
TransitionUtil.createOutFader(weatherIconView),
TransitionUtil.createOutFader(cityLabel),
TransitionUtil.createOutFader(degreeLabel),
TransitionUtil.createOutFader(tempLabel)
);
transition.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
weatherIconView.setImage(image);
cityLabel.setText(activeWeather.getCity());
degreeLabel.setText(activeWeather.getTemp() + "°C");
tempLabel.setText(activeWeather.getHighTemp() + "/" + activeWeather.getLowTemp() + " °C");
ParallelTransition pt = new ParallelTransition(
TransitionUtil.createInFader(weatherIconView),
TransitionUtil.createInFader(cityLabel),
TransitionUtil.createInFader(degreeLabel),
TransitionUtil.createInFader(tempLabel)
);
pt.play();
}
});
transition.play();
Iterator<Weather> iterator = activeWeather.getForecast().iterator();
iterator.next();
Iterator<WeatherForecastPanel> panelIterator = forecastPanels.iterator();
while(iterator.hasNext()) {
panelIterator.next().setForecast(iterator.next());
}
}
// ------------------- Helper ----------------
private void buildUI() {
Weather weather = Callete.getWeatherService().getWeatherAt(1);
if(weather == null) {
return;
}
busyIndicator = new HBox();
ComponentUtil.createLabel("Lade Bildergallerie...", "weather-busy-indicator", busyIndicator);
busyIndicator.setPadding(new Insets(90, 30, 0, 30));
ProgressIndicator pi = new ProgressIndicator();
pi.setMaxHeight(25);
busyIndicator.getChildren().add(pi);
getChildren().add(busyIndicator);
getChildren().add(slideshowPanel);
VBox root = new VBox();
cityLabel = ComponentUtil.createCustomLabel("", "weather-city", root);
cityLabel.setPadding(new Insets(20, 30, 0, 30));
VBox spacer = new VBox();
spacer.setMinHeight(205);
root.getChildren().add(spacer);
root.getChildren().add(scroller);
StackPane status = new StackPane();
status.setMinHeight(120);
status.getStyleClass().add("weather-status-panel");
HBox weatherStatus = new HBox();
status.getChildren().add(weatherStatus);
weatherStatus.setPadding(new Insets(10, 0, 0, 0));
VBox locationDetailsBox = new VBox(0);
locationDetailsBox.setMinWidth(300);
locationDetailsBox.setAlignment(Pos.TOP_CENTER);
weatherStatus.getChildren().add(locationDetailsBox);
HBox row1 = new HBox(25);
row1.setAlignment(Pos.TOP_CENTER);
locationDetailsBox.getChildren().addAll(row1);
degreeLabel = ComponentUtil.createText(weather.getTemp() + "°C", "weather-degree", row1);
VBox imgWrapper = new VBox();
imgWrapper.setAlignment(Pos.TOP_CENTER);
imgWrapper.setPadding(new Insets(14, 0, 0, 0));
weatherIconView = new ImageView(new Image(WeatherConditionMapper.getWeatherForecastIcon(weather), 55, 55, false, true));
imgWrapper.getChildren().add(weatherIconView);
tempLabel = ComponentUtil.createText(weather.getHighTemp() + "/" + weather.getLowTemp() + " °C", "forecast-temp", imgWrapper);
row1.getChildren().add(imgWrapper);
Iterator<Weather> iterator = weather.getForecast().iterator();
iterator.next();
while(iterator.hasNext()) {
WeatherForecastPanel forecastPanel = new WeatherForecastPanel(iterator.next());
forecastPanel.setMinWidth(95);
weatherStatus.getChildren().add(forecastPanel);
forecastPanels.add(forecastPanel);
}
root.getChildren().add(status);
getChildren().add(root);
}
private SlideShow getSlideShow(String city) {
if(!cachedSlideShows.containsKey(city)) {
LOG.info("Loading image gallery for " + city + " into cache.");
cachedSlideShows.put(city, new SlideShowImpl(new File("slideshows/" + city.toLowerCase() + "/"), true));
}
return cachedSlideShows.get(city);
}
}