/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.log4j.chainsaw;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;

import java.util.Locale;
import javax.swing.*;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.chainsaw.helper.SwingHelper;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
import org.apache.log4j.net.SocketReceiver;
import org.apache.log4j.net.UDPReceiver;


/**
 * A panel providing receiver configuration options
 *
 * @author Paul Smith
 */
class ReceiverConfigurationPanel extends JPanel {
    private final Logger logger = LogManager.getLogger(ReceiverConfigurationPanel.class);

    private final PanelModel panelModel = new PanelModel();

    //network receiver widgets
    private JComboBox networkReceiverPortComboBox;
    private JComboBox networkReceiverClassNameComboBox;
    private DefaultComboBoxModel networkReceiverClassNameComboBoxModel;
    private DefaultComboBoxModel networkReceiverPortComboBoxModel;

    //log4j config receiver widgets
    private JButton browseLog4jConfigButton;
    private JTextField log4jConfigURLTextField;

    //logfile receiver widgets
    private JButton browseLogFileButton;
    private JComboBox logFileFormatTypeComboBox;

    private JComboBox logFileFormatComboBox;
    private JComboBox logFileFormatTimestampFormatComboBox;
    private JTextField logFileURLTextField;
    private DefaultComboBoxModel logFileFormatComboBoxModel;
    private DefaultComboBoxModel logFileFormatTimestampFormatComboBoxModel;

    //use existing configuration widgets
    private JButton browseForAnExistingConfigurationButton;
    private DefaultComboBoxModel existingConfigurationComboBoxModel;
    private JComboBox existingConfigurationComboBox;

    //don't warn again widgets
    private JCheckBox dontwarnIfNoReceiver;

    private JButton saveButton;
    private JButton okButton;
    private JButton cancelButton;

    //radiobutton widgets
    private JRadioButton log4jConfigReceiverRadioButton;
    private JRadioButton logFileReceiverRadioButton;
    private JRadioButton networkReceiverRadioButton;
    private JRadioButton useExistingConfigurationRadioButton;
    private ButtonGroup buttonGroup;

    private JPanel lowerPanel;

    private final JPanel networkReceiverPanel = buildNetworkReceiverPanel();
    private final JPanel logFileReceiverPanel = buildLogFileReceiverPanel();
    private final JPanel log4jConfigReceiverPanel = buildLog4jConfigReceiverPanel();
    private final JPanel useExistingConfigurationPanel = buildUseExistingConfigurationPanel();
    private final JPanel dontWarnAndOKPanel = buildDontWarnAndOKPanel();
    private final JPanel bottomDescriptionPanel = buildBottomDescriptionPanel();

    //set by LogUI to handle hiding of the dialog
    private ActionListener completionActionListener;
    //used as frame for file open dialogs
    private Container dialog;

