/*
 * Copyright 1997-2002 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.motif;

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

/**
 * A Motif L&F implementation of TabbedPaneUI.
 * <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.
 *
 * @author Amy Fowler
 * @author Philip Milne
 */
public class MotifTabbedPaneUI extends BasicTabbedPaneUI
{

// Instance variables initialized at installation

    protected Color unselectedTabBackground;
    protected Color unselectedTabForeground;
    protected Color unselectedTabShadow;
    protected Color unselectedTabHighlight;


// UI creation

    public static ComponentUI createUI(JComponent tabbedPane) {
        return new MotifTabbedPaneUI();
    }


// UI Installation/De-installation


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

        unselectedTabBackground = UIManager.getColor("TabbedPane.unselectedTabBackground");
        unselectedTabForeground = UIManager.getColor("TabbedPane.unselectedTabForeground");
        unselectedTabShadow = UIManager.getColor("TabbedPane.unselectedTabShadow");
        unselectedTabHighlight = UIManager.getColor("TabbedPane.unselectedTabHighlight");
    }

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

        unselectedTabBackground = null;
        unselectedTabForeground = null;
        unselectedTabShadow = null;
        unselectedTabHighlight = null;
    }

// UI Rendering

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

        // Draw unbroken line if tabs are not on TOP, OR
        // selected tab is not visible (SCROLL_TAB_LAYOUT)
        //
        if (tabPlacement != TOP || selectedIndex < 0 ||
            (selRect.x < x || selRect.x > x + w)) {
            g.drawLine(x, y, x+w-2, y);
        } else {
            // Break line to show visual connection to selected tab
            g.drawLine(x, y, selRect.x - 1, y);
            if (selRect.x + selRect.width < x + w - 2) {
                g.drawLine(selRect.x + selRect.width, y,
                           x+w-2, y);
            }
        }
    }

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

        // Draw unbroken line if tabs are not on BOTTOM, OR
        // selected tab is not visible (SCROLL_TAB_LAYOUT)
        //
        if (tabPlacement != BOTTOM || selectedIndex < 0 ||
             (selRect.x < x || selRect.x > x + w)) {
            g.drawLine(x+1, y+h-1, x+w-1, y+h-1);
        } else {
            // Break line to show visual connection to selected tab
            g.drawLine(x+1, y+h-1, selRect.x - 1, y+h-1);
            if (selRect.x + selRect.width < x + w - 2) {
                g.drawLine(selRect.x + selRect.width, y+h-1, x+w-2, y+h-1);
            }
        }
    }

    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(shadow);
        // Draw unbroken line if tabs are not on RIGHT, OR
        // selected tab is not visible (SCROLL_TAB_LAYOUT)
        //
        if (tabPlacement != RIGHT || selectedIndex < 0 ||
             (selRect.y < y || selRect.y > y + h)) {
            g.drawLine(x+w-1, y+1, x+w-1, y+h-1);
        } else {
            // Break line to show visual connection to selected tab
            g.drawLine(x+w-1, y+1, x+w-1, selRect.y - 1);
            if (selRect.y + selRect.height < y + h - 2 ) {
                g.drawLine(x+w-1, selRect.y + selRect.height,
                           x+w-1, y+h-2);
            }
        }
    }

    protected void paintTabBackground(Graphics g,
                                      int tabPlacement, int tabIndex,
                                      int x, int y, int w, int h,
                                      boolean isSelected ) {
        g.setColor(isSelected? tabPane.getBackgroundAt(tabIndex) : unselectedTabBackground);
        switch(tabPlacement) {
          case LEFT:
              g.fillRect(x+1, y+1, w-1, h-2);
              break;
          case RIGHT:
              g.fillRect(x, y+1, w-1, h-2);
              break;
          case BOTTOM:
              g.fillRect(x+1, y, w-2, h-3);
              g.drawLine(x+2, y+h-3, x+w-3, y+h-3);
              g.drawLine(x+3, y+h-2, x+w-4, y+h-2);
              break;
          case TOP:
          default:
              g.fillRect(x+1, y+3, w-2, h-3);
              g.drawLine(x+2, y+2, x+w-3, y+2);
              g.drawLine(x+3, y+1, x+w-4, y+1);
        }

    }

    protected void paintTabBorder(Graphics g,
                                  int tabPlacement, int tabIndex,
                                  int x, int y, int w, int h,
                                  boolean isSelected) {
        g.setColor(isSelected? lightHighlight : unselectedTabHighlight);

        switch(tabPlacement) {
          case LEFT:
              g.drawLine(x, y+2, x, y+h-3);
              g.drawLine(x+1, y+1, x+1, y+2);
              g.drawLine(x+2, y, x+2, y+1);
              g.drawLine(x+3, y, x+w-1, y);
              g.setColor(isSelected? shadow : unselectedTabShadow);
              g.drawLine(x+1, y+h-3, x+1, y+h-2);
              g.drawLine(x+2, y+h-2, x+2, y+h-1);
              g.drawLine(x+3, y+h-1, x+w-1, y+h-1);
              break;
          case RIGHT:
              g.drawLine(x, y, x+w-3, y);
              g.setColor(isSelected? shadow : unselectedTabShadow);
              g.drawLine(x+w-3, y, x+w-3, y+1);
              g.drawLine(x+w-2, y+1, x+w-2, y+2);
              g.drawLine(x+w-1, y+2, x+w-1, y+h-3);
              g.drawLine(x+w-2, y+h-3, x+w-2, y+h-2);
              g.drawLine(x+w-3, y+h-2, x+w-3, y+h-1);
              g.drawLine(x, y+h-1, x+w-3, y+h-1);
              break;
          case BOTTOM:
              g.drawLine(x, y, x, y+h-3);
              g.drawLine(x+1, y+h-3, x+1, y+h-2);
              g.drawLine(x+2, y+h-2, x+2, y+h-1);
              g.setColor(isSelected? shadow : unselectedTabShadow);
              g.drawLine(x+3, y+h-1, x+w-4, y+h-1);
              g.drawLine(x+w-3, y+h-2, x+w-3, y+h-1);
              g.drawLine(x+w-2, y+h-3, x+w-2, y+h-2);
              g.drawLine(x+w-1, y, x+w-1, y+h-3);
              break;
          case TOP:
          default:
              g.drawLine(x, y+2, x, y+h-1);
              g.drawLine(x+1, y+1, x+1, y+2);
              g.drawLine(x+2, y, x+2, y+1);
              g.drawLine(x+3, y, x+w-4, y);
              g.setColor(isSelected? shadow : unselectedTabShadow);
              g.drawLine(x+w-3, y, x+w-3, y+1);
              g.drawLine(x+w-2, y+1, x+w-2, y+2);
              g.drawLine(x+w-1, y+2, x+w-1, y+h-1);
        }

    }

    protected void paintFocusIndicator(Graphics g, int tabPlacement,
                                       Rectangle[] rects, int tabIndex,
                                       Rectangle iconRect, Rectangle textRect,
                                       boolean isSelected) {
        Rectangle tabRect = rects[tabIndex];
        if (tabPane.hasFocus() && isSelected) {
            int x, y, w, h;
            g.setColor(focus);
            switch(tabPlacement) {
              case LEFT:
                  x = tabRect.x + 3;
                  y = tabRect.y + 3;
                  w = tabRect.width - 6;
                  h = tabRect.height - 7;
                  break;
              case RIGHT:
                  x = tabRect.x + 2;
                  y = tabRect.y + 3;
                  w = tabRect.width - 6;
                  h = tabRect.height - 7;
                  break;
              case BOTTOM:
                  x = tabRect.x + 3;
                  y = tabRect.y + 2;
                  w = tabRect.width - 7;
                  h = tabRect.height - 6;
                  break;
              case TOP:
              default:
                  x = tabRect.x + 3;
                  y = tabRect.y + 3;
                  w = tabRect.width - 7;
                  h = tabRect.height - 6;
            }
            g.drawRect(x, y, w, h);
        }
    }

    protected int getTabRunIndent(int tabPlacement, int run) {
        return run*3;
    }

    protected int getTabRunOverlay(int tabPlacement) {
        tabRunOverlay = (tabPlacement == LEFT || tabPlacement == RIGHT)?
            (int)Math.round((float)maxTabWidth * .10) :
            (int)Math.round((float)maxTabHeight * .22);

        // Ensure that runover lay is not more than insets
        // 2 pixel offset is set from insets to each run
        switch(tabPlacement) {
        case LEFT:
                if( tabRunOverlay > tabInsets.right - 2 )
                    tabRunOverlay = tabInsets.right - 2 ;
                break;
        case RIGHT:
                if( tabRunOverlay > tabInsets.left - 2 )
                    tabRunOverlay = tabInsets.left - 2 ;
                break;
        case TOP:
                if( tabRunOverlay > tabInsets.bottom - 2 )
                    tabRunOverlay = tabInsets.bottom - 2 ;
                break;
        case BOTTOM:
                if( tabRunOverlay > tabInsets.top - 2 )
                    tabRunOverlay = tabInsets.top - 2 ;
                break;

        }

        return tabRunOverlay;
    }

}
