/*
 * 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.Cursor;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.chainsaw.icons.ChainsawIcons;
import org.apache.log4j.chainsaw.icons.LineIconFactory;
import org.apache.log4j.rule.AbstractRule;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.LoggingEvent;


/**
 * A panel that encapsulates the Logger Name tree, with associated actions
 * and implements the Rule interface so that it can filter in/out events
 * that do not match the users request for refining the view based on Loggers.
 *
 * @author Paul Smith <psmith@apache.org>
 */
final class LoggerNameTreePanel extends JPanel implements Rule
{
  //~ Static fields/initializers ==============================================

  private static final int WARN_DEPTH = 4;

  //~ Instance fields =========================================================

  private LoggerNameTreeCellRenderer cellRenderer =
    new LoggerNameTreeCellRenderer();
  private final Action clearIgnoreListAction;
  private final Action closeAction;
  private final JButton closeButton = new SmallButton();
  private final Action collapseAction;
  private final JButton collapseButton = new SmallButton();
  private final Action editLoggerAction;
  private final JButton editLoggerButton = new SmallButton();
  private final Action expandAction;
  private final JButton expandButton = new SmallButton();
  private final Action focusOnAction;
  private final SmallToggleButton focusOnLoggerButton =
    new SmallToggleButton();
  private final Set hiddenSet = new HashSet();
  private final Action hideAction;
  private final LogPanelPreferenceModel preferenceModel;

  private final JList ignoreList = new JList();
  private final JScrollPane ignoreListScroll = new JScrollPane(ignoreList);
  private final JDialog ignoreDialog = new JDialog();
  private final JLabel ignoreSummary = new JLabel("0 hidden loggers");
  private final SmallToggleButton ignoreLoggerButton = new SmallToggleButton();
  private final EventListenerList listenerList = new EventListenerList();
  private final JTree logTree;
  private final Logger logger = LogManager.getLogger(LoggerNameTreePanel.class);

  //  private final EventListenerList focusOnActionListeners =
  //    new EventListenerList();
  private final LogPanelLoggerTreeModel logTreeModel;
  private final PopupListener popupListener;
  private final LoggerTreePopupMenu popupMenu;
  private final Rule ruleDelegate;
  private Rule colorRuleDelegate; 
  private final JScrollPane scrollTree;
  private final JToolBar toolbar = new JToolBar();

  //~ Constructors ============================================================

