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

package org.apache.log4j.chainsaw.receivers;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import java.io.File;

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.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreePath;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.log4j.chainsaw.PopupListener;
import org.apache.log4j.chainsaw.SmallButton;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
import org.apache.log4j.chainsaw.prefs.SettingsListener;
import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent;
import org.apache.log4j.chainsaw.prefs.LoadSettingsEvent;
import org.apache.log4j.chainsaw.help.HelpManager;
import org.apache.log4j.chainsaw.helper.SwingHelper;
import org.apache.log4j.chainsaw.icons.ChainsawIcons;
import org.apache.log4j.chainsaw.icons.LevelIconFactory;
import org.apache.log4j.chainsaw.icons.LineIconFactory;
import org.apache.log4j.chainsaw.messages.MessageCenter;
import org.apache.log4j.net.SocketNodeEventListener;
import org.apache.log4j.net.SocketReceiver;
import org.apache.log4j.plugins.Pauseable;
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.spi.LoggerRepository;
import org.apache.log4j.spi.LoggerRepositoryEx;


/**
 * This panel is used to manage all the Receivers configured within Log4j
 *
 *
 * @author Paul Smith &lt;psmith@apache.org&gt;
 * @author Scott Deboy &lt;sdeboy@apache.org&gt;
 */
public class ReceiversPanel extends JPanel implements SettingsListener {
  final Action newReceiverButtonAction;
  final Action pauseReceiverButtonAction;
  final Action playReceiverButtonAction;
  final Action shutdownReceiverButtonAction;
  final Action saveReceiversButtonAction;
  final Action restartReceiverButtonAction;
  private final Action showReceiverHelpAction;
  private final Action startAllAction;
  private final JPopupMenu popupMenu = new ReceiverPopupMenu();
  private final JTree receiversTree = new JTree();
  private final NewReceiverPopupMenu newReceiverPopup =
    new NewReceiverPopupMenu();
  private final ReceiverToolbar buttonPanel;
  private final JSplitPane splitter = new JSplitPane();
  private final PluginPropertyEditorPanel pluginEditorPanel =
    new PluginPropertyEditorPanel();
  private final Logger logger = LogManager.getLogger(ReceiversPanel.class);
  
  private final PluginRegistry pluginRegistry;
  

  public ReceiversPanel() {
    super(new BorderLayout());
    LoggerRepository repo = LogManager.getLoggerRepository();
    final ReceiversTreeModel model = new ReceiversTreeModel();
    if (repo instanceof LoggerRepositoryEx) {
       pluginRegistry = ((LoggerRepositoryEx) repo).getPluginRegistry();
       pluginRegistry.addPluginListener(model);

       //iterate over visual receivers and call setcontainer
       Collection c = pluginRegistry.getPlugins(VisualReceiver.class);
       for (Iterator iter = c.iterator();iter.hasNext();) {
    	   ((VisualReceiver)iter.next()).setContainer(this);
       }
       
       pluginRegistry.addPluginListener(new PluginListener() {
		public void pluginStarted(PluginEvent e) {
			//if we get a plugin started callback, set the container
			if (e.getPlugin() instanceof VisualReceiver) {
				((VisualReceiver)e.getPlugin()).setContainer(ReceiversPanel.this);
			}
		}

		public void pluginStopped(PluginEvent e) {
		}
       });
    } else {
       pluginRegistry = null;
    }
    
    receiversTree.setModel(model);

    receiversTree.setExpandsSelectedPaths(true);
    model.addTreeModelListener(
      new TreeModelListener() {
        public void treeNodesChanged(TreeModelEvent e) {
          expandRoot();
        }

        public void treeNodesInserted(TreeModelEvent e) {
          expandRoot();
        }

        public void treeNodesRemoved(TreeModelEvent e) {
          expandRoot();
        }

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

        private void expandRoot() {
          receiversTree.expandPath(
            new TreePath(model.getPathToRoot(model.RootNode)));
        }
      });
    receiversTree.expandPath(
      new TreePath(model.getPathToRoot(model.RootNode)));

    receiversTree.addTreeWillExpandListener(
      new TreeWillExpandListener() {
        public void treeWillCollapse(TreeExpansionEvent event)
          throws ExpandVetoException {
          if (event.getPath().getLastPathComponent() == model.RootNode) {
            throw new ExpandVetoException(event);
          }
        }

        public void treeWillExpand(TreeExpansionEvent event)
          throws ExpandVetoException {
        }
      });

    receiversTree.addTreeSelectionListener(
      new TreeSelectionListener() {
        public void valueChanged(TreeSelectionEvent e) {
          TreePath path = e.getNewLeadSelectionPath();

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

            if (
              (node != null) && (node.getUserObject() != null)
                && (node.getUserObject() instanceof Plugin)) {
              Plugin p = (Plugin) node.getUserObject();
              logger.debug("plugin=" + p);
              pluginEditorPanel.setPlugin(p);
            } else {
              pluginEditorPanel.setPlugin(null);
            }
          }
        }
      });

