/*
 * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package sun.awt.X11;

import java.awt.*;
import java.awt.peer.*;
import java.awt.event.*;

import java.lang.reflect.Field;
import java.util.Vector;
import java.util.logging.*;
import sun.awt.SunToolkit;

public class XMenuBarPeer extends XBaseMenuWindow implements MenuBarPeer {

    /************************************************
     *
     * Data members
     *
     ************************************************/

    private static Logger log = Logger.getLogger("sun.awt.X11.XMenuBarPeer");

    /*
     * Primary members
     */
    private XFramePeer framePeer;
    private MenuBar menuBarTarget;

    /*
     * Index of help menu
     */
    private XMenuPeer helpMenu = null;

    /*
     * dimension constants
     */
    private final static int BAR_SPACING_TOP = 3;
    private final static int BAR_SPACING_BOTTOM = 3;
    private final static int BAR_SPACING_LEFT = 3;
    private final static int BAR_SPACING_RIGHT = 3;
    private final static int BAR_ITEM_SPACING = 2;
    private final static int BAR_ITEM_MARGIN_LEFT = 10;
    private final static int BAR_ITEM_MARGIN_RIGHT = 10;
    private final static int BAR_ITEM_MARGIN_TOP = 2;
    private final static int BAR_ITEM_MARGIN_BOTTOM = 2;

    //fields
    private static Field f_helpMenu;
    private static Field f_menus;

    static {
        f_helpMenu = SunToolkit.getField(MenuBar.class, "helpMenu");
        f_menus = SunToolkit.getField(MenuBar.class, "menus");
    }

    /************************************************
     *
     * Mapping data
     *
     ************************************************/

    /**
     * XBaseMenuWindow's mappingData is extended with
     * desired height of menu bar
     */
    static class MappingData extends XBaseMenuWindow.MappingData {
        int desiredHeight;

        MappingData(XMenuItemPeer[] items, int desiredHeight) {
            super(items);
            this.desiredHeight = desiredHeight;
        }

        /**
         * Constructs MappingData without items
         * This constructor should be used in case of errors
         */
        MappingData() {
            this.desiredHeight = 0;
        }

        public int getDesiredHeight() {
            return this.desiredHeight;
        }
    }

    /************************************************
     *
     * Construction
     *
     ************************************************/
    XMenuBarPeer(MenuBar menuBarTarget) {
        this.menuBarTarget = menuBarTarget;
    }

    /************************************************
     *
     * Implementaion of interface methods
     *
     ************************************************/

    /*
     * From MenuComponentPeer
     */
    public void setFont(Font f) {
        resetMapping();
        setItemsFont(f);
        postPaintEvent();
    }

    /*
     * From MenuBarPeer
     */

    /*
     * Functions addMenu, delMenu, addHelpMenu
     * need to have somewhat strange behaivour
     * deduced from java.awt.MenuBar.
     * We can not get index of particular item in
     * MenuBar.menus array, because MenuBar firstly
     * performs array operations and then calls peer.
     * So we need to synchronize indicies in 'items'
     * array with MenuBar.menus. We have to follow
     * these rules:
     * 1. Menus are always added to the end of array,
     * even when helpMenu is present
     * 2. Removal of any menu item acts as casual
     * remove from array
     * 3. MenuBar.setHelpMenu _firstly_ removes
     * previous helpMenu by calling delMenu() if
     * necessary, then it performs addMenu(),
     * and then - addHelpMenu().
     *
     * Note that these functions don't perform
     * type checks and checks for nulls or duplicates
     */
    public void addMenu(Menu m) {
        addItem(m);
        postPaintEvent();
    }

    public void delMenu(int index) {
        synchronized(getMenuTreeLock()) {
            XMenuItemPeer item = getItem(index);
            if (item != null && item == helpMenu) {
                helpMenu = null;
            }
            delItem(index);
        }
        postPaintEvent();
    }

    public void addHelpMenu(Menu m) {
        XMenuPeer mp = (XMenuPeer)m.getPeer();
        synchronized(getMenuTreeLock()) {
            helpMenu = mp;
        }
        postPaintEvent();
    }

    /************************************************
     *
     * Initialization
     *
     ************************************************/
    /**
     * called from XFramePeer.setMenuBar
     */
    public void init(Frame frame) {
        this.target = frame;
        this.framePeer = (XFramePeer)frame.getPeer();
        XCreateWindowParams params = getDelayedParams();
        params.remove(DELAYED);
        params.add(PARENT_WINDOW, framePeer.getShell());
        params.add(TARGET, frame);
        init(params);
    }

    /**
     * Overriden initialization
     */
    void postInit(XCreateWindowParams params) {
        super.postInit(params);
        Vector targetMenuVector = null;
        Menu targetHelpMenu = null;
        try {
            // Get menus from the target.
            targetMenuVector = (Vector)f_menus.get(menuBarTarget);
            targetHelpMenu = (Menu)f_helpMenu.get(menuBarTarget);
            reloadItems(targetMenuVector);
        } catch (IllegalAccessException iae) {
            iae.printStackTrace();
        }
        if (targetHelpMenu != null) {
            addHelpMenu(targetHelpMenu);
        }
        xSetVisible(true);
        toFront();
    }

    /************************************************
     *
     * Implementation of abstract methods
     *
     ************************************************/

    /**
     * Menu bar is always root window in menu window's
     * hierarchy
     */
    protected XBaseMenuWindow getParentMenuWindow() {
        return null;
    }

    /**
     * @see XBaseMenuWindow.map
     */
    protected MappingData map() {
        XMenuItemPeer[] itemVector = copyItems();
        int itemCnt = itemVector.length;
        XMenuItemPeer helpMenu = this.helpMenu;
        int helpMenuPos = -1;
        //find helpMenu and move it to the end of array
        if (helpMenu != null) {
            //Fixed 6270847: PIT: HELP menu is not shown at the right place when normal menus added to MB are removed, XToolkit
            for (int i = 0; i < itemCnt; i++) {
                if (itemVector[i] == helpMenu) {
                    helpMenuPos = i;
                    break;
                }
            }
            if (helpMenuPos != -1 && helpMenuPos != itemCnt - 1) {
                System.arraycopy(itemVector, helpMenuPos + 1, itemVector, helpMenuPos, itemCnt - 1 - helpMenuPos);
                itemVector[itemCnt - 1] = helpMenu;
            }
        }
        //We need maximum height before calculating item's bounds
        int maxHeight = 0;
        XMenuItemPeer.TextMetrics[] itemMetrics = new XMenuItemPeer.TextMetrics[itemCnt];
        for (int i = 0; i < itemCnt; i++) {
            itemMetrics[i] = itemVector[i].getTextMetrics();
            Dimension dim = itemMetrics[i].getTextDimension();
            if (dim != null) {
                maxHeight = Math.max(maxHeight, dim.height);
            }
        }
        //Calculate bounds
        int nextOffset = 0;
        int itemHeight = BAR_ITEM_MARGIN_TOP + maxHeight + BAR_ITEM_MARGIN_BOTTOM;
        int mappedCnt = itemCnt;
        for (int i = 0; i < itemCnt; i++) {
            XMenuItemPeer item = itemVector[i];
            XMenuItemPeer.TextMetrics metrics = itemMetrics[i];
            Dimension dim = metrics.getTextDimension();
            if (dim != null) {
                int itemWidth = BAR_ITEM_MARGIN_LEFT + dim.width + BAR_ITEM_MARGIN_RIGHT;
                //Fix for 6270757: PIT: Menus and Sub-menus are shown outside the frame, XToolkit
                //Cut-off items that don't fit in window
                //At least one item must remain in menu
                if ((nextOffset + itemWidth > this.width) && (i > 0)) {
                    mappedCnt = i;
                    break;
                }
                //If this item is help menu, move it to the right edge
                if ((i == itemCnt - 1) && helpMenuPos != -1) {
                    nextOffset = Math.max(nextOffset, this.width - itemWidth - BAR_SPACING_RIGHT);
                }
                Rectangle bounds = new Rectangle(nextOffset, BAR_SPACING_TOP, itemWidth, itemHeight);
                //text should be centered vertically in menu item's bounds
                int y = (maxHeight + dim.height) / 2  - metrics.getTextBaseline();
                Point textOrigin = new Point(nextOffset + BAR_ITEM_MARGIN_LEFT, BAR_SPACING_TOP + BAR_ITEM_MARGIN_TOP + y);
                nextOffset += itemWidth + BAR_ITEM_SPACING;
                item.map(bounds, textOrigin);
            } else {
                Rectangle bounds = new Rectangle(nextOffset, BAR_SPACING_TOP, 0, 0);
                Point textOrigin = new Point(nextOffset + BAR_ITEM_MARGIN_LEFT, BAR_SPACING_TOP + BAR_ITEM_MARGIN_TOP);
            }
        }
        XMenuItemPeer mappedVector[] = new XMenuItemPeer[mappedCnt];
        System.arraycopy(itemVector, 0, mappedVector, 0, mappedCnt);
        MappingData mappingData = new MappingData(mappedVector, BAR_SPACING_TOP + itemHeight + BAR_SPACING_BOTTOM);
        return mappingData;
    }

    /**
     * @see XBaseMenuWindow.getSubmenuBounds
     */
    protected Rectangle getSubmenuBounds(Rectangle itemBounds, Dimension windowSize) {
        Rectangle globalBounds = toGlobal(itemBounds);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Rectangle res;
        res = fitWindowBelow(globalBounds, windowSize, screenSize);
        if (res != null) {
            return res;
        }
        res = fitWindowAbove(globalBounds, windowSize, screenSize);
        if (res != null) {
            return res;
        }
        res = fitWindowRight(globalBounds, windowSize, screenSize);
        if (res != null) {
            return res;
        }
        res = fitWindowLeft(globalBounds, windowSize, screenSize);
        if (res != null) {
            return res;
        }
        return fitWindowToScreen(windowSize, screenSize);
    }

    /**
     * This function is called when it's likely that
     * size of items has changed.
     * Invokes framePeer's updateChildrenSizes()
     */
    protected void updateSize() {
        resetMapping();
        if (framePeer != null) {
            framePeer.reshapeMenubarPeer();
        }
    }

    /************************************************
     *
     * Utility functions
     *
     ************************************************/

    /**
     * Returns desired height of menu bar
     */
    int getDesiredHeight() {
        MappingData mappingData = (MappingData)getMappingData();
        return mappingData.getDesiredHeight();
    }

    /**
     * Returns true if framePeer is not null and is enabled
     * Used to fix 6185057: Disabling a frame does not disable
     * the menus on the frame, on solaris/linux
     */
    boolean isFramePeerEnabled() {
        if (framePeer != null) {
            return framePeer.isEnabled();
        }
        return false;
    }

    /************************************************
     *
     * Overriden XBaseMenuWindow functions
     *
     ************************************************/

    /**
     * @see XBaseMenuWindow.doDispose()
     */
    protected void doDispose() {
        super.doDispose();
        XToolkit.targetDisposedPeer(menuBarTarget, this);
    }

    /************************************************
     *
     * Overriden XWindow general-purpose functions
     *
     ************************************************/

    /**
     * For menu bars this function is called from framePeer's
     * reshape(...) and updateChildrenSizes()
     */
    public void reshape(int x, int y, int width, int height) {
        if ((width != this.width) || (height != this.height)) {
            resetMapping();
        }
        super.reshape(x, y, width, height);
    }

    /**
     * Performs ungrabbing of input
     * @see XBaseWindow.ungrabInputImpl()
     */
    void ungrabInputImpl() {
        selectItem(null, false);
        super.ungrabInputImpl();
        postPaintEvent();
    }

    /************************************************
     *
     * Overriden XWindow painting & printing
     *
     ************************************************/
    public void paint(Graphics g) {
        resetColors();
        /* Calculate menubar dimension. */
        int width = getWidth();
        int height = getHeight();

        flush();
        //Fill background of rectangle
        g.setColor(getBackgroundColor());
        g.fillRect(1, 1, width - 2, height - 2);

        draw3DRect(g, 0, 0, width, height, true);

        //Paint menus
        MappingData mappingData = (MappingData)getMappingData();
        XMenuItemPeer[] itemVector = mappingData.getItems();
        XMenuItemPeer selectedItem = getSelectedItem();
        for (int i = 0; i < itemVector.length; i++) {
            XMenuItemPeer item = itemVector[i];
            //paint item
            g.setFont(item.getTargetFont());
            Rectangle bounds = item.getBounds();
            Point textOrigin = item.getTextOrigin();
            if (item == selectedItem) {
                g.setColor(getSelectedColor());
                g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
                draw3DRect(g, bounds.x, bounds.y, bounds.width, bounds.height, false);
            }
            if (isFramePeerEnabled() && item.isTargetItemEnabled()) {
                g.setColor(getForegroundColor());
            } else {
                g.setColor(getDisabledColor());
            }
            g.drawString(item.getTargetLabel(), textOrigin.x, textOrigin.y);
        }
        flush();
    }

    static final int W_DIFF = (XFramePeer.CROSSHAIR_INSET + 1) * 2;
    static final int H_DIFF = XFramePeer.BUTTON_Y + XFramePeer.BUTTON_H;

    void print(Graphics g) {
        //TODO:Implement
    }

    /************************************************
     *
     * Overriden XBaseMenuWindow event handling
     *
     ************************************************/
    protected void handleEvent(AWTEvent event) {
        // explicitly block all events except PaintEvent.PAINT for menus,
        // that are in the modal blocked window
        if ((framePeer != null) &&
            (event.getID() != PaintEvent.PAINT))
        {
            if (framePeer.isModalBlocked()) {
                return;
            }
        }
        switch(event.getID()) {
        case MouseEvent.MOUSE_PRESSED:
        case MouseEvent.MOUSE_RELEASED:
        case MouseEvent.MOUSE_CLICKED:
        case MouseEvent.MOUSE_MOVED:
        case MouseEvent.MOUSE_ENTERED:
        case MouseEvent.MOUSE_EXITED:
        case MouseEvent.MOUSE_DRAGGED:
            //Fix for 6185057: Disabling a frame does not disable
            //the menus on the frame, on solaris/linux
            if (isFramePeerEnabled()) {
                doHandleJavaMouseEvent((MouseEvent)event);
            }
            break;
        case KeyEvent.KEY_PRESSED:
        case KeyEvent.KEY_RELEASED:
            //Fix for 6185057: Disabling a frame does not disable
            //the menus on the frame, on solaris/linux
            if (isFramePeerEnabled()) {
                doHandleJavaKeyEvent((KeyEvent)event);
            }
            break;
        default:
            super.handleEvent(event);
            break;
        }
    }



    /************************************************
     *
     * Overriden XWindow keyboard processing
     *
     ************************************************/

    /*
     * This function is called from XWindow
     * @see XWindow.handleF10onEDT()
     */
    void handleF10KeyPress(KeyEvent event) {
        int keyState = event.getModifiers();
        if (((keyState & InputEvent.ALT_MASK) != 0) ||
            ((keyState & InputEvent.SHIFT_MASK) != 0) ||
            ((keyState & InputEvent.CTRL_MASK) != 0)) {
            return;
        }
        grabInput();
        selectItem(getFirstSelectableItem(), true);
    }

    /*
     * In previous version keys were handled in handleKeyPress.
     * Now we override this function do disable F10 explicit
     * processing. All processing is done using KeyEvent.
     */
    public void handleKeyPress(XEvent xev) {
        XKeyEvent xkey = xev.get_xkey();
        if (log.isLoggable(Level.FINE)) log.fine(xkey.toString());
        if (isEventDisabled(xev)) {
            return;
        }
        final Component currentSource = (Component)getEventSource();
        //This is the only difference from XWindow.handleKeyPress
        //Ancestor's function can invoke handleF10KeyPress here
        handleKeyPress(xkey);
    }

} //class XMenuBarPeer
