/*
 * Copyright (c) 2005, 2011, 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 java.awt.Container;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.Border;
import javax.swing.plaf.UIResource;

/**
 * An implementation of <code>LayoutStyle</code> that returns 6 for related
 * components, otherwise 12.  This class also provides helper methods for
 * subclasses.
 *
 */
public class DefaultLayoutStyle extends LayoutStyle {
    private static final DefaultLayoutStyle INSTANCE =
            new DefaultLayoutStyle();

    public static LayoutStyle getInstance() {
        return INSTANCE;
    }

    @Override
    public int getPreferredGap(JComponent component1, JComponent component2,
            ComponentPlacement type, int position, Container parent) {
        if (component1 == null || component2 == null || type == null) {
            throw new NullPointerException();
        }

        checkPosition(position);

        if (type == ComponentPlacement.INDENT &&
                (position == SwingConstants.EAST ||
                 position == SwingConstants.WEST)) {
            int indent = getIndent(component1, position);
            if (indent > 0) {
                return indent;
            }
        }
        return (type == ComponentPlacement.UNRELATED) ? 12 : 6;
    }

    @Override
    public int getContainerGap(JComponent component, int position,
                               Container parent) {
        if (component == null) {
            throw new NullPointerException();
        }
        checkPosition(position);
        return 6;
    }

    /**
     * Returns true if the classes identify a JLabel and a non-JLabel
     * along the horizontal axis.
     */
    protected boolean isLabelAndNonlabel(JComponent c1, JComponent c2,
                                         int position) {
        if (position == SwingConstants.EAST ||
                position == SwingConstants.WEST) {
            boolean c1Label = (c1 instanceof JLabel);
            boolean c2Label = (c2 instanceof JLabel);
            return ((c1Label || c2Label) && (c1Label != c2Label));
        }
        return false;
    }

    /**
     * For some look and feels check boxes and radio buttons typically
     * don't paint the border, yet they have padding for a border.  Look
     * and feel guidelines generally don't include this space.  Use
     * this method to subtract this space from the specified
     * components.
     *
     * @param source First component
     * @param target Second component
     * @param position Position doing layout along.
     * @param offset Ideal offset, not including border/margin
     * @return offset - border/margin around the component.
     */
    protected int getButtonGap(JComponent source, JComponent target,
                               int position, int offset) {
        offset -= getButtonGap(source, position);
        if (offset > 0) {
            offset -= getButtonGap(target, flipDirection(position));
        }
        if (offset < 0) {
            return 0;
        }
        return offset;
    }

    /**
     * For some look and feels check boxes and radio buttons typically
     * don't paint the border, yet they have padding for a border.  Look
     * and feel guidelines generally don't include this space.  Use
     * this method to subtract this space from the specified
     * components.
     *
     * @param source Component
     * @param position Position doing layout along.
     * @param offset Ideal offset, not including border/margin
     * @return offset - border/margin around the component.
     */
    protected int getButtonGap(JComponent source, int position, int offset) {
        offset -= getButtonGap(source, position);
        return Math.max(offset, 0);
    }

    /**
     * If <code>c</code> is a check box or radio button, and the border is
     * not painted this returns the inset along the specified axis.
     */
    public int getButtonGap(JComponent c, int position) {
        String classID = c.getUIClassID();
        if ((classID == "CheckBoxUI" || classID == "RadioButtonUI") &&
                !((AbstractButton)c).isBorderPainted()) {
            Border border = c.getBorder();
            if (border instanceof UIResource) {
                return getInset(c, position);
            }
        }
        return 0;
    }

    private void checkPosition(int position) {
        if (position != SwingConstants.NORTH &&
                position != SwingConstants.SOUTH &&
                position != SwingConstants.WEST &&
                position != SwingConstants.EAST) {
            throw new IllegalArgumentException();
        }
    }

    protected int flipDirection(int position) {
        switch(position) {
        case SwingConstants.NORTH:
            return SwingConstants.SOUTH;
        case SwingConstants.SOUTH:
            return SwingConstants.NORTH;
        case SwingConstants.EAST:
            return SwingConstants.WEST;
        case SwingConstants.WEST:
            return SwingConstants.EAST;
        }
        assert false;
        return 0;
    }

    /**
     * Returns the amount to indent the specified component if it's
     * a JCheckBox or JRadioButton.  If the component is not a JCheckBox or
     * JRadioButton, 0 will be returned.
     */
    protected int getIndent(JComponent c, int position) {
        String classID = c.getUIClassID();
        if (classID == "CheckBoxUI" || classID == "RadioButtonUI") {
            AbstractButton button = (AbstractButton)c;
            Insets insets = c.getInsets();
            Icon icon = getIcon(button);
            int gap = button.getIconTextGap();
            if (isLeftAligned(button, position)) {
                return insets.left + icon.getIconWidth() + gap;
            } else if (isRightAligned(button, position)) {
                return insets.right + icon.getIconWidth() + gap;
            }
        }
        return 0;
    }

    private Icon getIcon(AbstractButton button) {
        Icon icon = button.getIcon();
        if (icon != null) {
            return icon;
        }
        String key = null;
        if (button instanceof JCheckBox) {
            key = "CheckBox.icon";
        } else if (button instanceof JRadioButton) {
            key = "RadioButton.icon";
        }
        if (key != null) {
            Object oIcon = UIManager.get(key);
            if (oIcon instanceof Icon) {
                return (Icon)oIcon;
            }
        }
        return null;
    }

    private boolean isLeftAligned(AbstractButton button, int position) {
        if (position == SwingConstants.WEST) {
            boolean ltr = button.getComponentOrientation().isLeftToRight();
            int hAlign = button.getHorizontalAlignment();
            return ((ltr && (hAlign == SwingConstants.LEFT ||
                             hAlign == SwingConstants.LEADING)) ||
                    (!ltr && (hAlign == SwingConstants.TRAILING)));
        }
        return false;
    }

    private boolean isRightAligned(AbstractButton button, int position) {
        if (position == SwingConstants.EAST) {
            boolean ltr = button.getComponentOrientation().isLeftToRight();
            int hAlign = button.getHorizontalAlignment();
            return ((ltr && (hAlign == SwingConstants.RIGHT ||
                             hAlign == SwingConstants.TRAILING)) ||
                    (!ltr && (hAlign == SwingConstants.LEADING)));
        }
        return false;
    }

    private int getInset(JComponent c, int position) {
        return getInset(c.getInsets(), position);
    }

    private int getInset(Insets insets, int position) {
        if (insets == null) {
            return 0;
        }
        switch(position) {
        case SwingConstants.NORTH:
            return insets.top;
        case SwingConstants.SOUTH:
            return insets.bottom;
        case SwingConstants.EAST:
            return insets.right;
        case SwingConstants.WEST:
            return insets.left;
        }
        assert false;
        return 0;
    }
}