  ReceiverConfigurationPanel() {
        setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
        setLayout(new GridBagLayout());

        buttonGroup = new ButtonGroup();

        lowerPanel = new JPanel(new BorderLayout());
        lowerPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(), BorderFactory.createEmptyBorder(5, 5, 5, 5)));
        lowerPanel.setPreferredSize(new Dimension(600, 200));
        lowerPanel.setMinimumSize(new Dimension(600, 200));

        int yPos = 0;

        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = yPos++;
        c.fill = GridBagConstraints.HORIZONTAL;
        log4jConfigReceiverRadioButton = new JRadioButton(" Use fileappender entries from a log4j config file ");
        buttonGroup.add(log4jConfigReceiverRadioButton);
        add(log4jConfigReceiverRadioButton, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = yPos++;
        c.fill = GridBagConstraints.HORIZONTAL;
        logFileReceiverRadioButton = new JRadioButton(" Process a log file ");
        buttonGroup.add(logFileReceiverRadioButton);
        add(logFileReceiverRadioButton, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = yPos++;
        c.fill = GridBagConstraints.HORIZONTAL;
        networkReceiverRadioButton = new JRadioButton(" Receive events from the network ");
        buttonGroup.add(networkReceiverRadioButton);
        add(networkReceiverRadioButton, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = yPos++;
        c.fill = GridBagConstraints.HORIZONTAL;
        useExistingConfigurationRadioButton = new JRadioButton(" Use a Chainsaw config file ");
        buttonGroup.add(useExistingConfigurationRadioButton);
        add(useExistingConfigurationRadioButton, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = yPos++;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(10, 10, 10, 0);
        add(lowerPanel, c);
        
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = yPos++;
        c.weightx = 0.5;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(0, 10, 0, 0);
        add(dontWarnAndOKPanel, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = yPos++;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(10, 10, 10, 0);
        add(bottomDescriptionPanel, c);

        /**
         * This listener activates/deactivates certain controls based on the current
         * state of the options
         */
        ActionListener al = e -> updateEnabledState((Component)e.getSource());

        logFileReceiverRadioButton.addActionListener(al);
        log4jConfigReceiverRadioButton.addActionListener(al);
        networkReceiverRadioButton.addActionListener(al);
        useExistingConfigurationRadioButton.addActionListener(al);

        buttonGroup.setSelected(log4jConfigReceiverRadioButton.getModel(), true);
        updateEnabledState(log4jConfigReceiverRadioButton);
    }

    private JPanel buildDontWarnAndOKPanel() {
        JPanel panel = new JPanel(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1.0;
        c.anchor = GridBagConstraints.LINE_START;
        dontwarnIfNoReceiver = new JCheckBox(" Always start Chainsaw with this configuration ");
        panel.add(dontwarnIfNoReceiver, c);

        saveButton = new JButton(" Save configuration as... ");
        c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 0;
        c.insets = new Insets(0, 0, 0, 10);
        panel.add(saveButton, c);

        okButton = new JButton(" OK ");
        cancelButton = new JButton(" Cancel ");

        List okCancelButtons = SwingHelper.orderOKCancelButtons(okButton, cancelButton);

        c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 2;
        c.gridy = 0;
        c.insets = new Insets(0, 0, 0, 10);
        panel.add((JButton)okCancelButtons.get(0), c);

        c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 3;
        c.gridy = 0;
        panel.add((JButton)okCancelButtons.get(1), c);

        cancelButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                panelModel.setCancelled(true);
                completionActionListener.actionPerformed(new ActionEvent(this, -1, "cancelled"));
            }
        });

        okButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                panelModel.setCancelled(false);
                if (logFileFormatComboBox.getSelectedItem() != null && !(logFileFormatComboBox.getSelectedItem().toString().trim().equals(""))) {
                  panelModel.setLogFormat(logFileFormatComboBox.getSelectedItem().toString());
                }
                completionActionListener.actionPerformed(new ActionEvent(this, -1, "ok"));
            }
        });

      saveButton.addActionListener(e -> {
        try {
            URL url = browseFile("Choose a path and file name to save", false);
            if (url != null) {
              File file = new File(url.toURI());
              panelModel.setSaveConfigFile(file);
            }
        } catch (Exception ex) {
            logger.error(
                "Error browsing for log file", ex);
        }
      });
      return panel;
    }

    private JPanel buildBottomDescriptionPanel() {
        JTextPane descriptionTextPane = new JTextPane();
        StyledDocument doc = descriptionTextPane.getStyledDocument();
        SimpleAttributeSet center = new SimpleAttributeSet();
        StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
        doc.setParagraphAttributes(0, doc.getLength(), center, false);

        descriptionTextPane.setText(" An example configuration file is available from the Welcome tab ");
        descriptionTextPane.setEditable(false);
        descriptionTextPane.setOpaque(false);
        descriptionTextPane.setFont(getFont());

        JPanel panel = new JPanel(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1.0;
        c.fill = GridBagConstraints.HORIZONTAL;

        panel.add(descriptionTextPane, c);

        return panel;
    }

    private JPanel buildNetworkReceiverPanel() {
        networkReceiverPortComboBoxModel = new DefaultComboBoxModel();
        networkReceiverPortComboBoxModel.addElement("4445");
        networkReceiverPortComboBoxModel.addElement("4560");

        networkReceiverPortComboBox = new JComboBox(networkReceiverPortComboBoxModel);
        networkReceiverPortComboBox.setEditable(true);
        networkReceiverPortComboBox.setOpaque(false);

        networkReceiverClassNameComboBoxModel = new DefaultComboBoxModel();
        networkReceiverClassNameComboBoxModel.addElement(SocketReceiver.class.getName());
        networkReceiverClassNameComboBoxModel.addElement(UDPReceiver.class.getName());

        networkReceiverClassNameComboBox = new JComboBox(networkReceiverClassNameComboBoxModel);

        networkReceiverClassNameComboBox.setEditable(false);
        networkReceiverClassNameComboBox.setOpaque(false);

        JPanel panel = new JPanel(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 0;
        c.gridy = 0;
        c.insets = new Insets(0, 0, 0, 5);
        panel.add(networkReceiverClassNameComboBox, c);

        c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 0.5;
        c.gridx = 1;
        c.gridy = 0;
        panel.add(networkReceiverPortComboBox, c);

        return panel;
    }

    private JPanel buildLog4jConfigReceiverPanel() {
        log4jConfigURLTextField = new JTextField();
        browseLog4jConfigButton = new JButton(new AbstractAction(" Open File... ") {
                    public void actionPerformed(ActionEvent e) {
                        try {

                            URL url = browseConfig();

                            if (url != null) {
                                log4jConfigURLTextField.setText(url.toExternalForm());
                            }
                        } catch (Exception ex) {
                            logger.error(
                                "Error browsing for log4j config file", ex);
                        }
                    }
                });

        browseLog4jConfigButton.setToolTipText(
            "Shows a File Open dialog to allow you to find a log4j configuration file");
        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 2;
        c.anchor = GridBagConstraints.LINE_START;
        c.insets = new Insets(0, 0, 5, 0);
        panel.add(browseLog4jConfigButton, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 1;
        c.insets = new Insets(0, 5, 0, 5);
        panel.add(new JLabel(" log4j configuration file URL "), c);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 1;
        c.weightx = 0.5;
        c.fill = GridBagConstraints.HORIZONTAL;
        panel.add(log4jConfigURLTextField, c);


        return panel;
    }

    private JPanel buildLogFileReceiverPanel() {
        JPanel panel = new JPanel(new GridBagLayout());
        browseLogFileButton = new JButton(new AbstractAction(" Open File... ") {
            public void actionPerformed(ActionEvent e) {
                try {
                    URL url = browseFile("Select a log file", true);
                    if (url != null) {
                        String item = url.toURI().toString();
                        logFileURLTextField.setText(item);
                    }
                } catch (Exception ex) {
                    logger.error(
                        "Error browsing for log file", ex);
                }
            }
        });

        browseLogFileButton.setToolTipText("Shows a File Open dialog to allow you to find a log file");
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.anchor = GridBagConstraints.LINE_START;
        c.insets = new Insets(0, 0, 5, 0);
        panel.add(browseLogFileButton, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 1;
        c.anchor = GridBagConstraints.LINE_END;
        c.insets = new Insets(0, 0, 5, 5);
        panel.add(new JLabel(" Log file URL "), c);
        logFileURLTextField = new JTextField();
        logFileURLTextField.setEditable(true);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 1;
        c.weightx = 1.0;
        c.gridwidth = 1;
        c.anchor = GridBagConstraints.LINE_START;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(0, 0, 5, 0);
        panel.add(logFileURLTextField, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 2;
        c.anchor = GridBagConstraints.LINE_END;
        c.insets = new Insets(0, 0, 5, 5);
        panel.add(new JLabel(" Log file format type "), c);

        DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
        comboBoxModel.addElement("LogFilePatternReceiver LogFormat");
        comboBoxModel.addElement("PatternLayout format");

        logFileFormatTypeComboBox = new JComboBox(comboBoxModel);
        logFileFormatTypeComboBox.setOpaque(false);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 2;
        c.anchor = GridBagConstraints.LINE_START;
        c.insets = new Insets(0, 0, 5, 0);
        panel.add(logFileFormatTypeComboBox, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 3;
        c.anchor = GridBagConstraints.LINE_END;
        c.insets = new Insets(0, 5, 5, 5);
        panel.add(new JLabel(" Log file format "), c);

        logFileFormatComboBoxModel = new DefaultComboBoxModel();
        seedLogFileFormatComboBoxModel();
        logFileFormatComboBox = new JComboBox(logFileFormatComboBoxModel);
        logFileFormatComboBox.setEditable(true);
        logFileFormatComboBox.setOpaque(false);
        logFileFormatComboBox.setSelectedIndex(0);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 3;
        c.weightx = 0.5;
        c.anchor = GridBagConstraints.LINE_START;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(0, 0, 5, 0);
        panel.add(logFileFormatComboBox, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 4;
        c.insets = new Insets(0, 5, 5, 5);
        panel.add(new JLabel(" Log file timestamp format "), c);

        logFileFormatTimestampFormatComboBoxModel = new DefaultComboBoxModel();
        seedLogFileFormatTimestampComboBoxModel();
        logFileFormatTimestampFormatComboBox = new JComboBox(logFileFormatTimestampFormatComboBoxModel);
        logFileFormatTimestampFormatComboBox.setEditable(true);
        logFileFormatTimestampFormatComboBox.setOpaque(false);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 4;
        c.weightx = 0.5;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(0, 0, 0, 0);
        panel.add(logFileFormatTimestampFormatComboBox, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 5;
        c.gridwidth=5;
        c.insets = new Insets(15, 5, 0, 5);
        panel.add(new JLabel("<html> See PatternLayout or LogFilePatternReceiver JavaDoc for details </html>"), c);
        return panel;
    }

    private void seedLogFileFormatComboBoxModel()
    {
        logFileFormatComboBoxModel.addElement("MESSAGE");
        logFileFormatComboBoxModel.addElement("%p %t %c - %m%n");
        logFileFormatComboBoxModel.addElement("LEVEL THREAD LOGGER - MESSAGE");
        logFileFormatComboBoxModel.addElement("%d{ABSOLUTE} %-5p [%c{1}] %m%n");
        logFileFormatComboBoxModel.addElement("TIMESTAMP LEVEL [LOGGER] MESSAGE");
    }

    private void seedLogFileFormatTimestampComboBoxModel()
    {
        logFileFormatTimestampFormatComboBoxModel.addElement("yyyy-MM-dd HH:mm:ss,SSS");
        logFileFormatTimestampFormatComboBoxModel.addElement("yyyyMMdd HH:mm:ss.SSS");
        logFileFormatTimestampFormatComboBoxModel.addElement("yyyy/MM/dd HH:mm:ss");
        logFileFormatTimestampFormatComboBoxModel.addElement("dd MMM yyyy HH:mm:ss,SSS");
        logFileFormatTimestampFormatComboBoxModel.addElement("HH:mm:ss,SSS");
        logFileFormatTimestampFormatComboBoxModel.addElement("yyyy-MM-ddTHH:mm");
        logFileFormatTimestampFormatComboBoxModel.addElement("yyyy-MM-ddTHH:mm:ss.SSS");
    }

    private JPanel buildUseExistingConfigurationPanel() {
        existingConfigurationComboBoxModel = new DefaultComboBoxModel();

        existingConfigurationComboBox = new JComboBox(existingConfigurationComboBoxModel);
        existingConfigurationComboBox.setOpaque(false);
        existingConfigurationComboBox.setToolTipText("Previously loaded configurations can be chosen here");
        existingConfigurationComboBox.setEditable(true);

        existingConfigurationComboBox.getEditor().getEditorComponent().addFocusListener(
            new FocusListener() {
                public void focusGained(FocusEvent e) {
                    selectAll();
                }

                private void selectAll() {
                    existingConfigurationComboBox.getEditor().selectAll();
                }

                public void focusLost(FocusEvent e) {
                }
            });

        browseForAnExistingConfigurationButton = new JButton(new AbstractAction(" Open File... ") {
                    public void actionPerformed(ActionEvent e) {
                        try {

                            URL url = browseConfig();

                            if (url != null) {
                                existingConfigurationComboBoxModel.addElement(url.toExternalForm());
                                existingConfigurationComboBox.getModel().setSelectedItem(
                                    url);
                            }
                        } catch (Exception ex) {
                            logger.error(
                                "Error browsing for Configuration file", ex);
                        }
                    }
                });

        browseForAnExistingConfigurationButton.setToolTipText(
            "Shows a File Open dialog to allow you to find a configuration file");
        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 2;
        c.anchor = GridBagConstraints.LINE_START;
        c.insets = new Insets(0, 0, 5, 0);
        panel.add(browseForAnExistingConfigurationButton, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 1;
        c.insets = new Insets(0, 5, 0, 5);
        panel.add(new JLabel(" Configuration file URL "), c);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 1;
        c.weightx = 0.5;
        c.fill = GridBagConstraints.HORIZONTAL;
        panel.add(existingConfigurationComboBox, c);


        return panel;
    }

    /**
     * Returns the current Model/state of the chosen options by the user.
     * @return model
     */
    PanelModel getModel() {
        return panelModel;
    }

    /**
     * Clients of this panel can configure the ActionListener to be used
     * when the user presses the OK button, so they can read
     * back this Panel's model top determine what to do.
     * @param actionListener listener which will be notified that ok was selected
     */
    void setCompletionActionListener(ActionListener actionListener) {
        completionActionListener = actionListener;
    }

    private void updateEnabledState(Component component) {
        lowerPanel.removeAll();
        if (component == useExistingConfigurationRadioButton) {
            lowerPanel.add(useExistingConfigurationPanel, BorderLayout.NORTH);
        }
        if (component == networkReceiverRadioButton) {
            lowerPanel.add(networkReceiverPanel, BorderLayout.NORTH);
        }
        if (component == logFileReceiverRadioButton) {
            lowerPanel.add(logFileReceiverPanel, BorderLayout.NORTH);
        }
        if (component == log4jConfigReceiverRadioButton) {
            lowerPanel.add(log4jConfigReceiverPanel, BorderLayout.NORTH);
        }
        lowerPanel.revalidate();
        lowerPanel.repaint();
    }

    /**
     * Returns the URL chosen by the user for a Configuration file
     * or null if they cancelled.
     */
    private URL browseConfig() throws MalformedURLException {
        //hiding and showing the dialog to avoid focus issues with 2 dialogs
        dialog.setVisible(false);
        File selectedFile = SwingHelper.promptForFile(dialog, null, "Choose a Chainsaw configuration file", true);
        URL result = null;
        if (selectedFile == null) {
            result = null;
        }
        if (selectedFile != null && (!selectedFile.exists() || !selectedFile.canRead())) {
            result = null;
        }
        if (selectedFile != null) {
          result = selectedFile.toURI().toURL();
        }
        EventQueue.invokeLater(() -> dialog.setVisible(true));
        return result;
    }

    /**
     * Returns the URL chosen by the user for a Configuration file
     * or null if they cancelled.
     */
    private URL browseFile(String title, boolean loadDialog) throws MalformedURLException {
        //hiding and showing the dialog to avoid focus issues with 2 dialogs
        dialog.setVisible(false);
        File selectedFile = SwingHelper.promptForFile(dialog, null, title, loadDialog);
        URL result = null;
        if (selectedFile == null) {
            result = null;
        }
        if (selectedFile != null && (!selectedFile.exists() || !selectedFile.canRead())) {
            result = null;
        }
        if (selectedFile != null) {
          result = selectedFile.toURI().toURL();
        }
        EventQueue.invokeLater(() -> dialog.setVisible(true));
        return result;
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.getContentPane().add(new ReceiverConfigurationPanel());
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    /**
     * @return Returns the dontWarnMeAgain.
     */
    public final boolean isDontWarnMeAgain() {

        return dontwarnIfNoReceiver.isSelected();
    }

  public void setDialog(Container dialog) {
    this.dialog = dialog;
  }

  /**
     * This class represents the model of the chosen options the user
     * has configured.
     *
     */
    class PanelModel {

    private File file;
    //default to cancelled
    private boolean cancelled = true;
    private String lastLogFormat;
    private File saveConfigFile;

    public PanelModel(){
            file = new File(SettingsManager.getInstance().getSettingsDirectory(), "receiver-config.xml");
        }

        boolean isNetworkReceiverMode() {

            return !cancelled && networkReceiverRadioButton.isSelected();
        }

        int getNetworkReceiverPort() {

            return Integer.parseInt(networkReceiverPortComboBoxModel.getSelectedItem().toString());
        }

        Class getNetworkReceiverClass() throws ClassNotFoundException {
            return Class.forName(networkReceiverClassNameComboBoxModel.getSelectedItem().toString());
        }

        boolean isLoadConfig() {

            return !cancelled && useExistingConfigurationRadioButton.isSelected();
        }

        boolean isLogFileReceiverConfig() {
            return !cancelled && logFileReceiverRadioButton.isSelected();
        }

        boolean isLog4jConfig() {
            return !cancelled && log4jConfigReceiverRadioButton.isSelected();
        }

        URL getConfigToLoad() {

            try
            {
                return new URL(existingConfigurationComboBoxModel.getSelectedItem().toString());
            }
            catch (MalformedURLException e)
            {
                return null;
            }
        }

        URL getDefaultConfigFileURL() {
            try {
                return file.toURI().toURL();
            } catch (MalformedURLException e) {
                logger.error("Error loading saved configurations by Chainsaw", e);
            }
            return null;
        }

        File getSaveConfigFile() {
          return saveConfigFile;
        }

        void setSaveConfigFile(File file) {
          this.saveConfigFile = file;
        }

        URL getLogFileURL() {
            try
            {
                Object item = logFileURLTextField.getText();
                if (item != null) {
                    return new URL(item.toString());
                }
            }
            catch (MalformedURLException e)
            {
                logger.error("Error retrieving log file URL", e);
            }
            return null;
        }

        String getLogFormat() {
            if (cancelled) {
              return lastLogFormat;
            }
            Object item = logFileFormatComboBox.getSelectedItem();
            if (item != null) {
                return item.toString();
            }
            return null;
        }

        boolean isPatternLayoutLogFormat() {
            Object item = logFileFormatTypeComboBox.getSelectedItem();
            return item != null && item.toString().toLowerCase(Locale.ENGLISH).contains("patternlayout");
        }

        String getLogFormatTimestampFormat() {
            Object item = logFileFormatTimestampFormatComboBox.getSelectedItem();
            if (item != null) {
                return item.toString();
            }

            return null;
        }

        public void setCancelled(boolean cancelled)
        {
            this.cancelled = cancelled;
        }

        public void setLogFormat(String lastLogFormat) {
          this.lastLogFormat = lastLogFormat;
          logFileFormatComboBoxModel.removeElement(lastLogFormat);
          logFileFormatComboBoxModel.insertElementAt(lastLogFormat, 0);
          logFileFormatComboBox.setSelectedIndex(0);
        }

        public boolean isCancelled() {
          return cancelled;
        }

    public File getLog4jConfigFile() {
      try {
        URL newConfigurationURL = new URL(log4jConfigURLTextField.getText());
        return new File(newConfigurationURL.toURI());
      } catch (URISyntaxException | MalformedURLException e) {
        e.printStackTrace();
      }
        return null;
    }
  }
}