    receiversTree.setToolTipText("Allows you to manage Log4j Receivers");
    newReceiverButtonAction =
      new AbstractAction() {
          public void actionPerformed(ActionEvent e) {
            newReceiverPopup.show(
              buttonPanel.newReceiverButton, 0,
              buttonPanel.newReceiverButton.getHeight());
          }
        };
    newReceiverButtonAction.putValue(
      Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_NEW_RECEIVER));
    newReceiverButtonAction.putValue(
      Action.SHORT_DESCRIPTION, "Creates and configures a new Receiver");
    newReceiverButtonAction.putValue(Action.NAME, "New Receiver");
    newReceiverButtonAction.putValue(
      Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_N));

    newReceiverButtonAction.setEnabled(true);

    playReceiverButtonAction =
      new AbstractAction() {
          public void actionPerformed(ActionEvent e) {
            playCurrentlySelectedReceiver();
          }
        };

    playReceiverButtonAction.putValue(
      Action.SHORT_DESCRIPTION, "Resumes the selected Node");
    playReceiverButtonAction.putValue(Action.NAME, "Resume");
    playReceiverButtonAction.putValue(
      Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_RESUME_RECEIVER));
    playReceiverButtonAction.setEnabled(false);
    playReceiverButtonAction.putValue(
      Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_R));

    pauseReceiverButtonAction =
      new AbstractAction() {
          public void actionPerformed(ActionEvent e) {
            pauseCurrentlySelectedReceiver();
          }
        };

    pauseReceiverButtonAction.putValue(
      Action.SHORT_DESCRIPTION,
      "Pause the selected Receiver.  All events received will be discarded.");
    pauseReceiverButtonAction.putValue(Action.NAME, "Pause");

    pauseReceiverButtonAction.putValue(
      Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_P));

    pauseReceiverButtonAction.putValue(
      Action.SMALL_ICON, new ImageIcon(ChainsawIcons.PAUSE));
    pauseReceiverButtonAction.setEnabled(false);

    shutdownReceiverButtonAction =
      new AbstractAction() {
          public void actionPerformed(ActionEvent e) {
            shutdownCurrentlySelectedReceiver();
          }
        };

    shutdownReceiverButtonAction.putValue(
      Action.SHORT_DESCRIPTION,
      "Shuts down the selected Receiver, and removes it from the Plugin registry");
    shutdownReceiverButtonAction.putValue(Action.NAME, "Shutdown");

    shutdownReceiverButtonAction.putValue(
      Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_STOP_RECEIVER));
    shutdownReceiverButtonAction.putValue(
      Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_S));

    shutdownReceiverButtonAction.setEnabled(false);

    saveReceiversButtonAction =
      new AbstractAction() {
          public void actionPerformed(ActionEvent e) {
            saveReceivers();
          }
        };

    saveReceiversButtonAction.putValue(
      Action.SHORT_DESCRIPTION,
      "Save the current receiver configuration");
    saveReceiversButtonAction.putValue(Action.NAME, "Save receivers");

    saveReceiversButtonAction.putValue(
      Action.SMALL_ICON, new ImageIcon(ChainsawIcons.FILE_SAVE_AS));
    saveReceiversButtonAction.putValue(
      Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_V));


    restartReceiverButtonAction =
        new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
              Receiver selectedReceiver = getCurrentlySelectedReceiver();
              if(selectedReceiver == null){
              	return;
              }
              selectedReceiver.shutdown();
              selectedReceiver.activateOptions();
              //allow the visual receiver to get a container on restart
              if (selectedReceiver instanceof VisualReceiver) {
                  ((VisualReceiver)selectedReceiver).setContainer(ReceiversPanel.this);
              }
            }
          };

      restartReceiverButtonAction.putValue(
        Action.SHORT_DESCRIPTION,
        "Restarts the selected Receiver");
      restartReceiverButtonAction.putValue(Action.NAME, "Restart");

      restartReceiverButtonAction.putValue(
        Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_RESTART));
      restartReceiverButtonAction.putValue(
        Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_R));

      restartReceiverButtonAction.setEnabled(false);

    showReceiverHelpAction =
      new AbstractAction("Help") {
          public void actionPerformed(ActionEvent e) {
            Receiver receiver = getCurrentlySelectedReceiver();

            if (receiver != null) {
              HelpManager.getInstance().showHelpForClass(receiver.getClass());
            }
          }
        };

    showReceiverHelpAction.putValue(
      Action.SMALL_ICON, new ImageIcon(ChainsawIcons.HELP));
    showReceiverHelpAction.putValue(
      Action.SHORT_DESCRIPTION, "Displays the JavaDoc page for this Plugin");

    startAllAction =
      new AbstractAction(
        "(Re)start All Receivers", new ImageIcon(ChainsawIcons.ICON_RESTART_ALL)) {
          public void actionPerformed(ActionEvent e) {
            if (
              JOptionPane.showConfirmDialog(
                  null,
                  "This will cause any active Receiver to stop, and disconnect.  Is this ok?",
                  "Confirm", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
              new Thread(
                new Runnable() {
                  public void run() {
                    Collection allReceivers =
                        pluginRegistry.getPlugins(Receiver.class);

                    for (Iterator iter = allReceivers.iterator();
                        iter.hasNext();) {
                      Receiver item = (Receiver) iter.next();
                      item.shutdown();
                      item.activateOptions();
                    }

                    updateReceiverTreeInDispatchThread();
                    MessageCenter.getInstance().getLogger().info(
                      "All Receivers have been (re)started");
                  }
                }).start();
            }
          }
        };

    startAllAction.putValue(
      Action.SHORT_DESCRIPTION,
      "Ensures that any Receiver that isn't active, is started, and any started action is stopped, and then restarted");

    receiversTree.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    receiversTree.setCellRenderer(new ReceiverTreeCellRenderer());
    receiversTree.setRowHeight(19);

    buttonPanel = new ReceiverToolbar();
    receiversTree.addTreeSelectionListener(buttonPanel);

    PopupListener popupListener = new PopupListener(popupMenu);
    receiversTree.addMouseListener(popupListener);
    this.addMouseListener(popupListener);

    JComponent component = receiversTree;
    JScrollPane pane = new JScrollPane(component);

    splitter.setOrientation(JSplitPane.VERTICAL_SPLIT);

    splitter.setTopComponent(pane);
    splitter.setBottomComponent(pluginEditorPanel);

    splitter.setResizeWeight(0.7);
    add(buttonPanel, BorderLayout.NORTH);
    add(splitter, BorderLayout.CENTER);

    /**
     * This Tree likes to be notified when Socket's are accepted so
     * we listen for them and update the Tree.
     */
    SocketNodeEventListener listener =
      new SocketNodeEventListener() {
        public void socketOpened(String remoteInfo) {
          updateReceiverTreeInDispatchThread();
        }

        public void socketClosedEvent(Exception e) {
          updateReceiverTreeInDispatchThread();
        }
      };

    /**
     * add this listener to all SocketReceivers
     */
    if (pluginRegistry != null) {
    	List socketReceivers =
      		pluginRegistry.getPlugins(SocketReceiver.class);

    	for (Iterator iter = socketReceivers.iterator(); iter.hasNext();) {
      		SocketReceiver element = (SocketReceiver) iter.next();
      		element.addSocketNodeEventListener(listener);
    	}
     }
  }

  private void saveReceivers() {
    File saveConfigFile = SwingHelper.promptForFile(this, null, "Save receiver configuration XML file", false);
    if (saveConfigFile != null) {
      ReceiversHelper.getInstance().saveReceiverConfiguration(saveConfigFile);
    }
  }

  protected ReceiversTreeModel getReceiverTreeModel() {
    return ((ReceiversTreeModel) receiversTree.getModel());
  }

  /**
   *
   */
  protected void updateCurrentlySelectedNodeInDispatchThread() {
    SwingUtilities.invokeLater(
      new Runnable() {
        public void run() {
          DefaultMutableTreeNode node =
            (DefaultMutableTreeNode) receiversTree
            .getLastSelectedPathComponent();

          if (node == null) {
            return;
          }

          getReceiverTreeModel().nodeChanged(node);
          updateActions();
        }
      });
  }

  /**
   * Returns the currently selected Receiver, or null if there is no
   * selected Receiver (this could be because a) nothing at all is selected
   * or b) a non Receiver type node is selected
   *
   * @return Receiver or null
   */
  private Receiver getCurrentlySelectedReceiver() {
    DefaultMutableTreeNode node =
      (DefaultMutableTreeNode) receiversTree.getLastSelectedPathComponent();

    if (node == null) {
      return null;
    }

    Object userObject = node.getUserObject();

    if (userObject instanceof Receiver) {
      return (Receiver) userObject;
    }

    return null;
  }

  private Receiver[] getSelectedReceivers() {
    TreePath[] paths = receiversTree.getSelectionPaths();
    Collection receivers = new ArrayList();

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

      if ((node != null) && node.getUserObject() instanceof Receiver) {
        receivers.add(node.getUserObject());
      }
    }

    return (Receiver[]) receivers.toArray(new Receiver[0]);
  }

  /**
   * Returns the currently seleted node's User Object, or null
   * if there is no selected node, or if the currently selected node has
   * not user Object
   * @return Object representing currently seleted Node's User Object
   */
  private Object getCurrentlySelectedUserObject() {
    DefaultMutableTreeNode node =
      (DefaultMutableTreeNode) receiversTree.getLastSelectedPathComponent();

    if (node == null) {
      return null;
    }

    return node.getUserObject();
  }

  /**
   * Takes the currently selected Receiver and pauess it, effectively
   * discarding any received event BEFORE it is even posted to the logger
   * repository.
   *
   * The user is NOT asked to confirm this operation
   *
   */
  private void pauseCurrentlySelectedReceiver() {
    new Thread(
      new Runnable() {
        public void run() {
          Object obj = getCurrentlySelectedUserObject();

          if ((obj != null) && obj instanceof Pauseable) {
            ((Pauseable) obj).setPaused(true);
            updateCurrentlySelectedNodeInDispatchThread();
          }
        }
      }).start();
  }

  /**
   * Ensures that the currently selected receiver active property is set to
   * true
   *
   */
  private void playCurrentlySelectedReceiver() {
    new Thread(
      new Runnable() {
        public void run() {
          Object obj = getCurrentlySelectedUserObject();

          if ((obj != null) && obj instanceof Pauseable) {
            ((Pauseable) obj).setPaused(false);

            updateCurrentlySelectedNodeInDispatchThread();
          }
        }
      }).start();
  }

  /**
   * Takes the currently selected Receiver and stops it, which effectively
   * removes it from the PluginRegistry.
   *
   * The user is asked to confirm this operation
   *
   */
  private void shutdownCurrentlySelectedReceiver() {
    if (
      JOptionPane.showConfirmDialog(
          null,
          "Are you sure you wish to shutdown this receiver?\n\nThis will disconnect any network resources, and remove it from the PluginRegistry.",
          "Confirm stop of Receiver", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
      new Thread(
        new Runnable() {
          public void run() {
            Receiver[] receivers = getSelectedReceivers();

            if (receivers != null) {
              for (int i = 0; i < receivers.length; i++) {
                pluginRegistry.stopPlugin(receivers[i].getName());
              }
            }
          }
        }).start();
    }
  }

  /**
   * Sets the state of actions depending on certain conditions (i.e what is
   * currently selected etc.)
   */
  private void updateActions() {
    Object object = getCurrentlySelectedUserObject();

    if ((object != null) && object instanceof Pauseable) {
      Pauseable pauseable = (Pauseable) object;

      if (!pauseable.isPaused()) {
        pauseReceiverButtonAction.setEnabled(true);
        playReceiverButtonAction.setEnabled(false);
      } else {
        pauseReceiverButtonAction.setEnabled(false);
        playReceiverButtonAction.setEnabled(true);
      }
    } else {
      pauseReceiverButtonAction.setEnabled(false);
      playReceiverButtonAction.setEnabled(false);
    }

    if (object instanceof Receiver) {
      newReceiverButtonAction.setEnabled(true);
      shutdownReceiverButtonAction.setEnabled(true);
      restartReceiverButtonAction.setEnabled(true);
    } else {
      shutdownReceiverButtonAction.setEnabled(false);
      restartReceiverButtonAction.setEnabled(false);
    }
  }

  /**
   * Ensures that the Receiver tree is updated with the latest information
   * and that this operation occurs in the Swing Event Dispatch thread.
   *
   */
  public void updateReceiverTreeInDispatchThread() {
    logger.debug(
      "updateReceiverTreeInDispatchThread, should not be needed now");

    //    if (SwingUtilities.isEventDispatchThread()) {
    //      updateReceiverTree.run();
    //    } else {
    //      SwingUtilities.invokeLater(updateReceiverTree);
    //    }
  }

  /* (non-Javadoc)
   * @see java.awt.Component#setVisible(boolean)
   */
  public void setVisible(boolean aFlag) {
    boolean oldValue = isVisible();
    super.setVisible(aFlag);
    firePropertyChange("visible", oldValue, isVisible());
  }

  public void loadSettings(LoadSettingsEvent event){}

   /**
    * Saves all the receivers which are active at shut down as a configuration
    * file which can be loaded when Chainsaw will be restarted.
    */

  public void saveSettings(SaveSettingsEvent event){
     File file = new File(SettingsManager.getInstance().getSettingsDirectory(), "receiver-config.xml");
     ReceiversHelper.getInstance().saveReceiverConfiguration(file);
  }

  /**
   * A popup menu that allows the user to choose which
   * style of Receiver to create, which spawns a relevant Dialog
   * to enter the information and create the Receiver
   *
   * @author Paul Smith &lt;psmith@apache.org&gt;
   *
   */
  class NewReceiverPopupMenu extends JPopupMenu {
    NewReceiverPopupMenu() {
      try {
        final List receiverList =
          ReceiversHelper.getInstance().getKnownReceiverClasses();
        String separatorCheck = null;

        for (Iterator iter = receiverList.iterator(); iter.hasNext();) {
          final Class toCreate = (Class) iter.next();
          Package thePackage = toCreate.getPackage();
          final String name =
            toCreate.getName().substring(thePackage.getName().length() + 1);

          if (separatorCheck == null) {
            separatorCheck = name.substring(0, 1);
          } else {
            String current = name.substring(0, 1);

            if (!current.equals(separatorCheck)) {
              addSeparator();
              separatorCheck = current;
            }
          }

          add(
            new AbstractAction("New " + name + "...") {
              public void actionPerformed(ActionEvent e) {
                Container container = SwingUtilities.getAncestorOfClass(JFrame.class, ReceiversPanel.this);
                final JDialog dialog = new JDialog((JFrame) container,"New " + toCreate.getName() + "..." ,true);
                
                try {
                  final NewReceiverDialogPanel panel =
                    NewReceiverDialogPanel.create(toCreate);
                  dialog.getContentPane().add(panel);
                  dialog.pack();
                  SwingHelper.centerOnScreen(dialog);

                  /**
                   * Make the default button the ok button
                   */
                  dialog.getRootPane().setDefaultButton(panel.getOkPanel().getOkButton());
                  
                  /**
                   * Use the standard Cancel metaphor
                   */
                  SwingHelper.configureCancelForDialog(dialog, panel.getOkPanel().getCancelButton());
                  

                  panel.getOkPanel().getOkButton().addActionListener(
                    new ActionListener() {
                      public void actionPerformed(ActionEvent e2) {
                        Plugin plugin = panel.getPlugin();
                        if (plugin.getName() != null && !plugin.getName().trim().equals("")) {
                            dialog.dispose();
                            pluginRegistry.addPlugin(plugin);
                            plugin.activateOptions();
                            MessageCenter.getInstance().addMessage("Plugin '" + plugin.getName() + "' started");
                        } else {
                            MessageCenter.getInstance().getLogger().error("Name required to create receiver");
                        }
                      }
                    });
                  dialog.setVisible(true);
                } catch (Exception e1) {
                  e1.printStackTrace();
                  MessageCenter.getInstance().getLogger().error(
                    "Failed to create the new Receiver dialog", e1);
                }
              }
            });
        }
      } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e.getMessage());
      }
    }
  }

  /**
   * A popup menu class for when the user uses the popup trigger action
   * on a node in the Receiver tree.
   *
   * @author Paul Smith &lt;psmith@apache.org&gt;
   *
   */
  class ReceiverPopupMenu extends JPopupMenu {
    ReceiverPopupMenu() {
    }

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

      if (node == null) {
        return;
      }

      Object userObject = node.getUserObject();
      removeAll();

      if (userObject == getRootOfTree().getUserObject()) {
        buildForReceiversRoot();
      } else if (getCurrentlySelectedReceiver() != null) {
        buildForReceiverNode();
      } else {
        return;
      }

      this.invalidate();
      this.validate();

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

    /**
     *
     */
    private DefaultMutableTreeNode getRootOfTree() {
      return (DefaultMutableTreeNode) receiversTree.getModel().getRoot();
    }

    /**
     * Builds the popup menu with relevant items for a selected
     * Receiver node in the Tree.
     */
    private void buildForReceiverNode() {

      add(playReceiverButtonAction);
      add(pauseReceiverButtonAction);
      add(restartReceiverButtonAction);
      add(shutdownReceiverButtonAction);
      add(saveReceiversButtonAction);

      addSeparator();

      final Receiver r = getCurrentlySelectedReceiver();
      add(createLevelRadioButton(r, Level.TRACE));
      add(createLevelRadioButton(r, Level.DEBUG));
      add(createLevelRadioButton(r, Level.INFO));
      add(createLevelRadioButton(r, Level.WARN));
      add(createLevelRadioButton(r, Level.ERROR));
      addSeparator();
      add(createLevelRadioButton(r, Level.OFF));
      add(createLevelRadioButton(r, Level.ALL));
      addSeparator();
      add(showReceiverHelpAction);
    }

    private JRadioButtonMenuItem createLevelRadioButton(
      final Receiver r, final Level l) {
      Map levelIconMap = LevelIconFactory.getInstance().getLevelToIconMap();

      Action action =
        new AbstractAction(
          l.toString(), (Icon) levelIconMap.get(l.toString())) {
          public void actionPerformed(ActionEvent e) {
            if (r != null) {
              r.setThreshold(l);
              updateCurrentlySelectedNodeInDispatchThread();
            }
          }
        };

      JRadioButtonMenuItem item = new JRadioButtonMenuItem(action);
      item.setSelected(r.getThreshold() == l);

      return item;
    }

    /**
     * Builds a relevant set of menus for when the Root node in the Receiver
     * tree has been selected
     *
     */
    private void buildForReceiversRoot() {
      JMenuItem startAll = new JMenuItem(startAllAction);

      add(newReceiverButtonAction);

      addSeparator();
      add(startAll);
    }
  }

  /**
   * A simple Panel that has toolbar buttons for restarting,
   * playing, pausing, and stoping receivers
   *
   * @author Paul Smith &lt;psmith@apache.org&gt;
   *
   */
  private class ReceiverToolbar extends JToolBar
    implements TreeSelectionListener {
    final SmallButton newReceiverButton;

    private ReceiverToolbar() {
      setFloatable(false);

      SmallButton restartReceiverButton = new SmallButton(restartReceiverButtonAction);
      restartReceiverButton.setText(null);
      
      SmallButton shutdownReceiverButton =
        new SmallButton(shutdownReceiverButtonAction);
      shutdownReceiverButton.setText(null);

      SmallButton saveReceiversButton =
        new SmallButton(saveReceiversButtonAction);
      saveReceiversButton.setText(null);

      SmallButton restartAllButton = new SmallButton(startAllAction);
      restartAllButton.setText(null);
      
      

      newReceiverButton = new SmallButton(newReceiverButtonAction);
      newReceiverButton.setText(null);
      newReceiverButton.addMouseListener(new PopupListener(newReceiverPopup));

      add(newReceiverButton);
      add(restartAllButton);

      addSeparator();

      add(restartReceiverButton);
      add(shutdownReceiverButton);
      add(saveReceiversButton);

      addSeparator();

      Action closeAction =
        new AbstractAction(null, LineIconFactory.createCloseIcon()) {
          public void actionPerformed(ActionEvent e) {
            ReceiversPanel.this.setVisible(false);
          }
        };

      closeAction.putValue(
        Action.SHORT_DESCRIPTION, "Closes the Receiver panel");

      add(Box.createHorizontalGlue());

      add(new SmallButton(closeAction));

      add(Box.createHorizontalStrut(5));
    }

    /**
     * Ensures the enabled property of the actions is set properly
     * according to the currently selected node in the tree
     */
    public void valueChanged(TreeSelectionEvent e) {
      updateActions();
    }
  }
}
