/*******************************************************************************
*                                                                              *
*  File:        Applet_03.java                          Revision:  1.0         *
*                                                                              *
*  Contents:    an applet examining it's context                               *
*                                                                              *
*  Creation:    09.07.1996                     Last Modification:  17.04.2002  *
*                                                                              *
*  Platform:    IBM-compatible PC running Windows 98SE                         *
*                                                                              *
*  Environment: Java 1.4                                                       *
*                                                                              *
*  Author:      Andreas Rozek           Phone:  ++49 (711) 6770682             *
*               Kirschblütenweg 15      Fax:    -                              *
*             D-70569 Stuttgart         EMail:  Andreas.Rozek@T-Online.De      *
*               Germany                                                        *
*                                                                              *
*  URL:         http://www.Andreas-Rozek.de/                                   *
*                                                                              *
*  Copyright:   this software is published under the "GNU General Public Li-   *
*               cense" (see "http://www.gnu.org/copyleft/gpl.html" for addi-   *
*               tional information)                                            *
*                                                                              *
*  Comments:    meanwhile, the original source code (for Java 1.0.2) has been  *
*               updated in order to compile under Java 1.1.8 and Java 1.4 w/o  *
*               major problems                                                 *
*                                                                              *
*******************************************************************************/

import java.applet.*;                                    // basic applet classes
import java.awt.*;                           // basic AWT classes (& interfaces)
import java.io.*;                            // Java file handling and stream IO
import java.util.*;                  // Java utility classes and data structures

public class Applet_03 extends java.applet.Applet {

/**** information about author, version and copyright of this applet ****/

  final static String  AppletInfo =
//  "Applet_03 - an example for applet parameter parsing\n" +
    "\n" +
    "Andreas Rozek\n" +
    "Kirschblütenweg 15\n" +
    "D-70569 Stuttgart\n" +
    "Germany\n" +
    "\n" +
    "Phone: ++49 (711) 6770682\n" +
    "Fax: -\n" +
    "EMail: Andreas.Rozek@T-Online.De\n" +
    "URL: http://www.Andreas-Rozek.de";

/**** information about foreseen applet parameters ****/

  final static String[][]  ParameterInfo = {
    {"Name", "String", "distinguishes the three different instances of Applet_03"}
  };

/**** desired applet insets ****/

  final static Insets  AppletInsets = new Insets(0,4,4,4);

/**** for an easier instance discrimination ****/

  int  Variant;             // indicates which if the 3 instances THIS applet is

  final static int AppletDisplay        = 0;
  final static int AppletInfoDisplay    = 1;
  final static int ParameterInfoDisplay = 2;

/**** user interface components ****/

  java.awt.List AppletList = null;                             // applet display
  TextArea  AppletArea = null;                     // applet information display
  TextArea  ParameterArea = null;               // parameter information display

/*******************************************************************************
*                                                                              *
* getApplet   provides an alternative to Netscape's buggy AppletContext method *
*                                                                              *
*******************************************************************************/

  public Applet getApplet (String AppletName) {
    Enumeration AppletSet = getAppletContext().getApplets();
    while (AppletSet.hasMoreElements()) {
      Applet Neighbour = (Applet) AppletSet.nextElement();
      String Name      = Neighbour.getParameter("Name");
      if ((Name != null) && Name.equals(AppletName)) return Neighbour;
    };

    return null;
  };

/*******************************************************************************
*                                                                              *
* getAppletInfo       provides information about author, version and copyright *
*                                                                              *
*******************************************************************************/

  public String getAppletInfo () {
    String  Name = getParameter("Name");

    if (Name == null) {
      return "Applet_03\n" + AppletInfo;
    } else {
      return "Applet_03 - " + Name + "\n" + AppletInfo;
    }
  };

/*******************************************************************************
*                                                                              *
* getInsets                                       returns actual applet insets *
*                                                                              *
*******************************************************************************/

  public final Insets getInsets () {
    return AppletInsets;
  };

/*******************************************************************************
*                                                                              *
* getParameter                     synchronized version of the original method *
*                                                                              *
*******************************************************************************/

  public synchronized String getParameter (String Name) {
    return super.getParameter(Name);
  };

/*******************************************************************************
*                                                                              *
* getParameterInfo       provides information about foreseen applet parameters *
*                                                                              *
*******************************************************************************/

  public String[][] getParameterInfo () {
    return ParameterInfo;         // see above for definition of "ParameterInfo"
  };

/*******************************************************************************
*                                                                              *
* handleEvent                                               main event handler *
*                                                                              *
*******************************************************************************/

