/****************************************************************************
  $Archive: /njcl_sample/NJCLApplet/src/plugins/ServerPopupHandler.java $
  $Revision: 2 $
  $Modtime: 3/11/99 2:50p $

  Copyright (c) 1999 Novell, Inc.  All Rights Reserved.

 THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
 USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE AGREEMENT
 ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS THIS WORK.
 PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO DEVELOPER A
 ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE CODE IN ITS
 PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS TO MARKET,
 DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF DEVELOPER'S
 PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR DEVELOPER'S
 CUSTOMERS WITH RESPECT TO THIS CODE.
 ***************************************************************************/

import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.naming.*;
import javax.naming.directory.*;

import com.novell.service.server.NWServer;
import com.novell.service.server.ServerVersions;

/**
 * This class provides a 'snap-in' that keys off of a popup menu for simple
 * server management.
 *
 * <p>Essentially, this handler will display the server name (in the title),
 * the server version and allow the user to load or unload NLMs.
 * </p>
 */
public class ServerPopupHandler
   implements PopupHandler
{
   /**
    * Required public, null constructor.
    */
   public ServerPopupHandler ()
   {
   }
   
   /**
    * Method called for registered handlers when the popup event occurs.
    *
    * @param frame               The frame in which the popup is being
    *                            requested.
    * @param popup               The popup menu being created. If the handler
    *                            wants to provide custom handling for the
    *                            object being passed, it can add one or more
    *                            to this menu before returnning. Otherwise
    *                            it can ignore this request.
    * @param obj                 The object being customized. This is likely
    *                            to be a ContextTreeNode.
    */
   public void popupRequested (
         JFrame frame,
         JPopupMenu popup,
         Object obj)
   {
      Context ctx;
                        
      if (obj instanceof ContextTreeNode)
      {
         ctx = ((ContextTreeNode) obj).getThisContext ();
         //System.out.println (
         //            "ServerPopupHandler called with context:" +
         //            ctx.getClass ().getName ());
         if ((null != ctx) &&
             (ctx instanceof DirContext) &&
             (ctx instanceof NWServer))
            new NWServerActionListener (obj.toString(), (DirContext) ctx, popup);
      }
   } // popupRequested ()
   
} // class ServerPopupHandler

/**
 * Internal class to handle NetWare server object.
 */
class NWServerActionListener
   implements ActionListener
{
   String serverName;
   DirContext serverCtx;
   JMenuItem serverMenuItem;

   private static int buttonHeight = 25;

   /**
    * Public, default constructor required for plugins.
    *
    * <p>Even though this is not a plug-in, it is in the plug-in directory.
    * </p>
    */
   public NWServerActionListener () {}

   /**
    * Constructor which hangs onto the server.
    *
    * @param serverName          The name of the server.
    * @param serverCtx           The server context to be used.
    * @param popup               The popup menu being created. If the handler
    *                            wants to provide custom handling for the
    *                            object being passed, it can add one or more
    *                            to this menu before returnning. Otherwise
    *                            it can ignore this request.
    */   
   public NWServerActionListener (
         String serverName,
         DirContext serverCtx,
         JPopupMenu popup)
   {
      this.serverName = serverName;
      this.serverCtx = serverCtx;   // already checked for NWServer
      serverMenuItem = new JMenuItem ("Manage Server");
      serverMenuItem.setToolTipText ("NetWare server management functions");
      serverMenuItem.addActionListener (this);
      popup.add (serverMenuItem);
   } // NWServerActionListener ()

   // ActionListener methods ------------------------------------------------
   /**
    * ActionListener event handler method.
    *
    * @param event               The event describing what action occured.
    */
   public void actionPerformed (
         ActionEvent event)
   {
      Object object = event.getSource ();
   
      if (object == serverMenuItem)
         server_Action (event);
   } // actionPerformed ()

   /**
    * Action handler for the server menu item.
    *
    * @param event               The event describing what action occured.
    */
   void server_Action (
         ActionEvent event)
   {
      ServerMgmtFrame frame = new ServerMgmtFrame (serverName, serverCtx);
      Point p = ((Component) event.getSource ()).getLocation ();
      p.translate (buttonHeight, buttonHeight);
      frame.setLocation (p);
      frame.show ();
   } // server_Action ()
   
} // class NWServerActionListener

/**
 * Internal class which presents and handles server management features.
 */
