/*
 * 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 org.apache.log4j.*;
import org.apache.log4j.chainsaw.color.RuleColorizer;
import org.apache.log4j.chainsaw.dnd.FileDnDTarget;
import org.apache.log4j.chainsaw.help.HelpManager;
import org.apache.log4j.chainsaw.help.Tutorial;
import org.apache.log4j.chainsaw.helper.SwingHelper;
import org.apache.log4j.chainsaw.icons.ChainsawIcons;
import org.apache.log4j.chainsaw.icons.LineIconFactory;
import org.apache.log4j.chainsaw.osx.OSXIntegration;
import org.apache.log4j.chainsaw.plugins.PluginClassLoaderFactory;
import org.apache.log4j.chainsaw.prefs.*;
import org.apache.log4j.chainsaw.receivers.ReceiversPanel;
import org.apache.log4j.chainsaw.vfs.VFSLogFilePatternReceiver;
import org.apache.log4j.net.SocketNodeEventListener;
import org.apache.log4j.plugins.*;
import org.apache.log4j.rewrite.PropertyRewritePolicy;
import org.apache.log4j.rewrite.RewriteAppender;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.Decoder;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggerRepositoryEx;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.xml.DOMConfigurator;
import org.apache.log4j.xml.XMLDecoder;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.HyperlinkEvent;
import java.awt.*;
import java.awt.event.*;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyChangeListener;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.*;
import java.util.*;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
import org.apache.logging.log4j.core.LoggerContext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;


/**
 * The main entry point for Chainsaw, this class represents the first frame
 * that is used to display a Welcome panel, and any other panels that are
 * generated because Logging Events are streamed via a Receiver, or other
 * mechanism.
 * <p>
 * NOTE: Some of Chainsaw's application initialization should be performed prior
 * to activating receivers and the logging framework used to perform self-logging.
 * <p>
 * DELAY as much as possible the logging framework initialization process,
 * currently initialized by the creation of a ChainsawAppenderHandler.
 *
 * @author Scott Deboy &lt;sdeboy@apache.org&gt;
 * @author Paul Smith  &lt;psmith@apache.org&gt;
 */
public class LogUI extends JFrame implements ChainsawViewer, SettingsListener {
    private static final String MAIN_WINDOW_HEIGHT = "main.window.height";
    private static final String MAIN_WINDOW_WIDTH = "main.window.width";
    private static final String MAIN_WINDOW_Y = "main.window.y";
    private static final String MAIN_WINDOW_X = "main.window.x";
    private static ChainsawSplash splash;
    private static final double DEFAULT_MAIN_RECEIVER_SPLIT_LOCATION = 0.85d;
    private final JFrame preferencesFrame = new JFrame();
    private boolean noReceiversDefined;
    private ReceiversPanel receiversPanel;
    private ChainsawTabbedPane tabbedPane;
    private JToolBar toolbar;
    private ChainsawStatusBar statusBar;
    private ApplicationPreferenceModel applicationPreferenceModel;
    private ApplicationPreferenceModelPanel applicationPreferenceModelPanel;
    private final Map tableModelMap = new HashMap();
    private final Map tableMap = new HashMap();
    private final List<String> filterableColumns = new ArrayList<>();
    private final Map<String, Component> panelMap = new HashMap<>();
    private ChainsawAppender chainsawAppender;
    private ChainsawToolBarAndMenus tbms;
    private ChainsawAbout aboutBox;
    private final SettingsManager sm = SettingsManager.getInstance();
    private final JFrame tutorialFrame = new JFrame("Chainsaw Tutorial");
    private JSplitPane mainReceiverSplitPane;
    private double lastMainReceiverSplitLocation = DEFAULT_MAIN_RECEIVER_SPLIT_LOCATION;
    private final List<LogPanel> identifierPanels = new ArrayList<>();
    private int dividerSize;
    private int cyclicBufferSize;
    private static String configurationURLAppArg;
    private List<ChainsawReceiver> m_receivers = new ArrayList<>();
    private List<ReceiverEventListener> m_receiverListeners = new ArrayList<>();

    private static org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getLogger();

    /**
     * Set to true, if and only if the GUI has completed it's full
     * initialization. Any logging events that come in must wait until this is
     * true, and if it is false, should wait on the initializationLock object
     * until notified.
     */
    private boolean isGUIFullyInitialized = false;
    private final Object initializationLock = new Object();

    /**
     * The shutdownAction is called when the user requests to exit Chainsaw, and
     * by default this exits the VM, but a developer may replace this action with
     * something that better suits their needs
     */
    private Action shutdownAction = null;

    /**
     * Clients can register a ShutdownListener to be notified when the user has
     * requested Chainsaw to exit.
     */
    private EventListenerList shutdownListenerList = new EventListenerList();
    private WelcomePanel welcomePanel;

    //map of tab names to rulecolorizers
    private Map<String, RuleColorizer> allColorizers = new HashMap<>();
    private ReceiverConfigurationPanel receiverConfigurationPanel = new ReceiverConfigurationPanel();

    /**
     * Constructor which builds up all the visual elements of the frame including
     * the Menu bar
     */
    public LogUI() {
        super("Chainsaw");
        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

        if (ChainsawIcons.WINDOW_ICON != null) {
            setIconImage(new ImageIcon(ChainsawIcons.WINDOW_ICON).getImage());
        }
    }

    private static final void showSplash(Frame owner) {
        splash = new ChainsawSplash(owner);
        SwingHelper.centerOnScreen(splash);
        splash.setVisible(true);
    }

    private static final void removeSplash() {
        if (splash != null) {
            splash.setVisible(false);
            splash.dispose();
        }
    }

    /**
     * Registers a ShutdownListener with this calss so that it can be notified
     * when the user has requested that Chainsaw exit.
     *
     * @param l
     */
    public void addShutdownListener(ShutdownListener l) {
        shutdownListenerList.add(ShutdownListener.class, l);
    }

    /**
     * Removes the registered ShutdownListener so that the listener will not be
     * notified on a shutdown.
     *
     * @param l
     */
    public void removeShutdownListener(ShutdownListener l) {
        shutdownListenerList.remove(ShutdownListener.class, l);
    }

    /**
     * Starts Chainsaw by attaching a new instance to the Log4J main root Logger
     * via a ChainsawAppender, and activates itself
     *
     * @param args
     */
    public static void main(String[] args) {
        if (args.length > 0) {
            configurationURLAppArg = args[0];
        }

        if (OSXIntegration.IS_OSX) {
            System.setProperty("apple.laf.useScreenMenuBar", "true");
        }

        final ApplicationPreferenceModel model = new ApplicationPreferenceModel();

        SettingsManager.getInstance().configure(new ApplicationPreferenceModelSaver(model));
        //if a configuration URL param was provided, set the configuration URL field to null
        if (configurationURLAppArg != null) {
            model.setBypassConfigurationURL(configurationURLAppArg);
        }

        EventQueue.invokeLater(() -> {
            String lookAndFeelClassName = model.getLookAndFeelClassName();
            if (lookAndFeelClassName == null || lookAndFeelClassName.trim().equals("")) {
                String osName = System.getProperty("os.name");
                if (osName.toLowerCase(Locale.ENGLISH).startsWith("mac")) {
                    //no need to assign look and feel
                } else if (osName.toLowerCase(Locale.ENGLISH).startsWith("windows")) {
                    lookAndFeelClassName = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
                    model.setLookAndFeelClassName(lookAndFeelClassName);
                } else if (osName.toLowerCase(Locale.ENGLISH).startsWith("linux")) {
                    lookAndFeelClassName = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
                    model.setLookAndFeelClassName(lookAndFeelClassName);
                }
            }

            if (lookAndFeelClassName != null && !(lookAndFeelClassName.trim().equals(""))) {
                loadLookAndFeelUsingPluginClassLoader(lookAndFeelClassName);
            }
            createChainsawGUI(model, null);
        });
    }

