/*
 * Copyright (c) 2002, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.swing;

import static sun.swing.SwingUtilities2.BASICMENUITEMUI_MAX_TEXT_OFFSET;

import javax.swing.*;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.Map;
import java.util.HashMap;

/**
 * Calculates preferred size and layouts menu items.
 */
public class MenuItemLayoutHelper {

    /* Client Property keys for calculation of maximal widths */
    public static final StringUIClientPropertyKey MAX_ARROW_WIDTH =
                        new StringUIClientPropertyKey("maxArrowWidth");
    public static final StringUIClientPropertyKey MAX_CHECK_WIDTH =
                        new StringUIClientPropertyKey("maxCheckWidth");
    public static final StringUIClientPropertyKey MAX_ICON_WIDTH =
                        new StringUIClientPropertyKey("maxIconWidth");
    public static final StringUIClientPropertyKey MAX_TEXT_WIDTH =
                        new StringUIClientPropertyKey("maxTextWidth");
    public static final StringUIClientPropertyKey MAX_ACC_WIDTH =
                        new StringUIClientPropertyKey("maxAccWidth");
    public static final StringUIClientPropertyKey MAX_LABEL_WIDTH =
                        new StringUIClientPropertyKey("maxLabelWidth");

    private JMenuItem mi;
    private JComponent miParent;

    private Font font;
    private Font accFont;
    private FontMetrics fm;
    private FontMetrics accFm;

    private Icon icon;
    private Icon checkIcon;
    private Icon arrowIcon;
    private String text;
    private String accText;

    private boolean isColumnLayout;
    private boolean useCheckAndArrow;
    private boolean isLeftToRight;
    private boolean isTopLevelMenu;
    private View htmlView;

    private int verticalAlignment;
    private int horizontalAlignment;
    private int verticalTextPosition;
    private int horizontalTextPosition;
    private int gap;
    private int leadingGap;
    private int afterCheckIconGap;
    private int minTextOffset;

    private int leftTextExtraWidth;

    private Rectangle viewRect;

    private RectSize iconSize;
    private RectSize textSize;
    private RectSize accSize;
    private RectSize checkSize;
    private RectSize arrowSize;
    private RectSize labelSize;

    /**
     * The empty protected constructor is necessary for derived classes.
     */
    protected MenuItemLayoutHelper() {
    }

    public MenuItemLayoutHelper(JMenuItem mi, Icon checkIcon, Icon arrowIcon,
                      Rectangle viewRect, int gap, String accDelimiter,
                      boolean isLeftToRight, Font font, Font accFont,
                      boolean useCheckAndArrow, String propertyPrefix) {
        reset(mi, checkIcon, arrowIcon, viewRect, gap, accDelimiter,
              isLeftToRight, font, accFont, useCheckAndArrow, propertyPrefix);
    }

    protected void reset(JMenuItem mi, Icon checkIcon, Icon arrowIcon,
                      Rectangle viewRect, int gap, String accDelimiter,
                      boolean isLeftToRight, Font font, Font accFont,
                      boolean useCheckAndArrow, String propertyPrefix) {
        this.mi = mi;
        this.miParent = getMenuItemParent(mi);
        this.accText = getAccText(accDelimiter);
        this.verticalAlignment = mi.getVerticalAlignment();
        this.horizontalAlignment = mi.getHorizontalAlignment();
        this.verticalTextPosition = mi.getVerticalTextPosition();
        this.horizontalTextPosition = mi.getHorizontalTextPosition();
        this.useCheckAndArrow = useCheckAndArrow;
        this.font = font;
        this.accFont = accFont;
        this.fm = mi.getFontMetrics(font);
        this.accFm = mi.getFontMetrics(accFont);
        this.isLeftToRight = isLeftToRight;
        this.isColumnLayout = isColumnLayout(isLeftToRight,
                horizontalAlignment, horizontalTextPosition,
                verticalTextPosition);
        this.isTopLevelMenu = (this.miParent == null) ? true : false;
        this.checkIcon = checkIcon;
        this.icon = getIcon(propertyPrefix);
        this.arrowIcon = arrowIcon;
        this.text = mi.getText();
        this.gap = gap;
        this.afterCheckIconGap = getAfterCheckIconGap(propertyPrefix);
        this.minTextOffset = getMinTextOffset(propertyPrefix);
        this.htmlView = (View) mi.getClientProperty(BasicHTML.propertyKey);
        this.viewRect = viewRect;

        this.iconSize = new RectSize();
        this.textSize = new RectSize();
        this.accSize = new RectSize();
        this.checkSize = new RectSize();
        this.arrowSize = new RectSize();
        this.labelSize = new RectSize();
        calcExtraWidths();
        calcWidthsAndHeights();
        setOriginalWidths();
        calcMaxWidths();

        this.leadingGap = getLeadingGap(propertyPrefix);
        calcMaxTextOffset(viewRect);
    }

    private void calcExtraWidths() {
        leftTextExtraWidth = getLeftExtraWidth(text);
    }