  public synchronized boolean handleEvent (Event AWTEvent) {
    if (AWTEvent.id == Event.LIST_SELECT) {
      AppletContext  Context = getAppletContext();

    /**** which applet has been selected? ****/

      String  AppletName     = AppletList.getItem(((Integer) AWTEvent.arg).intValue());
//    Applet  AppletInstance = Context.getApplet(AppletName);
      Applet  AppletInstance = getApplet(AppletName);

      if (AppletInstance == null) return false;            // just to be sure...

    /**** show corresponding applet and parameter info ****/

//    Applet_03  InfoDisplay = (Applet_03) Context.getApplet("Applet Information Display");
      Applet_03  InfoDisplay = (Applet_03) getApplet("Applet Information Display");

      if (InfoDisplay != null) {
        InfoDisplay.AppletArea.setText(AppletInstance.getAppletInfo());
      };

//    Applet_03  ParameterDisplay = (Applet_03) Context.getApplet("Parameter Information Display");
      Applet_03  ParameterDisplay = (Applet_03) getApplet("Parameter Information Display");

      if (ParameterDisplay != null) {
        String[][] ParameterInfo = AppletInstance.getParameterInfo();

        ParameterDisplay.ParameterArea.setText("");
        for (int i = 0; i < ParameterInfo.length; i++) {
          ParameterDisplay.ParameterArea.append(
            ParameterInfo[i][0] + " -- " +
            ParameterInfo[i][1] + " -- " +
            ParameterInfo[i][2]
          );
        };
      };
    };

    return false;
  };

/*******************************************************************************
*                                                                              *
* init                  initialize an applet each time it's loaded or reloaded *
*                                                                              *
*******************************************************************************/

  public void init () {
    Label  TextLabel;                         // temporarily stores a text label

  /**** determine, which of the three instances THIS applet is ****/

    String Name = getParameter("Name");
    if (Name == null) Name = "applet context examination";

    int Variant = AppletDisplay;
    if (Name.equals("Applet Information Display"))     Variant = AppletInfoDisplay;
    if (Name.equals("Parameter Information Display"))  Variant = ParameterInfoDisplay;

  /**** unify the visual appearance of an applet on different platforms ****/

    setBackground(Color.lightGray);
    setFont(new Font("Helvetica", Font.PLAIN, 11));

  /**** prepare user interface ****/

    setLayout(new GridBagLayout());

    TextLabel = new Label("Applet_03 - " + Name);
      TextLabel.setFont(new Font("Helvetica", Font.BOLD, 12));
      add_GridItem(TextLabel,  0,0, 1,1, fill_x,    0,0, 1,2,0,0, align_w, 0,0);
      add_GridItem(new ColorBox(0,2, Color.black),
                               0,1, 1,1, fill_x,    0,0, 0,0,4,0, align_w, 0,0);

  /**** distinguish between three different variants ****/

    switch (Variant) {
      case AppletDisplay:
        TextLabel = new Label("List of available Applets:");
          add_GridItem(TextLabel,  0,2, 1,1, fill_x,    0,0, 0,2,0,0, align_w, 0,0);
        AppletList = new java.awt.List();
          add_GridItem(AppletList, 0,3, 1,1, fill_both, 0,0, 0,0,0,0, align_w, 9,9);

      /**** create a list of available applets ****/

        Enumeration AppletSet = getAppletContext().getApplets();
        while (AppletSet.hasMoreElements()) {
          Applet Neighbour = (Applet) AppletSet.nextElement();
          AppletList.add(Neighbour.getParameter("Name"));
        };

        break;
      case AppletInfoDisplay:
        TextLabel = new Label("Applet Information:");
          add_GridItem(TextLabel,  0,2, 1,1, fill_x,    0,0, 0,2,0,0, align_w, 0,0);
        AppletArea = new TextArea();
          AppletArea.setText("(no applet selected)");
          add_GridItem(AppletArea, 0,3, 1,1, fill_both, 0,0, 0,0,0,0, align_w, 9,9);

        break;
      case ParameterInfoDisplay:
        TextLabel = new Label("Parameter Information:");
          add_GridItem(TextLabel,     0,2, 1,1, fill_x,    0,0, 0,2,0,0, align_w, 0,0);
        ParameterArea = new TextArea();
          ParameterArea.setText("(no applet selected)");
          add_GridItem(ParameterArea, 0,3, 1,1, fill_both, 0,0, 0,0,0,0, align_w, 9,9);
    };

  /**** resize and show applet ****/

//  resize(preferredSize());
    setVisible(true);
  };

/*******************************************************************************
*                                                                              *
* paint                                              (re)draws applet contents *
*                                                                              *
*******************************************************************************/

