import com.install4j.api.*;

import javax.swing.*;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

// This is an example of a typical custom screen that is inserted into the
// default screen flow. It asks the user for some information that is used
// by an InstallAction to customize the installation.
public class HelloScreen extends CustomScreen implements ActionListener {

    // radio button for "greet the whole world"
    private JRadioButton radioWorld;
    // radio button for "greet a single person"
    private JRadioButton radioName;
    // button group for the two radio buttons
    private ButtonGroup buttonGroup;

    // label in front of the text field. This label is disabled if radioWorld is selected.
    private JLabel labelTextField;
    // text field for entering a name. This text field is disabled if radioWorld is selected.
    private JTextField textField;
    // "Show example" button that activates the ExampleScreen
    private JButton button;

    // set of ChangeListeners that are notified when the greeting text changes. In this
    // case, the ExampleScreen will install a ChangeListener.
    private Set listeners;

    // A custom screen is a panel and you can set any layout manager and add your components to it.
    public HelloScreen() {
        listeners = new HashSet();

        radioWorld = new JRadioButton("greet the whole world", true);
        radioName = new JRadioButton("greet a single person");
        buttonGroup = new ButtonGroup();
        buttonGroup.add(radioWorld);
        buttonGroup.add(radioName);
        radioWorld.addActionListener(this);
        radioName.addActionListener(this);

        labelTextField = new JLabel("Please enter the name of the person: ");
        textField = new JTextField(20);
        textField.addFocusListener(new FocusAdapter() {
            public void focusLost(FocusEvent event) {
                fireChangeEvent();
            }
        });

        button = new JButton("Show example");
        button.addActionListener(this);
        button.setAlignmentX(0f);

        setLayout(new BorderLayout());
        Box outerBox = Box.createVerticalBox();
        outerBox.add(new JLabel("Please choose the desired greeting mode for Hello World Suite:"));
        outerBox.add(Box.createVerticalStrut(10));
        outerBox.add(radioWorld);
        outerBox.add(radioName);

        Box nameBox = Box.createHorizontalBox();
        nameBox.add(labelTextField);
        nameBox.add(textField);

        // Must wrap this in a JPanel for 1.3 where Box is not a JComponent
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(nameBox);
        panel.setAlignmentX(0f);
        panel.setBorder(new EmptyBorder(0, new JRadioButton().getPreferredSize().width, 0, 0));

        outerBox.add(panel);
        outerBox.add(Box.createVerticalStrut(20));
        outerBox.add(button);

        add(outerBox, BorderLayout.CENTER);

        checkEnabled();
    }

    // Getter method for the greeting text. Used by the ExampleScreen
    // and the HelloInstallAction.
    public String getGreetingName() {
        if (radioWorld.isSelected()) {
            return "world";
        } else {
            return textField.getText();
        }
    }

    // Adds a ChangeListener that is notified of changes in the greeting text.
    public void addChangeListener(ChangeListener listener) {
        listeners.add(listener);
    }

    // Removes a ChangeListener that was notified of changes in the greeting text.
    public void removeChangeListener(ChangeListener listener) {
        listeners.remove(listener);
    }

    // Implementation of the ActionListener interface. Reacts to the "Show example" button and to
    // the two radio buttons.
    public void actionPerformed(ActionEvent event) {
        Object source = event.getSource();
        if (source == button) {
            InstallerWizardContext context = getInstallerContext();
            CustomScreen exampleScreen = context.getCustomScreenOfClass(ExampleScreen.class);
            if (exampleScreen == null) {
                JOptionPane.showMessageDialog(getFrame(), "ExampleScreen is not registered", "Installer", JOptionPane.ERROR_MESSAGE);
            } else {
                context.gotoCustomScreen(exampleScreen);
            }
        } else if (source == radioWorld || source == radioName) {
            checkEnabled();
            fireChangeEvent();
        }
    }

    // Implementation of abstract method. Determines the title of this screen.
    public String getTitle() {
        return "Configure the greeting mode";
    }

    // Implementation of abstract method. Determines the subtitle of this screen.
    public String getSubTitle() {
        return "Should Hello World Suite should greet the whole world or a single person?";
    }

    // Implementation of abstract method. The components in this screen cannot grow to fill
    // the vertical axis. They want to be at their preferred size at the top of the screen.
    public boolean isFillVertical() {
        return false;
    }

    // Implementation of abstract method. The components in this screen cannot grow to fill
    // the horizontal axis. The want to be at their preferred size at the left of the screen.
    public boolean isFillHorizontal() {
        return false;
    }

    // If you want to check the consistency of the user input in the screen and possibly prevent
    // the next screen from being shown, you have to override the next() method.
    // If the current screen should remain visible, you should return "false" . In that case
    // it is recommended to show a message box and put the focus in the incomplete component.
    // The parent frame of the installer wizard for dialogs and message boxes can be retrieved with
    // the getFrame() method.
    public boolean next() {
        if (radioName.isSelected() && textField.getText().trim().length() == 0) {
            JOptionPane.showMessageDialog(getFrame(), "Please enter a name for the person who should be greeted.", "Installer", JOptionPane.WARNING_MESSAGE);
            textField.requestFocus();
            return false;
        } else {
            return true;
        }
    }

    // Helper method to fire a ChangeEvent to all registered ChangeListeners.
    private void fireChangeEvent() {
        ChangeEvent event = new ChangeEvent(this);
        Iterator it = listeners.iterator();
        while (it.hasNext()) {
            ChangeListener listener = (ChangeListener)it.next();
            listener.stateChanged(event);

        }
    }

    // Helper method that adjusts the enabled state of all components. If the "Greet whole world"
    // radio button is enabled, the text field and its header label are disabled.
    private void checkEnabled() {
        boolean enabled = radioName.isSelected();
        labelTextField.setEnabled(enabled);
        textField.setEnabled(enabled);
    }

}