    private int getLeftExtraWidth(String str) {
        int lsb = SwingUtilities2.getLeftSideBearing(mi, fm, str);
        if (lsb < 0) {
            return -lsb;
        } else {
            return 0;
        }
    }

    private void setOriginalWidths() {
        iconSize.origWidth = iconSize.width;
        textSize.origWidth = textSize.width;
        accSize.origWidth = accSize.width;
        checkSize.origWidth = checkSize.width;
        arrowSize.origWidth = arrowSize.width;
    }

    private String getAccText(String acceleratorDelimiter) {
        String accText = "";
        KeyStroke accelerator = mi.getAccelerator();
        if (accelerator != null) {
            int modifiers = accelerator.getModifiers();
            if (modifiers > 0) {
                accText = KeyEvent.getKeyModifiersText(modifiers);
                accText += acceleratorDelimiter;
            }
            int keyCode = accelerator.getKeyCode();
            if (keyCode != 0) {
                accText += KeyEvent.getKeyText(keyCode);
            } else {
                accText += accelerator.getKeyChar();
            }
        }
        return accText;
    }

    private Icon getIcon(String propertyPrefix) {
        // In case of column layout, .checkIconFactory is defined for this UI,
        // the icon is compatible with it and useCheckAndArrow() is true,
        // then the icon is handled by the checkIcon.
        Icon icon = null;
        MenuItemCheckIconFactory iconFactory =
                (MenuItemCheckIconFactory) UIManager.get(propertyPrefix
                        + ".checkIconFactory");
        if (!isColumnLayout || !useCheckAndArrow || iconFactory == null
                || !iconFactory.isCompatible(checkIcon, propertyPrefix)) {
            icon = mi.getIcon();
        }
        return icon;
    }

    private int getMinTextOffset(String propertyPrefix) {
        int minimumTextOffset = 0;
        Object minimumTextOffsetObject =
                UIManager.get(propertyPrefix + ".minimumTextOffset");
        if (minimumTextOffsetObject instanceof Integer) {
            minimumTextOffset = (Integer) minimumTextOffsetObject;
        }
        return minimumTextOffset;
    }

    private int getAfterCheckIconGap(String propertyPrefix) {
        int afterCheckIconGap = gap;
        Object afterCheckIconGapObject =
                UIManager.get(propertyPrefix + ".afterCheckIconGap");
        if (afterCheckIconGapObject instanceof Integer) {
            afterCheckIconGap = (Integer) afterCheckIconGapObject;
        }
        return afterCheckIconGap;
    }

    private int getLeadingGap(String propertyPrefix) {
        if (checkSize.getMaxWidth() > 0) {
            return getCheckOffset(propertyPrefix);
        } else {
            return gap; // There is no any check icon
        }
    }

    private int getCheckOffset(String propertyPrefix) {
        int checkIconOffset = gap;
        Object checkIconOffsetObject =
                UIManager.get(propertyPrefix + ".checkIconOffset");
        if (checkIconOffsetObject instanceof Integer) {
            checkIconOffset = (Integer) checkIconOffsetObject;
        }
        return checkIconOffset;
    }

    protected void calcWidthsAndHeights() {
        // iconRect
        if (icon != null) {
            iconSize.width = icon.getIconWidth();
            iconSize.height = icon.getIconHeight();
        }

        // accRect
        if (!accText.equals("")) {
            accSize.width = SwingUtilities2.stringWidth(mi, accFm, accText);
            accSize.height = accFm.getHeight();
        }

        // textRect
        if (text == null) {
            text = "";
        } else if (!text.equals("")) {
            if (htmlView != null) {
                // Text is HTML
                textSize.width =
                        (int) htmlView.getPreferredSpan(View.X_AXIS);
                textSize.height =
                        (int) htmlView.getPreferredSpan(View.Y_AXIS);
            } else {
                // Text isn't HTML
                textSize.width = SwingUtilities2.stringWidth(mi, fm, text);
                textSize.height = fm.getHeight();
            }
        }

        if (useCheckAndArrow) {
            // checkIcon
            if (checkIcon != null) {
                checkSize.width = checkIcon.getIconWidth();
                checkSize.height = checkIcon.getIconHeight();
            }
            // arrowRect
            if (arrowIcon != null) {
                arrowSize.width = arrowIcon.getIconWidth();
                arrowSize.height = arrowIcon.getIconHeight();
            }
        }

        // labelRect
        if (isColumnLayout) {
            labelSize.width = iconSize.width + textSize.width + gap;
            labelSize.height = max(checkSize.height, iconSize.height,
                    textSize.height, accSize.height, arrowSize.height);
        } else {
            Rectangle textRect = new Rectangle();
            Rectangle iconRect = new Rectangle();
            SwingUtilities.layoutCompoundLabel(mi, fm, text, icon,
                    verticalAlignment, horizontalAlignment,
                    verticalTextPosition, horizontalTextPosition,
                    viewRect, iconRect, textRect, gap);
            textRect.width += leftTextExtraWidth;
            Rectangle labelRect = iconRect.union(textRect);
            labelSize.height = labelRect.height;
            labelSize.width = labelRect.width;
        }
    }