  public void paint (Graphics Graf) {
    int  Width  = getSize().width-1;                // "cache" applet dimensions
    int  Height = getSize().height-1;

  /**** draw border with "3D" effect ****/

    Graf.setColor(Color.white);
      Graf.drawLine(0,0, Width-1,0);        Graf.drawLine(0,0, 0,Height);
    Graf.setColor(Color.gray);
      Graf.drawLine(Width,0, Width,Height); Graf.drawLine(1,Height, Width,Height);
  };

/*******************************************************************************
*                                                                              *
*                         Assisting Fields and Methods                         *
*                                                                              *
*******************************************************************************/

/**** local equivalents of "GridBagConstraints" constants ****/

  final static int align_c  = GridBagConstraints.CENTER;
  final static int align_n  = GridBagConstraints.NORTH;
  final static int align_ne = GridBagConstraints.NORTHEAST;
  final static int align_e  = GridBagConstraints.EAST;
  final static int align_se = GridBagConstraints.SOUTHEAST;
  final static int align_s  = GridBagConstraints.SOUTH;
  final static int align_sw = GridBagConstraints.SOUTHWEST;
  final static int align_w  = GridBagConstraints.WEST;
  final static int align_nw = GridBagConstraints.NORTHWEST;

  final static int fill_none = GridBagConstraints.NONE;
  final static int fill_x    = GridBagConstraints.HORIZONTAL;
  final static int fill_y    = GridBagConstraints.VERTICAL;
  final static int fill_both = GridBagConstraints.BOTH;

/*******************************************************************************
*                                                                              *
* add_GridItem   adds a "Component" to a "GridBag" using the given constraints *
*                                                                              *
*******************************************************************************/

  void add_GridItem (
    Component  Item,                         // the item to be added to the grid
    int  GridX,              // leftmost column to be occupied by a grid element
    int  GridY,                  // topmost row to be occupied by a grid element
    int  GridWidth,        // number of columns to be occupied by a grid element
    int  GridHeight,          // number of rows to be occupied by a grid element
    int  Fill,          // in which direction should a grid element be expanded?
    int  IPadX,                                   // internal horizontal padding
    int  IPadY,                                     // internal vertical padding
    int  InsetTop,                   // top margin between cell and grid element
    int  InsetLeft,                 // left margin between cell and grid element
    int  InsetBottom,             // bottom margin between cell and grid element
    int  InsetRight,               // right margin between cell and grid element
    int  Anchor,                         // grid element alignment inside a cell
    int  WeightX,       // element "priority" for gaining extra horizontal space
    int  WeightY          // element "priority" for gaining extra vertical space
  ) {
    if (Item == null) return;

  /**** create a new "GridBagConstraints" object... ****/

    GridBagConstraints  Constraints = new GridBagConstraints();

  /**** fill in the given arguments... ****/

    Constraints.gridx = GridX;
    Constraints.gridy = GridY;

    Constraints.gridwidth  = GridWidth;
    Constraints.gridheight = GridHeight;

    Constraints.fill = Fill;

    Constraints.ipadx = IPadX;
    Constraints.ipady = IPadY;

    Constraints.insets = new Insets(InsetTop, InsetLeft, InsetBottom, InsetRight);

    Constraints.anchor = Anchor;

    Constraints.weightx = Math.max(0,Math.min(99,WeightX)) * 100.0;
    Constraints.weighty = Math.max(0,Math.min(99,WeightY)) * 100.0;

  /**** then add "Item" using the given constraints ****/

    add(Item);
    ((GridBagLayout) getLayout()).setConstraints(Item,Constraints);
  };
};




/*******************************************************************************
*                                                                              *
*                                   ColorBox                                   *
*                                                                              *
*******************************************************************************/

class ColorBox extends Canvas {
  int Width, Height;                                       // desired dimensions

  public ColorBox (int LineWidth, int LineHeight, Color LineColor) {
    super();                                              // just to be complete

    Width  = Math.max(0,LineWidth);
    Height = Math.max(0,LineHeight);

    setBackground(LineColor);
  };

  public Dimension getMinimumSize () {
    return new Dimension((Width == 0 ? 1 : Width),(Height == 0 ? 1 : Height));
  };

  public Dimension getPreferredSize () {
    return new Dimension((Width  == 0 ? Math.max(getSize().width, 1) : Width),
                         (Height == 0 ? Math.max(getSize().height,1) : Height));
  };
};