    /**
     * Creates, activates, and then shows the Chainsaw GUI, optionally showing
     * the splash screen, and using the passed shutdown action when the user
     * requests to exit the application (if null, then Chainsaw will exit the vm)
     *
     * @param model
     * @param newShutdownAction DOCUMENT ME!
     */
    public static void createChainsawGUI(
        ApplicationPreferenceModel model, Action newShutdownAction) {

        if (model.isOkToRemoveSecurityManager()) {
//            statusBar.setMessage("User has authorised removal of Java Security Manager via preferences");
            System.setSecurityManager(null);
            // this SHOULD set the Policy/Permission stuff for any
            // code loaded from our custom classloader.  
            // crossing fingers...
            Policy.setPolicy(new Policy() {

                public void refresh() {
                }

                public PermissionCollection getPermissions(CodeSource codesource) {
                    Permissions perms = new Permissions();
                    perms.add(new AllPermission());
                    return (perms);
                }
            });
        }

        final LogUI logUI = new LogUI();
        logUI.applicationPreferenceModel = model;

        if (model.isShowSplash()) {
            showSplash(logUI);
        }
        logUI.cyclicBufferSize = model.getCyclicBufferSize();

        final LoggerContext ctx = (LoggerContext) org.apache.logging.log4j.LogManager.getContext(false);
        logUI.chainsawAppender = ctx.getConfiguration().getAppender("chainsaw");

        /**
         * TODO until we work out how JoranConfigurator might be able to have
         * configurable class loader, if at all.  For now we temporarily replace the
         * TCCL so that Plugins that need access to resources in
         * the Plugins directory can find them (this is particularly
         * important for the Web start version of Chainsaw
         */
        //configuration initialized here

        //set hostname, application and group properties which will cause Chainsaw and other apache-generated
        //logging events to route (by default) to a tab named 'chainsaw-log'
        PropertyRewritePolicy policy = new PropertyRewritePolicy();
        policy.setProperties("hostname=chainsaw,application=log,group=chainsaw");

        RewriteAppender rewriteAppender = new RewriteAppender();
        rewriteAppender.setRewritePolicy(policy);

        Enumeration appenders = Logger.getLogger("org.apache").getAllAppenders();
        if (!appenders.hasMoreElements()) {
            appenders = Logger.getRootLogger().getAllAppenders();
        }
        while (appenders.hasMoreElements()) {
            Appender nextAppender = (Appender) appenders.nextElement();
            rewriteAppender.addAppender(nextAppender);
        }
        Logger.getLogger("org.apache").removeAllAppenders();
        Logger.getLogger("org.apache").addAppender(rewriteAppender);
        Logger.getLogger("org.apache").setAdditivity(false);

        //commons-vfs uses httpclient for http filesystem support, route this to the chainsaw-log tab as well
        appenders = Logger.getLogger("httpclient").getAllAppenders();
        if (!appenders.hasMoreElements()) {
            appenders = Logger.getRootLogger().getAllAppenders();
        }
        while (appenders.hasMoreElements()) {
            Appender nextAppender = (Appender) appenders.nextElement();
            rewriteAppender.addAppender(nextAppender);
        }
        Logger.getLogger("httpclient").removeAllAppenders();
        Logger.getLogger("httpclient").addAppender(rewriteAppender);
        Logger.getLogger("httpclient").setAdditivity(false);

        //set the commons.vfs.cache logger to info, since it can contain password information
        Logger.getLogger("org.apache.commons.vfs.cache").setLevel(Level.INFO);

        Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
            e.printStackTrace();
            logger.error("Uncaught exception in thread " + t, e);
        });

        String config = configurationURLAppArg;
        if (config != null) {
            logger.info("Command-line configuration arg provided (overriding auto-configuration URL) - using: " + config);
        } else {
            config = model.getConfigurationURL();
        }

        if (config != null && (!config.trim().equals(""))) {
            config = config.trim();
            try {
                URL configURL = new URL(config);
                logger.info("Using '" + config + "' for auto-configuration");
                logUI.loadConfigurationUsingPluginClassLoader(configURL);
            } catch (MalformedURLException e) {
                logger.error("Initial configuration - failed to convert config string to url", e);
            } catch (IOException e) {
                logger.error("Unable to access auto-configuration URL: " + config);
            }
        }

        //register a listener to load the configuration when it changes (avoid having to restart Chainsaw when applying a new configuration)
        //this doesn't remove receivers from receivers panel, it just triggers DOMConfigurator.configure.
        model.addPropertyChangeListener("configurationURL", evt -> {
            String newConfiguration = evt.getNewValue().toString();
            if (newConfiguration != null && !(newConfiguration.trim().equals(""))) {
                newConfiguration = newConfiguration.trim();
                try {
                    logger.info("loading updated configuration: " + newConfiguration);
                    URL newConfigurationURL = new URL(newConfiguration);
                    File file = new File(newConfigurationURL.toURI());
                    if (file.exists()) {
                        logUI.loadConfigurationUsingPluginClassLoader(newConfigurationURL);
                    } else {
                        logger.info("Updated configuration but file does not exist");
                    }
                } catch (MalformedURLException | URISyntaxException e) {
                    logger.error("Updated configuration - failed to convert config string to URL", e);
                }
            }
        });

        LogManager.getRootLogger().setLevel(Level.TRACE);
        EventQueue.invokeLater(logUI::activateViewer);
        EventQueue.invokeLater(logUI::buildChainsawLogPanel);

        logger.info("SecurityManager is now: " + System.getSecurityManager());

        if (newShutdownAction != null) {
            logUI.setShutdownAction(newShutdownAction);
        } else {
            logUI.setShutdownAction(
                new AbstractAction() {
                    public void actionPerformed(ActionEvent e) {
                        System.exit(0);
                    }
                });
        }
    }

    /**
     * Allow Chainsaw v2 to be ran in-process (configured as a ChainsawAppender)
     * NOTE: Closing Chainsaw will NOT stop the application generating the events.
     *
     * @param appender
     */
    public void activateViewer(ChainsawAppender appender) {

        if (OSXIntegration.IS_OSX) {
            System.setProperty("apple.laf.useScreenMenuBar", "true");
        }

        //if Chainsaw is launched as an appender, ensure the root logger level is TRACE
        LogManager.getRootLogger().setLevel(Level.TRACE);

        final ApplicationPreferenceModel model = new ApplicationPreferenceModel();
        SettingsManager.getInstance().configure(new ApplicationPreferenceModelSaver(model));

        cyclicBufferSize = model.getCyclicBufferSize();

        setShutdownAction(
            new AbstractAction() {
                public void actionPerformed(ActionEvent e) {
                }
            });

        applicationPreferenceModel = new ApplicationPreferenceModel();

        SettingsManager.getInstance().configure(new ApplicationPreferenceModelSaver(model));

        EventQueue.invokeLater(() -> {
            loadLookAndFeelUsingPluginClassLoader(model.getLookAndFeelClassName());
            createChainsawGUI(model, null);
            getApplicationPreferenceModel().apply(model);
            activateViewer();
        });
    }

    /**
     * Initialises the menu's and toolbars, but does not actually create any of
     * the main panel components.
     */
    private void initGUI() {

        setupHelpSystem();
        statusBar = new ChainsawStatusBar(this);
        setupReceiverPanel();

        setToolBarAndMenus(new ChainsawToolBarAndMenus(this));
        toolbar = getToolBarAndMenus().getToolbar();
        setJMenuBar(getToolBarAndMenus().getMenubar());

        setTabbedPane(new ChainsawTabbedPane());
        getSettingsManager().addSettingsListener(getTabbedPane());
        getSettingsManager().configure(getTabbedPane());

        /**
         * This adds Drag & Drop capability to Chainsaw
         */
        FileDnDTarget dnDTarget = new FileDnDTarget(tabbedPane);
        dnDTarget.addPropertyChangeListener("fileList", evt -> {
            final List fileList = (List) evt.getNewValue();

            Thread thread = new Thread(() -> {
                logger.debug("Loading files: " + fileList);
                for (Object aFileList : fileList) {
                    File file = (File) aFileList;
                    final Decoder decoder = new XMLDecoder();
                    try {
                        getStatusBar().setMessage("Loading " + file.getAbsolutePath() + "...");
//                        FileLoadAction.importURL(handler, decoder, file
//                            .getName(), file.toURI().toURL());
                    } catch (Exception e) {
                        String errorMsg = "Failed to import a file";
                        logger.error(errorMsg, e);
                        getStatusBar().setMessage(errorMsg);
                    }
                }

            });

            thread.setPriority(Thread.MIN_PRIORITY);
            thread.start();

        });

        applicationPreferenceModelPanel = new ApplicationPreferenceModelPanel(applicationPreferenceModel);

        applicationPreferenceModelPanel.setOkCancelActionListener(
            e -> preferencesFrame.setVisible(false));
        KeyStroke escape = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
        Action closeAction = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                preferencesFrame.setVisible(false);
            }
        };
        preferencesFrame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escape, "ESCAPE");
        preferencesFrame.getRootPane().
            getActionMap().put("ESCAPE", closeAction);

        OSXIntegration.init(this);

    }

    private void initPlugins(PluginRegistry pluginRegistry) {
        pluginRegistry.addPluginListener(
            new PluginListener() {
                public void pluginStarted(PluginEvent e) {
                    if (e.getPlugin() instanceof JComponent) {
                        JComponent plugin = (JComponent) e.getPlugin();
                        getTabbedPane().addANewTab(plugin.getName(), plugin, null, null);
                        getPanelMap().put(plugin.getName(), plugin);
                    }
                }

                public void pluginStopped(PluginEvent e) {
                    //TODO remove the plugin from the gui
                }
            });

        // TODO this should all be in a config file
//    ChainsawCentral cc = new ChainsawCentral();
//    pluginRegistry.addPlugin(cc);
//    cc.activateOptions();

        try {
            Class<? extends Plugin> pluginClass = Class.forName("org.apache.log4j.chainsaw.zeroconf.ZeroConfPlugin").asSubclass(Plugin.class);
            Plugin plugin = pluginClass.newInstance();
            pluginRegistry.addPlugin(plugin);
            plugin.activateOptions();
            statusBar.setMessage("Looks like ZeroConf is available... WooHoo!");
        } catch (Throwable e) {
            statusBar.setMessage("Doesn't look like ZeroConf is available");
        }
    }

    private void setupReceiverPanel() {
        receiversPanel = new ReceiversPanel(this, statusBar);
        receiversPanel.addPropertyChangeListener(
            "visible",
            evt -> getApplicationPreferenceModel().setReceivers(
                (Boolean) evt.getNewValue()));
    }

    /**
     * Initialises the Help system and the WelcomePanel
     */
    private void setupHelpSystem() {
        welcomePanel = new WelcomePanel();

        JToolBar tb = welcomePanel.getToolbar();


        tb.add(
            new SmallButton(
                new AbstractAction("Tutorial", new ImageIcon(ChainsawIcons.HELP)) {
                    public void actionPerformed(ActionEvent e) {
                        setupTutorial();
                    }
                }));
        tb.addSeparator();

        final Action exampleConfigAction =
            new AbstractAction("View example Receiver configuration") {
                public void actionPerformed(ActionEvent e) {
                    HelpManager.getInstance().setHelpURL(
                        ChainsawConstants.EXAMPLE_CONFIG_URL);
                }
            };

        exampleConfigAction.putValue(
            Action.SHORT_DESCRIPTION,
            "Displays an example Log4j configuration file with several Receivers defined.");

        JButton exampleButton = new SmallButton(exampleConfigAction);
        tb.add(exampleButton);

        tb.add(Box.createHorizontalGlue());

        /**
         * Setup a listener on the HelpURL property and automatically change the WelcomePages URL
         * to it.
         */
        HelpManager.getInstance().addPropertyChangeListener(
            "helpURL",
            evt -> {
                URL newURL = (URL) evt.getNewValue();

                if (newURL != null) {
                    welcomePanel.setURL(newURL);
                    ensureWelcomePanelVisible();
                }
            });
    }

    private void ensureWelcomePanelVisible() {
        // ensure that the Welcome Panel is made visible
        if (!getTabbedPane().containsWelcomePanel()) {
            addWelcomePanel();
        }
        getTabbedPane().setSelectedComponent(welcomePanel);
    }

    /**
     * Given the load event, configures the size/location of the main window etc
     * etc.
     *
     * @param event DOCUMENT ME!
     */
    public void loadSettings(LoadSettingsEvent event) {
        setLocation(
            event.asInt(LogUI.MAIN_WINDOW_X), event.asInt(LogUI.MAIN_WINDOW_Y));
        int width = event.asInt(LogUI.MAIN_WINDOW_WIDTH);
        int height = event.asInt(LogUI.MAIN_WINDOW_HEIGHT);
        if (width == -1 && height == -1) {
            width = Toolkit.getDefaultToolkit().getScreenSize().width;
            height = Toolkit.getDefaultToolkit().getScreenSize().height;
            setSize(width, height);
            setExtendedState(getExtendedState() | MAXIMIZED_BOTH);
        } else {
            setSize(width, height);
        }

        getToolBarAndMenus().stateChange();
        RuleColorizer colorizer = new RuleColorizer();
        colorizer.loadColorSettings(ChainsawConstants.DEFAULT_COLOR_RULE_NAME);
        allColorizers.put(ChainsawConstants.DEFAULT_COLOR_RULE_NAME, colorizer);
        if (event.getSetting("SavedConfig.logFormat") != null) {
            receiverConfigurationPanel.getModel().setLogFormat(event.getSetting("SavedConfig.logFormat"));
        }
    }

    /**
     * Ensures the location/size of the main window is stored with the settings
     *
     * @param event DOCUMENT ME!
     */
    public void saveSettings(SaveSettingsEvent event) {
        event.saveSetting(LogUI.MAIN_WINDOW_X, (int) getLocation().getX());
        event.saveSetting(LogUI.MAIN_WINDOW_Y, (int) getLocation().getY());

        event.saveSetting(LogUI.MAIN_WINDOW_WIDTH, getWidth());
        event.saveSetting(LogUI.MAIN_WINDOW_HEIGHT, getHeight());
        RuleColorizer colorizer = allColorizers.get(ChainsawConstants.DEFAULT_COLOR_RULE_NAME);
        colorizer.saveColorSettings(ChainsawConstants.DEFAULT_COLOR_RULE_NAME);
        if (receiverConfigurationPanel.getModel().getLogFormat() != null) {
            event.saveSetting("SavedConfig.logFormat", receiverConfigurationPanel.getModel().getLogFormat());
        }
    }

    public void buildChainsawLogPanel(){
        List<ChainsawLoggingEvent> events = new ArrayList<>();
        buildLogPanel(false, "Chainsaw", events, chainsawAppender.getReceiver());
    }

    /**
     * Activates itself as a viewer by configuring Size, and location of itself,
     * and configures the default Tabbed Pane elements with the correct layout,
     * table columns, and sets itself viewable.
     */
    public void activateViewer() {
        initGUI();

        initPrefModelListeners();

        if (m_receivers.size() == 0) {
            noReceiversDefined = true;
        }

        getFilterableColumns().add(ChainsawConstants.LEVEL_COL_NAME);
        getFilterableColumns().add(ChainsawConstants.LOGGER_COL_NAME);
        getFilterableColumns().add(ChainsawConstants.THREAD_COL_NAME);
        getFilterableColumns().add(ChainsawConstants.NDC_COL_NAME);
        getFilterableColumns().add(ChainsawConstants.PROPERTIES_COL_NAME);
        getFilterableColumns().add(ChainsawConstants.CLASS_COL_NAME);
        getFilterableColumns().add(ChainsawConstants.METHOD_COL_NAME);
        getFilterableColumns().add(ChainsawConstants.FILE_COL_NAME);
        getFilterableColumns().add(ChainsawConstants.NONE_COL_NAME);

        JPanel panePanel = new JPanel();
        panePanel.setLayout(new BorderLayout(2, 2));

        getContentPane().setLayout(new BorderLayout());

        getTabbedPane().addChangeListener(getToolBarAndMenus());
        getTabbedPane().addChangeListener(e -> {
            LogPanel thisLogPanel = getCurrentLogPanel();
            if (thisLogPanel != null) {
                thisLogPanel.updateStatusBar();
            }
        });

        KeyStroke ksRight =
            KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
        KeyStroke ksLeft =
            KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
        KeyStroke ksGotoLine =
            KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());

        getTabbedPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
            ksRight, "MoveRight");
        getTabbedPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
            ksLeft, "MoveLeft");
        getTabbedPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
            ksGotoLine, "GotoLine");

        Action moveRight =
            new AbstractAction() {
                public void actionPerformed(ActionEvent e) {
                    int temp = getTabbedPane().getSelectedIndex();
                    ++temp;

                    if (temp != getTabbedPane().getTabCount()) {
                        getTabbedPane().setSelectedTab(temp);
                    }
                }
            };

        Action moveLeft =
            new AbstractAction() {
                public void actionPerformed(ActionEvent e) {
                    int temp = getTabbedPane().getSelectedIndex();
                    --temp;

                    if (temp > -1) {
                        getTabbedPane().setSelectedTab(temp);
                    }
                }
            };

        Action gotoLine =
            new AbstractAction() {
                public void actionPerformed(ActionEvent e) {
                    String inputLine = JOptionPane.showInputDialog(LogUI.this, "Enter the line number to go:", "Goto Line", JOptionPane.PLAIN_MESSAGE);
                    try {
                        int lineNumber = Integer.parseInt(inputLine);
                        int row = getCurrentLogPanel().setSelectedEvent(lineNumber);
                        if (row == -1) {
                            JOptionPane.showMessageDialog(LogUI.this, "You have entered an invalid line number", "Error", JOptionPane.ERROR_MESSAGE);
                        }
                    } catch (NumberFormatException nfe) {
                        JOptionPane.showMessageDialog(LogUI.this, "You have entered an invalid line number", "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            };


        getTabbedPane().getActionMap().put("MoveRight", moveRight);
        getTabbedPane().getActionMap().put("MoveLeft", moveLeft);
        getTabbedPane().getActionMap().put("GotoLine", gotoLine);

        /**
         * We listen for double clicks, and auto-undock currently selected Tab if
         * the mouse event location matches the currently selected tab
         */
        getTabbedPane().addMouseListener(
            new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    super.mouseClicked(e);

                    if (
                        (e.getClickCount() > 1)
                            && ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0)) {
                        int tabIndex = getTabbedPane().getSelectedIndex();

                        if (
                            (tabIndex != -1)
                                && (tabIndex == getTabbedPane().getSelectedIndex())) {
                            LogPanel logPanel = getCurrentLogPanel();

                            if (logPanel != null) {
                                logPanel.undock();
                            }
                        }
                    }
                }
            });

        panePanel.add(getTabbedPane());
        addWelcomePanel();

        getContentPane().add(toolbar, BorderLayout.NORTH);
        getContentPane().add(statusBar, BorderLayout.SOUTH);

        mainReceiverSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panePanel, receiversPanel);
        dividerSize = mainReceiverSplitPane.getDividerSize();
        mainReceiverSplitPane.setDividerLocation(-1);

        getContentPane().add(mainReceiverSplitPane, BorderLayout.CENTER);

        mainReceiverSplitPane.setResizeWeight(1.0);
        addWindowListener(
            new WindowAdapter() {
                public void windowClosing(WindowEvent event) {
                    exit();
                }
            });
        preferencesFrame.setTitle("'Application-wide Preferences");
        preferencesFrame.setIconImage(
            ((ImageIcon) ChainsawIcons.ICON_PREFERENCES).getImage());
        preferencesFrame.getContentPane().add(applicationPreferenceModelPanel);

        preferencesFrame.setSize(750, 520);

        Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
        preferencesFrame.setLocation(
            new Point(
                (screenDimension.width / 2) - (preferencesFrame.getSize().width / 2),
                (screenDimension.height / 2) - (preferencesFrame.getSize().height / 2)));

        pack();

        final JPopupMenu tabPopup = new JPopupMenu();
        final Action hideCurrentTabAction =
            new AbstractAction("Hide") {
                public void actionPerformed(ActionEvent e) {
                    Component selectedComp = getTabbedPane().getSelectedComponent();
                    if (selectedComp instanceof LogPanel) {
                        displayPanel(getCurrentLogPanel().getIdentifier(), false);
                        tbms.stateChange();
                    } else {
                        getTabbedPane().remove(selectedComp);
                    }
                }
            };

        final Action hideOtherTabsAction =
            new AbstractAction("Hide Others") {
                public void actionPerformed(ActionEvent e) {
                    Component selectedComp = getTabbedPane().getSelectedComponent();
                    String currentName;
                    if (selectedComp instanceof LogPanel) {
                        currentName = getCurrentLogPanel().getIdentifier();
                    } else if (selectedComp instanceof WelcomePanel) {
                        currentName = ChainsawTabbedPane.WELCOME_TAB;
                    } else {
                        currentName = ChainsawTabbedPane.ZEROCONF;
                    }

                    int count = getTabbedPane().getTabCount();
                    int index = 0;

                    for (int i = 0; i < count; i++) {
                        String name = getTabbedPane().getTitleAt(index);

                        if (
                            getPanelMap().keySet().contains(name)
                                && !name.equals(currentName)) {
                            displayPanel(name, false);
                            tbms.stateChange();
                        } else {
                            index++;
                        }
                    }
                }
            };

        Action showHiddenTabsAction =
            new AbstractAction("Show All Hidden") {
                public void actionPerformed(ActionEvent e) {
                    for (Object o : getPanels().entrySet()) {
                        Map.Entry entry = (Map.Entry) o;
                        Boolean docked = (Boolean) entry.getValue();
                        if (docked) {
                            String identifier = (String) entry.getKey();
                            int count = getTabbedPane().getTabCount();
                            boolean found = false;

                            for (int i = 0; i < count; i++) {
                                String name = getTabbedPane().getTitleAt(i);

                                if (name.equals(identifier)) {
                                    found = true;

                                    break;
                                }
                            }

                            if (!found) {
                                displayPanel(identifier, true);
                                tbms.stateChange();
                            }
                        }
                    }
                }
            };

        tabPopup.add(hideCurrentTabAction);
        tabPopup.add(hideOtherTabsAction);
        tabPopup.addSeparator();
        tabPopup.add(showHiddenTabsAction);

        final PopupListener tabPopupListener = new PopupListener(tabPopup);
        getTabbedPane().addMouseListener(tabPopupListener);