    protected void calcMaxWidths() {
        calcMaxWidth(checkSize, MAX_CHECK_WIDTH);
        calcMaxWidth(arrowSize, MAX_ARROW_WIDTH);
        calcMaxWidth(accSize, MAX_ACC_WIDTH);

        if (isColumnLayout) {
            calcMaxWidth(iconSize, MAX_ICON_WIDTH);
            calcMaxWidth(textSize, MAX_TEXT_WIDTH);
            int curGap = gap;
            if ((iconSize.getMaxWidth() == 0)
                    || (textSize.getMaxWidth() == 0)) {
                curGap = 0;
            }
            labelSize.maxWidth =
                    calcMaxValue(MAX_LABEL_WIDTH, iconSize.maxWidth
                            + textSize.maxWidth + curGap);
        } else {
            // We shouldn't use current icon and text widths
            // in maximal widths calculation for complex layout.
            iconSize.maxWidth = getParentIntProperty(MAX_ICON_WIDTH);
            calcMaxWidth(labelSize, MAX_LABEL_WIDTH);
            // If maxLabelWidth is wider
            // than the widest icon + the widest text + gap,
            // we should update the maximal text witdh
            int candidateTextWidth = labelSize.maxWidth - iconSize.maxWidth;
            if (iconSize.maxWidth > 0) {
                candidateTextWidth -= gap;
            }
            textSize.maxWidth = calcMaxValue(MAX_TEXT_WIDTH, candidateTextWidth);
        }
    }

    protected void calcMaxWidth(RectSize rs, Object key) {
        rs.maxWidth = calcMaxValue(key, rs.width);
    }

    /**
     * Calculates and returns maximal value through specified parent component
     * client property.
     *
     * @param propertyName name of the property, which stores the maximal value.
     * @param value a value which pretends to be maximal
     * @return maximal value among the parent property and the value.
     */
    protected int calcMaxValue(Object propertyName, int value) {
        // Get maximal value from parent client property
        int maxValue = getParentIntProperty(propertyName);
        // Store new maximal width in parent client property
        if (value > maxValue) {
            if (miParent != null) {
                miParent.putClientProperty(propertyName, value);
            }
            return value;
        } else {
            return maxValue;
        }
    }

    /**
     * Returns parent client property as int.
     * @param propertyName name of the parent property.
     * @return value of the property as int.
     */
    protected int getParentIntProperty(Object propertyName) {
        Object value = null;
        if (miParent != null) {
            value = miParent.getClientProperty(propertyName);
        }
        if ((value == null) || !(value instanceof Integer)) {
            value = 0;
        }
        return (Integer) value;
    }

    public static boolean isColumnLayout(boolean isLeftToRight,
                                         JMenuItem mi) {
        assert(mi != null);
        return isColumnLayout(isLeftToRight, mi.getHorizontalAlignment(),
                mi.getHorizontalTextPosition(), mi.getVerticalTextPosition());
    }

    /**
     * Answers should we do column layout for a menu item or not.
     * We do it when a user doesn't set any alignments
     * and text positions manually, except the vertical alignment.
     */
    public static boolean isColumnLayout(boolean isLeftToRight,
                                         int horizontalAlignment,
                                         int horizontalTextPosition,
                                         int verticalTextPosition) {
        if (verticalTextPosition != SwingConstants.CENTER) {
            return false;
        }
        if (isLeftToRight) {
            if (horizontalAlignment != SwingConstants.LEADING
                    && horizontalAlignment != SwingConstants.LEFT) {
                return false;
            }
            if (horizontalTextPosition != SwingConstants.TRAILING
                    && horizontalTextPosition != SwingConstants.RIGHT) {
                return false;
            }
        } else {
            if (horizontalAlignment != SwingConstants.LEADING
                    && horizontalAlignment != SwingConstants.RIGHT) {
                return false;
            }
            if (horizontalTextPosition != SwingConstants.TRAILING
                    && horizontalTextPosition != SwingConstants.LEFT) {
                return false;
            }
        }
        return true;
    }

    /**
     * Calculates maximal text offset.
     * It is required for some L&Fs (ex: Vista L&F).
     * The offset is meaningful only for L2R column layout.
     *
     * @param viewRect the rectangle, the maximal text offset
     * will be calculated for.
     */
    private void calcMaxTextOffset(Rectangle viewRect) {
        if (!isColumnLayout || !isLeftToRight) {
            return;
        }

        // Calculate the current text offset
        int offset = viewRect.x + leadingGap + checkSize.maxWidth
                + afterCheckIconGap + iconSize.maxWidth + gap;
        if (checkSize.maxWidth == 0) {
            offset -= afterCheckIconGap;
        }
        if (iconSize.maxWidth == 0) {
            offset -= gap;
        }

        // maximal text offset shouldn't be less than minimal text offset;
        if (offset < minTextOffset) {
            offset = minTextOffset;
        }

        // Calculate and store the maximal text offset
        calcMaxValue(SwingUtilities2.BASICMENUITEMUI_MAX_TEXT_OFFSET, offset);
    }