class ServerMgmtFrame 
   extends JFrame
   implements ActionListener
{
   Context serverCtx;
   
   private static int emptySpace = 5;
   private static int buttonHeight = 25;
   private static int buttonWidth = 110;
   private static int mainPaneHeight = (buttonHeight + emptySpace) * 4;
   private static int mainPaneWidth = 400;
   
   private JLabel       versionLabel;
   private JLabel       nlmLabel;
   private JTextField   nlmTextField;
   private JButton      loadNLMButton;
   private JButton      unloadNLMButton;
   private JButton      closeButton;

   /**
    * Public, default constructor required for plugins.
    *
    * <p>Even though this is not a plug-in, it is in the plug-in directory.
    * </p>
    */
   public ServerMgmtFrame () {}

   /**
    * Constructs a server management frame given its name and context.
    *
    * @param serverName          The name of the server.
    * @param serverCtx           The server context to be used.
    */
   public ServerMgmtFrame (
         String serverName,
         DirContext serverCtx)
   {
      super ("Server Management: " + serverName);
      this.serverCtx = serverCtx;
      getContentPane ().setLayout (null);
      setSize (mainPaneWidth, mainPaneHeight);

      // Version info
      try
      {
         Attributes attrs;
         attrs = serverCtx.getAttributes (
                                 "",
                                 new String [] {ServerVersions.ATTR_ID});
         ServerVersions ver;
         ver = (ServerVersions) attrs.get (ServerVersions.ATTR_ID).get ();
         versionLabel = new JLabel ("Server Version " +
                                 ver.getMajorVersion () + "." +
                                 ver.getMinorVersion () + " rev " +
                                 ver.getRevision ());
         versionLabel.setBorder (new EtchedBorder (EtchedBorder.LOWERED));
         versionLabel.setBounds (
                           emptySpace,
                           emptySpace,
                           mainPaneWidth - (emptySpace * 3),
                           buttonHeight);
         versionLabel.setHorizontalAlignment (SwingConstants.CENTER);
         getContentPane ().add (versionLabel);
      }
      catch (Exception e)
      {
         (new MessageBox (
                  "Error",
                  "Unable to get attributes for object:\n" +
                  Util.getExceptionTrace (e))).show ();
      }

      // Nlm stuff
      nlmLabel = new JLabel ("NLM command:");
      nlmLabel.setBounds (
                        emptySpace,
                        (buttonHeight + emptySpace) + emptySpace,
                        buttonWidth,
                        buttonHeight);
      getContentPane ().add (nlmLabel);
      nlmTextField = new JTextField ();
      nlmTextField.setBounds (
                        (buttonWidth + emptySpace) + emptySpace,
                        (buttonHeight + emptySpace) + emptySpace,
                        mainPaneWidth - (buttonWidth + (emptySpace * 3)),
                        buttonHeight);
      nlmTextField.setToolTipText ("<vol:><path>NLMname<.ext> <parameters>");
      getContentPane ().add (nlmTextField);
      
      // Buttons
      loadNLMButton = new JButton ("Load NLM");
      loadNLMButton.setToolTipText ("Load the specified NLM");
      loadNLMButton.setBounds (
                        (mainPaneWidth - buttonWidth) / 2 - (buttonWidth + emptySpace),
                        ((buttonHeight + emptySpace) * 2) + emptySpace,
                        buttonWidth,
                        buttonHeight);
      loadNLMButton.addActionListener (this);
      getContentPane ().add (loadNLMButton);
      unloadNLMButton = new JButton ("Unload NLM");
      unloadNLMButton.setToolTipText ("Unload the specified NLM");
      unloadNLMButton.setBounds (
                        (mainPaneWidth - buttonWidth) / 2,
                        ((buttonHeight + emptySpace) * 2) + emptySpace,
                        buttonWidth,
                        buttonHeight);
      unloadNLMButton.addActionListener (this);
      getContentPane ().add (unloadNLMButton);
      closeButton = new JButton ("Close");
      closeButton.setToolTipText ("Exit this window");
      closeButton.setBounds (
                        (mainPaneWidth - buttonWidth) / 2 + (buttonWidth + emptySpace),
                        ((buttonHeight + emptySpace) * 2) + emptySpace,
                        buttonWidth,
                        buttonHeight);
      closeButton.addActionListener (this);
      getContentPane ().add (closeButton);
   } // ServerMgmtFrame ()

   /**
    * ActionListener event handler method.
    */
   public void actionPerformed (
         ActionEvent event)
   {
      Object object = event.getSource ();
      String loadNLMText = nlmTextField.getText ();
      
      if (object == loadNLMButton)
      {
         if ((null != loadNLMText) && (!loadNLMText.equals ("")))
            ((NWServer) serverCtx).loadNLM (loadNLMText);
      }
      else if (object == unloadNLMButton)
      {
         if ((null != loadNLMText) && (!loadNLMText.equals ("")))
            ((NWServer) serverCtx).unloadNLM (loadNLMText);
      }
      else if (object == closeButton)
      {
         setVisible (false);
      }
   } // actionPerformed ()
} // class ServerMgmtFrame