/*
 * Copyright 1999,2004 The Apache Software Foundation.
 *
 * Licensed 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.Event;
import java.awt.Frame;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.JWindow;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
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.messages.MessageCenter;
import org.apache.log4j.chainsaw.plugins.PluginClassLoaderFactory;
import org.apache.log4j.chainsaw.prefs.LoadSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SettingsListener;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
import org.apache.log4j.chainsaw.receivers.ReceiversPanel;
import org.apache.log4j.chainsaw.version.VersionManager;
import org.apache.log4j.helpers.Constants;
import org.apache.log4j.joran.JoranConfigurator;
import org.apache.log4j.net.SocketNodeEventListener;
import org.apache.log4j.plugins.Plugin;
import org.apache.log4j.plugins.PluginEvent;
import org.apache.log4j.plugins.PluginListener;
import org.apache.log4j.plugins.PluginRegistry;
import org.apache.log4j.plugins.Receiver;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.Decoder;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.xml.XMLDecoder;


/**
 * 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.
 * 
 * NOTE: Some of Chainsaw's application initialization should be performed prior 
 * to activating receivers and the logging framework used to perform self-logging.  
 * 
 * DELAY as much as possible the logging framework initialization process,
 * currently initialized by the creation of a ChainsawAppenderHandler.
 * 
 * @author Scott Deboy <sdeboy@apache.org>
 * @author Paul Smith  <psmith@apache.org>
 *
 */
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 = .8d;
  private final JFrame preferencesFrame = new JFrame();
  private boolean noReceiversDefined;
  private ReceiversPanel receiversPanel;
  private ChainsawTabbedPane tabbedPane;
  private JToolBar toolbar;
  private ChainsawStatusBar statusBar;
  private final ApplicationPreferenceModel applicationPreferenceModel =
    new ApplicationPreferenceModel();
  private ApplicationPreferenceModelPanel applicationPreferenceModelPanel;
  private final Map tableModelMap = new HashMap();
  private final Map tableMap = new HashMap();
  private final List filterableColumns = new ArrayList();
  private final Map panelMap = new HashMap();
  ChainsawAppenderHandler handler;
  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 identifierPanels = new ArrayList();
  private int dividerSize;
  private int cyclicBufferSize;
  private static Logger logger;

  /**
   * 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 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;
  private PluginRegistry pluginRegistry;

  /**
   * Constructor which builds up all the visual elements of the frame including
   * the Menu bar
   */
  public LogUI() {
    super("Chainsaw v2 - Log Viewer");
    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) {
    ApplicationPreferenceModel model = new ApplicationPreferenceModel();

    SettingsManager.getInstance().configure(model);

    applyLookAndFeel(model.getLookAndFeelClassName());

    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()) {
			MessageCenter
					.getInstance()
					.addMessage(
							"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);
				}
			});
    }
    
    LogUI logUI = new LogUI();

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

    logUI.handler = new ChainsawAppenderHandler();
    logUI.handler.addEventBatchListener(logUI.new NewTabEventBatchReceiver());
    /**
     * 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
    logUI.ensureChainsawAppenderHandlerAdded();
    logger = LogManager.getLogger(LogUI.class);
    logger.getLoggerRepository().setProperty(Constants.APPLICATION_KEY,"log");
    logger.getLoggerRepository().setProperty(Constants.HOSTNAME_KEY,"chainsaw");
    
    String config = model.getConfigurationURL();
    if(config!=null && (!(config.trim().equals("")))) {
        config = config.trim();
        try {
          URL configURL = new URL(config);
          logUI.loadConfigurationUsingPluginClassLoader(configURL);
        }catch(MalformedURLException e) {
            logger.error("Failed to convert config string to url", e);
        }
    }

    if (config == null) {
      logger.info("No auto-configuration file found within the ApplicationPreferenceModel");
    } else {
      logger.info("Using '" + config + "' for auto-configuration");
    }
    LogManager.getRootLogger().setLevel(Level.TRACE);

    logUI.activateViewer();

    logUI.getApplicationPreferenceModel().apply(model);

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

    logUI.checkForNewerVersion();
    
    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 Chainsaw is launched as an appender, ensure the root logger level is TRACE
    LogManager.getRootLogger().setLevel(Level.TRACE);
    ApplicationPreferenceModel model = new ApplicationPreferenceModel();
    SettingsManager.getInstance().configure(model);

    cyclicBufferSize = model.getCyclicBufferSize();
    applyLookAndFeel(model.getLookAndFeelClassName());

    handler = new ChainsawAppenderHandler(appender);
    handler.addEventBatchListener(new NewTabEventBatchReceiver());
    
    logger = LogManager.getLogger(LogUI.class);

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

    getApplicationPreferenceModel().apply(model);
  }

  /**
   * Initialises the menu's and toolbars, but does not actually create any of
   * the main panel components.
   *
   */
  private void initGUI() {
    setupHelpSystem();
    statusBar = new ChainsawStatusBar();
    setupReceiverPanel();

    setToolBarAndMenus(new ChainsawToolBarAndMenus(this));
    toolbar = getToolBarAndMenus().getToolbar();
    setJMenuBar(getToolBarAndMenus().getMenubar());
    
    setTabbedPane(new ChainsawTabbedPane());
    
    /**
     * This adds Drag & Drop capability to Chainsaw
     */
    FileDnDTarget dnDTarget = new FileDnDTarget(tabbedPane);
    dnDTarget.addPropertyChangeListener("fileList", new PropertyChangeListener() {

        public void propertyChange(PropertyChangeEvent evt) {
            final List fileList = (List) evt.getNewValue();
            
            Thread thread = new Thread(new Runnable() {

                public void run() {
                    logger.debug("Loading files: " + fileList);
                    for (Iterator iter = fileList.iterator(); iter.hasNext();) {
                        File  file = (File) iter.next();
                        final Decoder decoder = new XMLDecoder();
                        try {
                            getStatusBar().setMessage("Loading " + file.getAbsolutePath() + "...");
                            FileLoadAction.importURL(handler, decoder, file
                                    .getName(), file.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();
            
        }});
   
    JLabel lbl  = new JLabel();
    lbl.setEnabled(false);
    String dndTitle = "Drag & Drop XML log files here";
    getTabbedPane().addANewTab(dndTitle,lbl,null, "You can Drag & Drop XML log files onto the Tabbed Pane and they will be loaded into Chainsaw" );
    getTabbedPane().setEnabledAt(getTabbedPane().indexOfTab(dndTitle), false);
    ensureWelcomePanelVisible();
    
    applicationPreferenceModelPanel = new ApplicationPreferenceModelPanel(applicationPreferenceModel);
    applicationPreferenceModelPanel.setOkCancelActionListener(
      new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          preferencesFrame.setVisible(false);
        }
      });
  }

  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);
          }
        }

        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();
    
//    TODO this should also be fixed up, as VFS bits and pieces might not be built in an Ant build when they don't have all the VFS jars local
    try {
      Class vfsPluginClass = Class.forName("org.apache.log4j.chainsaw.vfs.VFSPlugin");
      Plugin vfsPlugin = (Plugin) vfsPluginClass.newInstance();
      vfsPlugin.activateOptions();
      pluginRegistry.addPlugin(vfsPlugin);
      MessageCenter.getInstance().getLogger().info("Looks like VFS is available... WooHoo!");
    } catch (Throwable e) {
      MessageCenter.getInstance().getLogger().error("Doesn't look like VFS is available", e);
    }
  }

  private void setupReceiverPanel() {
    receiversPanel = new ReceiversPanel();
    receiversPanel.addPropertyChangeListener(
      "visible",
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
          MessageCenter.getInstance().getLogger().debug(
            "Receiver's panel:" + evt.getNewValue());
          getApplicationPreferenceModel().setReceivers(
            ((Boolean) evt.getNewValue()).booleanValue());
        }
      });
  }

  /**
   * 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.EXAMLE_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",
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent 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();
      }
      if(getTabbedPane().getSelectedComponent()!=welcomePanel) {
          getTabbedPane().setSelectedIndex(getTabbedPane().indexOfComponent(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));
    setSize(
      event.asInt(LogUI.MAIN_WINDOW_WIDTH),
      event.asInt(LogUI.MAIN_WINDOW_HEIGHT));

    getToolBarAndMenus().stateChange();
  }

  /**
   * 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());

  }

  /**
   * 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() {
    this.pluginRegistry = LogManager.getLoggerRepository().getPluginRegistry();  
    initGUI();

    initPrefModelListeners();

    /**
     * We add a simple appender to the MessageCenter logger
     * so that each message is displayed in the Status bar
     */
    MessageCenter.getInstance().getLogger().addAppender(
      new AppenderSkeleton() {
        protected void append(LoggingEvent event) {
          getStatusBar().setMessage(event.getMessage().toString());
        }

        public void close() {
        }

        public boolean requiresLayout() {
          return false;
        }
      });



    initSocketConnectionListener();

    if (pluginRegistry.getPlugins(Receiver.class).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());

    KeyStroke ksRight =
      KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, Event.CTRL_MASK);
    KeyStroke ksLeft =
      KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, Event.CTRL_MASK);

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

    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);
          }
        }
      };

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

    /**
         * 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();
    initPlugins(pluginRegistry);

    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(640, 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) {
          displayPanel(getCurrentLogPanel().getIdentifier(), false);
          tbms.stateChange();
        }
      };

    final Action hideOtherTabsAction =
      new AbstractAction("Hide Others") {
        public void actionPerformed(ActionEvent e) {
          String currentName = getCurrentLogPanel().getIdentifier();

          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 (Iterator iter = getPanels().entrySet().iterator();
              iter.hasNext();) {
          	Map.Entry entry = (Map.Entry)iter.next();
          	Boolean docked = (Boolean)entry.getValue();
          	if (docked.booleanValue()) {
	            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);

    final ChangeListener actionEnabler =
      new ChangeListener() {
        public void stateChanged(ChangeEvent arg0) {
          boolean enabled = getCurrentLogPanel() != null;
          hideCurrentTabAction.setEnabled(enabled);
          hideOtherTabsAction.setEnabled(enabled);
        }
      };

    getTabbedPane().addChangeListener(actionEnabler);

    getTabbedPane().addContainerListener(
      new ContainerListener() {
        public void componentAdded(ContainerEvent arg0) {
          actionEnabler.stateChanged(null);
        }

        public void componentRemoved(ContainerEvent arg0) {
          actionEnabler.stateChanged(null);
        }
      });

    this.handler.addPropertyChangeListener(
      "dataRate",
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
          double dataRate = ((Double) evt.getNewValue()).doubleValue();
          statusBar.setDataRate(dataRate);
        }
      });

    getSettingsManager().addSettingsListener(this);
    getSettingsManager().addSettingsListener(applicationPreferenceModel);
    getSettingsManager().loadSettings();

    setVisible(true);

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

    removeSplash();

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

    
    
    if (
      noReceiversDefined
        && applicationPreferenceModel.isShowNoReceiverWarning()) {
      showNoReceiversWarningPanel();
    }

    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);
      container.add(new JScrollPane(tutorialArea), BorderLayout.CENTER);
    } catch (Exception e) {
      MessageCenter.getInstance().getLogger().error(
        "Error occurred loading the Tutorial", e);
    }

    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(
              new Runnable() {
                public void run() {
                  PluginRegistry pluginRegistry = LogManager.getLoggerRepository().getPluginRegistry();
                  List list = pluginRegistry.getPlugins(Generator.class);

                  for (Iterator iter = list.iterator(); iter.hasNext();) {
                    Plugin plugin = (Plugin) iter.next();
                    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 =
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
          stopTutorial.setEnabled(
            ((Boolean) 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(
      new HyperlinkListener() {
        public void hyperlinkUpdate(HyperlinkEvent 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) {
                MessageCenter.getInstance().getLogger().error(
                  "Failed to change the URL for the Tutorial", e1);
              }
            }
          }
        }
      });
  }

  /**
   * Checks the last run version number against this compiled version number and prompts the user
   * to view the release notes if the 2 strings are different.
   */
  private void checkForNewerVersion()
  {
      /**
       * Now check if the version they last used (if any) is
       * different than the version that is currently running
       */
      
      String lastUsedVersion = getApplicationPreferenceModel().getLastUsedVersion();
      String currentVersionNumber = VersionManager.getInstance().getVersionNumber();
      if(lastUsedVersion==null || !lastUsedVersion.equals(currentVersionNumber)) {
          if(JOptionPane.showConfirmDialog(this, "This version looks like it is different than the version you last ran. (" + lastUsedVersion + " vs " + currentVersionNumber+")\n\nWould you like to view the Release Notes?", "Newer Version?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
              SwingUtilities.invokeLater(new Runnable() {
                  
                  public void run()
                  {
                      HelpManager.getInstance().setHelpURL(ChainsawConstants.RELEASE_NOTES_URL);
                      
                  }});
          }
      }
      // Lets set this new version as the current version so we don't get nagged all the time...
      getApplicationPreferenceModel().setLastUsedVersion(currentVersionNumber);
  }

/**
   * 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 initSocketConnectionListener() {
    final SocketNodeEventListener socketListener =
      new SocketNodeEventListener() {
        public void socketOpened(String remoteInfo) {
          statusBar.remoteConnectionReceived(remoteInfo);
        }

        public void socketClosedEvent(Exception e) {
          MessageCenter.getInstance().getLogger().info(
            "Connection lost! :: " + e.getMessage());
        }
      };

    PluginListener pluginListener =
      new PluginListener() {
        public void pluginStarted(PluginEvent e) {
          MessageCenter.getInstance().getLogger().info(
            e.getPlugin().getName() + " started!");

          Method method = getAddListenerMethod(e.getPlugin());

          if (method != null) {
            try {
              method.invoke(e.getPlugin(), new Object[] { socketListener });
            } catch (Exception ex) {
              MessageCenter.getInstance().getLogger().error(
                "Failed to add a SocketNodeEventListener", ex);
            }
          }
        }

        Method getRemoveListenerMethod(Plugin p) {
          try {
            return p.getClass().getMethod(
              "removeSocketNodeEventListener",
              new Class[] { SocketNodeEventListener.class });
          } catch (Exception e) {
            return null;
          }
        }

        Method getAddListenerMethod(Plugin p) {
          try {
            return p.getClass().getMethod(
              "addSocketNodeEventListener",
              new Class[] { SocketNodeEventListener.class });
          } catch (Exception e) {
            return null;
          }
        }

        public void pluginStopped(PluginEvent e) {
          Method method = getRemoveListenerMethod(e.getPlugin());

          if (method != null) {
            try {
              method.invoke(e.getPlugin(), new Object[] { socketListener });
            } catch (Exception ex) {
              MessageCenter.getInstance().getLogger().error(
                "Failed to remove SocketNodeEventListener", ex);
            }
          }

          MessageCenter.getInstance().getLogger().info(
            e.getPlugin().getName() + " stopped!");
        }
      };

    pluginRegistry.addPluginListener(pluginListener);
  }

  private void initPrefModelListeners() {
    applicationPreferenceModel.addPropertyChangeListener(
      "identifierExpression",
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
          handler.setIdentifierExpression(evt.getNewValue().toString());
        }
      });

    applicationPreferenceModel.addPropertyChangeListener(
      "toolTipDisplayMillis",
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
          ToolTipManager.sharedInstance().setDismissDelay(
            ((Integer) evt.getNewValue()).intValue());
        }
      });
    ToolTipManager.sharedInstance().setDismissDelay(
      applicationPreferenceModel.getToolTipDisplayMillis());

    applicationPreferenceModel.addPropertyChangeListener(
      "responsiveness",
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
          int value = ((Integer) evt.getNewValue()).intValue();
          handler.setQueueInterval((value * 1000) - 750);
        }
      });

    applicationPreferenceModel.addPropertyChangeListener(
      "tabPlacement",
      new PropertyChangeListener() {
        public void propertyChange(final PropertyChangeEvent evt) {
          SwingUtilities.invokeLater(
            new Runnable() {
              public void run() {
                int placement = ((Integer) evt.getNewValue()).intValue();

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

                  break;

                default:
                  break;
                }
              }
            });
        }
      });

    applicationPreferenceModel.addPropertyChangeListener(
      "statusBar",
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
          boolean value = ((Boolean) evt.getNewValue()).booleanValue();
          setStatusBarVisible(value);
        }
      });

    applicationPreferenceModel.addPropertyChangeListener(
      "receivers",
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
          boolean value = ((Boolean) evt.getNewValue()).booleanValue();

          if (value) {
            showReceiverPanel();
          } else {
            hideReceiverPanel();
          }
        }
      });

    applicationPreferenceModel.addPropertyChangeListener(
      "toolbar",
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
          boolean value = ((Boolean) evt.getNewValue()).booleanValue();
          toolbar.setVisible(value);
        }
      });
    toolbar.setVisible(applicationPreferenceModel.isToolbar());

    setStatusBarVisible(applicationPreferenceModel.isStatusBar());
  }

  /**
   * Displays a warning dialog about having no Receivers defined and allows the
   * user to choose some options for configuration
   */
  private void showNoReceiversWarningPanel() {
    final NoReceiversWarningPanel noReceiversWarningPanel =
      new NoReceiversWarningPanel();

    final SettingsListener sl =
      new SettingsListener() {
        public void loadSettings(LoadSettingsEvent event) {
          int size = event.asInt("SavedConfigs.Size");
          Object[] configs = new Object[size];

          for (int i = 0; i < size; i++) {
            configs[i] = event.getSetting("SavedConfigs." + i);
          }

          noReceiversWarningPanel.getModel().setRememberedConfigs(configs);
        }

        public void saveSettings(SaveSettingsEvent event) {
          Object[] configs =
            noReceiversWarningPanel.getModel().getRememberedConfigs();
          event.saveSetting("SavedConfigs.Size", configs.length);

          for (int i = 0; i < configs.length; i++) {
            event.saveSetting("SavedConfigs." + i, configs[i].toString());
          }
        }
      };

    /**
         * This listener sets up the NoReciversWarningPanel and loads saves the
         * configs/logfiles
         */
    getSettingsManager().addSettingsListener(sl);
    getSettingsManager().configure(sl);

    SwingUtilities.invokeLater(
      new Runnable() {
        public void run() {
          final JDialog dialog = new JDialog(LogUI.this, true);
          dialog.setTitle("Warning: You have no Receivers defined...");
          dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

          dialog.setResizable(false);

          noReceiversWarningPanel.setOkActionListener(
            new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                dialog.setVisible(false);
              }
            });

          dialog.getContentPane().add(noReceiversWarningPanel);

          dialog.pack();

          Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
          dialog.setLocation(
            (screenSize.width / 2) - (dialog.getWidth() / 2),
            (screenSize.height / 2) - (dialog.getHeight() / 2));
          dialog.show();

          dialog.dispose();

          applicationPreferenceModel.setShowNoReceiverWarning(
            !noReceiversWarningPanel.isDontWarnMeAgain());

          if (noReceiversWarningPanel.getModel().isManualMode()) {
            applicationPreferenceModel.setReceivers(true);
          } else if (noReceiversWarningPanel.getModel().isSimpleReceiverMode()) {
            int port = noReceiversWarningPanel.getModel().getSimplePort();
            Class receiverClass =
              noReceiversWarningPanel.getModel().getSimpleReceiverClass();

            try {
              Receiver simpleReceiver = (Receiver) receiverClass.newInstance();
              simpleReceiver.setName("Simple Receiver");

              Method portMethod =
                simpleReceiver.getClass().getMethod(
                  "setPort", new Class[] { int.class });
              portMethod.invoke(
                simpleReceiver, new Object[] { new Integer(port) });

              simpleReceiver.setThreshold(Level.TRACE);

              pluginRegistry.addPlugin(simpleReceiver);
              simpleReceiver.activateOptions();
              receiversPanel.updateReceiverTreeInDispatchThread();
            } catch (Exception e) {
              MessageCenter.getInstance().getLogger().error(
                "Error creating Receiver", e);
              MessageCenter.getInstance().getLogger().info(
                "An error occurred creating your Receiver");
            }
          } else if (noReceiversWarningPanel.getModel().isLoadConfig()) {
            final URL url =
              noReceiversWarningPanel.getModel().getConfigToLoad();

            if (url != null) {
              MessageCenter.getInstance().getLogger().debug(
                "Initialiazing Log4j with " + url.toExternalForm());

              new Thread(
                new Runnable() {
                  public void run() {
                    loadConfigurationUsingPluginClassLoader(url);

                    receiversPanel.updateReceiverTreeInDispatchThread();
                  }
                }).start();
            }
          }
        }
      });
  }

  /**
   * Exits the application, ensuring Settings are saved.
   *
   */
  void exit() {
    //    TODO Ask the user if they want to save the settings via a dialog.
    getSettingsManager().saveSettings();

    shutdown();
  }

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

  void removeWelcomePanel() {
    if (getTabbedPane().containsWelcomePanel()) {
      getTabbedPane().remove(
        getTabbedPane().getComponentAt(getTabbedPane().indexOfTab("Welcome")));
    }
  }

  ChainsawStatusBar getStatusBar() {
    return statusBar;
  }

  void showApplicationPreferences() {
    applicationPreferenceModelPanel.updateModel();
    preferencesFrame.show();
  }

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

    aboutBox.setVisible(true);
  }

  Map getPanels() {
    Map m = new HashMap();
    Set panelSet = getPanelMap().entrySet();
    Iterator iter = panelSet.iterator();

    while (iter.hasNext()) {
      Map.Entry entry = (Map.Entry) iter.next();
      m.put(
        entry.getKey(),
        new Boolean(((DockablePanel) entry.getValue()).isDocked()));
    }

    return m;
  }

  void displayPanel(String panelName, boolean display) {
    Object o = getPanelMap().get(panelName);

    if (o instanceof LogPanel) {
      LogPanel p = (LogPanel) o;

      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.
   */
  private void 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;
      }
    }

    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 =
      new Runnable() {
        public void run() {
          try {
            int progress = 1;
            final int delay = 25;

            handler.close();
            panel.setProgress(progress++);

            Thread.sleep(delay);

            pluginRegistry.stopAllPlugins();
            panel.setProgress(progress++);

            Thread.sleep(delay);

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

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

    new Thread(runnable).start();
  }

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

    for (int i = 0; i < listeners.length; i++) {
      listeners[i].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() {
    MessageCenter.getInstance().getLogger().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;
    } else {
      //      System.out.println(selectedTab);
    }

    return null;
  }

  /**
   * @param visible
   */
  private void setStatusBarVisible(final boolean visible) {
    MessageCenter.getInstance().getLogger().debug(
      "Setting StatusBar to " + visible);
    SwingUtilities.invokeLater(
      new Runnable() {
        public void run() {
          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);
    }
  }

  /**
   * Changes the currently used Look And Feel of the App
   *
   * @param lookAndFeelClassName
   *                    The FQN of the LookANdFeel
   */
  private static void applyLookAndFeel(String lookAndFeelClassName) {
    if (
      UIManager.getLookAndFeel().getClass().getName().equals(
          lookAndFeelClassName)) {
      return;
    }

    if (
      (lookAndFeelClassName == null) || lookAndFeelClassName.trim().equals("")) {
      lookAndFeelClassName = UIManager.getSystemLookAndFeelClassName();
    }

    try {
      UIManager.setLookAndFeel(lookAndFeelClassName);

    } catch (Exception e) {
    }
  }

  /**
   * 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() {
    if (getCurrentLogPanel() == null) {
      return false;
    }

    return getCurrentLogPanel().isLogTreeVisible();
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public Map 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 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(
      new Runnable() {
        public void run() {
          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 events)
      throws IllegalArgumentException {
      final LogPanel thisPanel = new LogPanel(getStatusBar(), ident, cyclicBufferSize);

      /**
               * 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 =
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent evt) {
            tbms.stateChange();
          }
        };

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

      thisPanel.addPropertyChangeListener(
        "docked",
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent 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);

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

      /**
               * Let the new LogPanel receive this batch
               */
      thisPanel.receiveEventBatch(ident, events);

      SwingUtilities.invokeLater(
        new Runnable() {
          public void run() {
            getTabbedPane().addANewTab(
              ident, thisPanel, new ImageIcon(ChainsawIcons.ANIM_RADIO_TOWER));
          }
        });

      String msg = "added tab " + ident;
      MessageCenter.getInstance().getLogger().debug(msg);
    }


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

      while (iter.hasNext()) {
        LogPanel panel = (LogPanel) iter.next();
        Iterator iter2 = panel.getMatchingEvents(rule).iterator();

        while (iter2.hasNext()) {
          LoggingEvent e = (LoggingEvent) iter2.next();
          list.add(e);
        }
      }

      buildLogPanel(true, ident, list);
    } catch (IllegalArgumentException iae) {
      MessageCenter.getInstance().getLogger().info(
        "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);
              JoranConfigurator jc = new JoranConfigurator();
              jc.doConfigure(url, LogManager.getLoggerRepository());
            }finally{
                // now switch it back...
                Thread.currentThread().setContextClassLoader(previousTCCL);
            }
        }
        ensureChainsawAppenderHandlerAdded();
    }

    /**
     * Makes sure that the LoggerRepository has the ChainsawAppenderHandler
     * added to the root logger so Chainsaw can receive all the events.  
     */
    private void ensureChainsawAppenderHandlerAdded() {
        if(!LogManager.getLoggerRepository().getRootLogger().isAttached(handler)) {
            LogManager.getLoggerRepository().getRootLogger().addAppender(handler);
        }
    }