    /**
     * Layout icon, text, check icon, accelerator text and arrow icon
     * in the viewRect and return their positions.
     *
     * If horizontalAlignment, verticalTextPosition and horizontalTextPosition
     * are default (user doesn't set any manually) the layouting algorithm is:
     * Elements are layouted in the five columns:
     * check icon + icon + text + accelerator text + arrow icon
     *
     * In the other case elements are layouted in the four columns:
     * check icon + label + accelerator text + arrow icon
     * Label is union of icon and text.
     *
     * The order of columns can be reversed.
     * It depends on the menu item orientation.
     */
    public LayoutResult layoutMenuItem() {
        LayoutResult lr = createLayoutResult();
        prepareForLayout(lr);

        if (isColumnLayout()) {
            if (isLeftToRight()) {
                doLTRColumnLayout(lr, getLTRColumnAlignment());
            } else {
                doRTLColumnLayout(lr, getRTLColumnAlignment());
            }
        } else {
            if (isLeftToRight()) {
                doLTRComplexLayout(lr, getLTRColumnAlignment());
            } else {
                doRTLComplexLayout(lr, getRTLColumnAlignment());
            }
        }

        alignAccCheckAndArrowVertically(lr);
        return lr;
    }

    private LayoutResult createLayoutResult() {
        return new LayoutResult(
                new Rectangle(iconSize.width, iconSize.height),
                new Rectangle(textSize.width, textSize.height),
                new Rectangle(accSize.width,  accSize.height),
                new Rectangle(checkSize.width, checkSize.height),
                new Rectangle(arrowSize.width, arrowSize.height),
                new Rectangle(labelSize.width, labelSize.height)
        );
    }

    public ColumnAlignment getLTRColumnAlignment() {
        return ColumnAlignment.LEFT_ALIGNMENT;
    }

    public ColumnAlignment getRTLColumnAlignment() {
        return ColumnAlignment.RIGHT_ALIGNMENT;
    }

    protected void prepareForLayout(LayoutResult lr) {
        lr.checkRect.width = checkSize.maxWidth;
        lr.accRect.width = accSize.maxWidth;
        lr.arrowRect.width = arrowSize.maxWidth;
    }

    /**
     * Aligns the accelertor text and the check and arrow icons vertically
     * with the center of the label rect.
     */
    private void alignAccCheckAndArrowVertically(LayoutResult lr) {
        lr.accRect.y = (int)(lr.labelRect.y
                + (float)lr.labelRect.height/2
                - (float)lr.accRect.height/2);
        fixVerticalAlignment(lr, lr.accRect);
        if (useCheckAndArrow) {
            lr.arrowRect.y = (int)(lr.labelRect.y
                    + (float)lr.labelRect.height/2
                    - (float)lr.arrowRect.height/2);
            lr.checkRect.y = (int)(lr.labelRect.y
                    + (float)lr.labelRect.height/2
                    - (float)lr.checkRect.height/2);
            fixVerticalAlignment(lr, lr.arrowRect);
            fixVerticalAlignment(lr, lr.checkRect);
        }
    }

    /**
     * Fixes vertical alignment of all menu item elements if rect.y
     * or (rect.y + rect.height) is out of viewRect bounds
     */
    private void fixVerticalAlignment(LayoutResult lr, Rectangle r) {
        int delta = 0;
        if (r.y < viewRect.y) {
            delta = viewRect.y - r.y;
        } else if (r.y + r.height > viewRect.y + viewRect.height) {
            delta = viewRect.y + viewRect.height - r.y - r.height;
        }
        if (delta != 0) {
            lr.checkRect.y += delta;
            lr.iconRect.y += delta;
            lr.textRect.y += delta;
            lr.accRect.y += delta;
            lr.arrowRect.y += delta;
            lr.labelRect.y += delta;
        }
    }

    private void doLTRColumnLayout(LayoutResult lr, ColumnAlignment alignment) {
        // Set maximal width for all the five basic rects
        // (three other ones are already maximal)
        lr.iconRect.width = iconSize.maxWidth;
        lr.textRect.width = textSize.maxWidth;

        // Set X coordinates
        // All rects will be aligned at the left side
        calcXPositionsLTR(viewRect.x, leadingGap, gap, lr.checkRect,
                lr.iconRect, lr.textRect);

        // Tune afterCheckIconGap
        if (lr.checkRect.width > 0) { // there is the afterCheckIconGap
            lr.iconRect.x += afterCheckIconGap - gap;
            lr.textRect.x += afterCheckIconGap - gap;
        }

        calcXPositionsRTL(viewRect.x + viewRect.width, leadingGap, gap,
                lr.arrowRect, lr.accRect);

        // Take into account minimal text offset
        int textOffset = lr.textRect.x - viewRect.x;
        if (!isTopLevelMenu && (textOffset < minTextOffset)) {
            lr.textRect.x += minTextOffset - textOffset;
        }

        alignRects(lr, alignment);

        // Set Y coordinate for text and icon.
        // Y coordinates for other rects
        // will be calculated later in layoutMenuItem.
        calcTextAndIconYPositions(lr);

        // Calculate valid X and Y coordinates for labelRect
        lr.setLabelRect(lr.textRect.union(lr.iconRect));
    }

