package de.calette.mephisto3.ui;
import callete.api.services.impl.music.google.AlbumCoverCache;
import callete.api.services.music.model.Album;
import de.calette.mephisto3.resources.ResourceLoader;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* This cache loads images only for the given collection of albums.
* If the collection changes, the image are forgotten to handle
* the limited amount of memory on the embedded system.
*/
public class LazyAlbumCoverCache {
private final static Logger LOG = LoggerFactory.getLogger(LazyAlbumCoverCache.class);
private static AlbumLoader loader;
private static int width = AlbumBox.COVER_WIDTH;
private static int height = AlbumBox.COVER_HEIGHT;
private static Map<Album, ImageView> cache = new HashMap<>();
public static void loadImageViewFor(BorderPane pane, Album album) {
if(loader != null && loader.running) {
try {
synchronized(loader) {
LOG.info("Waiting on album loader thread...");
loader.wait(); //TODO
LOG.info("Continuing to build UI after cover has been loaded.");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
pane.setCenter(cache.get(album));
}
public static void load(Collection<Album> albumCollection) {
cache.clear();
if(loader != null && loader.isAlive()) {
loader.setRunning(false);
}
loader = new AlbumLoader(albumCollection);
loader.start();
}
/**
* Asynchronous loading of images
*/
static class AlbumLoader extends Thread {
private Collection<Album> albums;
private boolean running = true;
private AlbumLoader(Collection<Album> albums) {
this.albums = albums;
}
@Override
public void run() {
Thread.currentThread().setName("AlbumLoader/" + Thread.currentThread().getName());
LOG.info("Starting new album cover loading thread for " + albums.size() + " images");
for(Album album : albums) {
String url = AlbumCoverCache.loadCover(album);
if(url != null) {
ImageView cover = new ImageView(new Image(url, width, height, false, true));
cache.put(album, cover);
}
else {
ImageView cover = new ImageView(new Image(ResourceLoader.getResource("folder.png"), width, height, false, true));
cache.put(album, cover);
}
if(!running) {
break;
}
}
LOG.info("Finished loading album covers, notifying waiting threads.");
this.running = false;
synchronized(this) {
notifyAll();
}
}
public void setRunning(boolean running) {
this.running = running;
}
}
}