  /**
   * Creates a new LoggerNameTreePanel object.
   *
   * @param logTreeModel
   */
  LoggerNameTreePanel(LogPanelLoggerTreeModel logTreeModel, LogPanelPreferenceModel preferenceModel)
  {
    super();
    this.logTreeModel = logTreeModel;
    this.preferenceModel = preferenceModel;

    setLayout(new BorderLayout());

    ruleDelegate = new AbstractRule() {
    	public boolean evaluate(LoggingEvent e)
        {
          String currentlySelectedLoggerName = getCurrentlySelectedLoggerName();
          if (currentlySelectedLoggerName == null) {
          	//if there is no selected logger, all events should pass
          	return true;
          }
          boolean isHidden = getHiddenSet().contains(e.getLoggerName());
          boolean result = (e.getLoggerName() != null) && (!isHidden);

          if (result && isFocusOnSelected())
          {
            result = result &&  (e.getLoggerName() != null && (e.getLoggerName().startsWith(currentlySelectedLoggerName+".") || e.getLoggerName().endsWith(currentlySelectedLoggerName))) ;
          }

          return result;
        }
      };
    
    colorRuleDelegate = 
        new AbstractRule()
        {
          public boolean evaluate(LoggingEvent e)
          {
            boolean isHidden = getHiddenSet().contains(e.getLoggerName());
            String currentlySelectedLoggerName = getCurrentlySelectedLoggerName();

            if (!isFocusOnSelected() && !isHidden && currentlySelectedLoggerName != null && !"".equals(currentlySelectedLoggerName))
            {
            	return (e.getLoggerName().startsWith(currentlySelectedLoggerName+".") || e.getLoggerName().endsWith(currentlySelectedLoggerName)) ;
            }
            return false;
          }
        };

    logTree =
    new JTree(logTreeModel)
      {
        public String getToolTipText(MouseEvent ev)
        {
          if (ev == null)
          {
            return null;
          }

          TreePath path = logTree.getPathForLocation(ev.getX(), ev.getY());

          String loggerName = getLoggerName(path);

          if (hiddenSet.contains(loggerName))
          {
            loggerName += " (you are ignoring this logger)";
          }

          return loggerName;
        }
      };

    ToolTipManager.sharedInstance().registerComponent(logTree);
    logTree.setCellRenderer(cellRenderer);

    //	============================================
    logTreeModel.addTreeModelListener(new TreeModelListener()
      {
        private boolean latched = false;

        public void treeNodesChanged(TreeModelEvent e)
        {
        }

        public void treeNodesInserted(TreeModelEvent e)
        {
          if (!latched)
          {
            ensureRootExpanded();
            latched = true;
          }
        }

        public void treeNodesRemoved(TreeModelEvent e)
        {
        }

        public void treeStructureChanged(TreeModelEvent e)
        {
        }
      });

    logTree.setEditable(false);

    //	TODO decide if Multi-selection is useful, and how it would work	
    TreeSelectionModel selectionModel = new DefaultTreeSelectionModel();
    selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    logTree.setSelectionModel(selectionModel);

    logTree.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
    scrollTree = new JScrollPane(logTree);
    toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS));

    expandAction = createExpandAction();
    editLoggerAction = createEditLoggerAction();
    closeAction = createCloseAction();
    collapseAction = createCollapseAction();
    focusOnAction = createFocusOnAction();
    hideAction = createIgnoreAction();
    clearIgnoreListAction = createClearIgnoreListAction();

    popupMenu = new LoggerTreePopupMenu();
    popupListener = new PopupListener(popupMenu);

    setupListeners();
    configureToolbarPanel();

    add(toolbar, BorderLayout.NORTH);
    add(scrollTree, BorderLayout.CENTER);

    ignoreDialog.setTitle("Hidden/Ignored Loggers");
    ignoreDialog.setModal(true);
    JPanel ignoreSummaryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    ignoreSummaryPanel.add(ignoreSummary);
    
    Action showIgnoreDialogAction = new AbstractAction("...") {

        public void actionPerformed(ActionEvent e)
        {
            ignoreDialog.setVisible(true);
        }};
    showIgnoreDialogAction.putValue(Action.SHORT_DESCRIPTION, "Click to view and manage your hidden/ignored loggers");
    JButton btnShowIgnoreDialog = new SmallButton(showIgnoreDialogAction);
    
    ignoreSummaryPanel.add(btnShowIgnoreDialog);
    add(ignoreSummaryPanel, BorderLayout.SOUTH);

    ignoreList.setModel(new DefaultListModel());
    ignoreList.addMouseListener(new MouseAdapter()
      {
        public void mouseClicked(MouseEvent e)
        {
          if (
            (e.getClickCount() > 1)
              && ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0))
          {
            int index = ignoreList.locationToIndex(e.getPoint());

            if (index >= 0)
            {
              String string =
                ignoreList.getModel().getElementAt(index).toString();
              toggleHiddenLogger(string);
              fireChangeEvent();

              /**
               * TODO this needs to get the node that has this logger and fire a visual update
               */
              LoggerNameTreePanel.this.logTreeModel.nodeStructureChanged(
                (TreeNode) LoggerNameTreePanel.this.logTreeModel.getRoot());
            }
          }
        }
      });
    
    JPanel ignoreListPanel = new JPanel(new BorderLayout());
    ignoreListScroll.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),"Double click an entry to unhide it"));
    ignoreListPanel.add(ignoreListScroll, BorderLayout.CENTER);
    
    Box ignoreListButtonPanel = Box.createHorizontalBox();
    
    JButton unhideAll = new JButton(new AbstractAction("Unhide All") {

        public void actionPerformed(final ActionEvent e)
        {
             SwingUtilities.invokeLater(new Runnable() {

                public void run()
                {
                    clearIgnoreListAction.actionPerformed(e);
                }}); 
            
        }});
    ignoreListButtonPanel.add(unhideAll);
    
    ignoreListButtonPanel.add(Box.createHorizontalGlue());
    JButton ignoreCloseButton = new JButton(new AbstractAction("Close") {

        public void actionPerformed(ActionEvent e)
        {
            ignoreDialog.setVisible(false);
            
        }});
    ignoreListButtonPanel.add(ignoreCloseButton);
    
    
    ignoreListPanel.add(ignoreListButtonPanel, BorderLayout.SOUTH);
    
    
    ignoreDialog.getContentPane().add(ignoreListPanel);
    ignoreDialog.pack();
  }

  //~ Methods =================================================================

  /**
   * Adds a change Listener to this LoggerNameTreePanel to be notfied
   * when the State of the Focus or Hidden details have changed.
   *
   * @param l
   */
  public void addChangeListener(ChangeListener l)
  {
    listenerList.add(ChangeListener.class, l);
  }

  /* (non-Javadoc)
   * @see org.apache.log4j.chainsaw.rule.Rule#evaluate(org.apache.log4j.spi.LoggingEvent)
   */
  /**
   * DOCUMENT ME!
   *
   * @param e DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public boolean evaluate(LoggingEvent e)
  {
    return ruleDelegate.evaluate(e);
  }
  
  public Rule getLoggerColorRule() {
  	return colorRuleDelegate;
  }

  /**
   * DOCUMENT ME!
   *
   * @param l DOCUMENT ME!
   */
  public void removeChangeListener(ChangeListener l)
  {
    listenerList.remove(ChangeListener.class, l);
  }

  /**
   * Ensures the Focus is set to a specific logger name
   * @param logger
   */
  public void setFocusOn(String newLogger)
  {
    DefaultMutableTreeNode node = logTreeModel.lookupLogger(newLogger);

    if (node != null)
    {
      TreeNode[] nodes = node.getPath();
      TreePath treePath = new TreePath(nodes);
      logTree.setSelectionPath(treePath);

      if (!focusOnLoggerButton.isSelected())
      {
        focusOnLoggerButton.doClick();
      }
    }
    else
    {
      logger.error("failed to lookup logger " + newLogger);
    }
  }

  /**
   * DOCUMENT ME!
   *
   * @param logger
   */
  protected void toggleHiddenLogger(String logger)
  {
    if (!hiddenSet.contains(logger))
    {
      hiddenSet.add(logger);
    }
    else
    {
      hiddenSet.remove(logger);
    }

    firePropertyChange("hiddenSet", (Object) null, (Object) null);
  }

  /**
   * Returns the full name of the Logger that is represented by
   * the currently selected Logger node in the tree.
   *
   * This is the dotted name, of the current node including all it's parents.
   *
   * If multiple Nodes are selected, the first path is used
   * @return Logger Name or null if nothing selected
   */
  String getCurrentlySelectedLoggerName()
  {
    TreePath[] paths = logTree.getSelectionPaths();

    if ((paths == null) || (paths.length == 0))
    {
      return null;
    }

    TreePath firstPath = paths[0];

    return getLoggerName(firstPath);
  }

  /**
   * Returns an unmodifiable set of those Loggers marked as hidden.
   * @return
   */
  Set getHiddenSet()
  {
    return Collections.unmodifiableSet(hiddenSet);
  }

  /**
   * Returns the full
   * @param path DOCUMENT ME!
   * @return
   */
  String getLoggerName(TreePath path)
  {
    if (path != null)
    {
      Object[] objects = path.getPath();
      StringBuffer buf = new StringBuffer();

      for (int i = 1; i < objects.length; i++)
      {
        buf.append(objects[i].toString());

        if (i < (objects.length - 1))
        {
          buf.append(".");
        }
      }

      return buf.toString();
    }

    return null;
  }

  /**
   * adds a Collection of Strings to the ignore List and notifise all listeners of
   * both the "hiddenSet" property and those expecting the Rule to change
   * via the ChangeListener interface 
   * @param fqnLoggersToIgnore
   */
  void ignore(Collection fqnLoggersToIgnore)
  {
    hiddenSet.addAll(fqnLoggersToIgnore);
    firePropertyChange("hiddenSet", null, null);
    fireChangeEvent();
  }

  /**
   * Returns true if the FocusOn element has been selected
   * @return true if the FocusOn action/lement has been selected
   */
  boolean isFocusOnSelected()
  {
    return focusOnAction.getValue("checked") != null;
  }

  void setFocusOnSelected(boolean selected)
  {
    if (selected)
    {
      focusOnAction.putValue("checked", Boolean.TRUE);
    }
    else
    {
      focusOnAction.putValue("checked", null);
    }
  }

  /**
   * Given the currently selected nodes
   * collapses all the children of those nodes.
   *
   */
  private void collapseCurrentlySelectedNode()
  {
    TreePath[] paths = logTree.getSelectionPaths();

    if (paths == null)
    {
      return;
    }

      logger.debug("Collapsing all children of selected node");

    for (int i = 0; i < paths.length; i++)
    {
      TreePath path = paths[i];
      DefaultMutableTreeNode node =
        (DefaultMutableTreeNode) path.getLastPathComponent();
      Enumeration enumeration = node.depthFirstEnumeration();

      while (enumeration.hasMoreElements())
      {
        DefaultMutableTreeNode child =
          (DefaultMutableTreeNode) enumeration.nextElement();

        if ((child.getParent() != null) && (child != node))
        {
          TreeNode[] nodes =
            ((DefaultMutableTreeNode) child.getParent()).getPath();

          TreePath treePath = new TreePath(nodes);
          logTree.collapsePath(treePath);
        }
      }
    }

    ensureRootExpanded();
  }

  /**
     * configures all the components that are used in the mini-toolbar of this
     * component
     */
  private void configureToolbarPanel()
  {
    toolbar.setFloatable(false);

    expandButton.setAction(expandAction);
    expandButton.setText(null);
    collapseButton.setAction(collapseAction);
    collapseButton.setText(null);
    focusOnLoggerButton.setAction(focusOnAction);
    focusOnLoggerButton.setText(null);
    ignoreLoggerButton.setAction(hideAction);
    ignoreLoggerButton.setText(null);

    expandButton.setFont(expandButton.getFont().deriveFont(Font.BOLD));
    collapseButton.setFont(collapseButton.getFont().deriveFont(Font.BOLD));

    editLoggerButton.setAction(editLoggerAction);
    editLoggerButton.setText(null);
    closeButton.setAction(closeAction);
    closeButton.setText(null);

    toolbar.add(expandButton);
    toolbar.add(collapseButton);
    toolbar.addSeparator();
    toolbar.add(focusOnLoggerButton);
    toolbar.add(ignoreLoggerButton);

    //    toolbar.add(editLoggerButton);
    toolbar.addSeparator();

    toolbar.add(Box.createHorizontalGlue());
    toolbar.add(closeButton);
    toolbar.add(Box.createHorizontalStrut(5));
  }

  /**
   * DOCUMENT ME!
   *
   * @return
  */
  private Action createClearIgnoreListAction()
  {
    Action action = new AbstractAction("Clear Ignore list", null)
      {
        public void actionPerformed(ActionEvent e)
        {
          ignoreLoggerButton.setSelected(false);
          logTreeModel.reload();
          hiddenSet.clear();
          fireChangeEvent();
        }
      };

    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Removes all entries from the Ignore list so you can see their events in the view");

    return action;
  }

  /**
     * An action that closes (hides) this panel
    * @return
    */
  private Action createCloseAction()
  {
    Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
            preferenceModel.setLogTreePanelVisible(false);
        }
      };

    action.putValue(Action.NAME, "Close");
    action.putValue(Action.SHORT_DESCRIPTION, "Closes the Logger panel");
    action.putValue(Action.SMALL_ICON, LineIconFactory.createCloseIcon());

    return action;
  }

  /**
   * DOCUMENT ME!
   *
   * @return
  */
  private Action createCollapseAction()
  {
    Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
          collapseCurrentlySelectedNode();
        }
      };

    action.putValue(Action.SMALL_ICON, LineIconFactory.createCollapseIcon());
    action.putValue(Action.NAME, "Collapse Branch");
    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Collapses all the children of the currently selected node");
    action.setEnabled(false);

    return action;
  }

  private Action createEditLoggerAction()
  {
    Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
          // TODO Auto-generated method stub
        }
      };

    //    TODO enable this when it's ready.
    action.putValue("enabled", Boolean.FALSE);

    action.putValue(Action.NAME, "Edit filters/colors");
    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Allows you to specify filters and coloring for this Logger");
    action.putValue(
      Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_EDIT_RECEIVER));
    action.setEnabled(false);

    return action;
  }

  /**
   * Creates an action that is used to expand the selected node
   * and all children
   * @return an Action
   */
  private Action createExpandAction()
  {
    Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
          expandCurrentlySelectedNode();
        }
      };

    action.putValue(Action.SMALL_ICON, LineIconFactory.createExpandIcon());
    action.putValue(Action.NAME, "Expand branch");
    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Expands all the child nodes of the currently selected node, recursively");
    action.setEnabled(false);

    return action;
  }

  /**
   * DOCUMENT ME!
   *
   * @return
  */
  private Action createFocusOnAction()
  {
    final Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
          toggleFocusOnState();
        }
      };

    action.putValue(Action.NAME, "Focus");
    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Allows you to Focus on the selected logger by setting a filter that discards all but this Logger");
    action.putValue(
      Action.SMALL_ICON, new ImageIcon(ChainsawIcons.WINDOW_ICON));

    action.setEnabled(false);

    return action;
  }

  /**
   * DOCUMENT ME!
   *
   * @return
    */
  private Action createIgnoreAction()
  {
    Action action =
      new AbstractAction(
        "Ignore this Logger", new ImageIcon(ChainsawIcons.ICON_COLLAPSE))
      {
        public void actionPerformed(ActionEvent e)
        {
          String logger = getCurrentlySelectedLoggerName();

          if (logger != null)
          {
            toggleHiddenLogger(logger);
            logTreeModel.nodeChanged(
              (TreeNode) logTree.getSelectionPath().getLastPathComponent());
            ignoreLoggerButton.setSelected(hiddenSet.contains(logger));
            focusOnAction.setEnabled(!hiddenSet.contains(logger));
            popupMenu.hideCheck.setSelected(hiddenSet.contains(logger));
          }

          fireChangeEvent();
        }
      };

    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Adds the selected Logger to your Ignore list, filtering those events from view");

    return action;
  }

  private void ensureRootExpanded()
  {
      logger.debug("Ensuring Root node is expanded.");

    final DefaultMutableTreeNode root =
      (DefaultMutableTreeNode) logTreeModel.getRoot();
    SwingUtilities.invokeLater(new Runnable()
      {
        public void run()
        {
          logTree.expandPath(new TreePath(root));
        }
      });
  }

  /**
   * Expands the currently selected node (if any)
   * including all the children.
   *
   */
  private void expandCurrentlySelectedNode()
  {
    TreePath[] paths = logTree.getSelectionPaths();

    if (paths == null)
    {
      return;
    }

      logger.debug("Expanding all children of selected node");

    for (int i = 0; i < paths.length; i++)
    {
      TreePath path = paths[i];

      /**
       * TODO this is commented out, right now it expands all nodes including the root, so if there is a large tree..... look out.
       */

      //      /**
      //       * Handle an expansion of the Root node by only doing the first level.
      //       * Safe...
      //       */
      //      if (path.getPathCount() == 1) {
      //        logTree.expandPath(path);
      //
      //        return;
      //      }

      DefaultMutableTreeNode treeNode =
        (DefaultMutableTreeNode) path.getLastPathComponent();

      Enumeration depthEnum = treeNode.depthFirstEnumeration();

      if (!depthEnum.hasMoreElements())
      {
        break;
      }

      List depths = new ArrayList();

      while (depthEnum.hasMoreElements())
      {
        depths.add(
          new Integer(
            ((DefaultMutableTreeNode) depthEnum.nextElement()).getDepth()));
      }

      Collections.sort(depths);
      Collections.reverse(depths);

      int maxDepth = ((Integer) depths.get(0)).intValue();

      if (maxDepth > WARN_DEPTH)
      {
        logger.warn("Should warn user, depth=" + maxDepth);
      }

      depthEnum = treeNode.depthFirstEnumeration();

      while (depthEnum.hasMoreElements())
      {
        DefaultMutableTreeNode node =
          (DefaultMutableTreeNode) depthEnum.nextElement();

        if (node.isLeaf())
        {
          TreeNode[] nodes =
            ((DefaultMutableTreeNode) node.getParent()).getPath();
          TreePath treePath = new TreePath(nodes);

          logger.debug("Expanding path:" + treePath);

          logTree.expandPath(treePath);
        }
      }
    }
  }

  private void fireChangeEvent()
  {
    ChangeListener[] listeners =
      (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
    ChangeEvent e = null;

    for (int i = 0; i < listeners.length; i++)
    {
      if (e == null)
      {
        e = new ChangeEvent(this);
      }

      listeners[i].stateChanged(e);
    }
  }

  private void reconfigureMenuText()
  {
    String logger = getCurrentlySelectedLoggerName();

    if ((logger == null) || (logger.length() == 0))
    {
      focusOnAction.putValue(Action.NAME, "Focus On...");
      hideAction.putValue(Action.NAME, "Ignore ...");
    }
    else
    {
      focusOnAction.putValue(Action.NAME, "Focus On '" + logger + "'");
      hideAction.putValue(Action.NAME, "Ignore '" + logger + "'");
    }

    // need to ensure the button doens't update itself with the text, looks stupid otherwise
    focusOnLoggerButton.setText(null);
    ignoreLoggerButton.setText(null);
  }

  /**
    * Configures varoius listeners etc for the components within
    * this Class.
    */
  private void setupListeners()
  {
    logTree.addMouseMotionListener(new MouseKeyIconListener());

    /**
       * Enable the actions depending on state of the tree selection
       */
    logTree.addTreeSelectionListener(new TreeSelectionListener()
      {
        public void valueChanged(TreeSelectionEvent e)
        {
          TreePath path = e.getNewLeadSelectionPath();
          TreeNode node = null;

          if (path != null)
          {
            node = (TreeNode) path.getLastPathComponent();
          }

          //          editLoggerAction.setEnabled(path != null);
          String logger = getCurrentlySelectedLoggerName();
          focusOnAction.setEnabled(
            (path != null) && (node != null) && (node.getParent() != null)
            && !hiddenSet.contains(logger));
          hideAction.setEnabled(
            (path != null) && (node != null) && (node.getParent() != null)
            && !isFocusOnSelected());

          if (!focusOnAction.isEnabled())
          {
            setFocusOnSelected(false);
          }
          else
          {
          }

          expandAction.setEnabled(path != null);

          if (logger != null)
          {
            boolean isHidden = hiddenSet.contains(logger);
            popupMenu.hideCheck.setSelected(isHidden);
            ignoreLoggerButton.setSelected(isHidden);
          }

          collapseAction.setEnabled(path != null);

          reconfigureMenuText();
        }
      });

    logTree.addMouseListener(popupListener);

    /**
     * This listener ensures the Tool bar toggle button and popup menu check box
     * stay in sync, plus notifies all the ChangeListeners that
     * an effective filter criteria has been modified
     */
    focusOnAction.addPropertyChangeListener(new PropertyChangeListener()
      {
        public void propertyChange(PropertyChangeEvent evt)
        {
          popupMenu.focusOnCheck.setSelected(isFocusOnSelected());
          focusOnLoggerButton.setSelected(isFocusOnSelected());

          if (logTree.getSelectionPath() != null)
          {
            logTreeModel.nodeChanged(
              (TreeNode) logTree.getSelectionPath().getLastPathComponent());
          }

          fireChangeEvent();
        }
      });

    hideAction.addPropertyChangeListener(new PropertyChangeListener()
      {
        public void propertyChange(PropertyChangeEvent evt)
        {
          if (logTree.getSelectionPath() != null)
          {
            logTreeModel.nodeChanged(
              (TreeNode) logTree.getSelectionPath().getLastPathComponent());
          }

          fireChangeEvent();
        }
      });

    //    /**
    //     * Now add a MouseListener that fires the expansion
    //     * action if CTRL + DBL CLICK is done.
    //     */
    //    logTree.addMouseListener(
    //      new MouseAdapter() {
    //        public void mouseClicked(MouseEvent e) {
    //          if (
    //            (e.getClickCount() > 1)
    //              && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
    //              && ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0)) {
    //            expandCurrentlySelectedNode();
    //            e.consume();
    //          } else if (e.getClickCount() > 1) {
    //            super.mouseClicked(e);
    //            logger.debug("Ignoring dbl click event " + e);
    //          }
    //        }
    //      });

    logTree.addMouseListener(new MouseFocusOnListener());

    /**
     * We listen for when the FocusOn action changes, and then  translate
     * that to a RuleChange
     */
    addChangeListener(new ChangeListener()
      {
        public void stateChanged(ChangeEvent evt)
        {
          firePropertyChange("rule", null, null);
          updateAllIgnoreStuff();
        }
      });

    addPropertyChangeListener("hiddenSet", new PropertyChangeListener()
      {
        public void propertyChange(PropertyChangeEvent arg0)
        {
          updateAllIgnoreStuff();
        }
      });
  }

  private void updateAllIgnoreStuff() {
      updateHiddenSetModels();
      updateIgnoreSummary();
  }
  
  private void updateHiddenSetModels() {
      DefaultListModel model = (DefaultListModel) ignoreList.getModel();
      model.clear();
      List sortedIgnoreList = new ArrayList(getHiddenSet());
      Collections.sort(sortedIgnoreList);

      for (Iterator iter = sortedIgnoreList.iterator(); iter.hasNext();)
      {
        String string = (String) iter.next();
        model.addElement(string);
      }

//      ignoreList.setModel(model);

  }
  private void updateIgnoreSummary() {
      ignoreSummary.setText(ignoreList.getModel().getSize() + " hidden loggers");
  }
  
  private void toggleFocusOnState()
  {
    setFocusOnSelected(!isFocusOnSelected());
    hideAction.setEnabled(!isFocusOnSelected());
  }

  //~ Inner Classes ===========================================================

  /**
   * DOCUMENT ME!
   *
   * @author $author$
   * @version $Revision$, $Date$
   *
   * @author Paul Smith <psmith@apache.org>
        *
        */
  private class LoggerNameTreeCellRenderer extends DefaultTreeCellRenderer
  {
    //~ Constructors ==========================================================

    //    private JPanel panel = new JPanel();
    private LoggerNameTreeCellRenderer()
    {
      super();

      //      panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
      //      panel.add(this);
      setLeafIcon(null);
      setOpaque(false);
    }

    //~ Methods ===============================================================

    /* (non-Javadoc)
     * @see javax.swing.tree.TreeCellRenderer#getTreeCellRendererComponent(javax.swing.JTree, java.lang.Object, boolean, boolean, boolean, int, boolean)
     */
    /**
     * DOCUMENT ME!
     *
     * @param tree DOCUMENT ME!
     * @param value DOCUMENT ME!
     * @param sel DOCUMENT ME!
     * @param expanded DOCUMENT ME!
     * @param leaf DOCUMENT ME!
     * @param row DOCUMENT ME!
     * @param focus DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public Component getTreeCellRendererComponent(
      JTree tree, Object value, boolean sel, boolean expanded, boolean leaf,
      int row, boolean focus)
    {
      JLabel component =
        (JLabel) super.getTreeCellRendererComponent(
          tree, value, sel, expanded, leaf, row, focus);

      Font originalFont = component.getFont();

      int style = Font.PLAIN;

      if (sel && focusOnLoggerButton.isSelected())
      {
        style = style | Font.BOLD;
      }

      String logger =
        getLoggerName(
          new TreePath(((DefaultMutableTreeNode) value).getPath()));

      if (hiddenSet.contains(logger))
      {
        //        component.setEnabled(false);
        //        component.setIcon(leaf?null:getDefaultOpenIcon());
        style = style | Font.ITALIC;

        //        logger.debug("TreeRenderer: '" + logger + "' is in hiddenSet, italicizing");
      }
      else
      {
        //          logger.debug("TreeRenderer: '" + logger + "' is NOT in hiddenSet, leaving plain");
        //        component.setEnabled(true);
      }

      if (originalFont != null)
      {
        Font font2 = originalFont.deriveFont(style);

        if (font2 != null)
        {
          component.setFont(font2);
        }
      }

      return component;
    }
  }

  private class LoggerTreePopupMenu extends JPopupMenu
  {
    //~ Instance fields =======================================================

    JCheckBoxMenuItem focusOnCheck = new JCheckBoxMenuItem();
    JCheckBoxMenuItem hideCheck = new JCheckBoxMenuItem();

    //~ Constructors ==========================================================

    private LoggerTreePopupMenu()
    {
      initMenu();
    }

    //~ Methods ===============================================================

    /* (non-Javadoc)
     * @see javax.swing.JPopupMenu#show(java.awt.Component, int, int)
     */
    /**
     * DOCUMENT ME!
     *
     * @param invoker DOCUMENT ME!
     * @param x DOCUMENT ME!
     * @param y DOCUMENT ME!
     */
    public void show(Component invoker, int x, int y)
    {
      DefaultMutableTreeNode node =
        (DefaultMutableTreeNode) logTree.getLastSelectedPathComponent();

      if (node == null)
      {
        return;
      }

      super.show(invoker, x, y);
    }

    /**
     * DOCUMENT ME!
    */
    private void initMenu()
    {
      add(expandAction);
      add(collapseAction);
      addSeparator();
      focusOnCheck.setAction(focusOnAction);
      hideCheck.setAction(hideAction);
      add(focusOnCheck);
      add(hideCheck);

      //      add(editLoggerAction);
      addSeparator();
      add(clearIgnoreListAction);
    }
  }

  private final class MouseFocusOnListener extends MouseAdapter
  {
    //~ Methods ===============================================================

    /* (non-Javadoc)
     * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
     */
    /**
     * DOCUMENT ME!
     *
     * @param e DOCUMENT ME!
     */
    public void mouseClicked(MouseEvent e)
    {
      if (
        (e.getClickCount() > 1)
          && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
          && ((e.getModifiers() & InputEvent.SHIFT_MASK) > 0))
      {
        ignoreLoggerAtPoint(e.getPoint());
        e.consume();
        fireChangeEvent();
      }
      else if (
        (e.getClickCount() > 1)
          && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0))
      {
        focusAnLoggerAtPoint(e.getPoint());
        e.consume();
        fireChangeEvent();
      }
    }

    /**
     * DOCUMENT ME!
     *
     * @param point
     */
    private void focusAnLoggerAtPoint(Point point)
    {
      String logger = getLoggerAtPoint(point);

      if (logger != null)
      {
        toggleFocusOnState();
      }
    }

    /**
     * DOCUMENT ME!
     *
     * @param point
     * @return
     */
    private String getLoggerAtPoint(Point point)
    {
      TreePath path = logTree.getPathForLocation(point.x, point.y);

      if (path != null)
      {
        return getLoggerName(path);
      }

      return null;
    }

    /**
     * DOCUMENT ME!
     *
     * @param point
     */
    private void ignoreLoggerAtPoint(Point point)
    {
      String logger = getLoggerAtPoint(point);

      if (logger != null)
      {
        toggleHiddenLogger(logger);
      }
    }
  }

  private final class MouseKeyIconListener extends MouseMotionAdapter
    implements MouseMotionListener
  {
    //~ Instance fields =======================================================

    Cursor focusOnCursor =
      Toolkit.getDefaultToolkit().createCustomCursor(
        ChainsawIcons.FOCUS_ON_ICON.getImage(), new Point(10, 10), "");
    Cursor ignoreCursor =
      Toolkit.getDefaultToolkit().createCustomCursor(
        ChainsawIcons.IGNORE_ICON.getImage(), new Point(10, 10), "");

    //~ Methods ===============================================================

    /* (non-Javadoc)
     * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
     */
    /**
     * DOCUMENT ME!
     *
     * @param e DOCUMENT ME!
     */
    public void mouseMoved(MouseEvent e)
    {
      //      logger.debug(e.toString());
      if (
        ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
          && ((e.getModifiers() & InputEvent.SHIFT_MASK) > 0))
      {
        logTree.setCursor(ignoreCursor);
      }
      else if ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
      {
        logTree.setCursor(focusOnCursor);
      }
      else
      {
        logTree.setCursor(Cursor.getDefaultCursor());
      }
    }
  }
}