    private void doLTRComplexLayout(LayoutResult lr, ColumnAlignment alignment) {
        lr.labelRect.width = labelSize.maxWidth;

        // Set X coordinates
        calcXPositionsLTR(viewRect.x, leadingGap, gap, lr.checkRect,
                lr.labelRect);

        // Tune afterCheckIconGap
        if (lr.checkRect.width > 0) { // there is the afterCheckIconGap
            lr.labelRect.x += afterCheckIconGap - gap;
        }

        calcXPositionsRTL(viewRect.x + viewRect.width,
                leadingGap, gap, lr.arrowRect, lr.accRect);

        // Take into account minimal text offset
        int labelOffset = lr.labelRect.x - viewRect.x;
        if (!isTopLevelMenu && (labelOffset < minTextOffset)) {
            lr.labelRect.x += minTextOffset - labelOffset;
        }

        alignRects(lr, alignment);

        // Center labelRect vertically
        calcLabelYPosition(lr);

        layoutIconAndTextInLabelRect(lr);
    }

    private void doRTLColumnLayout(LayoutResult lr, ColumnAlignment alignment) {
        // Set maximal width for all the five basic rects
        // (three other ones are already maximal)
        lr.iconRect.width = iconSize.maxWidth;
        lr.textRect.width = textSize.maxWidth;

        // Set X coordinates
        calcXPositionsRTL(viewRect.x + viewRect.width, leadingGap, gap,
                lr.checkRect, lr.iconRect, lr.textRect);

        // Tune the gap after check icon
        if (lr.checkRect.width > 0) { // there is the gap after check icon
            lr.iconRect.x -= afterCheckIconGap - gap;
            lr.textRect.x -= afterCheckIconGap - gap;
        }

        calcXPositionsLTR(viewRect.x, leadingGap, gap, lr.arrowRect,
                lr.accRect);

        // Take into account minimal text offset
        int textOffset = (viewRect.x + viewRect.width)
                       - (lr.textRect.x + lr.textRect.width);
        if (!isTopLevelMenu && (textOffset < minTextOffset)) {
            lr.textRect.x -= minTextOffset - textOffset;
        }

        alignRects(lr, alignment);

        // Set Y coordinates for text and icon.
        // Y coordinates for other rects
        // will be calculated later in layoutMenuItem.
        calcTextAndIconYPositions(lr);

        // Calculate valid X and Y coordinate for labelRect
        lr.setLabelRect(lr.textRect.union(lr.iconRect));
    }

    private void doRTLComplexLayout(LayoutResult lr, ColumnAlignment alignment) {
        lr.labelRect.width = labelSize.maxWidth;

        // Set X coordinates
        calcXPositionsRTL(viewRect.x + viewRect.width, leadingGap, gap,
                lr.checkRect, lr.labelRect);

        // Tune the gap after check icon
        if (lr.checkRect.width > 0) { // there is the gap after check icon
            lr.labelRect.x -= afterCheckIconGap - gap;
        }

        calcXPositionsLTR(viewRect.x, leadingGap, gap, lr.arrowRect, lr.accRect);

        // Take into account minimal text offset
        int labelOffset = (viewRect.x + viewRect.width)
                        - (lr.labelRect.x + lr.labelRect.width);
        if (!isTopLevelMenu && (labelOffset < minTextOffset)) {
            lr.labelRect.x -= minTextOffset - labelOffset;
        }

        alignRects(lr, alignment);

        // Center labelRect vertically
        calcLabelYPosition(lr);

        layoutIconAndTextInLabelRect(lr);
    }

    private void alignRects(LayoutResult lr, ColumnAlignment alignment) {
        alignRect(lr.checkRect, alignment.getCheckAlignment(),
                  checkSize.getOrigWidth());
        alignRect(lr.iconRect, alignment.getIconAlignment(),
                  iconSize.getOrigWidth());
        alignRect(lr.textRect, alignment.getTextAlignment(),
                  textSize.getOrigWidth());
        alignRect(lr.accRect, alignment.getAccAlignment(),
                  accSize.getOrigWidth());
        alignRect(lr.arrowRect, alignment.getArrowAlignment(),
                  arrowSize.getOrigWidth());
    }

    private void alignRect(Rectangle rect, int alignment, int origWidth) {
        if (alignment == SwingConstants.RIGHT) {
            rect.x = rect.x + rect.width - origWidth;
        }
        rect.width = origWidth;
    }

    protected void layoutIconAndTextInLabelRect(LayoutResult lr) {
        lr.setTextRect(new Rectangle());
        lr.setIconRect(new Rectangle());
        SwingUtilities.layoutCompoundLabel(
                mi, fm, text,icon, verticalAlignment, horizontalAlignment,
                verticalTextPosition, horizontalTextPosition, lr.labelRect,
                lr.iconRect, lr.textRect, gap);
    }

