package com.marinilli.b2.c8.splash;
import java.awt.*;
import javax.swing.*;
import javax.jnlp.*;
import java.net.URL;
/**
 * Chapter 8 - Splash
 * @author Mauro Marinilli
 * @version 1.0
 */
public class Splash extends JWindow implements Runnable{
  private ClassLoader loader;
  private static ExtensionInstallerService extensionInstaller;
  private JLabel ImageLabel;
  private JLabel MessageLabel  = new JLabel();
  private JLabel animLabel;
  private JLabel resourceLabel  = new JLabel();
  private static Splash splash;
  //data
  private String[] jarSequence= {"first.jar", "second.jar", "third.jar"};
  private String[] msgSequence= {
    "Now Even More Powerful!",
    "Incredibly Fast And Reliable!",
    "Ready To Go?"};
  private String codebase = "http://server/b2/c8/splash/";
  /**
   * Private Constructor - Implements the Singleton Design Pattern
   */
  private Splash() {
    super();
    loader = getClass().getClassLoader();
    //prepare UI
    ImageLabel = new JLabel(new ImageIcon(loader.getResource("images/background.jpg")));
    animLabel = new JLabel(new ImageIcon(loader.getResource("images/working.gif")));
    resourceLabel.setBorder(BorderFactory.createEmptyBorder(6,6,6,6));
    ImageLabel.setLayout(new BorderLayout());
    ImageLabel.setBorder(BorderFactory.createRaisedBevelBorder());
    ImageLabel.add(resourceLabel, BorderLayout.NORTH);
    ImageLabel.add(MessageLabel, BorderLayout.SOUTH);
    ImageLabel.add(animLabel, BorderLayout.CENTER);
    getContentPane().setLayout(new BorderLayout());
    getContentPane().add(ImageLabel, BorderLayout.CENTER);
    pack();
    //Centers the window
    Dimension size = getSize();
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    if (size.height > screenSize.height) {
      size.height = screenSize.height;
    }
    if (size.width > screenSize.width) {
      size.width = screenSize.width;
    }
    setLocation((screenSize.width - size.width) / 2, (screenSize.height - size.height) / 2);
  }

  /**
   * Implements the Singleton Design Pattern
   *
   */
  public static Splash getInstance(){
    if (splash == null)
      splash = new Splash();
    return splash;
  }

  /**
   * Sets a message visible at the bottom
   * @param text Text to show
   */
  public static void setMessage(String text) {
    if (splash != null)
      splash.MessageLabel.setText("    " + text);
  }

  /**
   * Sets a message visible at the top showing the
   * currently downloading resource file
   * @param rsr Text to show
   */
  public static void setLoadingResource(String rsr) {
    if (splash != null) {
      splash.resourceLabel.setText("Downloading: "+rsr);
    }
  }

  /**
   * Shows up the splash window or destroys it
   * @param show
   */
  public static void showUp(boolean show) {
    if (splash == null)
      return;
    splash.setVisible(show);
    if (show == false) {
      splash.setCursor(Cursor.getDefaultCursor());
      splash = null;
    } else {
      splash.setCursor(new Cursor(Cursor.WAIT_CURSOR));
      try {
        // Lookup the Service
        extensionInstaller =
          (ExtensionInstallerService)ServiceManager.lookup("javax.jnlp.ExtensionInstallerService");
        // Hide JNLP Client's download window
        extensionInstaller.hideStatusWindow();
      } catch(UnavailableServiceException use) {
        System.out.println("Service not supported: "+use);
      }
    }
  }

  /**
   * Takes charge of all the JAR delivery
   */
  public void run() {
    DownloadService ds;
    int jarNumber = jarSequence.length;
    try {
      ds = (DownloadService)ServiceManager.lookup("javax.jnlp.DownloadService");
    } catch (UnavailableServiceException use) {
      ds = null;
      System.out.println("Service is not supported: "+use);
    }//once have a ds you can do a lot of things

    //begin downloading jars
    for (int i=0;i<jarNumber;i++){
      if (ds != null) {
        processJar(ds,i);
      }
      //take a breath
      try {
        Thread.currentThread().sleep(3000);//IT'S ONLY COSMETICS!
//        Thread.currentThread().yield();
      } catch (Exception e) {
        System.out.println("Synchronization Exception: "+e);
      }
    }//-for
    showUp(false);//all the needed JARs have processed
    extensionInstaller.installSucceeded(true);//we're optimistic
  }
  /**
   * A fancy method that finds out if a JAR is cached and removes it.
   * substitute it with your code.
   */
  private void processJar(DownloadService ds, int i){
    try {
      // determine if a particular resource is cached
      URL url =
        new URL(codebase + jarSequence[i]);
      boolean cached = ds.isResourceCached(url, null);
      // remove the resource from the cache, just for fun
      if (cached) {
       ds.removeResource(url, null);
      }

      // reload the resource into the cache, yes!
      setMessage(msgSequence[i]);
      setLoadingResource(jarSequence[i]);
      DownloadServiceListener dsl = ds.getDefaultProgressWindow();
      ds.loadResource(url, null, dsl);
    } catch (Exception e) {
      System.out.println("Loading Resource: " + e);
    }
  }
  public static void main(String[] args) {
    Splash splash1 = Splash.getInstance();
    splash1.showUp(true);
    splash1.run();
  }
}
