// MenuItem.java
// By Ned Etcode
// Copyright 1996 Netscape Communications Corp.  All rights reserved.

package netscape.application;

import netscape.util.*;

/** Object subclass representing a single item in a Menu. A MenuItem stores a
  * reference to a java.awt.MenuItem, which it uses as the actual menu item
  * control. A MenuItem may or may not have a submenu. In general, you don't
  * create MenuItems yourself, but instead use Menu's <b>addItem()</b> and
  * <b>addItemWithSubmenu()</b> methods.
  * @see Menu
  */

public class MenuItem implements Cloneable, EventProcessor {
    Menu submenu, supermenu;
    FoundationMenuItem foundationMenuItem;
    String command;
    String title;
    Target target;
    char commandKey;


    /** Constructs an empty MenuItem.
      */
    public MenuItem() {
        this("temp", (char)0, null, null);
    }

    /** Constructs a MenuItem with the specified title, command, and
      * Target.
      */
    public MenuItem(String title, String command, Target target) {
        this(title, (char)0, command, target);
    }

    /** Constructs a MenuItem with the specified title, command key
      * equivalent, command, and Target.
      */
    public MenuItem(String title, char key, String command, Target target) {
        super();

        commandKey = Character.toUpperCase(key);
        foundationMenuItem = new FoundationMenuItem(title, this);
        setTitle(title);
        setTarget(target);
        setCommand(command);
    }

    /** Clones the MenuItem. Menu adds addtional items by cloning its
      * prototype MenuItem.
      */
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InconsistencyException(
                                this + ": clone() not supported :" + e);
        }
    }

    /** Returns the FoundationMenuItem associated with this MenuItem.
      */
    FoundationMenuItem foundationMenuItem() {
        return foundationMenuItem;
    }

    /** Sets this MenuItem to have the specified submenu.
      */
    public void setSubmenu(Menu aMenu) {
        submenu = aMenu;
        if (submenu != null) {
            submenu.setSuperitem(this);
        }
    }

    /** Returns the MenuItem's submenu, <b>null</b> if it doesn't have one.
      */
    public Menu submenu() {
        return submenu;
    }

    /** Returns <b>true</b> if this MenuItem has a submenu.
      * @see #setSubmenu
      */
    public boolean hasSubmenu() {
        if (submenu != null) {
            return true;
        } else {
            return false;
        }
    }

    /** Sets the MenuItem's supermenu.
      */
    public void setSupermenu(Menu aMenu) {
        supermenu = aMenu;
    }

    /** Returns the MenuItem's supermenu.
      * @see #setSupermenu
      */
    public Menu supermenu() {
        return supermenu;
    }

    /** Sets the MenuItem's command key equivalent.
      */
    public void setCommandKey(char key) {
        commandKey = Character.toUpperCase(key);
        setTitle(title);
    }

    /** Returns the MenuItem's command key equivalent, '\0' if it doesn't have
      * one.
      * @see #setCommandKey
      */
    public char commandKey() {
        return commandKey;
    }

    /** Sets the MenuItem's command.
      */
    public void setCommand(String newCommand) {
        command = newCommand;
    }

    /** Returns the MenuItem's command.
      * @see #setCommand
      */
    public String command() {
        return command;
    }

    /** Sets the MenuItem's Target.
      */
    public void setTarget(Target aTarget) {
        target = aTarget;
    }

    /** Returns the MenuItem's Target.
      * @see #setTarget
      */
    public Target target() {
        return target;
    }

    /** Called by the EventLoop to process a selection event. Calls
      * <b>sendCommand()</b>.
      */
    public void processEvent(Event event) {
        sendCommand();
    }

    /** Tells the MenuItem to send its command to its Target.
      * @see #setTarget
      */
    public void sendCommand() {
        if (target != null) {
            target.performCommand(command, this);
        }
    }

    // ALERT.  This is doing OS checks.  Be afraid.
    private boolean canUseTabFormatter() {
        if ("x86".equals(System.getProperty("os.arch")) ||
            "Pentium".equals(System.getProperty("os.arch"))) {
            return true;
        } else {
            return false;
        }
    }

    /** Sets the MenuItem's title.
      */
    public void setTitle(String aString) {
        FontMetrics   metrics;
        String        tmpString;
        StringBuffer  buf;
        int           numSpaces, i, maxWidth, width;

        tmpString = aString;
        title = aString;
        if (commandKey() != 0) {
            if (canUseTabFormatter()) {
                tmpString = aString + "\tCtrl+" + commandKey();
            } else {
                buf = new StringBuffer();
                metrics = font().fontMetrics();
                maxWidth = supermenu().maxMenuItemWidth();
                width = metrics.stringWidth(aString);

                buf.append(aString);
                numSpaces = (maxWidth - width) / metrics.stringWidth(" ");
                for (i = 0; i < numSpaces; i++) {
                    buf.append(' ');
                }
                tmpString = buf.toString() + "  Ctrl+" + commandKey();
            }
        }
        foundationMenuItem.setLabel(tmpString);
    }

    /** Returns the MenuItem's title.
      */
    public String title() {
        //return foundationMenuItem.getLabel();
        return title;
    }

    /** Enables or disables the MenuItem. Disabled MenuItems cannot be
      * selected and render their title using Color.gray. If this MenuItem has
      * a submenu, it enables or disables it as well.
      */
    public void setEnabled(boolean flag) {
        if (hasSubmenu()) {
            submenu.awtMenu().enable(flag);
        } else {
            foundationMenuItem.enable(flag);
        }
    }

    /** Returns <b>true</b> if the MenuItem is enabled.
      * @see #setEnabled
      */
    public boolean isEnabled() {
        if (hasSubmenu()) {
            return submenu.awtMenu().isEnabled();
        } else {
            return foundationMenuItem.isEnabled();
        }
    }

    /** Sets the Font used to display the MenuItem's title.
      */
    public void setFont(Font font) {
        java.awt.Font awtFont;

        awtFont = AWTCompatibility.awtFontForFont(font);
        foundationMenuItem.setFont(awtFont);
    }

    /** Returns the Font used to display the MenuItem's title.
      * @see #setFont
      */
    public Font font() {
        Font font;

        font = AWTCompatibility.fontForAWTFont(foundationMenuItem.getFont());
        return font;
    }
}