    private void calcXPositionsLTR(int startXPos, int leadingGap,
                                   int gap, Rectangle... rects) {
        int curXPos = startXPos + leadingGap;
        for (Rectangle rect : rects) {
            rect.x = curXPos;
            if (rect.width > 0) {
                curXPos += rect.width + gap;
            }
        }
    }

    private void calcXPositionsRTL(int startXPos, int leadingGap,
                                   int gap, Rectangle... rects) {
        int curXPos = startXPos - leadingGap;
        for (Rectangle rect : rects) {
            rect.x = curXPos - rect.width;
            if (rect.width > 0) {
                curXPos -= rect.width + gap;
            }
        }
    }

   /**
     * Sets Y coordinates of text and icon
     * taking into account the vertical alignment
     */
    private void calcTextAndIconYPositions(LayoutResult lr) {
        if (verticalAlignment == SwingUtilities.TOP) {
            lr.textRect.y  = (int)(viewRect.y
                    + (float)lr.labelRect.height/2
                    - (float)lr.textRect.height/2);
            lr.iconRect.y  = (int)(viewRect.y
                    + (float)lr.labelRect.height/2
                    - (float)lr.iconRect.height/2);
        } else if (verticalAlignment == SwingUtilities.CENTER) {
            lr.textRect.y = (int)(viewRect.y
                    + (float)viewRect.height/2
                    - (float)lr.textRect.height/2);
            lr.iconRect.y = (int)(viewRect.y
                    + (float)viewRect.height/2
                    - (float)lr.iconRect.height/2);
        }
        else if (verticalAlignment == SwingUtilities.BOTTOM) {
            lr.textRect.y = (int)(viewRect.y
                    + viewRect.height
                    - (float)lr.labelRect.height/2
                    - (float)lr.textRect.height/2);
            lr.iconRect.y = (int)(viewRect.y
                    + viewRect.height
                    - (float)lr.labelRect.height/2
                    - (float)lr.iconRect.height/2);
        }
    }

    /**
     * Sets labelRect Y coordinate
     * taking into account the vertical alignment
     */
    private void calcLabelYPosition(LayoutResult lr) {
        if (verticalAlignment == SwingUtilities.TOP) {
            lr.labelRect.y  = viewRect.y;
        } else if (verticalAlignment == SwingUtilities.CENTER) {
            lr.labelRect.y = (int)(viewRect.y
                    + (float)viewRect.height/2
                    - (float)lr.labelRect.height/2);
        } else if (verticalAlignment == SwingUtilities.BOTTOM) {
            lr.labelRect.y  = viewRect.y + viewRect.height
                    - lr.labelRect.height;
        }
    }

    /**
     * Returns parent of this component if it is not a top-level menu
     * Otherwise returns null.
     * @param menuItem the menu item whose parent will be returned.
     * @return parent of this component if it is not a top-level menu
     * Otherwise returns null.
     */
    public static JComponent getMenuItemParent(JMenuItem menuItem) {
        Container parent = menuItem.getParent();
        if ((parent instanceof JComponent) &&
             (!(menuItem instanceof JMenu) ||
               !((JMenu)menuItem).isTopLevelMenu())) {
            return (JComponent) parent;
        } else {
            return null;
        }
    }

    public static void clearUsedParentClientProperties(JMenuItem menuItem) {
        clearUsedClientProperties(getMenuItemParent(menuItem));
    }

    public static void clearUsedClientProperties(JComponent c) {
        if (c != null) {
            c.putClientProperty(MAX_ARROW_WIDTH, null);
            c.putClientProperty(MAX_CHECK_WIDTH, null);
            c.putClientProperty(MAX_ACC_WIDTH, null);
            c.putClientProperty(MAX_TEXT_WIDTH, null);
            c.putClientProperty(MAX_ICON_WIDTH, null);
            c.putClientProperty(MAX_LABEL_WIDTH, null);
            c.putClientProperty(BASICMENUITEMUI_MAX_TEXT_OFFSET, null);
        }
    }

    /**
     * Finds and returns maximal integer value in the given array.
     * @param values array where the search will be performed.
     * @return maximal vaule.
     */
    public static int max(int... values) {
        int maxValue = Integer.MIN_VALUE;
        for (int i : values) {
            if (i > maxValue) {
                maxValue = i;
            }
        }
        return maxValue;
    }