/**
   * This class handles the recption of the Event batches and creates new
   * LogPanels if the identifier is not in use otherwise it ignores the event
   * batch.
   *
   * @author Paul Smith
   *                <psmith@apache.org>
   *
   */
  private class NewTabEventBatchReceiver implements EventBatchListener {
    /**
         * DOCUMENT ME!
         *
         * @param ident
         * @param events
         */
    public void receiveEventBatch(
      final String ident, final List events) {
      if (events.size() == 0) {
        return;
      }

      if (!isGUIFullyInitialized) {
        synchronized (initializationLock) {
          while (!isGUIFullyInitialized) {
            System.out.println(
              "Wanting to add a row, but GUI not initialized, waiting...");

            /**
                         * Lets wait 1 seconds and recheck.
                         */
            try {
              initializationLock.wait(1000);
              logger.debug("waiting for initialization to complete");
            } catch (InterruptedException e) {
            }
          }
          logger.debug("out of system initialization wait loop");
        }
      }

      if (!getPanelMap().containsKey(ident)) {
          logger.debug("panel " + ident + " does not exist - creating");
        try {
          buildLogPanel(false, ident, events);
        } catch (IllegalArgumentException iae) {
            logger.error("error creating log panel", iae);
          //should not happen - not a custom expression panel
        }
      }
    }

    /*
         * (non-Javadoc)
         *
         * @see org.apache.log4j.chainsaw.EventBatchListener#getInterestedIdentifier()
         */

    /**
         * DOCUMENT ME!
         *
         * @return DOCUMENT ME!
         */
    public String getInterestedIdentifier() {
      // we are interested in all batches so we can detect new identifiers
      return null;
    }
  }

  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(
        new Runnable() {
          public void run() {
            while (true) {
              //if this tab is active, remove the icon
              //don't process undocked tabs
              if (
                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(handler.getQueueInterval() + 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) == getTabbedPane().getSelectedIndex()) {
        getTabbedPane().setIconAt(getTabbedPane().indexOfTab(ident), SELECTED);
      }
    }
  }
}
