/*
 * Copyright (c) 1998, 2006, 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 javax.swing.plaf.metal;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.plaf.*;
import java.io.Serializable;
import javax.swing.plaf.basic.BasicTabbedPaneUI;

/**
 * The Metal subclass of BasicTabbedPaneUI.
 * <p>
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases. The current serialization support is
 * appropriate for short term storage or RMI between applications running
 * the same version of Swing.  As of 1.4, support for long term storage
 * of all JavaBeans<sup><font size="-2">TM</font></sup>
 * has been added to the <code>java.beans</code> package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @author Tom Santos
 */

public class MetalTabbedPaneUI extends BasicTabbedPaneUI {

    protected int minTabWidth = 40;
    // Background color for unselected tabs that don't have an explicitly
    // set color.
    private Color unselectedBackground;
    protected Color tabAreaBackground;
    protected Color selectColor;
    protected Color selectHighlight;
    private boolean tabsOpaque = true;

    // Whether or not we're using ocean. This is cached as it is used
    // extensively during painting.
    private boolean ocean;
    // Selected border color for ocean.
    private Color oceanSelectedBorderColor;

    public static ComponentUI createUI( JComponent x ) {
        return new MetalTabbedPaneUI();
    }

    protected LayoutManager createLayoutManager() {
        if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) {
            return super.createLayoutManager();
        }
        return new TabbedPaneLayout();
    }

    protected void installDefaults() {
        super.installDefaults();

        tabAreaBackground = UIManager.getColor("TabbedPane.tabAreaBackground");
        selectColor = UIManager.getColor("TabbedPane.selected");
        selectHighlight = UIManager.getColor("TabbedPane.selectHighlight");
        tabsOpaque = UIManager.getBoolean("TabbedPane.tabsOpaque");
        unselectedBackground = UIManager.getColor(
                                         "TabbedPane.unselectedBackground");
        ocean = MetalLookAndFeel.usingOcean();
        if (ocean) {
            oceanSelectedBorderColor = UIManager.getColor(
                         "TabbedPane.borderHightlightColor");
        }
    }


    protected void paintTabBorder( Graphics g, int tabPlacement,
                                   int tabIndex, int x, int y, int w, int h,
                                   boolean isSelected) {
        int bottom = y + (h-1);
        int right = x + (w-1);

        switch ( tabPlacement ) {
        case LEFT:
            paintLeftTabBorder(tabIndex, g, x, y, w, h, bottom, right, isSelected);
            break;
        case BOTTOM:
            paintBottomTabBorder(tabIndex, g, x, y, w, h, bottom, right, isSelected);
            break;
        case RIGHT:
            paintRightTabBorder(tabIndex, g, x, y, w, h, bottom, right, isSelected);
            break;
        case TOP:
        default:
            paintTopTabBorder(tabIndex, g, x, y, w, h, bottom, right, isSelected);
        }
    }


    protected void paintTopTabBorder( int tabIndex, Graphics g,
                                      int x, int y, int w, int h,
                                      int btm, int rght,
                                      boolean isSelected ) {
        int currentRun = getRunForTab( tabPane.getTabCount(), tabIndex );
        int lastIndex = lastTabInRun( tabPane.getTabCount(), currentRun );
        int firstIndex = tabRuns[ currentRun ];
        boolean leftToRight = MetalUtils.isLeftToRight(tabPane);
        int selectedIndex = tabPane.getSelectedIndex();
        int bottom = h - 1;
        int right = w - 1;

        //
        // Paint Gap
        //

        if (shouldFillGap( currentRun, tabIndex, x, y ) ) {
            g.translate( x, y );

            if ( leftToRight ) {
                g.setColor( getColorForGap( currentRun, x, y + 1 ) );
                g.fillRect( 1, 0, 5, 3 );
                g.fillRect( 1, 3, 2, 2 );
            } else {
                g.setColor( getColorForGap( currentRun, x + w - 1, y + 1 ) );
                g.fillRect( right - 5, 0, 5, 3 );
                g.fillRect( right - 2, 3, 2, 2 );
            }

            g.translate( -x, -y );
        }

        g.translate( x, y );

        //
        // Paint Border
        //

        if (ocean && isSelected) {
            g.setColor(oceanSelectedBorderColor);
        }
        else {
            g.setColor( darkShadow );
        }

        if ( leftToRight ) {

            // Paint slant
            g.drawLine( 1, 5, 6, 0 );

            // Paint top
            g.drawLine( 6, 0, right, 0 );

            // Paint right
            if ( tabIndex==lastIndex ) {
                // last tab in run
                g.drawLine( right, 1, right, bottom );
            }

            if (ocean && tabIndex - 1 == selectedIndex &&
                                currentRun == getRunForTab(
                                tabPane.getTabCount(), selectedIndex)) {
                g.setColor(oceanSelectedBorderColor);
            }

            // Paint left
            if ( tabIndex != tabRuns[ runCount - 1 ] ) {
                // not the first tab in the last run
                if (ocean && isSelected) {
                    g.drawLine(0, 6, 0, bottom);
                    g.setColor(darkShadow);
                    g.drawLine(0, 0, 0, 5);
                }
                else {
                    g.drawLine( 0, 0, 0, bottom );
                }
            } else {
                // the first tab in the last run
                g.drawLine( 0, 6, 0, bottom );
            }
        } else {

            // Paint slant
            g.drawLine( right - 1, 5, right - 6, 0 );

            // Paint top
            g.drawLine( right - 6, 0, 0, 0 );

            // Paint left
            if ( tabIndex==lastIndex ) {
                // last tab in run
                g.drawLine( 0, 1, 0, bottom );
            }

            // Paint right
            if (ocean && tabIndex - 1 == selectedIndex &&
                                currentRun == getRunForTab(
                                tabPane.getTabCount(), selectedIndex)) {
                g.setColor(oceanSelectedBorderColor);
                g.drawLine(right, 0, right, bottom);
            }
            else if (ocean && isSelected) {
                g.drawLine(right, 6, right, bottom);
                if (tabIndex != 0) {
                    g.setColor(darkShadow);
                    g.drawLine(right, 0, right, 5);
                }
            }
            else {
                if ( tabIndex != tabRuns[ runCount - 1 ] ) {
                    // not the first tab in the last run
                    g.drawLine( right, 0, right, bottom );
                } else {
                    // the first tab in the last run
                    g.drawLine( right, 6, right, bottom );
                }
            }
        }

        //
        // Paint Highlight
        //

        g.setColor( isSelected ? selectHighlight : highlight );

        if ( leftToRight ) {

            // Paint slant
            g.drawLine( 1, 6, 6, 1 );

            // Paint top
            g.drawLine( 6, 1, (tabIndex == lastIndex) ? right - 1 : right, 1 );

            // Paint left
            g.drawLine( 1, 6, 1, bottom );

            // paint highlight in the gap on tab behind this one
            // on the left end (where they all line up)
            if ( tabIndex==firstIndex && tabIndex!=tabRuns[runCount - 1] ) {
                //  first tab in run but not first tab in last run
                if (tabPane.getSelectedIndex()==tabRuns[currentRun+1]) {
                    // tab in front of selected tab
                    g.setColor( selectHighlight );
                }
                else {
                    // tab in front of normal tab
                    g.setColor( highlight );
                }
                g.drawLine( 1, 0, 1, 4 );
            }
        } else {

            // Paint slant
            g.drawLine( right - 1, 6, right - 6, 1 );

            // Paint top
            g.drawLine( right - 6, 1, 1, 1 );

            // Paint left
            if ( tabIndex==lastIndex ) {
                // last tab in run
                g.drawLine( 1, 1, 1, bottom );
            } else {
                g.drawLine( 0, 1, 0, bottom );
            }
        }

        g.translate( -x, -y );
    }

    protected boolean shouldFillGap( int currentRun, int tabIndex, int x, int y ) {
        boolean result = false;

        if (!tabsOpaque) {
            return false;
        }

        if ( currentRun == runCount - 2 ) {  // If it's the second to last row.
            Rectangle lastTabBounds = getTabBounds( tabPane, tabPane.getTabCount() - 1 );
            Rectangle tabBounds = getTabBounds( tabPane, tabIndex );
            if (MetalUtils.isLeftToRight(tabPane)) {
                int lastTabRight = lastTabBounds.x + lastTabBounds.width - 1;

                // is the right edge of the last tab to the right
                // of the left edge of the current tab?
                if ( lastTabRight > tabBounds.x + 2 ) {
                    return true;
                }
            } else {
                int lastTabLeft = lastTabBounds.x;
                int currentTabRight = tabBounds.x + tabBounds.width - 1;

                // is the left edge of the last tab to the left
                // of the right edge of the current tab?
                if ( lastTabLeft < currentTabRight - 2 ) {
                    return true;
                }
            }
        } else {
            // fill in gap for all other rows except last row
            result = currentRun != runCount - 1;
        }

        return result;
    }

    protected Color getColorForGap( int currentRun, int x, int y ) {
        final int shadowWidth = 4;
        int selectedIndex = tabPane.getSelectedIndex();
        int startIndex = tabRuns[ currentRun + 1 ];
        int endIndex = lastTabInRun( tabPane.getTabCount(), currentRun + 1 );
        int tabOverGap = -1;
        // Check each tab in the row that is 'on top' of this row
        for ( int i = startIndex; i <= endIndex; ++i ) {
            Rectangle tabBounds = getTabBounds( tabPane, i );
            int tabLeft = tabBounds.x;
            int tabRight = (tabBounds.x + tabBounds.width) - 1;
            // Check to see if this tab is over the gap
            if ( MetalUtils.isLeftToRight(tabPane) ) {
                if ( tabLeft <= x && tabRight - shadowWidth > x ) {
                    return selectedIndex == i ? selectColor : getUnselectedBackgroundAt( i );
                }
            }
            else {
                if ( tabLeft + shadowWidth < x && tabRight >= x ) {
                    return selectedIndex == i ? selectColor : getUnselectedBackgroundAt( i );
                }
            }
        }

        return tabPane.getBackground();
    }

    protected void paintLeftTabBorder( int tabIndex, Graphics g,
                                       int x, int y, int w, int h,
                                       int btm, int rght,
                                       boolean isSelected ) {
        int tabCount = tabPane.getTabCount();
        int currentRun = getRunForTab( tabCount, tabIndex );
        int lastIndex = lastTabInRun( tabCount, currentRun );
        int firstIndex = tabRuns[ currentRun ];

        g.translate( x, y );

        int bottom = h - 1;
        int right = w - 1;

        //
        // Paint part of the tab above
        //

        if ( tabIndex != firstIndex && tabsOpaque ) {
            g.setColor( tabPane.getSelectedIndex() == tabIndex - 1 ?
                        selectColor :
                        getUnselectedBackgroundAt( tabIndex - 1 ) );
            g.fillRect( 2, 0, 4, 3 );
            g.drawLine( 2, 3, 2, 3 );
        }


        //
        // Paint Highlight
        //

        if (ocean) {
            g.setColor(isSelected ? selectHighlight :
                       MetalLookAndFeel.getWhite());
        }
        else {
            g.setColor( isSelected ? selectHighlight : highlight );
        }

        // Paint slant
        g.drawLine( 1, 6, 6, 1 );

        // Paint left
        g.drawLine( 1, 6, 1, bottom );

        // Paint top
        g.drawLine( 6, 1, right, 1 );

        if ( tabIndex != firstIndex ) {
            if (tabPane.getSelectedIndex() == tabIndex - 1) {
                g.setColor(selectHighlight);
            } else {
                g.setColor(ocean ? MetalLookAndFeel.getWhite() : highlight);
            }

            g.drawLine( 1, 0, 1, 4 );
        }

        //
        // Paint Border
        //

        if (ocean) {
            if (isSelected) {
                g.setColor(oceanSelectedBorderColor);
            }
            else {
                g.setColor( darkShadow );
            }
        }
        else {
            g.setColor( darkShadow );
        }

        // Paint slant
        g.drawLine( 1, 5, 6, 0 );

        // Paint top
        g.drawLine( 6, 0, right, 0 );

        // Paint bottom
        if ( tabIndex == lastIndex ) {
            g.drawLine( 0, bottom, right, bottom );
        }

        // Paint left
        if (ocean) {
            if (tabPane.getSelectedIndex() == tabIndex - 1) {
                g.drawLine(0, 5, 0, bottom);
                g.setColor(oceanSelectedBorderColor);
                g.drawLine(0, 0, 0, 5);
            }
            else if (isSelected) {
                g.drawLine( 0, 6, 0, bottom );
                if (tabIndex != 0) {
                    g.setColor(darkShadow);
                    g.drawLine(0, 0, 0, 5);
                }
            }
            else if ( tabIndex != firstIndex ) {
                g.drawLine( 0, 0, 0, bottom );
            } else {
                g.drawLine( 0, 6, 0, bottom );
            }
        }
        else { // metal
            if ( tabIndex != firstIndex ) {
                g.drawLine( 0, 0, 0, bottom );
            } else {
                g.drawLine( 0, 6, 0, bottom );
            }
        }

        g.translate( -x, -y );
    }


    protected void paintBottomTabBorder( int tabIndex, Graphics g,
                                         int x, int y, int w, int h,
                                         int btm, int rght,
                                         boolean isSelected ) {
        int tabCount = tabPane.getTabCount();
        int currentRun = getRunForTab( tabCount, tabIndex );
        int lastIndex = lastTabInRun( tabCount, currentRun );
        int firstIndex = tabRuns[ currentRun ];
        boolean leftToRight = MetalUtils.isLeftToRight(tabPane);

        int bottom = h - 1;
        int right = w - 1;

        //
        // Paint Gap
        //

        if ( shouldFillGap( currentRun, tabIndex, x, y ) ) {
            g.translate( x, y );

            if ( leftToRight ) {
                g.setColor( getColorForGap( currentRun, x, y ) );
                g.fillRect( 1, bottom - 4, 3, 5 );
                g.fillRect( 4, bottom - 1, 2, 2 );
            } else {
                g.setColor( getColorForGap( currentRun, x + w - 1, y ) );
                g.fillRect( right - 3, bottom - 3, 3, 4 );
                g.fillRect( right - 5, bottom - 1, 2, 2 );
                g.drawLine( right - 1, bottom - 4, right - 1, bottom - 4 );
            }

            g.translate( -x, -y );
        }

        g.translate( x, y );


        //
        // Paint Border
        //

        if (ocean && isSelected) {
            g.setColor(oceanSelectedBorderColor);
        }
        else {
            g.setColor( darkShadow );
        }

        if ( leftToRight ) {

            // Paint slant
            g.drawLine( 1, bottom - 5, 6, bottom );

            // Paint bottom
            g.drawLine( 6, bottom, right, bottom );

            // Paint right
            if ( tabIndex == lastIndex ) {
                g.drawLine( right, 0, right, bottom );
            }

            // Paint left
            if (ocean && isSelected) {
                g.drawLine(0, 0, 0, bottom - 6);
                if ((currentRun == 0 && tabIndex != 0) ||
                    (currentRun > 0 && tabIndex != tabRuns[currentRun - 1])) {
                    g.setColor(darkShadow);
                    g.drawLine(0, bottom - 5, 0, bottom);
                }
            }
            else {
                if (ocean && tabIndex == tabPane.getSelectedIndex() + 1) {
                    g.setColor(oceanSelectedBorderColor);
                }
                if ( tabIndex != tabRuns[ runCount - 1 ] ) {
                    g.drawLine( 0, 0, 0, bottom );
                } else {
                    g.drawLine( 0, 0, 0, bottom - 6 );
                }
            }
        } else {

            // Paint slant
            g.drawLine( right - 1, bottom - 5, right - 6, bottom );

            // Paint bottom
            g.drawLine( right - 6, bottom, 0, bottom );

            // Paint left
            if ( tabIndex==lastIndex ) {
                // last tab in run
                g.drawLine( 0, 0, 0, bottom );
            }

            // Paint right
            if (ocean && tabIndex == tabPane.getSelectedIndex() + 1) {
                g.setColor(oceanSelectedBorderColor);
                g.drawLine(right, 0, right, bottom);
            }
            else if (ocean && isSelected) {
                g.drawLine(right, 0, right, bottom - 6);
                if (tabIndex != firstIndex) {
                    g.setColor(darkShadow);
                    g.drawLine(right, bottom - 5, right, bottom);
                }
            }
            else if ( tabIndex != tabRuns[ runCount - 1 ] ) {
                // not the first tab in the last run
                g.drawLine( right, 0, right, bottom );
            } else {
                // the first tab in the last run
                g.drawLine( right, 0, right, bottom - 6 );
            }
        }

        //
        // Paint Highlight
        //

        g.setColor( isSelected ? selectHighlight : highlight );

        if ( leftToRight ) {

            // Paint slant
            g.drawLine( 1, bottom - 6, 6, bottom - 1 );

            // Paint left
            g.drawLine( 1, 0, 1, bottom - 6 );

            // paint highlight in the gap on tab behind this one
            // on the left end (where they all line up)
            if ( tabIndex==firstIndex && tabIndex!=tabRuns[runCount - 1] ) {
                //  first tab in run but not first tab in last run
                if (tabPane.getSelectedIndex()==tabRuns[currentRun+1]) {
                    // tab in front of selected tab
                    g.setColor( selectHighlight );
                }
                else {
                    // tab in front of normal tab
                    g.setColor( highlight );
                }
                g.drawLine( 1, bottom - 4, 1, bottom );
            }
        } else {

            // Paint left
            if ( tabIndex==lastIndex ) {
                // last tab in run
                g.drawLine( 1, 0, 1, bottom - 1 );
            } else {
                g.drawLine( 0, 0, 0, bottom - 1 );
            }
        }

        g.translate( -x, -y );
    }

    protected void paintRightTabBorder( int tabIndex, Graphics g,
                                        int x, int y, int w, int h,
                                        int btm, int rght,
                                        boolean isSelected ) {
        int tabCount = tabPane.getTabCount();
        int currentRun = getRunForTab( tabCount, tabIndex );
        int lastIndex = lastTabInRun( tabCount, currentRun );
        int firstIndex = tabRuns[ currentRun ];

        g.translate( x, y );

        int bottom = h - 1;
        int right = w - 1;

        //
        // Paint part of the tab above
        //

        if ( tabIndex != firstIndex && tabsOpaque ) {
            g.setColor( tabPane.getSelectedIndex() == tabIndex - 1 ?
                        selectColor :
                        getUnselectedBackgroundAt( tabIndex - 1 ) );
            g.fillRect( right - 5, 0, 5, 3 );
            g.fillRect( right - 2, 3, 2, 2 );
        }


        //
        // Paint Highlight
        //

        g.setColor( isSelected ? selectHighlight : highlight );

        // Paint slant
        g.drawLine( right - 6, 1, right - 1, 6 );

        // Paint top
        g.drawLine( 0, 1, right - 6, 1 );

        // Paint left
        if ( !isSelected ) {
            g.drawLine( 0, 1, 0, bottom );
        }


        //
        // Paint Border
        //

        if (ocean && isSelected) {
            g.setColor(oceanSelectedBorderColor);
        }
        else {
            g.setColor( darkShadow );
        }

        // Paint bottom
        if ( tabIndex == lastIndex ) {
            g.drawLine( 0, bottom, right, bottom );
        }

        // Paint slant
        if (ocean && tabPane.getSelectedIndex() == tabIndex - 1) {
            g.setColor(oceanSelectedBorderColor);
        }
        g.drawLine( right - 6, 0, right, 6 );

        // Paint top
        g.drawLine( 0, 0, right - 6, 0 );

        // Paint right
        if (ocean && isSelected) {
            g.drawLine(right, 6, right, bottom);
            if (tabIndex != firstIndex) {
                g.setColor(darkShadow);
                g.drawLine(right, 0, right, 5);
            }
        }
        else if (ocean && tabPane.getSelectedIndex() == tabIndex - 1) {
            g.setColor(oceanSelectedBorderColor);
            g.drawLine(right, 0, right, 6);
            g.setColor(darkShadow);
            g.drawLine(right, 6, right, bottom);
        }
        else if ( tabIndex != firstIndex ) {
            g.drawLine( right, 0, right, bottom );
        } else {
            g.drawLine( right, 6, right, bottom );
        }

        g.translate( -x, -y );
    }

    public void update( Graphics g, JComponent c ) {
        if ( c.isOpaque() ) {
            g.setColor( tabAreaBackground );
            g.fillRect( 0, 0, c.getWidth(),c.getHeight() );
        }
        paint( g, c );
    }

    protected void paintTabBackground( Graphics g, int tabPlacement,
                                       int tabIndex, int x, int y, int w, int h, boolean isSelected ) {
        int slantWidth = h / 2;
        if ( isSelected ) {
            g.setColor( selectColor );
        } else {
            g.setColor( getUnselectedBackgroundAt( tabIndex ) );
        }

        if (MetalUtils.isLeftToRight(tabPane)) {
            switch ( tabPlacement ) {
                case LEFT:
                    g.fillRect( x + 5, y + 1, w - 5, h - 1);
                    g.fillRect( x + 2, y + 4, 3, h - 4 );
                    break;
                case BOTTOM:
                    g.fillRect( x + 2, y, w - 2, h - 4 );
                    g.fillRect( x + 5, y + (h - 1) - 3, w - 5, 3 );
                    break;
                case RIGHT:
                    g.fillRect( x, y + 2, w - 4, h - 2);
                    g.fillRect( x + (w - 1) - 3, y + 5, 3, h - 5 );
                    break;
                case TOP:
                default:
                    g.fillRect( x + 4, y + 2, (w - 1) - 3, (h - 1) - 1 );
                    g.fillRect( x + 2, y + 5, 2, h - 5 );
            }
        } else {
            switch ( tabPlacement ) {
                case LEFT:
                    g.fillRect( x + 5, y + 1, w - 5, h - 1);
                    g.fillRect( x + 2, y + 4, 3, h - 4 );
                    break;
                case BOTTOM:
                    g.fillRect( x, y, w - 5, h - 1 );
                    g.fillRect( x + (w - 1) - 4, y, 4, h - 5);
                    g.fillRect( x + (w - 1) - 4, y + (h - 1) - 4, 2, 2);
                    break;
                case RIGHT:
                    g.fillRect( x + 1, y + 1, w - 5, h - 1);
                    g.fillRect( x + (w - 1) - 3, y + 5, 3, h - 5 );
                    break;
                case TOP:
                default:
                    g.fillRect( x, y + 2, (w - 1) - 3, (h - 1) - 1 );
                    g.fillRect( x + (w - 1) - 3, y + 5, 3, h - 3 );
            }
        }
    }

    /**
     * Overridden to do nothing for the Java L&F.
     */
    protected int getTabLabelShiftX( int tabPlacement, int tabIndex, boolean isSelected ) {
        return 0;
    }


    /**
     * Overridden to do nothing for the Java L&F.
     */
    protected int getTabLabelShiftY( int tabPlacement, int tabIndex, boolean isSelected ) {
        return 0;
    }

    /**
     * {@inheritDoc}
     *
     * @since 1.6
     */
    protected int getBaselineOffset() {
        return 0;
    }

    public void paint( Graphics g, JComponent c ) {
        int tabPlacement = tabPane.getTabPlacement();

        Insets insets = c.getInsets(); Dimension size = c.getSize();

        // Paint the background for the tab area
        if ( tabPane.isOpaque() ) {
            Color bg = UIManager.getColor("TabbedPane.tabAreaBackground");
            if (bg != null) {
                g.setColor(bg);
            }
            else {
                g.setColor( c.getBackground() );
            }
            switch ( tabPlacement ) {
            case LEFT:
                g.fillRect( insets.left, insets.top,
                            calculateTabAreaWidth( tabPlacement, runCount, maxTabWidth ),
                            size.height - insets.bottom - insets.top );
                break;
            case BOTTOM:
                int totalTabHeight = calculateTabAreaHeight( tabPlacement, runCount, maxTabHeight );
                g.fillRect( insets.left, size.height - insets.bottom - totalTabHeight,
                            size.width - insets.left - insets.right,
                            totalTabHeight );
                break;
            case RIGHT:
                int totalTabWidth = calculateTabAreaWidth( tabPlacement, runCount, maxTabWidth );
                g.fillRect( size.width - insets.right - totalTabWidth,
                            insets.top, totalTabWidth,
                            size.height - insets.top - insets.bottom );
                break;
            case TOP:
            default:
                g.fillRect( insets.left, insets.top,
                            size.width - insets.right - insets.left,
                            calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight) );
                paintHighlightBelowTab();
            }
        }

        super.paint( g, c );
    }

    protected void paintHighlightBelowTab( ) {

    }


    protected void paintFocusIndicator(Graphics g, int tabPlacement,
                                       Rectangle[] rects, int tabIndex,
                                       Rectangle iconRect, Rectangle textRect,
                                       boolean isSelected) {
        if ( tabPane.hasFocus() && isSelected ) {
            Rectangle tabRect = rects[tabIndex];
            boolean lastInRun = isLastInRun( tabIndex );
            g.setColor( focus );
            g.translate( tabRect.x, tabRect.y );
            int right = tabRect.width - 1;
            int bottom = tabRect.height - 1;
            boolean leftToRight = MetalUtils.isLeftToRight(tabPane);
            switch ( tabPlacement ) {
            case RIGHT:
                g.drawLine( right - 6,2 , right - 2,6 );         // slant
                g.drawLine( 1,2 , right - 6,2 );                 // top
                g.drawLine( right - 2,6 , right - 2,bottom );    // right
                g.drawLine( 1,2 , 1,bottom );                    // left
                g.drawLine( 1,bottom , right - 2,bottom );       // bottom
                break;
            case BOTTOM:
                if ( leftToRight ) {
                    g.drawLine( 2, bottom - 6, 6, bottom - 2 );   // slant
                    g.drawLine( 6, bottom - 2,
                                right, bottom - 2 );              // bottom
                    g.drawLine( 2, 0, 2, bottom - 6 );            // left
                    g.drawLine( 2, 0, right, 0 );                 // top
                    g.drawLine( right, 0, right, bottom - 2 );    // right
                } else {
                    g.drawLine( right - 2, bottom - 6,
                                right - 6, bottom - 2 );          // slant
                    g.drawLine( right - 2, 0,
                                right - 2, bottom - 6 );          // right
                    if ( lastInRun ) {
                        // last tab in run
                        g.drawLine( 2, bottom - 2,
                                    right - 6, bottom - 2 );      // bottom
                        g.drawLine( 2, 0, right - 2, 0 );         // top
                        g.drawLine( 2, 0, 2, bottom - 2 );        // left
                    } else {
                        g.drawLine( 1, bottom - 2,
                                    right - 6, bottom - 2 );      // bottom
                        g.drawLine( 1, 0, right - 2, 0 );         // top
                        g.drawLine( 1, 0, 1, bottom - 2 );        // left
                    }
                }
                break;
            case LEFT:
                g.drawLine( 2, 6, 6, 2 );                         // slant
                g.drawLine( 2, 6, 2, bottom - 1);                 // left
                g.drawLine( 6, 2, right, 2 );                     // top
                g.drawLine( right, 2, right, bottom - 1 );        // right
                g.drawLine( 2, bottom - 1,
                            right, bottom - 1 );                  // bottom
                break;
            case TOP:
             default:
                    if ( leftToRight ) {
                        g.drawLine( 2, 6, 6, 2 );                     // slant
                        g.drawLine( 2, 6, 2, bottom - 1);             // left
                        g.drawLine( 6, 2, right, 2 );                 // top
                        g.drawLine( right, 2, right, bottom - 1 );    // right
                        g.drawLine( 2, bottom - 1,
                                    right, bottom - 1 );              // bottom
                    }
                    else {
                        g.drawLine( right - 2, 6, right - 6, 2 );     // slant
                        g.drawLine( right - 2, 6,
                                    right - 2, bottom - 1);           // right
                        if ( lastInRun ) {
                            // last tab in run
                            g.drawLine( right - 6, 2, 2, 2 );         // top
                            g.drawLine( 2, 2, 2, bottom - 1 );        // left
                            g.drawLine( right - 2, bottom - 1,
                                        2, bottom - 1 );              // bottom
                        }
                        else {
                            g.drawLine( right - 6, 2, 1, 2 );         // top
                            g.drawLine( 1, 2, 1, bottom - 1 );        // left
                            g.drawLine( right - 2, bottom - 1,
                                        1, bottom - 1 );              // bottom
                        }
                    }
            }
            g.translate( -tabRect.x, -tabRect.y );
        }
    }

    protected void paintContentBorderTopEdge( Graphics g, int tabPlacement,
                                              int selectedIndex,
                                              int x, int y, int w, int h ) {
        boolean leftToRight = MetalUtils.isLeftToRight(tabPane);
        int right = x + w - 1;
        Rectangle selRect = selectedIndex < 0? null :
                               getTabBounds(selectedIndex, calcRect);
        if (ocean) {
            g.setColor(oceanSelectedBorderColor);
        }
        else {
            g.setColor(selectHighlight);
        }

        // Draw unbroken line if tabs are not on TOP, OR
        // selected tab is not in run adjacent to content, OR
        // selected tab is not visible (SCROLL_TAB_LAYOUT)
        //
         if (tabPlacement != TOP || selectedIndex < 0 ||
            (selRect.y + selRect.height + 1 < y) ||
            (selRect.x < x || selRect.x > x + w)) {
            g.drawLine(x, y, x+w-2, y);
            if (ocean && tabPlacement == TOP) {
                g.setColor(MetalLookAndFeel.getWhite());
                g.drawLine(x, y + 1, x+w-2, y + 1);
            }
        } else {
            // Break line to show visual connection to selected tab
            boolean lastInRun = isLastInRun(selectedIndex);

            if ( leftToRight || lastInRun ) {
                g.drawLine(x, y, selRect.x + 1, y);
            } else {
                g.drawLine(x, y, selRect.x, y);
            }

            if (selRect.x + selRect.width < right - 1) {
                if ( leftToRight && !lastInRun ) {
                    g.drawLine(selRect.x + selRect.width, y, right - 1, y);
                } else {
                    g.drawLine(selRect.x + selRect.width - 1, y, right - 1, y);
                }
            } else {
                g.setColor(shadow);
                g.drawLine(x+w-2, y, x+w-2, y);
            }

            if (ocean) {
                g.setColor(MetalLookAndFeel.getWhite());

                if ( leftToRight || lastInRun ) {
                    g.drawLine(x, y + 1, selRect.x + 1, y + 1);
                } else {
                    g.drawLine(x, y + 1, selRect.x, y + 1);
                }

                if (selRect.x + selRect.width < right - 1) {
                    if ( leftToRight && !lastInRun ) {
                        g.drawLine(selRect.x + selRect.width, y + 1,
                                   right - 1, y + 1);
                    } else {
                        g.drawLine(selRect.x + selRect.width - 1, y + 1,
                                   right - 1, y + 1);
                    }
                } else {
                    g.setColor(shadow);
                    g.drawLine(x+w-2, y + 1, x+w-2, y + 1);
                }
            }
        }
    }

    protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
                                                int selectedIndex,
                                                int x, int y, int w, int h) {
        boolean leftToRight = MetalUtils.isLeftToRight(tabPane);
        int bottom = y + h - 1;
        int right = x + w - 1;
        Rectangle selRect = selectedIndex < 0? null :
                               getTabBounds(selectedIndex, calcRect);

        g.setColor(darkShadow);

        // Draw unbroken line if tabs are not on BOTTOM, OR
        // selected tab is not in run adjacent to content, OR
        // selected tab is not visible (SCROLL_TAB_LAYOUT)
        //
        if (tabPlacement != BOTTOM || selectedIndex < 0 ||
             (selRect.y - 1 > h) ||
             (selRect.x < x || selRect.x > x + w)) {
            if (ocean && tabPlacement == BOTTOM) {
                g.setColor(oceanSelectedBorderColor);
            }
            g.drawLine(x, y+h-1, x+w-1, y+h-1);
        } else {
            // Break line to show visual connection to selected tab
            boolean lastInRun = isLastInRun(selectedIndex);

            if (ocean) {
                g.setColor(oceanSelectedBorderColor);
            }

            if ( leftToRight || lastInRun ) {
                g.drawLine(x, bottom, selRect.x, bottom);
            } else {
                g.drawLine(x, bottom, selRect.x - 1, bottom);
            }

            if (selRect.x + selRect.width < x + w - 2) {
                if ( leftToRight && !lastInRun ) {
                    g.drawLine(selRect.x + selRect.width, bottom,
                                                   right, bottom);
                } else {
                    g.drawLine(selRect.x + selRect.width - 1, bottom,
                                                       right, bottom);
                }
            }
        }
    }

    protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
                                              int selectedIndex,
                                              int x, int y, int w, int h) {
        Rectangle selRect = selectedIndex < 0? null :
                               getTabBounds(selectedIndex, calcRect);
        if (ocean) {
            g.setColor(oceanSelectedBorderColor);
        }
        else {
            g.setColor(selectHighlight);
        }

        // Draw unbroken line if tabs are not on LEFT, OR
        // selected tab is not in run adjacent to content, OR
        // selected tab is not visible (SCROLL_TAB_LAYOUT)
        //
        if (tabPlacement != LEFT || selectedIndex < 0 ||
            (selRect.x + selRect.width + 1 < x) ||
            (selRect.y < y || selRect.y > y + h)) {
            g.drawLine(x, y + 1, x, y+h-2);
            if (ocean && tabPlacement == LEFT) {
                g.setColor(MetalLookAndFeel.getWhite());
                g.drawLine(x + 1, y, x + 1, y + h - 2);
            }
        } else {
            // Break line to show visual connection to selected tab
            g.drawLine(x, y, x, selRect.y + 1);
            if (selRect.y + selRect.height < y + h - 2) {
              g.drawLine(x, selRect.y + selRect.height + 1,
                         x, y+h+2);
            }
            if (ocean) {
                g.setColor(MetalLookAndFeel.getWhite());
                g.drawLine(x + 1, y + 1, x + 1, selRect.y + 1);
                if (selRect.y + selRect.height < y + h - 2) {
                    g.drawLine(x + 1, selRect.y + selRect.height + 1,
                               x + 1, y+h+2);
                }
            }
        }
    }

    protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
                                               int selectedIndex,
                                               int x, int y, int w, int h) {
        Rectangle selRect = selectedIndex < 0? null :
                               getTabBounds(selectedIndex, calcRect);

        g.setColor(darkShadow);
        // Draw unbroken line if tabs are not on RIGHT, OR
        // selected tab is not in run adjacent to content, OR
        // selected tab is not visible (SCROLL_TAB_LAYOUT)
        //
        if (tabPlacement != RIGHT || selectedIndex < 0 ||
             (selRect.x - 1 > w) ||
             (selRect.y < y || selRect.y > y + h)) {
            if (ocean && tabPlacement == RIGHT) {
                g.setColor(oceanSelectedBorderColor);
            }
            g.drawLine(x+w-1, y, x+w-1, y+h-1);
        } else {
            // Break line to show visual connection to selected tab
            if (ocean) {
                g.setColor(oceanSelectedBorderColor);
            }
            g.drawLine(x+w-1, y, x+w-1, selRect.y);

            if (selRect.y + selRect.height < y + h - 2) {
                g.drawLine(x+w-1, selRect.y + selRect.height,
                           x+w-1, y+h-2);
            }
        }
    }

    protected int calculateMaxTabHeight( int tabPlacement ) {
        FontMetrics metrics = getFontMetrics();
        int height = metrics.getHeight();
        boolean tallerIcons = false;

        for ( int i = 0; i < tabPane.getTabCount(); ++i ) {
            Icon icon = tabPane.getIconAt( i );
            if ( icon != null ) {
                if ( icon.getIconHeight() > height ) {
                    tallerIcons = true;
                    break;
                }
            }
        }
        return super.calculateMaxTabHeight( tabPlacement ) -
                  (tallerIcons ? (tabInsets.top + tabInsets.bottom) : 0);
    }


    protected int getTabRunOverlay( int tabPlacement ) {
        // Tab runs laid out vertically should overlap
        // at least as much as the largest slant
        if ( tabPlacement == LEFT || tabPlacement == RIGHT ) {
            int maxTabHeight = calculateMaxTabHeight(tabPlacement);
            return maxTabHeight / 2;
        }
        return 0;
    }

    // Don't rotate runs!
    protected boolean shouldRotateTabRuns( int tabPlacement, int selectedRun ) {
        return false;
    }

    // Don't pad last run
    protected boolean shouldPadTabRun( int tabPlacement, int run ) {
        return runCount > 1 && run < runCount - 1;
    }

    private boolean isLastInRun( int tabIndex ) {
        int run = getRunForTab( tabPane.getTabCount(), tabIndex );
        int lastIndex = lastTabInRun( tabPane.getTabCount(), run );
        return tabIndex == lastIndex;
    }

    /**
     * Returns the color to use for the specified tab.
     */
    private Color getUnselectedBackgroundAt(int index) {
        Color color = tabPane.getBackgroundAt(index);
        if (color instanceof UIResource) {
            if (unselectedBackground != null) {
                return unselectedBackground;
            }
        }
        return color;
    }

    /**
     * Returns the tab index of JTabbedPane the mouse is currently over
     */
    int getRolloverTabIndex() {
        return getRolloverTab();
    }

    /**
     * This inner class is marked &quot;public&quot; due to a compiler bug.
     * This class should be treated as a &quot;protected&quot; inner class.
     * Instantiate it only within subclasses of MetalTabbedPaneUI.
     */
    public class TabbedPaneLayout extends BasicTabbedPaneUI.TabbedPaneLayout {

        public TabbedPaneLayout() {
            MetalTabbedPaneUI.this.super();
        }

        protected void normalizeTabRuns( int tabPlacement, int tabCount,
                                     int start, int max ) {
            // Only normalize the runs for top & bottom;  normalizing
            // doesn't look right for Metal's vertical tabs
            // because the last run isn't padded and it looks odd to have
            // fat tabs in the first vertical runs, but slimmer ones in the
            // last (this effect isn't noticeable for horizontal tabs).
            if ( tabPlacement == TOP || tabPlacement == BOTTOM ) {
                super.normalizeTabRuns( tabPlacement, tabCount, start, max );
            }
        }

        // Don't rotate runs!
        protected void rotateTabRuns( int tabPlacement, int selectedRun ) {
        }

        // Don't pad selected tab
        protected void padSelectedTab( int tabPlacement, int selectedIndex ) {
        }
    }

}
