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

package com.sun.java.swing.plaf.windows;

import java.awt.*;

import javax.swing.plaf.basic.*;
import javax.swing.plaf.*;
import javax.swing.*;
import java.util.Set;
import java.util.HashSet;
import java.awt.event.*;

import static com.sun.java.swing.plaf.windows.TMSchema.*;
import static com.sun.java.swing.plaf.windows.XPStyle.Skin;


/**
 * Windows rendition of the component.
 * <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.  A future release of Swing will provide support for
 * long term persistence.
 */
public class WindowsTabbedPaneUI extends BasicTabbedPaneUI {
    /**
     * Keys to use for forward focus traversal when the JComponent is
     * managing focus.
     */
    private static Set managingFocusForwardTraversalKeys;

    /**
     * Keys to use for backward focus traversal when the JComponent is
     * managing focus.
     */
    private static Set managingFocusBackwardTraversalKeys;

    private boolean contentOpaque = true;

    protected void installDefaults() {
        super.installDefaults();
        contentOpaque = UIManager.getBoolean("TabbedPane.contentOpaque");

        // focus forward traversal key
        if (managingFocusForwardTraversalKeys==null) {
            managingFocusForwardTraversalKeys = new HashSet();
            managingFocusForwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
        }
        tabPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, managingFocusForwardTraversalKeys);
        // focus backward traversal key
        if (managingFocusBackwardTraversalKeys==null) {
            managingFocusBackwardTraversalKeys = new HashSet();
            managingFocusBackwardTraversalKeys.add( KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));
        }
        tabPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, managingFocusBackwardTraversalKeys);
    }

    protected void uninstallDefaults() {
        // sets the focus forward and backward traversal keys to null
        // to restore the defaults
        tabPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
        tabPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
        super.uninstallDefaults();
    }

    public static ComponentUI createUI(JComponent c) {
        return new WindowsTabbedPaneUI();
    }

    protected void setRolloverTab(int index) {
        // Rollover is only supported on XP
        if (XPStyle.getXP() != null) {
            int oldRolloverTab = getRolloverTab();
            super.setRolloverTab(index);
            Rectangle r1 = null;
            Rectangle r2 = null;
            if ( (oldRolloverTab >= 0) && (oldRolloverTab < tabPane.getTabCount()) ) {
                r1 = getTabBounds(tabPane, oldRolloverTab);
            }
            if (index >= 0) {
                r2 = getTabBounds(tabPane, index);
            }
            if (r1 != null) {
                if (r2 != null) {
                    tabPane.repaint(r1.union(r2));
                } else {
                    tabPane.repaint(r1);
                }
            } else if (r2 != null) {
                tabPane.repaint(r2);
            }
        }
    }

    protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
        XPStyle xp = XPStyle.getXP();
        if (xp != null && (contentOpaque || tabPane.isOpaque())) {
            Skin skin = xp.getSkin(tabPane, Part.TABP_PANE);
            if (skin != null) {
                Insets insets = tabPane.getInsets();
                // Note: don't call getTabAreaInsets(), because it causes rotation.
                // Make sure "TabbedPane.tabsOverlapBorder" is set to true in WindowsLookAndFeel
                Insets tabAreaInsets = UIManager.getInsets("TabbedPane.tabAreaInsets");
                int x = insets.left;
                int y = insets.top;
                int w = tabPane.getWidth() - insets.right - insets.left;
                int h = tabPane.getHeight() - insets.top - insets.bottom;

                // Expand area by tabAreaInsets.bottom to allow tabs to overlap onto the border.
                if (tabPlacement == LEFT || tabPlacement == RIGHT) {
                    int tabWidth = calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
                    if (tabPlacement == LEFT) {
                        x += (tabWidth - tabAreaInsets.bottom);
                    }
                    w -= (tabWidth - tabAreaInsets.bottom);
                } else {
                    int tabHeight = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
                    if (tabPlacement == TOP) {
                        y += (tabHeight - tabAreaInsets.bottom);
                    }
                    h -= (tabHeight - tabAreaInsets.bottom);
                }

                paintRotatedSkin(g, skin, tabPlacement, x, y, w, h, null);
                return;
            }
        }
        super.paintContentBorder(g, tabPlacement, selectedIndex);
    }

    protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex,
                                      int x, int y, int w, int h, boolean isSelected ) {
        if (XPStyle.getXP() == null) {
            super.paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
        }
    }

    protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
                                  int x, int y, int w, int h, boolean isSelected ) {
        XPStyle xp = XPStyle.getXP();
        if (xp != null) {
            Part part;

            int tabCount = tabPane.getTabCount();
            int tabRun = getRunForTab(tabCount, tabIndex);
            if (tabRuns[tabRun] == tabIndex) {
                part = Part.TABP_TABITEMLEFTEDGE;
            } else if (tabCount > 1 && lastTabInRun(tabCount, tabRun) == tabIndex) {
                part = Part.TABP_TABITEMRIGHTEDGE;
                if (isSelected) {
                    // Align with right edge
                    if (tabPlacement == TOP || tabPlacement == BOTTOM) {
                        w++;
                    } else {
                        h++;
                    }
                }
            } else {
                part = Part.TABP_TABITEM;
            }

            State state = State.NORMAL;
            if (isSelected) {
                state = State.SELECTED;
            } else if (tabIndex == getRolloverTab()) {
                state = State.HOT;
            }

            paintRotatedSkin(g, xp.getSkin(tabPane, part), tabPlacement, x, y, w, h, state);
        } else {
            super.paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
        }
    }

    private void paintRotatedSkin(Graphics g, Skin skin, int tabPlacement,
                                  int x, int y, int w, int h, State state) {
        Graphics2D g2d = (Graphics2D)g.create();
        g2d.translate(x, y);
        switch (tabPlacement) {
           case RIGHT:  g2d.translate(w, 0);
                        g2d.rotate(Math.toRadians(90.0));
                        skin.paintSkin(g2d, 0, 0, h, w, state);
                        break;

           case LEFT:   g2d.scale(-1.0, 1.0);
                        g2d.rotate(Math.toRadians(90.0));
                        skin.paintSkin(g2d, 0, 0, h, w, state);
                        break;

           case BOTTOM: g2d.translate(0, h);
                        g2d.scale(-1.0, 1.0);
                        g2d.rotate(Math.toRadians(180.0));
                        skin.paintSkin(g2d, 0, 0, w, h, state);
                        break;

           case TOP:
           default:     skin.paintSkin(g2d, 0, 0, w, h, state);
        }
        g2d.dispose();
    }
}
