import java.util.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import javax.swing.*;
import javax.swing.filechooser.*;
import javax.swing.border.*;
import javax.swing.SwingUtilities;
import java.net.*;

public class SmartInstaller extends JPanel implements ActionListener {
  int       BUFFER = 1024;

  JFrame    mainFrame;
  JTextArea logArea;

  // configuration chooser buttons
  String       configurations[] = {"32 bits", "64 bits"};
  JRadioButton configurationButtons[];

  // program chooser buttons
  String    programChoosers[] = {"R", "R Color Brewer Package", "R HMisc Package", "Python 2.6", "S-MART"};
  JCheckBox programChooserButtons[];

  JButton   goButton;

  // install directory
  JButton    installDirectoryChooserButton;
  JTextField installDirectoryChooserTextField;


  public SmartInstaller() {
    super();

    Box box = Box.createVerticalBox();

    // Header
    JPanel       headerPanel = new JPanel(false);
    JTextArea    headerArea  = new JTextArea("This is the S-MART installation tool.\r\nIt will download and install the needed softwares, as well as S-MART itself.\r\nYou can unselect the software that you already have installed.\r\nDuring the installation, accept all the default parameters.");
    TitledBorder headerBorder = BorderFactory.createTitledBorder("Welcome to the S-MART installer!");
    headerArea.setEditable(false);
    headerArea.setBackground(headerPanel.getBackground());
    headerPanel.add(headerArea);
    headerPanel.setBorder(headerBorder);


    // Configuration
    JPanel configurationPanel = new JPanel(false);
    configurationPanel.setLayout(new GridLayout(1, 0));
    configurationButtons = new JRadioButton[configurations.length];
    ButtonGroup configurationGroup = new ButtonGroup();
    for (int i = 0; i < configurations.length; i++) {
      JRadioButton button = new JRadioButton(configurations[i]);
      configurationPanel.add(button);
      configurationButtons[i] = button;
      configurationGroup.add(button);
    }
    configurationButtons[0].setSelected(true);
    TitledBorder configurationBorder = BorderFactory.createTitledBorder("Configuration");
    configurationPanel.setBorder(configurationBorder);


    // Program chooser panel
    JPanel programPanel = new JPanel(false);
    programPanel.setLayout(new GridLayout(0, 1));

    JLabel programLabel = new JLabel("Choose which programs to install:");
    programPanel.add(programLabel);
    programChooserButtons = new JCheckBox[programChoosers.length];
    for (int i = 0; i < programChoosers.length; i++) {
      JCheckBox button = new JCheckBox(programChoosers[i]);
      button.setSelected(true);
      programPanel.add(button);
      programChooserButtons[i] = button;
    }
    TitledBorder programBorder = BorderFactory.createTitledBorder("Programs");
    programPanel.setBorder(programBorder);

    // Install directory chooser
    JPanel installDirectoryChooserPanel = new JPanel(false);
    installDirectoryChooserPanel.setLayout(new GridLayout(1, 0));
    JLabel installDirectoryChooserLabel = new JLabel("Choose a directory to install S-MART: ");
    installDirectoryChooserTextField = new JTextField();
    installDirectoryChooserButton = new JButton("Open...");
    installDirectoryChooserButton.addActionListener(this);

    installDirectoryChooserPanel.add(installDirectoryChooserLabel);
    installDirectoryChooserPanel.add(installDirectoryChooserTextField);
    installDirectoryChooserPanel.add(installDirectoryChooserButton);
    TitledBorder installDirectoryChooserBorder = BorderFactory.createTitledBorder("Installation directory");
    installDirectoryChooserPanel.setBorder(installDirectoryChooserBorder);

    // GO!
    JPanel goPanel = new JPanel(false);
    goButton = new JButton("GO!");
    goButton.addActionListener(this);
    goButton.setSelected(true);
    goPanel.add(goButton);
    TitledBorder goBorder = BorderFactory.createTitledBorder("Start install");
    goPanel.setBorder(goBorder);

    // Log
    logArea = new JTextArea(10, 120);
    logArea.setFont(new Font("Monospaced", logArea.getFont().getStyle(), logArea.getFont().getSize()));
    JScrollPane logScroll  = new JScrollPane(logArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    TitledBorder logBorder = BorderFactory.createTitledBorder("Log");
    logScroll.setBorder(logBorder);

    GridLayout horizontalLayout = new GridLayout(1, 0);

    box.add(headerPanel);
    box.add(configurationPanel);
    box.add(programPanel);
    box.add(installDirectoryChooserPanel);
    box.add(goPanel);
    box.add(logScroll);

    add(box);
  }


  public void actionPerformed(ActionEvent e) {

    // Install directories chooser
    if (e.getSource() == goButton) {
      boolean[] selectedPrograms = new boolean[programChoosers.length];
      for (int i = 0; i < programChoosers.length; i++) {
        selectedPrograms[i] = programChooserButtons[i].isSelected();
      }
      SmartInstallerTask task = new SmartInstallerTask(logArea, selectedPrograms, installDirectoryChooserTextField.getText(), (configurationButtons[0].isSelected())? 0: 1);
      task.execute();
    }
    // Install directories chooser
    else if (e.getSource() == installDirectoryChooserButton) {
      JFileChooser chooser = new JFileChooser();
      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
      if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
        installDirectoryChooserTextField.setText(chooser.getSelectedFile().getPath());
      }
    }
  }

  private static void createAndShowGUI() {
    // Create and set up the window.
    JFrame mainFrame = new JFrame("S-Mart Installer");
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Create and set up the content pane.
    JComponent newContentPane = new SmartInstaller();
    newContentPane.setOpaque(true);
    mainFrame.setContentPane(newContentPane);

    // Display the window.
    mainFrame.pack();
    mainFrame.setVisible(true);
  }


  public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }
}