//        this.handler.addPropertyChangeListener(
//            "dataRate",
//            evt -> {
//                double dataRate = (Double) evt.getNewValue();
//                statusBar.setDataRate(dataRate);
//            });

        getSettingsManager().addSettingsListener(this);
        getSettingsManager().addSettingsListener(MRUFileListPreferenceSaver.getInstance());
        getSettingsManager().addSettingsListener(receiversPanel);
        try {
            //if an uncaught exception is thrown, allow the UI to continue to load
            getSettingsManager().loadSettings();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //app preferences have already been loaded (and configuration url possibly set to blank if being overridden)
        //but we need a listener so the settings will be saved on exit (added after loadsettings was called)
        getSettingsManager().addSettingsListener(new ApplicationPreferenceModelSaver(applicationPreferenceModel));

        setVisible(true);

        if (applicationPreferenceModel.isReceivers()) {
            showReceiverPanel();
        } else {
            hideReceiverPanel();
        }

        removeSplash();

        synchronized (initializationLock) {
            isGUIFullyInitialized = true;
            initializationLock.notifyAll();
        }

        if (
            noReceiversDefined
                && applicationPreferenceModel.isShowNoReceiverWarning()) {
            SwingHelper.invokeOnEDT(this::showReceiverConfigurationPanel);
        }

//        Container container = tutorialFrame.getContentPane();
//        final JEditorPane tutorialArea = new JEditorPane();
//        tutorialArea.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
//        tutorialArea.setEditable(false);
//        container.setLayout(new BorderLayout());
//
//        try {
//            tutorialArea.setPage(ChainsawConstants.TUTORIAL_URL);
//            JTextComponentFormatter.applySystemFontAndSize(tutorialArea);
//
//            container.add(new JScrollPane(tutorialArea), BorderLayout.CENTER);
//        } catch (Exception e) {
//            logger.error("Can't load tutorial", e);
//            statusBar.setMessage("Can't load tutorail");
//        }
//
//        tutorialFrame.setIconImage(new ImageIcon(ChainsawIcons.HELP).getImage());
//        tutorialFrame.setSize(new Dimension(640, 480));
//
//        final Action startTutorial =
//            new AbstractAction(
//                "Start Tutorial", new ImageIcon(ChainsawIcons.ICON_RESUME_RECEIVER)) {
//                public void actionPerformed(ActionEvent e) {
//                    if (
//                        JOptionPane.showConfirmDialog(
//                            null,
//                            "This will start 3 \"Generator\" receivers for use in the Tutorial.  Is that ok?",
//                            "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
//                        new Thread(new Tutorial()).start();
//                        putValue("TutorialStarted", Boolean.TRUE);
//                    } else {
//                        putValue("TutorialStarted", Boolean.FALSE);
//                    }
//                }
//            };
//
//        final Action stopTutorial =
//            new AbstractAction(
//                "Stop Tutorial", new ImageIcon(ChainsawIcons.ICON_STOP_RECEIVER)) {
//                public void actionPerformed(ActionEvent e) {
//                    if (
//                        JOptionPane.showConfirmDialog(
//                            null,
//                            "This will stop all of the \"Generator\" receivers used in the Tutorial, but leave any other Receiver untouched.  Is that ok?",
//                            "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
//                        new Thread(
//                            () -> {
//                                LoggerRepository repo1 = LogManager.getLoggerRepository();
//                                if (repo1 instanceof LoggerRepositoryEx) {
//                                    PluginRegistry pluginRegistry = ((LoggerRepositoryEx) repo1).getPluginRegistry();
//                                    List list = pluginRegistry.getPlugins(Generator.class);
//
//                                    for (Object aList : list) {
//                                        Plugin plugin = (Plugin) aList;
//                                        pluginRegistry.stopPlugin(plugin.getName());
//                                    }
//                                }
//                            }).start();
//                        setEnabled(false);
//                        startTutorial.putValue("TutorialStarted", Boolean.FALSE);
//                    }
//                }
//            };
//
//        stopTutorial.putValue(
//            Action.SHORT_DESCRIPTION,
//            "Removes all of the Tutorials Generator Receivers, leaving all other Receivers untouched");
//        startTutorial.putValue(
//            Action.SHORT_DESCRIPTION,
//            "Begins the Tutorial, starting up some Generator Receivers so you can see Chainsaw in action");
//        stopTutorial.setEnabled(false);
//
//        final SmallToggleButton startButton = new SmallToggleButton(startTutorial);
//        PropertyChangeListener pcl =
//            evt -> {
//                stopTutorial.setEnabled(
//                    startTutorial.getValue("TutorialStarted").equals(Boolean.TRUE));
//                startButton.setSelected(stopTutorial.isEnabled());
//            };
//
//        startTutorial.addPropertyChangeListener(pcl);
//        stopTutorial.addPropertyChangeListener(pcl);
//
//        pluginRegistry.addPluginListener(
//            new PluginListener() {
//                public void pluginStarted(PluginEvent e) {
//                }
//
//                public void pluginStopped(PluginEvent e) {
//                    List list = pluginRegistry.getPlugins(Generator.class);
//
//                    if (list.size() == 0) {
//                        startTutorial.putValue("TutorialStarted", Boolean.FALSE);
//                    }
//                }
//            });
//
//        final SmallButton stopButton = new SmallButton(stopTutorial);
//
//        final JToolBar tutorialToolbar = new JToolBar();
//        tutorialToolbar.setFloatable(false);
//        tutorialToolbar.add(startButton);
//        tutorialToolbar.add(stopButton);
//        container.add(tutorialToolbar, BorderLayout.NORTH);
//        tutorialArea.addHyperlinkListener(
//            e -> {
//                if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
//                    if (e.getDescription().equals("StartTutorial")) {
//                        startTutorial.actionPerformed(null);
//                    } else if (e.getDescription().equals("StopTutorial")) {
//                        stopTutorial.actionPerformed(null);
//                    } else {
//                        try {
//                            tutorialArea.setPage(e.getURL());
//                        } catch (IOException e1) {
//                            statusBar.setMessage("Failed to change URL for tutorial");
//                            logger.error(
//                                "Failed to change the URL for the Tutorial", e1);
//                        }
//                    }
//                }
//            });

        /**
         * loads the saved tab settings and if there are hidden tabs,
         * hide those tabs out of currently loaded tabs..
         */

        if (!getTabbedPane().tabSetting.isWelcome()) {
            displayPanel(ChainsawTabbedPane.WELCOME_TAB, false);
        }
        if (!getTabbedPane().tabSetting.isZeroconf()) {
            displayPanel(ChainsawTabbedPane.ZEROCONF, false);
        }
        tbms.stateChange();

    }

    /**
     * Display the log tree pane, using the last known divider location
     */
    private void showReceiverPanel() {
        mainReceiverSplitPane.setDividerSize(dividerSize);
        mainReceiverSplitPane.setDividerLocation(lastMainReceiverSplitLocation);
        receiversPanel.setVisible(true);
        mainReceiverSplitPane.repaint();
    }

    /**
     * Hide the log tree pane, holding the current divider location for later use
     */
    private void hideReceiverPanel() {
        //subtract one to make sizes match
        int currentSize = mainReceiverSplitPane.getWidth() - mainReceiverSplitPane.getDividerSize();
        if (mainReceiverSplitPane.getDividerLocation() > -1) {
            if (!(((mainReceiverSplitPane.getDividerLocation() + 1) == currentSize)
                || ((mainReceiverSplitPane.getDividerLocation() - 1) == 0))) {
                lastMainReceiverSplitLocation = ((double) mainReceiverSplitPane
                    .getDividerLocation() / currentSize);
            }
        }
        mainReceiverSplitPane.setDividerSize(0);
        receiversPanel.setVisible(false);
        mainReceiverSplitPane.repaint();
    }

    private void initPrefModelListeners() {
//        applicationPreferenceModel.addPropertyChangeListener(
//            "identifierExpression",
//            evt -> handler.setIdentifierExpression(evt.getNewValue().toString()));
//        handler.setIdentifierExpression(applicationPreferenceModel.getIdentifierExpression());


        applicationPreferenceModel.addPropertyChangeListener(
            "toolTipDisplayMillis",
            evt -> ToolTipManager.sharedInstance().setDismissDelay(
                (Integer) evt.getNewValue()));
        ToolTipManager.sharedInstance().setDismissDelay(
            applicationPreferenceModel.getToolTipDisplayMillis());

//        applicationPreferenceModel.addPropertyChangeListener(
//            "responsiveness",
//            evt -> {
//                int value = (Integer) evt.getNewValue();
//                handler.setQueueInterval((value * 1000) - 750);
//            });
//        handler.setQueueInterval((applicationPreferenceModel.getResponsiveness() * 1000) - 750);

        applicationPreferenceModel.addPropertyChangeListener(
            "tabPlacement",
            evt -> SwingUtilities.invokeLater(
                () -> {
                    int placement = (Integer) evt.getNewValue();

                    switch (placement) {
                        case SwingConstants.TOP:
                        case SwingConstants.BOTTOM:
                            tabbedPane.setTabPlacement(placement);

                            break;

                        default:
                            break;
                    }
                }));

        applicationPreferenceModel.addPropertyChangeListener(
            "statusBar",
            evt -> {
                boolean value = (Boolean) evt.getNewValue();
                setStatusBarVisible(value);
            });
        setStatusBarVisible(applicationPreferenceModel.isStatusBar());

        applicationPreferenceModel.addPropertyChangeListener(
            "receivers",
            evt -> {
                boolean value = (Boolean) evt.getNewValue();

                if (value) {
                    showReceiverPanel();
                } else {
                    hideReceiverPanel();
                }
            });
//    if (applicationPreferenceModel.isReceivers()) {
//      showReceiverPanel();
//    } else {
//      hideReceiverPanel();
//    }


        applicationPreferenceModel.addPropertyChangeListener(
            "toolbar",
            evt -> {
                boolean value = (Boolean) evt.getNewValue();
                toolbar.setVisible(value);
            });
        toolbar.setVisible(applicationPreferenceModel.isToolbar());

    }

    /**
     * Displays a dialog which will provide options for selecting a configuration
     */
    private void showReceiverConfigurationPanel() {
//        SwingUtilities.invokeLater(
//            () -> {
//                final JDialog dialog = new JDialog(LogUI.this, true);
//                dialog.setTitle("Load events into Chainsaw");
//                dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
//
//                dialog.setResizable(false);
//
//                receiverConfigurationPanel.setCompletionActionListener(
//                    e -> {
//                        dialog.setVisible(false);
//
//                        if (receiverConfigurationPanel.getModel().isCancelled()) {
//                            return;
//                        }
//                        applicationPreferenceModel.setShowNoReceiverWarning(!receiverConfigurationPanel.isDontWarnMeAgain());
//                        //remove existing plugins
//                        List<Plugin> plugins = pluginRegistry.getPlugins();
//                        for (Object plugin1 : plugins) {
//                            Plugin plugin = (Plugin) plugin1;
//                            //don't stop ZeroConfPlugin if it is registered
//                            if (!plugin.getName().toLowerCase(Locale.ENGLISH).contains("zeroconf")) {
//                                pluginRegistry.stopPlugin(plugin.getName());
//                            }
//                        }
//                        URL configURL = null;
//
//                        if (receiverConfigurationPanel.getModel().isNetworkReceiverMode()) {
//                            int port = receiverConfigurationPanel.getModel().getNetworkReceiverPort();
//
//                            try {
//                                Class<? extends Receiver> receiverClass = receiverConfigurationPanel.getModel().getNetworkReceiverClass();
//                                Receiver networkReceiver = receiverClass.newInstance();
//                                networkReceiver.setName(receiverClass.getSimpleName() + "-" + port);
//
//                                Method portMethod =
//                                    networkReceiver.getClass().getMethod(
//                                        "setPort", int.class);
//                                portMethod.invoke(
//                                    networkReceiver, port);
//
//                                networkReceiver.setThreshold(Level.TRACE);
//
//                                pluginRegistry.addPlugin(networkReceiver);
//                                networkReceiver.activateOptions();
//                                receiversPanel.updateReceiverTreeInDispatchThread();
//                            } catch (Exception e3) {
//                                logger.error(
//                                    "Error creating Receiver", e3);
//                                statusBar.setMessage(
//                                    "An error occurred creating your Receiver");
//                            }
//                        } else if (receiverConfigurationPanel.getModel().isLog4jConfig()) {
//                            File log4jConfigFile = receiverConfigurationPanel.getModel().getLog4jConfigFile();
//                            if (log4jConfigFile != null) {
//                                try {
//                                    Map<String, Map<String, String>> entries = LogFilePatternLayoutBuilder.getAppenderConfiguration(log4jConfigFile);
//                                    for (Object o : entries.entrySet()) {
//                                        try {
//                                            Map.Entry entry = (Map.Entry) o;
//                                            String name = (String) entry.getKey();
//                                            Map values = (Map) entry.getValue();
//                                            //values: conversion, file
//                                            String conversionPattern = values.get("conversion").toString();
//                                            File file = new File(values.get("file").toString());
//                                            URL fileURL = file.toURI().toURL();
//                                            String timestampFormat = LogFilePatternLayoutBuilder.getTimeStampFormat(conversionPattern);
//                                            String receiverPattern = LogFilePatternLayoutBuilder.getLogFormatFromPatternLayout(conversionPattern);
//                                            VFSLogFilePatternReceiver fileReceiver = new VFSLogFilePatternReceiver();
//                                            fileReceiver.setName(name);
//                                            fileReceiver.setAutoReconnect(true);
//                                            fileReceiver.setContainer(LogUI.this);
//                                            fileReceiver.setAppendNonMatches(true);
//                                            fileReceiver.setFileURL(fileURL.toURI().toString());
//                                            fileReceiver.setTailing(true);
//                                            fileReceiver.setLogFormat(receiverPattern);
//                                            fileReceiver.setTimestampFormat(timestampFormat);
////                                            fileReceiver.setThreshold(Level.TRACE);
////                                            pluginRegistry.addPlugin(fileReceiver);
//                                            fileReceiver.activateOptions();
//                                            receiversPanel.updateReceiverTreeInDispatchThread();
//                                        } catch (URISyntaxException e1) {
//                                            e1.printStackTrace();
//                                        }
//                                    }
//                                } catch (IOException e1) {
//                                    e1.printStackTrace();
//                                }
//                            }
//                        } else if (receiverConfigurationPanel.getModel().isLoadConfig()) {
//                            configURL = receiverConfigurationPanel.getModel().getConfigToLoad();
//                        } else if (receiverConfigurationPanel.getModel().isLogFileReceiverConfig()) {
//                            try {
//                                URL fileURL = receiverConfigurationPanel.getModel().getLogFileURL();
//                                if (fileURL != null) {
//                                    VFSLogFilePatternReceiver fileReceiver = new VFSLogFilePatternReceiver();
//                                    fileReceiver.setName(fileURL.getFile());
//                                    fileReceiver.setAutoReconnect(true);
//                                    fileReceiver.setContainer(LogUI.this);
//                                    fileReceiver.setAppendNonMatches(true);
//                                    fileReceiver.setFileURL(fileURL.toURI().toString());
//                                    fileReceiver.setTailing(true);
//                                    if (receiverConfigurationPanel.getModel().isPatternLayoutLogFormat()) {
//                                        fileReceiver.setLogFormat(LogFilePatternLayoutBuilder.getLogFormatFromPatternLayout(receiverConfigurationPanel.getModel().getLogFormat()));
//                                    } else {
//                                        fileReceiver.setLogFormat(receiverConfigurationPanel.getModel().getLogFormat());
//                                    }
//                                    fileReceiver.setTimestampFormat(receiverConfigurationPanel.getModel().getLogFormatTimestampFormat());
////                                    fileReceiver.setThreshold(Level.TRACE);
////
////                                    pluginRegistry.addPlugin(fileReceiver);
//                                    fileReceiver.activateOptions();
//                                    receiversPanel.updateReceiverTreeInDispatchThread();
//                                }
//                            } catch (Exception e2) {
//                                logger.error(
//                                    "Error creating Receiver", e2);
//                                statusBar.setMessage(
//                                    "An error occurred creating your Receiver");
//                            }
//                        }
//                        if (configURL == null && receiverConfigurationPanel.isDontWarnMeAgain()) {
//                            //use the saved config file as the config URL if defined
//                            if (receiverConfigurationPanel.getModel().getSaveConfigFile() != null) {
//                                try {
//                                    configURL = receiverConfigurationPanel.getModel().getSaveConfigFile().toURI().toURL();
//                                } catch (MalformedURLException e1) {
//                                    e1.printStackTrace();
//                                }
//                            } else {
//                                //no saved config defined but don't warn me is checked - use default config
//                                configURL = receiverConfigurationPanel.getModel().getDefaultConfigFileURL();
//                            }
//                        }
//                        if (configURL != null) {
////                            MessageCenter.getInstance().getLogger().debug(
////                                "Initialiazing Log4j with " + configURL.toExternalForm());
//                            final URL finalURL = configURL;
//                            new Thread(
//                                () -> {
//                                    if (receiverConfigurationPanel.isDontWarnMeAgain()) {
//                                        applicationPreferenceModel.setConfigurationURL(finalURL.toExternalForm());
//                                    } else {
//                                        try {
//                                            if (new File(finalURL.toURI()).exists()) {
//                                                loadConfigurationUsingPluginClassLoader(finalURL);
//                                            }
//                                        } catch (URISyntaxException e12) {
//                                            //ignore
//                                        }
//                                    }
//
//                                    receiversPanel.updateReceiverTreeInDispatchThread();
//                                }).start();
//                        }
//                        File saveConfigFile = receiverConfigurationPanel.getModel().getSaveConfigFile();
//                        if (saveConfigFile != null) {
//                            saveReceiversToFile(saveConfigFile);
//                        }
//                    });
//
//                receiverConfigurationPanel.setDialog(dialog);
//                dialog.getContentPane().add(receiverConfigurationPanel);
//
//                dialog.pack();
//
//                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//                dialog.setLocation(
//                    (screenSize.width / 2) - (dialog.getWidth() / 2),
//                    (screenSize.height / 2) - (dialog.getHeight() / 2));
//
//                dialog.setVisible(true);
//            });
    }

    /**
     * Exits the application, ensuring Settings are saved.
     */
    public boolean exit() {
        getSettingsManager().saveSettings();

        return shutdown();
    }

    void addWelcomePanel() {
        getTabbedPane().insertTab(
            ChainsawTabbedPane.WELCOME_TAB, new ImageIcon(ChainsawIcons.ABOUT), welcomePanel,
            "Welcome/Help", 0);
        getTabbedPane().setSelectedComponent(welcomePanel);
        getPanelMap().put(ChainsawTabbedPane.WELCOME_TAB, welcomePanel);
    }

    void removeWelcomePanel() {
        EventQueue.invokeLater(() -> {
            if (getTabbedPane().containsWelcomePanel()) {
                getTabbedPane().remove(
                    getTabbedPane().getComponentAt(getTabbedPane().indexOfTab(ChainsawTabbedPane.WELCOME_TAB)));
            }
        });
    }

    ChainsawStatusBar getStatusBar() {
        return statusBar;
    }

    public void showApplicationPreferences() {
        applicationPreferenceModelPanel.updateModel();
        preferencesFrame.setVisible(true);
    }

    public void showReceiverConfiguration() {
        showReceiverConfigurationPanel();
    }

    public void showAboutBox() {
        if (aboutBox == null) {
            aboutBox = new ChainsawAbout(this);
        }

        aboutBox.setVisible(true);
    }

    Map getPanels() {
        Map m = new HashMap();
        Set<Map.Entry<String, Component>> panelSet = getPanelMap().entrySet();

        for (Object aPanelSet : panelSet) {
            Map.Entry entry = (Map.Entry) aPanelSet;
            Object o = entry.getValue();
            boolean valueToSend;
            valueToSend = !(o instanceof LogPanel) || ((DockablePanel) entry.getValue()).isDocked();
            m.put(entry.getKey(), valueToSend);
        }

        return m;
    }

    void displayPanel(String panelName, boolean display) {
        Component p = getPanelMap().get(panelName);

        int index = getTabbedPane().indexOfTab(panelName);

        if ((index == -1) && display) {
            getTabbedPane().addTab(panelName, p);
        }

        if ((index > -1) && !display) {
            getTabbedPane().removeTabAt(index);
        }
    }


    /**
     * Shutsdown by ensuring the Appender gets a chance to close.
     */
    public boolean shutdown() {
        if (getApplicationPreferenceModel().isConfirmExit()) {
            if (
                JOptionPane.showConfirmDialog(
                    LogUI.this, "Are you sure you want to exit Chainsaw?",
                    "Confirm Exit", JOptionPane.YES_NO_OPTION,
                    JOptionPane.INFORMATION_MESSAGE) != JOptionPane.YES_OPTION) {
                return false;
            }

        }

        final JWindow progressWindow = new JWindow();
        final ProgressPanel panel = new ProgressPanel(1, 3, "Shutting down");
        progressWindow.getContentPane().add(panel);
        progressWindow.pack();

        Point p = new Point(getLocation());
        p.move((int) getSize().getWidth() >> 1, (int) getSize().getHeight() >> 1);
        progressWindow.setLocation(p);
        progressWindow.setVisible(true);

        Runnable runnable =
            () -> {
                try {
                    int progress = 1;
                    final int delay = 25;

                    panel.setProgress(progress++);

                    Thread.sleep(delay);

                    for( ChainsawReceiver rx : m_receivers ){
                        rx.shutdown();
                    }
                    panel.setProgress(progress++);

                    Thread.sleep(delay);

                    panel.setProgress(progress++);
                    Thread.sleep(delay);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                fireShutdownEvent();
                performShutdownAction();
                progressWindow.setVisible(false);
            };

        if (OSXIntegration.IS_OSX) {
            /**
             * or OSX we do it in the current thread because otherwise returning
             * will exit the process before it's had a chance to save things
             *
             */
            runnable.run();
        } else {
            new Thread(runnable).start();
        }
        return true;
    }

    /**
     * Ensures all the registered ShutdownListeners are notified.
     */
    private void fireShutdownEvent() {
        ShutdownListener[] listeners =
            shutdownListenerList.getListeners(
                ShutdownListener.class);

        for (ShutdownListener listener : listeners) {
            listener.shuttingDown();
        }
    }

    /**
     * Configures LogUI's with an action to execute when the user requests to
     * exit the application, the default action is to exit the VM. This Action is
     * called AFTER all the ShutdownListeners have been notified
     *
     * @param shutdownAction
     */
    public final void setShutdownAction(Action shutdownAction) {
        this.shutdownAction = shutdownAction;
    }

    /**
     * Using the current thread, calls the registed Shutdown action's
     * actionPerformed(...) method.
     */
    private void performShutdownAction() {
        logger.debug(
            "Calling the shutdown Action. Goodbye!");

        shutdownAction.actionPerformed(
            new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "Shutting Down"));
    }

    /**
     * Returns the currently selected LogPanel, if there is one, otherwise null
     *
     * @return current log panel
     */
    LogPanel getCurrentLogPanel() {
        Component selectedTab = getTabbedPane().getSelectedComponent();

        if (selectedTab instanceof LogPanel) {
            return (LogPanel) selectedTab;
        }

        return null;
    }

    /**
     * @param visible
     */
    private void setStatusBarVisible(final boolean visible) {
        logger.debug(
            "Setting StatusBar to " + visible);
        SwingUtilities.invokeLater(
            () -> statusBar.setVisible(visible));
    }

    boolean isStatusBarVisible() {
        return statusBar.isVisible();
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getActiveTabName() {
        int index = getTabbedPane().getSelectedIndex();

        if (index == -1) {
            return null;
        } else {
            return getTabbedPane().getTitleAt(index);
        }
    }

    /**
     * Causes the Welcome Panel to become visible, and shows the URL specified as
     * it's contents
     *
     * @param url for content to show
     */
    public void showHelp(URL url) {
        ensureWelcomePanelVisible();
        //    TODO ensure the Welcome Panel is the selected tab
        getWelcomePanel().setURL(url);
    }

    /**
     * DOCUMENT ME!
     *
     * @return welcome panel
     */
    private WelcomePanel getWelcomePanel() {
        return welcomePanel;
    }

    /**
     * DOCUMENT ME!
     *
     * @return log tree panel visible flag
     */
    public boolean isLogTreePanelVisible() {
        return getCurrentLogPanel() != null && getCurrentLogPanel().isLogTreeVisible();

    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public Map<String, Component> getPanelMap() {
        return panelMap;
    }

    //  public Map getLevelMap() {
    //    return levelMap;
    //  }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public SettingsManager getSettingsManager() {
        return sm;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public List<String> getFilterableColumns() {
        return filterableColumns;
    }

    /**
     * DOCUMENT ME!
     *
     * @param tbms DOCUMENT ME!
     */
    public void setToolBarAndMenus(ChainsawToolBarAndMenus tbms) {
        this.tbms = tbms;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public ChainsawToolBarAndMenus getToolBarAndMenus() {
        return tbms;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public Map getTableMap() {
        return tableMap;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public Map getTableModelMap() {
        return tableModelMap;
    }

    /**
     * DOCUMENT ME!
     *
     * @param tabbedPane DOCUMENT ME!
     */
    public void setTabbedPane(ChainsawTabbedPane tabbedPane) {
        this.tabbedPane = tabbedPane;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public ChainsawTabbedPane getTabbedPane() {
        return tabbedPane;
    }

    /**
     * @return Returns the applicationPreferenceModel.
     */
    public final ApplicationPreferenceModel getApplicationPreferenceModel() {
        return applicationPreferenceModel;
    }

    /**
     * DOCUMENT ME!
     */
    public void setupTutorial() {
        SwingUtilities.invokeLater(
            () -> {
                Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
                setLocation(0, getLocation().y);

                double chainsawwidth = 0.7;
                double tutorialwidth = 1 - chainsawwidth;
                setSize((int) (screen.width * chainsawwidth), getSize().height);
                invalidate();
                validate();

                Dimension size = getSize();
                Point loc = getLocation();
                tutorialFrame.setSize(
                    (int) (screen.width * tutorialwidth), size.height);
                tutorialFrame.setLocation(loc.x + size.width, loc.y);
                tutorialFrame.setVisible(true);
            });
    }

    private void buildLogPanel(
        boolean customExpression, final String ident, final List<ChainsawLoggingEvent> events, final ChainsawReceiver rx)
        throws IllegalArgumentException {
        final LogPanel thisPanel = new LogPanel(getStatusBar(), ident, cyclicBufferSize, allColorizers, applicationPreferenceModel, statusBar);

        getSettingsManager().addSettingsListener(thisPanel);
        getSettingsManager().configure(thisPanel);

        if( !customExpression && rx != null ){
            thisPanel.setReceiver(rx);
        }

        /**
         * Now add the panel as a batch listener so it can handle it's own
         * batchs
         */
        if (customExpression) {
//            handler.addCustomEventBatchListener(ident, thisPanel);
        } else {
            identifierPanels.add(thisPanel);
//            handler.addEventBatchListener(thisPanel);
        }

        TabIconHandler iconHandler = new TabIconHandler(ident);
        thisPanel.addEventCountListener(iconHandler);


        tabbedPane.addChangeListener(iconHandler);

        PropertyChangeListener toolbarMenuUpdateListener =
            evt -> tbms.stateChange();

        thisPanel.addPropertyChangeListener(toolbarMenuUpdateListener);
        thisPanel.addPreferencePropertyChangeListener(toolbarMenuUpdateListener);

        thisPanel.addPropertyChangeListener(
            "docked",
            evt -> {
                LogPanel logPanel = (LogPanel) evt.getSource();

                if (logPanel.isDocked()) {
                    getPanelMap().put(logPanel.getIdentifier(), logPanel);
                    getTabbedPane().addANewTab(
                        logPanel.getIdentifier(), logPanel, null);
                    getTabbedPane().setSelectedTab(getTabbedPane().indexOfTab(logPanel.getIdentifier()));
                } else {
                    getTabbedPane().remove(logPanel);
                }
            });

        logger.debug("adding logpanel to tabbed pane: " + ident);

        //NOTE: tab addition is a very fragile process - if you modify this code,
        //verify the frames in the individual log panels initialize to their
        //correct sizes
        getTabbedPane().add(ident, thisPanel);
        getPanelMap().put(ident, thisPanel);

        /**
         * Let the new LogPanel receive this batch
         */

        SwingUtilities.invokeLater(
            () -> {
                getTabbedPane().addANewTab(
                    ident, thisPanel, new ImageIcon(ChainsawIcons.ANIM_RADIO_TOWER));
                thisPanel.layoutComponents();
//                thisPanel.receiveEventBatch(ident, events);
                if (!getTabbedPane().tabSetting.isChainsawLog()) {
                    displayPanel("chainsaw-log", false);
                }
            });

        String msg = "added tab " + ident;
        logger.debug(msg);
    }

    public void createCustomExpressionLogPanel(String ident) {
        //collect events matching the rule from all of the tabs
        try {
            List<ChainsawLoggingEvent> list = new ArrayList<>();
            Rule rule = ExpressionRule.getRule(ident);

            for (Object identifierPanel : identifierPanels) {
                LogPanel panel = (LogPanel) identifierPanel;

                for (Object o : panel.getMatchingEvents(rule)) {
                    LoggingEventWrapper e = (LoggingEventWrapper) o;
                    list.add(e.getLoggingEvent());
                }
            }

            buildLogPanel(true, ident, list, null);
        } catch (IllegalArgumentException iae) {
            statusBar.setMessage(
                "Unable to add tab using expression: " + ident + ", reason: "
                    + iae.getMessage());
        }
    }

    /**
     * Loads the log4j configuration file specified by the url, using
     * the PluginClassLoader instance as a TCCL, but only replacing it temporarily, with the original
     * TCCL being restored in a finally block to ensure consitency.
     *
     * @param url
     */
    private void loadConfigurationUsingPluginClassLoader(final URL url) {
        ClassLoader classLoader = PluginClassLoaderFactory.getInstance().getClassLoader();
        ClassLoader previousTCCL = Thread.currentThread().getContextClassLoader();

        if (url != null) {
            try {
                // we temporarily swap the TCCL so that plugins can find resources
                Thread.currentThread().setContextClassLoader(classLoader);
                try {
                    DOMConfigurator.configure(url);
                } catch (Exception e) {
                    logger.warn("Unable to load configuration URL: " + url, e);
                }
            } finally {
                // now switch it back...
                Thread.currentThread().setContextClassLoader(previousTCCL);
            }
        }
    }

    private static void loadLookAndFeelUsingPluginClassLoader(String lookAndFeelClassName) {
        ClassLoader classLoader = PluginClassLoaderFactory.getInstance().getClassLoader();
        ClassLoader previousTCCL = Thread.currentThread().getContextClassLoader();
        try {
            // we temporarily swap the TCCL so that plugins can find resources
            Thread.currentThread().setContextClassLoader(classLoader);
            UIManager.setLookAndFeel(lookAndFeelClassName);
            UIManager.getLookAndFeelDefaults().put("ClassLoader", classLoader);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // now switch it back...
            Thread.currentThread().setContextClassLoader(previousTCCL);
        }
    }

    private class TabIconHandler implements EventCountListener, ChangeListener {
        //the tabIconHandler is associated with a new tab, and a new tab always
        //shows the 'new events' icon
        private boolean newEvents = true;
        private boolean seenEvents = false;
        private final String ident;
        ImageIcon NEW_EVENTS = new ImageIcon(ChainsawIcons.ANIM_RADIO_TOWER);
        ImageIcon HAS_EVENTS = new ImageIcon(ChainsawIcons.INFO);
        Icon SELECTED = LineIconFactory.createBlankIcon();

        public TabIconHandler(String identifier) {
            ident = identifier;

            new Thread(
                () -> {
                    while (true) {
                        //if this tab is active, remove the icon
                        //don't process undocked tabs
                        if (getTabbedPane().indexOfTab(ident) > -1 &&
                            getTabbedPane().getSelectedIndex() == getTabbedPane()
                                .indexOfTab(ident)) {
                            getTabbedPane().setIconAt(
                                getTabbedPane().indexOfTab(ident), SELECTED);
                            newEvents = false;
                            seenEvents = true;
                        } else if (getTabbedPane().indexOfTab(ident) > -1) {
                            if (newEvents) {
                                getTabbedPane().setIconAt(
                                    getTabbedPane().indexOfTab(ident), NEW_EVENTS);
                                newEvents = false;
                                seenEvents = false;
                            } else if (!seenEvents) {
                                getTabbedPane().setIconAt(
                                    getTabbedPane().indexOfTab(ident), HAS_EVENTS);
                            }
                        }

                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException ie) {
                        }
                    }
                }).start();
        }

        /**
         * DOCUMENT ME!
         *
         * @param currentCount DOCUMENT ME!
         * @param totalCount   DOCUMENT ME!
         */
        public void eventCountChanged(int currentCount, int totalCount) {
            newEvents = true;
        }

        public void stateChanged(ChangeEvent event) {
            if (
                getTabbedPane().indexOfTab(ident) > -1 && getTabbedPane().indexOfTab(ident) == getTabbedPane().getSelectedIndex()) {
                getTabbedPane().setIconAt(getTabbedPane().indexOfTab(ident), SELECTED);
            }
        }
    }
    
    public void addReceiver(ChainsawReceiver rx){
        m_receivers.add(rx);
        List<ChainsawLoggingEvent> list = new ArrayList<>();
        buildLogPanel(false, rx.getName(), list, rx);
        
        for(ReceiverEventListener listen : m_receiverListeners){
            listen.receiverAdded(rx);
        }
    }
    
    public void removeReceiver(ChainsawReceiver rx){
        if( !m_receivers.remove(rx) ){
            return;
        }
        
        for(ReceiverEventListener listen : m_receiverListeners){
            listen.receiverRemoved(rx);
        }
    }
    
    public void addReceiverEventListener(ReceiverEventListener listener){
        m_receiverListeners.add(listener);
    }
    
    public void removeReceiverEventListener(ReceiverEventListener listener){
        m_receiverListeners.remove(listener);
    }
    
    public List<ChainsawReceiver> getAllReceivers(){
        return m_receivers;
    }

    public void saveReceiversToFile(File file){
        try {
            //we programmatically register the ZeroConf plugin in the plugin registry
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.newDocument();
            Element rootElement = document.createElementNS("http://jakarta.apache.org/log4j/", "configuration");
            rootElement.setPrefix("log4j");
            rootElement.setAttribute("xmlns:log4j", "http://jakarta.apache.org/log4j/");
            rootElement.setAttribute("debug", "true");

            for (ChainsawReceiver receiver : m_receivers) {
                Element pluginElement = document.createElement("plugin");
                pluginElement.setAttribute("name", receiver.getName());
                pluginElement.setAttribute("class", receiver.getClass().getName());

                BeanInfo beanInfo = Introspector.getBeanInfo(receiver.getClass());
                List<PropertyDescriptor> list = new ArrayList<>(Arrays.asList(beanInfo.getPropertyDescriptors()));

                for (PropertyDescriptor desc : list) {
                    Object o = desc.getReadMethod().invoke(receiver);
                    if (o != null) {
                        Element paramElement = document.createElement("param");
                        paramElement.setAttribute("name", desc.getName());
                        paramElement.setAttribute("value", o.toString());
                        pluginElement.appendChild(paramElement);
                    }
                }

                rootElement.appendChild(pluginElement);

            }

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            DOMSource source = new DOMSource(rootElement);
            FileOutputStream stream = new FileOutputStream(file);
            StreamResult result = new StreamResult(stream);
            transformer.transform(source, result);
            stream.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
