package com.marinilli.b2.c7.installerapplet;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.*;

/**
 * Chapter 7 - The installer applet
 *
 * @author Mauro Marinilli
 * @version 1.0
 */
public class InstallerApplet extends JApplet {
  boolean isStandalone = false;
  JLabel titleLabel = new JLabel();
  JTextArea messagesArea = new JTextArea();

  /**Get a parameter value*/
  public String getParameter(String key) {
    if (isStandalone)
      return System.getProperty(key);
    return super.getParameter(key);
  }

  /**Construct the applet*/
  public InstallerApplet() {
  }

  /**Initialize the applet*/
  public void init() {
    titleLabel.setText("<html><body><b>"+
            "<i>"+getParameter("appname")+
            "</i> Installation Applet</b>");

    setSize(new Dimension(512,300));
    messagesArea.setForeground(Color.blue);
    messagesArea.setEditable(false);
    messagesArea.setText("Installation started..\n");
    getContentPane().add(titleLabel, BorderLayout.NORTH);
    getContentPane().add(new JScrollPane(messagesArea,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER);
  }
  /**Start the applet*/
  public void start() {
    int choice = JOptionPane.showConfirmDialog(this,
                                "This will Install "+
                                getParameter("appname")+
                                " on your computer",
                                "Continue with Installation?",
                              JOptionPane.OK_CANCEL_OPTION,
                              JOptionPane.WARNING_MESSAGE);
    if (choice == JOptionPane.OK_OPTION) {
      copy();
    } else {
      printMessage("User decided to abort installation.");
      printMessage("To restart the installation visit again this page.");
    }
  }

  /**Stop the applet*/
  public void stop() {
  }

  /**Destroy the applet*/
  public void destroy() {
  }

  /**
   * copies specified files on the specified local destination
   */
  public void copy(){
    String[] resources = getItems( getParameter("resources") );
    String destDir = getParameter("destination");

    if (resources==null || destDir==null) {
      printMessage("Invalid Parameter Settings.\n Installation aborted.");
      return;
    }

    BufferedInputStream in = null;
    URL serverURL;
    byte[] buffer;
    try {
      for (int i = 0; i < resources.length; i++) {
        serverURL = new URL(getCodeBase(), resources[i]);
        URLConnection conn = serverURL.openConnection();
        in = new BufferedInputStream(conn.getInputStream());
        String res = destDir+System.getProperty("file.separator")+resources[i];
        new File(new File(res).getParent()).mkdirs();
        FileOutputStream out = new FileOutputStream(res);
        printMessage(" - copying from:"+serverURL+" to:"+res);
        buffer = new byte[2048];
        int j;
        while((j = in.read(buffer)) != -1)
          out.write(buffer, 0, j);
      }//for
      printMessage("Installation finished.");

    } catch (Exception ex) {
      printMessage("copy: "+ex);
      printMessage("Installation aborted.");
    } finally {
        try {
          if(in != null)
            in.close();
        } catch (Exception ex) {
          printMessage("copy() closing InputStream "+ex);
        }
    }
  }

  /**
   * overwritten for application support
   */
  public URL getCodeBase() {
    try {
      if (isStandalone)
        return new File(".").toURL();
    } catch (MalformedURLException mue) {
      System.out.println("getCodebase() "+mue);
    }

    return super.getCodeBase();
  }

  /**
   * tokenize a string
   */
  private String[] getItems(String s){
    if (s==null)
      return null;
    ArrayList result = new ArrayList();
    StringTokenizer st = new StringTokenizer(s,";:,");
    while (st.hasMoreTokens()) {
      String w = st.nextToken();
      result.add(w);
    }
    String[] a = new String[result.size()];
    result.toArray(a);
    return a;
  }

  /**
   * writes on the applet's message area
   */
  private void printMessage(String msg){
    messagesArea.append(msg+"\n");
  }

  /**
   * main method
   */
  static public void main(String[] args) {
    System.getProperties().put("resources","setup\\res\\a.jar");
    System.getProperties().put("destination","c:\\appzz");
    System.getProperties().put("appname","MegaAppz 1.0");
    InstallerApplet a = new InstallerApplet();
    a.isStandalone = true;

    JFrame f = new JFrame("Test Frame");
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    a.init();
    f.getContentPane().add(a);
    f.setSize(400,300);
    f.setVisible(true);
    a.start();
  }

}