    public static Rectangle createMaxRect() {
        return new Rectangle(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
    }

    public static void addMaxWidth(RectSize size, int gap, Dimension result) {
        if (size.maxWidth > 0) {
            result.width += size.maxWidth + gap;
        }
    }

    public static void addWidth(int width, int gap, Dimension result) {
        if (width > 0) {
            result.width += width + gap;
        }
    }

    public JMenuItem getMenuItem() {
        return mi;
    }

    public JComponent getMenuItemParent() {
        return miParent;
    }

    public Font getFont() {
        return font;
    }

    public Font getAccFont() {
        return accFont;
    }

    public FontMetrics getFontMetrics() {
        return fm;
    }

    public FontMetrics getAccFontMetrics() {
        return accFm;
    }

    public Icon getIcon() {
        return icon;
    }

    public Icon getCheckIcon() {
        return checkIcon;
    }

    public Icon getArrowIcon() {
        return arrowIcon;
    }

    public String getText() {
        return text;
    }

    public String getAccText() {
        return accText;
    }

    public boolean isColumnLayout() {
        return isColumnLayout;
    }

    public boolean useCheckAndArrow() {
        return useCheckAndArrow;
    }

    public boolean isLeftToRight() {
        return isLeftToRight;
    }

    public boolean isTopLevelMenu() {
        return isTopLevelMenu;
    }

    public View getHtmlView() {
        return htmlView;
    }

    public int getVerticalAlignment() {
        return verticalAlignment;
    }

    public int getHorizontalAlignment() {
        return horizontalAlignment;
    }

    public int getVerticalTextPosition() {
        return verticalTextPosition;
    }

    public int getHorizontalTextPosition() {
        return horizontalTextPosition;
    }

    public int getGap() {
        return gap;
    }

    public int getLeadingGap() {
        return leadingGap;
    }

    public int getAfterCheckIconGap() {
        return afterCheckIconGap;
    }

    public int getMinTextOffset() {
        return minTextOffset;
    }

    public Rectangle getViewRect() {
        return viewRect;
    }

    public RectSize getIconSize() {
        return iconSize;
    }

    public RectSize getTextSize() {
        return textSize;
    }

    public RectSize getAccSize() {
        return accSize;
    }

    public RectSize getCheckSize() {
        return checkSize;
    }

    public RectSize getArrowSize() {
        return arrowSize;
    }

    public RectSize getLabelSize() {
        return labelSize;
    }

    protected void setMenuItem(JMenuItem mi) {
        this.mi = mi;
    }

    protected void setMenuItemParent(JComponent miParent) {
        this.miParent = miParent;
    }

    protected void setFont(Font font) {
        this.font = font;
    }

    protected void setAccFont(Font accFont) {
        this.accFont = accFont;
    }

    protected void setFontMetrics(FontMetrics fm) {
        this.fm = fm;
    }

    protected void setAccFontMetrics(FontMetrics accFm) {
        this.accFm = accFm;
    }

    protected void setIcon(Icon icon) {
        this.icon = icon;
    }

    protected void setCheckIcon(Icon checkIcon) {
        this.checkIcon = checkIcon;
    }

    protected void setArrowIcon(Icon arrowIcon) {
        this.arrowIcon = arrowIcon;
    }

    protected void setText(String text) {
        this.text = text;
    }

    protected void setAccText(String accText) {
        this.accText = accText;
    }

    protected void setColumnLayout(boolean columnLayout) {
        isColumnLayout = columnLayout;
    }

    protected void setUseCheckAndArrow(boolean useCheckAndArrow) {
        this.useCheckAndArrow = useCheckAndArrow;
    }

    protected void setLeftToRight(boolean leftToRight) {
        isLeftToRight = leftToRight;
    }

    protected void setTopLevelMenu(boolean topLevelMenu) {
        isTopLevelMenu = topLevelMenu;
    }

    protected void setHtmlView(View htmlView) {
        this.htmlView = htmlView;
    }

    protected void setVerticalAlignment(int verticalAlignment) {
        this.verticalAlignment = verticalAlignment;
    }

    protected void setHorizontalAlignment(int horizontalAlignment) {
        this.horizontalAlignment = horizontalAlignment;
    }

    protected void setVerticalTextPosition(int verticalTextPosition) {
        this.verticalTextPosition = verticalTextPosition;
    }

    protected void setHorizontalTextPosition(int horizontalTextPosition) {
        this.horizontalTextPosition = horizontalTextPosition;
    }

    protected void setGap(int gap) {
        this.gap = gap;
    }

    protected void setLeadingGap(int leadingGap) {
        this.leadingGap = leadingGap;
    }

    protected void setAfterCheckIconGap(int afterCheckIconGap) {
        this.afterCheckIconGap = afterCheckIconGap;
    }

    protected void setMinTextOffset(int minTextOffset) {
        this.minTextOffset = minTextOffset;
    }

    protected void setViewRect(Rectangle viewRect) {
        this.viewRect = viewRect;
    }

    protected void setIconSize(RectSize iconSize) {
        this.iconSize = iconSize;
    }

    protected void setTextSize(RectSize textSize) {
        this.textSize = textSize;
    }

    protected void setAccSize(RectSize accSize) {
        this.accSize = accSize;
    }

    protected void setCheckSize(RectSize checkSize) {
        this.checkSize = checkSize;
    }

    protected void setArrowSize(RectSize arrowSize) {
        this.arrowSize = arrowSize;
    }

    protected void setLabelSize(RectSize labelSize) {
        this.labelSize = labelSize;
    }

    public int getLeftTextExtraWidth() {
        return leftTextExtraWidth;
    }

    /**
     * Returns false if the component is a JMenu and it is a top
     * level menu (on the menubar).
     */
    public static boolean useCheckAndArrow(JMenuItem menuItem) {
        boolean b = true;
        if ((menuItem instanceof JMenu) &&
                (((JMenu) menuItem).isTopLevelMenu())) {
            b = false;
        }
        return b;
    }

    public static class LayoutResult {
        private Rectangle iconRect;
        private Rectangle textRect;
        private Rectangle accRect;
        private Rectangle checkRect;
        private Rectangle arrowRect;
        private Rectangle labelRect;

        public LayoutResult() {
            iconRect = new Rectangle();
            textRect = new Rectangle();
            accRect = new Rectangle();
            checkRect = new Rectangle();
            arrowRect = new Rectangle();
            labelRect = new Rectangle();
        }

        public LayoutResult(Rectangle iconRect, Rectangle textRect,
                            Rectangle accRect, Rectangle checkRect,
                            Rectangle arrowRect, Rectangle labelRect) {
            this.iconRect = iconRect;
            this.textRect = textRect;
            this.accRect = accRect;
            this.checkRect = checkRect;
            this.arrowRect = arrowRect;
            this.labelRect = labelRect;
        }

        public Rectangle getIconRect() {
            return iconRect;
        }

        public void setIconRect(Rectangle iconRect) {
            this.iconRect = iconRect;
        }

        public Rectangle getTextRect() {
            return textRect;
        }

        public void setTextRect(Rectangle textRect) {
            this.textRect = textRect;
        }

        public Rectangle getAccRect() {
            return accRect;
        }

        public void setAccRect(Rectangle accRect) {
            this.accRect = accRect;
        }

        public Rectangle getCheckRect() {
            return checkRect;
        }

        public void setCheckRect(Rectangle checkRect) {
            this.checkRect = checkRect;
        }

        public Rectangle getArrowRect() {
            return arrowRect;
        }

        public void setArrowRect(Rectangle arrowRect) {
            this.arrowRect = arrowRect;
        }

        public Rectangle getLabelRect() {
            return labelRect;
        }

        public void setLabelRect(Rectangle labelRect) {
            this.labelRect = labelRect;
        }

        public Map<String, Rectangle> getAllRects() {
            Map<String, Rectangle> result = new HashMap<String, Rectangle>();
            result.put("checkRect", checkRect);
            result.put("iconRect", iconRect);
            result.put("textRect", textRect);
            result.put("accRect", accRect);
            result.put("arrowRect", arrowRect);
            result.put("labelRect", labelRect);
            return result;
        }
    }

    public static class ColumnAlignment {
        private int checkAlignment;
        private int iconAlignment;
        private int textAlignment;
        private int accAlignment;
        private int arrowAlignment;

        public static final ColumnAlignment LEFT_ALIGNMENT =
                new ColumnAlignment(
                        SwingConstants.LEFT,
                        SwingConstants.LEFT,
                        SwingConstants.LEFT,
                        SwingConstants.LEFT,
                        SwingConstants.LEFT
                );

        public static final ColumnAlignment RIGHT_ALIGNMENT =
                new ColumnAlignment(
                        SwingConstants.RIGHT,
                        SwingConstants.RIGHT,
                        SwingConstants.RIGHT,
                        SwingConstants.RIGHT,
                        SwingConstants.RIGHT
                );

        public ColumnAlignment(int checkAlignment, int iconAlignment,
                               int textAlignment, int accAlignment,
                               int arrowAlignment) {
            this.checkAlignment = checkAlignment;
            this.iconAlignment = iconAlignment;
            this.textAlignment = textAlignment;
            this.accAlignment = accAlignment;
            this.arrowAlignment = arrowAlignment;
        }

        public int getCheckAlignment() {
            return checkAlignment;
        }

        public int getIconAlignment() {
            return iconAlignment;
        }

        public int getTextAlignment() {
            return textAlignment;
        }

        public int getAccAlignment() {
            return accAlignment;
        }

        public int getArrowAlignment() {
            return arrowAlignment;
        }
    }

    public static class RectSize {
        private int width;
        private int height;
        private int origWidth;
        private int maxWidth;

        public RectSize() {
        }

        public RectSize(int width, int height, int origWidth, int maxWidth) {
            this.width = width;
            this.height = height;
            this.origWidth = origWidth;
            this.maxWidth = maxWidth;
        }

        public int getWidth() {
            return width;
        }

        public int getHeight() {
            return height;
        }

        public int getOrigWidth() {
            return origWidth;
        }

        public int getMaxWidth() {
            return maxWidth;
        }

        public void setWidth(int width) {
            this.width = width;
        }

        public void setHeight(int height) {
            this.height = height;
        }

        public void setOrigWidth(int origWidth) {
            this.origWidth = origWidth;
        }

        public void setMaxWidth(int maxWidth) {
            this.maxWidth = maxWidth;
        }

        public String toString() {
            return "[w=" + width + ",h=" + height + ",ow="
                    + origWidth + ",mw=" + maxWidth + "]";
        }
    }
}
