Merge branch 'develop' into trialMerge
[jalview.git] / getdown / src / getdown / launcher / src / main / java / com / threerings / getdown / launcher / RotatingBackgrounds.java
diff --git a/getdown/src/getdown/launcher/src/main/java/com/threerings/getdown/launcher/RotatingBackgrounds.java b/getdown/src/getdown/launcher/src/main/java/com/threerings/getdown/launcher/RotatingBackgrounds.java
new file mode 100644 (file)
index 0000000..d3aa2bd
--- /dev/null
@@ -0,0 +1,132 @@
+//
+// Getdown - application installer, patcher and launcher
+// Copyright (C) 2004-2018 Getdown authors
+// https://github.com/threerings/getdown/blob/master/LICENSE
+
+package com.threerings.getdown.launcher;
+
+import java.awt.Image;
+import java.util.List;
+
+import static com.threerings.getdown.Log.log;
+
+public final class RotatingBackgrounds
+{
+    public interface ImageLoader {
+        /** Loads and returns the image with the supplied path. */
+        public Image loadImage (String path);
+    }
+
+    /**
+     * Creates a placeholder if there are no images. Just returns null from getImage every time.
+     */
+    public RotatingBackgrounds ()
+    {
+        makeEmpty();
+    }
+
+    /** Creates a single image background. */
+    public RotatingBackgrounds (Image background)
+    {
+        percentages = new int[] { 0 };
+        minDisplayTime = new int[] { 0 };
+        images = new Image[] { background };
+        errorImage = images[0];
+    }
+
+    /**
+     * Create a sequence of images to be rotated through from <code>backgrounds</code>.
+     *
+     * Each String in backgrounds should be the path to the image, a semicolon, and the minimum
+     * amount of time to display the image in seconds. Each image will be active for an equal
+     * percentage of the download process, unless one hasn't been active for its minimum display
+     * time when the next should be shown. In that case, it's left up until its been there for its
+     * minimum display time and then the next one gets to come up.
+     */
+    public RotatingBackgrounds (List<String> backgrounds, String errorBackground, ImageLoader loader)
+    {
+        percentages = new int[backgrounds.size()];
+        minDisplayTime = new int[backgrounds.size()];
+        images = new Image[backgrounds.size()];
+        for (int ii = 0; ii < backgrounds.size(); ii++) {
+            String background = backgrounds.get(ii);
+            String[] pieces = background.split(";");
+            if (pieces.length != 2) {
+                log.warning("Unable to parse background image '" + background + "'");
+                makeEmpty();
+                return;
+            }
+            images[ii] = loader.loadImage(pieces[0]);
+            try {
+                minDisplayTime[ii] = Integer.parseInt(pieces[1]);
+            } catch (NumberFormatException e) {
+                log.warning("Unable to parse background image display time '" + background + "'");
+                makeEmpty();
+                return;
+            }
+            percentages[ii] = (int)((ii/(float)backgrounds.size()) * 100);
+        }
+        if (errorBackground == null) {
+            errorImage = images[0];
+        } else {
+            errorImage = loader.loadImage(errorBackground);
+        }
+    }
+
+    /**
+     * @return the image to display at the given progress or null if there aren't any.
+     */
+    public Image getImage (int progress)
+    {
+        if (images.length == 0) {
+            return null;
+        }
+        long now = System.currentTimeMillis();
+        if (current != images.length - 1
+            && (current == -1 || (progress >= percentages[current + 1] &&
+                    (now - currentDisplayStart) / 1000 > minDisplayTime[current]))) {
+            current++;
+            currentDisplayStart = now;
+        }
+        return images[current];
+    }
+
+    /**
+     * Returns the image to display if an error has caused getdown to fail.
+     */
+    public Image getErrorImage ()
+    {
+        return errorImage;
+    }
+
+    /**
+     * @return the number of images in this RotatingBackgrounds
+     */
+    public int getNumImages() {
+        return images.length;
+    }
+
+    protected void makeEmpty ()
+    {
+        percentages = new int[] {};
+        minDisplayTime = new int[] {};
+        images = new Image[] {};
+    }
+
+    /** Time at which the currently displayed image was first displayed in millis. */
+    protected long currentDisplayStart;
+
+    /** The index of the currently displayed image or -1 if we haven't displayed any. */
+    protected int current = -1;
+
+    protected Image[] images;
+
+    /** The image to display if getdown has failed due to an error. */
+    protected Image errorImage;
+
+    /** Percentage at which each image should be displayed. */
+    protected int[] percentages;
+
+    /** Time to show each image in seconds. */
+    protected int[] minDisplayTime;
+}