/* BasicTabbedPaneUI.java --
   Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.plaf.basic;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JViewport;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PanelUI;
import javax.swing.plaf.TabbedPaneUI;
import javax.swing.plaf.UIResource;
import javax.swing.text.View;

/**
 * This is the Basic Look and Feel's UI delegate for JTabbedPane.
 */
public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
{
  /**
   * A helper class that handles focus.
   */
  public class FocusHandler extends FocusAdapter
  {
    /**
     * This method is called when the component gains focus.
     *
     * @param e The FocusEvent.
     */
    public void focusGained(FocusEvent e)
    {
      // FIXME: Implement.
    }

    /**
     * This method is called when the component loses focus.
     *
     * @param e The FocusEvent.
     */
    public void focusLost(FocusEvent e)
    {
      // FIXME: Implement.
    }
  }

  /**
   * A helper class for determining if mouse presses occur inside tabs and
   * sets the index appropriately. In SCROLL_TAB_MODE, this class also
   * handles the mouse clicks on the scrolling buttons.
   */
  public class MouseHandler extends MouseAdapter
  {
    /**
     * This method is called when the mouse is pressed. The index cannot
     * change to a tab that is  not enabled.
     *
     * @param e The MouseEvent.
     */
    public void mousePressed(MouseEvent e)
    {
      int x = e.getX();
      int y = e.getY();
      int tabCount = tabPane.getTabCount();

      if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
        {
	  if (e.getSource() == incrButton)
	    {
	      if (++currentScrollLocation >= tabCount)
		currentScrollLocation = tabCount - 1;

	      int width = 0;
	      for (int i = currentScrollLocation - 1; i < tabCount; i++)
		width += rects[i].width;
	      if (width < viewport.getWidth())
		// FIXME: Still getting mouse events after the button is disabled.
    //	incrButton.setEnabled(false);
		currentScrollLocation--;
	      else if (! decrButton.isEnabled())
		decrButton.setEnabled(true);
	      tabPane.revalidate();
	      tabPane.repaint();
	      return;
	    }
	  else if (e.getSource() == decrButton)
	    {
	      if (--currentScrollLocation < 0)
		currentScrollLocation = 0;
	      if (currentScrollLocation == 0)
		decrButton.setEnabled(false);
	      else if (! incrButton.isEnabled())
		incrButton.setEnabled(true);
	      tabPane.revalidate();
	      tabPane.repaint();
	      return;
	    }
        }

      int index = tabForCoordinate(tabPane, x, y);

      // We need to check since there are areas where tabs cannot be
      // e.g. in the inset area.
      if (index != -1 && tabPane.isEnabledAt(index))
	tabPane.setSelectedIndex(index);
      tabPane.revalidate();
      tabPane.repaint();
    }
  }

  /**
   * This class handles PropertyChangeEvents fired from the JTabbedPane.
   */
  public class PropertyChangeHandler implements PropertyChangeListener
  {
    /**
     * This method is called whenever one of the properties of the JTabbedPane
     * changes.
     *
     * @param e The PropertyChangeEvent.
     */
    public void propertyChange(PropertyChangeEvent e)
    {
      if (e.getPropertyName().equals("tabLayoutPolicy"))
        {
	  layoutManager = createLayoutManager();

	  tabPane.setLayout(layoutManager);
        }
      else if (e.getPropertyName().equals("tabPlacement")
               && tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
        {
	  incrButton = createIncreaseButton();
	  decrButton = createDecreaseButton();
        }
      tabPane.layout();
      tabPane.repaint();
    }
  }

  /**
   * A LayoutManager responsible for placing all the tabs and the visible
   * component inside the JTabbedPane. This class is only used for
   * WRAP_TAB_LAYOUT.
   */
  protected class TabbedPaneLayout implements LayoutManager
  {
    /**
     * This method is called when a component is added to the JTabbedPane.
     *
     * @param name The name of the component.
     * @param comp The component being added.
     */
    public void addLayoutComponent(String name, Component comp)
    {
      // Do nothing.
    }

    /**
     * This method is called when the rectangles need to be calculated. It
     * also fixes the size of the visible component.
     */
    public void calculateLayoutInfo()
    {
      calculateTabRects(tabPane.getTabPlacement(), tabPane.getTabCount());

      if (tabPane.getSelectedIndex() != -1)
        {
	  Component visible = getVisibleComponent();
	  Insets insets = getContentBorderInsets(tabPane.getTabPlacement());
	  if (visible != null)
	    visible.setBounds(contentRect.x + insets.left,
	                      contentRect.y + insets.top,
	                      contentRect.width - insets.left - insets.right,
	                      contentRect.height - insets.top - insets.bottom);
        }
    }

    /**
     * This method calculates the size of the the JTabbedPane.
     *
     * @param minimum Whether the JTabbedPane will try to be as small as it
     *        can.
     *
     * @return The desired size of the JTabbedPane.
     */
    protected Dimension calculateSize(boolean minimum)
    {
      int tabPlacement = tabPane.getTabPlacement();
      int width = 0;
      int height = 0;

      int componentHeight = 0;
      int componentWidth = 0;
      Component c;
      Dimension dims;
      for (int i = 0; i < tabPane.getTabCount(); i++)
        {
	  c = tabPane.getComponentAt(i);
	  if (c == null)
	    continue;
	  calcRect = c.getBounds();
	  dims = c.getPreferredSize();
	  if (dims != null)
	    {
	      componentHeight = Math.max(componentHeight, dims.height);
	      componentWidth = Math.max(componentWidth, dims.width);
	    }
        }
      Insets insets = tabPane.getInsets();

      if (tabPlacement == SwingConstants.TOP
          || tabPlacement == SwingConstants.BOTTOM)
        {
	  int min = calculateMaxTabWidth(tabPlacement);
	  width = Math.max(min, componentWidth);

	  int tabAreaHeight = preferredTabAreaHeight(tabPlacement, width);
	  height = tabAreaHeight + componentHeight;
        }
      else
        {
	  int min = calculateMaxTabHeight(tabPlacement);
	  height = Math.max(min, componentHeight);

	  int tabAreaWidth = preferredTabAreaWidth(tabPlacement, height);
	  width = tabAreaWidth + componentWidth;
        }

      return new Dimension(width, height);
    }

    // if tab placement is LEFT OR RIGHT, they share width.
    // if tab placement is TOP OR BOTTOM, they share height
    // PRE STEP: finds the default sizes for the labels as well as their locations.
    // AND where they will be placed within the run system.
    // 1. calls normalizeTab Runs.
    // 2. calls rotate tab runs.
    // 3. pads the tab runs.
    // 4. pads the selected tab.

    /**
     * This method is called to calculate the tab rectangles.  This method
     * will calculate the size and position of all  rectangles (taking into
     * account which ones should be in which tab run). It will pad them and
     * normalize them  as necessary.
     *
     * @param tabPlacement The JTabbedPane's tab placement.
     * @param tabCount The run the current selection is in.
     */
    protected void calculateTabRects(int tabPlacement, int tabCount)
    {
      if (tabCount == 0)
	return;
      assureRectsCreated(tabCount);

      FontMetrics fm = getFontMetrics();
      SwingUtilities.calculateInnerArea(tabPane, calcRect);
      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
      Insets insets = tabPane.getInsets();
      int max = 0;
      int runs = 0;
      int start = getTabRunIndent(tabPlacement, 1);
      if (tabPlacement == SwingConstants.TOP
          || tabPlacement == SwingConstants.BOTTOM)
        {
	  int maxHeight = calculateMaxTabHeight(tabPlacement);

	  calcRect.width -= tabAreaInsets.left + tabAreaInsets.right;
	  max = calcRect.width + tabAreaInsets.left + insets.left;
	  start += tabAreaInsets.left + insets.left;
	  int width = 0;
	  int runWidth = start;

	  for (int i = 0; i < tabCount; i++)
	    {
	      width = calculateTabWidth(tabPlacement, i, fm);

	      if (runWidth + width > max)
	        {
		  runWidth = tabAreaInsets.left + insets.left
		             + getTabRunIndent(tabPlacement, ++runs);
		  rects[i] = new Rectangle(runWidth,
		                           insets.top + tabAreaInsets.top,
		                           width, maxHeight);
		  runWidth += width;
		  if (runs > tabRuns.length - 1)
		    expandTabRunsArray();
		  tabRuns[runs] = i;
	        }
	      else
	        {
		  rects[i] = new Rectangle(runWidth,
		                           insets.top + tabAreaInsets.top,
		                           width, maxHeight);
		  runWidth += width;
	        }
	    }
	  runs++;
	  tabAreaRect.width = tabPane.getWidth() - insets.left - insets.right;
	  tabAreaRect.height = runs * maxTabHeight
	                       - (runs - 1) * tabRunOverlay
	                       + tabAreaInsets.top + tabAreaInsets.bottom;
	  contentRect.width = tabAreaRect.width;
	  contentRect.height = tabPane.getHeight() - insets.top
	                       - insets.bottom - tabAreaRect.height;
	  contentRect.x = insets.left;
	  tabAreaRect.x = insets.left;
	  if (tabPlacement == SwingConstants.BOTTOM)
	    {
	      contentRect.y = insets.top;
	      tabAreaRect.y = contentRect.y + contentRect.height;
	    }
	  else
	    {
	      tabAreaRect.y = insets.top;
	      contentRect.y = tabAreaRect.y + tabAreaRect.height;
	    }
        }
      else
        {
	  int maxWidth = calculateMaxTabWidth(tabPlacement);
	  calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom;
	  max = calcRect.height + tabAreaInsets.top + insets.top;

	  int height = 0;
	  start += tabAreaInsets.top + insets.top;
	  int runHeight = start;

	  int fontHeight = fm.getHeight();

	  for (int i = 0; i < tabCount; i++)
	    {
	      height = calculateTabHeight(tabPlacement, i, fontHeight);
	      if (runHeight + height > max)
	        {
		  runHeight = tabAreaInsets.top + insets.top
		              + getTabRunIndent(tabPlacement, ++runs);
		  rects[i] = new Rectangle(insets.left + tabAreaInsets.left,
		                           runHeight, maxWidth, height);
		  runHeight += height;
		  if (runs > tabRuns.length - 1)
		    expandTabRunsArray();
		  tabRuns[runs] = i;
	        }
	      else
	        {
		  rects[i] = new Rectangle(insets.left + tabAreaInsets.left,
		                           runHeight, maxWidth, height);
		  runHeight += height;
	        }
	    }
	  runs++;

	  tabAreaRect.width = runs * maxTabWidth - (runs - 1) * tabRunOverlay
	                      + tabAreaInsets.left + tabAreaInsets.right;
	  tabAreaRect.height = tabPane.getHeight() - insets.top
	                       - insets.bottom;
	  tabAreaRect.y = insets.top;
	  contentRect.width = tabPane.getWidth() - insets.left - insets.right
	                      - tabAreaRect.width;
	  contentRect.height = tabAreaRect.height;
	  contentRect.y = insets.top;
	  if (tabPlacement == SwingConstants.LEFT)
	    {
	      tabAreaRect.x = insets.left;
	      contentRect.x = tabAreaRect.x + tabAreaRect.width;
	    }
	  else
	    {
	      contentRect.x = insets.left;
	      tabAreaRect.x = contentRect.x + contentRect.width;
	    }
        }
      runCount = runs;

      tabRuns[0] = 0;
      normalizeTabRuns(tabPlacement, tabCount, start, max);
      selectedRun = getRunForTab(tabCount, tabPane.getSelectedIndex());
      if (shouldRotateTabRuns(tabPlacement))
	rotateTabRuns(tabPlacement, selectedRun);

      // Need to pad the runs and move them to the correct location.
      for (int i = 0; i < runCount; i++)
        {
	  int first = lastTabInRun(tabCount, getPreviousTabRun(i)) + 1;
	  if (first == tabCount)
	    first = 0;
	  int last = lastTabInRun(tabCount, i);
	  if (shouldPadTabRun(tabPlacement, i))
	    padTabRun(tabPlacement, first, last, max);

	  // Done padding, now need to move it.
	  if (tabPlacement == SwingConstants.TOP && i > 0)
	    {
	      for (int j = first; j <= last; j++)
		rects[j].y += (runCount - i) * maxTabHeight
		- (runCount - i) * tabRunOverlay;
	    }

	  if (tabPlacement == SwingConstants.BOTTOM)
	    {
	      int height = tabPane.getBounds().height - insets.bottom
	                   - tabAreaInsets.bottom;
	      int adjustment;
	      if (i == 0)
		adjustment = height - maxTabHeight;
	      else
		adjustment = height - (runCount - i + 1) * maxTabHeight
		             - (runCount - i) * tabRunOverlay;

	      for (int j = first; j <= last; j++)
		rects[j].y = adjustment;
	    }

	  if (tabPlacement == SwingConstants.LEFT && i > 0)
	    {
	      for (int j = first; j <= last; j++)
		rects[j].x += (runCount - i) * maxTabWidth
		- (runCount - i) * tabRunOverlay;
	    }

	  if (tabPlacement == SwingConstants.RIGHT)
	    {
	      int width = tabPane.getBounds().width - insets.right
	                  - tabAreaInsets.right;
	      int adjustment;
	      if (i == 0)
		adjustment = width - maxTabWidth;
	      else
		adjustment = width - (runCount - i + 1) * maxTabWidth
		             + (runCount - i) * tabRunOverlay;

	      for (int j = first; j <= last; j++)
		rects[j].x = adjustment;
	    }
        }
      padSelectedTab(tabPlacement, tabPane.getSelectedIndex());
    }

    /**
     * This method is called when the JTabbedPane is laid out in
     * WRAP_TAB_LAYOUT. It calls calculateLayoutInfo to  find the positions
     * of all its components.
     *
     * @param parent The Container to lay out.
     */
    public void layoutContainer(Container parent)
    {
      calculateLayoutInfo();
    }

    /**
     * This method returns the minimum layout size for the given container.
     *
     * @param parent The container that is being sized.
     *
     * @return The minimum size.
     */
    public Dimension minimumLayoutSize(Container parent)
    {
      return calculateSize(false);
    }

    // If there is more free space in an adjacent run AND the tab in the run can fit in the 
    // adjacent run, move it. This method is not perfect, it is merely an approximation.
    // If you play around with Sun's JTabbedPane, you'll see that 
    // it does do some pretty strange things with regards to not moving tabs 
    // that should be moved. 
    // start = the x position where the tabs will begin
    // max = the maximum position of where the tabs can go to (tabAreaInsets.left + the width of the tab area)

    /**
     * This method tries to "even out" the number of tabs in each run based on
     * their widths.
     *
     * @param tabPlacement The JTabbedPane's tab placement.
     * @param tabCount The number of tabs.
     * @param start The x position where the tabs will begin.
     * @param max The maximum x position where the tab can run to.
     */
    protected void normalizeTabRuns(int tabPlacement, int tabCount, int start,
                                    int max)
    {
      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
      if (tabPlacement == SwingUtilities.TOP
          || tabPlacement == SwingUtilities.BOTTOM)
        {
	  // We should only do this for runCount - 1, cause we can only shift that many times between
	  // runs.
	  for (int i = 1; i < runCount; i++)
	    {
	      Rectangle currRun = rects[lastTabInRun(tabCount, i)];
	      Rectangle nextRun = rects[lastTabInRun(tabCount, getNextTabRun(i))];
	      int spaceInCurr = currRun.x + currRun.width;
	      int spaceInNext = nextRun.x + nextRun.width;

	      int diffNow = spaceInCurr - spaceInNext;
	      int diffLater = (spaceInCurr - currRun.width)
	                      - (spaceInNext + currRun.width);
	      while (Math.abs(diffLater) < Math.abs(diffNow)
	             && spaceInNext + currRun.width < max)
	        {
		  tabRuns[i]--;
		  spaceInNext += currRun.width;
		  spaceInCurr -= currRun.width;
		  currRun = rects[lastTabInRun(tabCount, i)];
		  diffNow = spaceInCurr - spaceInNext;
		  diffLater = (spaceInCurr - currRun.width)
		              - (spaceInNext + currRun.width);
	        }

	      // Fix the bounds.
	      int first = lastTabInRun(tabCount, i) + 1;
	      int last = lastTabInRun(tabCount, getNextTabRun(i));
	      int currX = tabAreaInsets.left;
	      for (int j = first; j <= last; j++)
	        {
		  rects[j].x = currX;
		  currX += rects[j].width;
	        }
	    }
        }
      else
        {
	  for (int i = 1; i < runCount; i++)
	    {
	      Rectangle currRun = rects[lastTabInRun(tabCount, i)];
	      Rectangle nextRun = rects[lastTabInRun(tabCount, getNextTabRun(i))];
	      int spaceInCurr = currRun.y + currRun.height;
	      int spaceInNext = nextRun.y + nextRun.height;

	      int diffNow = spaceInCurr - spaceInNext;
	      int diffLater = (spaceInCurr - currRun.height)
	                      - (spaceInNext + currRun.height);
	      while (Math.abs(diffLater) < Math.abs(diffNow)
	             && spaceInNext + currRun.height < max)
	        {
		  tabRuns[i]--;
		  spaceInNext += currRun.height;
		  spaceInCurr -= currRun.height;
		  currRun = rects[lastTabInRun(tabCount, i)];
		  diffNow = spaceInCurr - spaceInNext;
		  diffLater = (spaceInCurr - currRun.height)
		              - (spaceInNext + currRun.height);
	        }

	      int first = lastTabInRun(tabCount, i) + 1;
	      int last = lastTabInRun(tabCount, getNextTabRun(i));
	      int currY = tabAreaInsets.top;
	      for (int j = first; j <= last; j++)
	        {
		  rects[j].y = currY;
		  currY += rects[j].height;
	        }
	    }
        }
    }

    /**
     * This method pads the tab at the selected index by the  selected tab pad
     * insets (so that it looks larger).
     *
     * @param tabPlacement The placement of the tabs.
     * @param selectedIndex The selected index.
     */
    protected void padSelectedTab(int tabPlacement, int selectedIndex)
    {
      Insets insets = getSelectedTabPadInsets(tabPlacement);
      rects[selectedIndex].x -= insets.left;
      rects[selectedIndex].y -= insets.top;
      rects[selectedIndex].width += insets.left + insets.right;
      rects[selectedIndex].height += insets.top + insets.bottom;
    }

    // If the tabs on the run don't fill the width of the window, make it fit now.
    // start = starting index of the run
    // end = last index of the run
    // max = tabAreaInsets.left + width (or equivalent)
    // assert start <= end.

    /**
     * This method makes each tab in the run larger so that the  tabs expand
     * to fill the runs width/height (depending on tabPlacement).
     *
     * @param tabPlacement The placement of the tabs.
     * @param start The index of the first tab.
     * @param end The last index of the tab
     * @param max The amount of space in the run (width for TOP and BOTTOM
     *        tabPlacement).
     */
    protected void padTabRun(int tabPlacement, int start, int end, int max)
    {
      if (tabPlacement == SwingConstants.TOP
          || tabPlacement == SwingConstants.BOTTOM)
        {
	  int runWidth = rects[end].x + rects[end].width;
	  int spaceRemaining = max - runWidth;
	  int numTabs = end - start + 1;

	  // now divvy up the space.
	  int spaceAllocated = spaceRemaining / numTabs;
	  int currX = rects[start].x;
	  for (int i = start; i <= end; i++)
	    {
	      rects[i].x = currX;
	      rects[i].width += spaceAllocated;
	      currX += rects[i].width;
	      // This is used because since the spaceAllocated 
	      // variable is an int, it rounds down. Sometimes,
	      // we don't fill an entire row, so we make it do
	      // so now.
	      if (i == end && rects[i].x + rects[i].width != max)
		rects[i].width = max - rects[i].x;
	    }
        }
      else
        {
	  int runHeight = rects[end].y + rects[end].height;
	  int spaceRemaining = max - runHeight;
	  int numTabs = end - start + 1;

	  int spaceAllocated = spaceRemaining / numTabs;
	  int currY = rects[start].y;
	  for (int i = start; i <= end; i++)
	    {
	      rects[i].y = currY;
	      rects[i].height += spaceAllocated;
	      currY += rects[i].height;
	      if (i == end && rects[i].y + rects[i].height != max)
		rects[i].height = max - rects[i].y;
	    }
        }
    }

    /**
     * This method returns the preferred layout size for the given container.
     *
     * @param parent The container to size.
     *
     * @return The preferred layout size.
     */
    public Dimension preferredLayoutSize(Container parent)
    {
      return calculateSize(false);
    }

    /**
     * This method returns the preferred tab height given a tabPlacement and
     * width.
     *
     * @param tabPlacement The JTabbedPane's tab placement.
     * @param width The expected width.
     *
     * @return The preferred tab area height.
     */
    protected int preferredTabAreaHeight(int tabPlacement, int width)
    {
      if (tabPane.getTabCount() == 0)
	return calculateTabAreaHeight(tabPlacement, 0, 0);

      int runs = 0;
      int runWidth = 0;
      int tabWidth = 0;

      FontMetrics fm = getFontMetrics();

      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
      Insets insets = tabPane.getInsets();

      // Only interested in width, this is a messed up rectangle now.
      width -= tabAreaInsets.left + tabAreaInsets.right + insets.left
      + insets.right;

      // The reason why we can't use runCount:
      // This method is only called to calculate the size request
      // for the tabbedPane. However, this size request is dependent on 
      // our desired width. We need to find out what the height would
      // be IF we got our desired width.
      for (int i = 0; i < tabPane.getTabCount(); i++)
        {
	  tabWidth = calculateTabWidth(tabPlacement, i, fm);
	  if (runWidth + tabWidth > width)
	    {
	      runWidth = tabWidth;
	      runs++;
	    }
	  else
	    runWidth += tabWidth;
        }
      runs++;

      int maxTabHeight = calculateMaxTabHeight(tabPlacement);
      int tabAreaHeight = calculateTabAreaHeight(tabPlacement, runs,
                                                 maxTabHeight);
      return tabAreaHeight;
    }

    /**
     * This method calculates the preferred tab area width given a tab
     * placement and height.
     *
     * @param tabPlacement The JTabbedPane's tab placement.
     * @param height The expected height.
     *
     * @return The preferred tab area width.
     */
    protected int preferredTabAreaWidth(int tabPlacement, int height)
    {
      if (tabPane.getTabCount() == 0)
	return calculateTabAreaHeight(tabPlacement, 0, 0);

      int runs = 0;
      int runHeight = 0;
      int tabHeight = 0;

      FontMetrics fm = getFontMetrics();

      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
      Insets insets = tabPane.getInsets();

      height -= tabAreaInsets.top + tabAreaInsets.bottom + insets.top
      + insets.bottom;
      int fontHeight = fm.getHeight();

      for (int i = 0; i < tabPane.getTabCount(); i++)
        {
	  tabHeight = calculateTabHeight(tabPlacement, i, fontHeight);
	  if (runHeight + tabHeight > height)
	    {
	      runHeight = tabHeight;
	      runs++;
	    }
	  else
	    runHeight += tabHeight;
        }
      runs++;

      int maxTabWidth = calculateMaxTabWidth(tabPlacement);
      int tabAreaWidth = calculateTabAreaWidth(tabPlacement, runs, maxTabWidth);
      return tabAreaWidth;
    }

    /**
     * This method rotates the places each run in the correct place  the
     * tabRuns array. See the comment for tabRuns for how the runs are placed
     * in the array.
     *
     * @param tabPlacement The JTabbedPane's tab placement.
     * @param selectedRun The run the current selection is in.
     */
    protected void rotateTabRuns(int tabPlacement, int selectedRun)
    {
      if (runCount == 1 || selectedRun == 1 || selectedRun == -1)
	return;
      int[] newTabRuns = new int[tabRuns.length];
      int currentRun = selectedRun;
      int i = 1;
      do
        {
	  newTabRuns[i] = tabRuns[currentRun];
	  currentRun = getNextTabRun(currentRun);
	  i++;
        }
      while (i < runCount);
      if (runCount > 1)
	newTabRuns[0] = tabRuns[currentRun];

      tabRuns = newTabRuns;
      BasicTabbedPaneUI.this.selectedRun = 1;
    }

    /**
     * This method is called when a component is removed  from the
     * JTabbedPane.
     *
     * @param comp The component removed.
     */
    public void removeLayoutComponent(Component comp)
    {
      // Do nothing.
    }
  }

  /**
   * This class acts as the LayoutManager for the JTabbedPane in
   * SCROLL_TAB_MODE.
   */
  private class TabbedPaneScrollLayout extends TabbedPaneLayout
  {
    /**
     * This method returns the preferred layout size for the given container.
     *
     * @param parent The container to calculate a size for.
     *
     * @return The preferred layout size.
     */
    public Dimension preferredLayoutSize(Container parent)
    {
      return super.calculateSize(true);
    }

    /**
     * This method returns the minimum layout size for the given container.
     *
     * @param parent The container to calculate a size for.
     *
     * @return The minimum layout size.
     */
    public Dimension minimumLayoutSize(Container parent)
    {
      return super.calculateSize(true);
    }

    /**
     * This method calculates the tab area height given  a desired width.
     *
     * @param tabPlacement The JTabbedPane's tab placement.
     * @param width The expected width.
     *
     * @return The tab area height given the width.
     */
    protected int preferredTabAreaHeight(int tabPlacement, int width)
    {
      if (tabPane.getTabCount() == 0)
	return calculateTabAreaHeight(tabPlacement, 0, 0);

      int runs = 1;

      int maxTabHeight = calculateMaxTabHeight(tabPlacement);
      int tabAreaHeight = calculateTabAreaHeight(tabPlacement, runs,
                                                 maxTabHeight);
      return tabAreaHeight;
    }

    /**
     * This method calculates the tab area width given a desired height.
     *
     * @param tabPlacement The JTabbedPane's tab placement.
     * @param height The expected height.
     *
     * @return The tab area width given the height.
     */
    protected int preferredTabAreaWidth(int tabPlacement, int height)
    {
      if (tabPane.getTabCount() == 0)
	return calculateTabAreaHeight(tabPlacement, 0, 0);

      int runs = 1;

      int maxTabWidth = calculateMaxTabWidth(tabPlacement);
      int tabAreaWidth = calculateTabAreaWidth(tabPlacement, runs, maxTabWidth);
      return tabAreaWidth;
    }

    /**
     * This method is called to calculate the tab rectangles.  This method
     * will calculate the size and position of all  rectangles (taking into
     * account which ones should be in which tab run). It will pad them and
     * normalize them  as necessary.
     *
     * @param tabPlacement The JTabbedPane's tab placement.
     * @param tabCount The number of tabs.
     */
    protected void calculateTabRects(int tabPlacement, int tabCount)
    {
      if (tabCount == 0)
	return;
      assureRectsCreated(tabCount);

      FontMetrics fm = getFontMetrics();
      SwingUtilities.calculateInnerArea(tabPane, calcRect);
      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
      Insets insets = tabPane.getInsets();
      int max = 0;
      int runs = 1;
      int start = 0;
      int top = 0;
      if (tabPlacement == SwingConstants.TOP
          || tabPlacement == SwingConstants.BOTTOM)
        {
	  int maxHeight = calculateMaxTabHeight(tabPlacement);
	  calcRect.width -= tabAreaInsets.left + tabAreaInsets.right;
	  max = calcRect.width + tabAreaInsets.left + insets.left;
	  start = tabAreaInsets.left + insets.left;
	  int width = 0;
	  int runWidth = start;
	  top = insets.top + tabAreaInsets.top;
	  for (int i = 0; i < tabCount; i++)
	    {
	      width = calculateTabWidth(tabPlacement, i, fm);

	      rects[i] = new Rectangle(runWidth, top, width, maxHeight);
	      runWidth += width;
	    }
	  tabAreaRect.width = tabPane.getWidth() - insets.left - insets.right;
	  tabAreaRect.height = runs * maxTabHeight
	                       - (runs - 1) * tabRunOverlay
	                       + tabAreaInsets.top + tabAreaInsets.bottom;
	  contentRect.width = tabAreaRect.width;
	  contentRect.height = tabPane.getHeight() - insets.top
	                       - insets.bottom - tabAreaRect.height;
	  contentRect.x = insets.left;
	  tabAreaRect.x = insets.left;
	  if (tabPlacement == SwingConstants.BOTTOM)
	    {
	      contentRect.y = insets.top;
	      tabAreaRect.y = contentRect.y + contentRect.height;
	    }
	  else
	    {
	      tabAreaRect.y = insets.top;
	      contentRect.y = tabAreaRect.y + tabAreaRect.height;
	    }
        }
      else
        {
	  int maxWidth = calculateMaxTabWidth(tabPlacement);

	  calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom;
	  max = calcRect.height + tabAreaInsets.top;
	  int height = 0;
	  start = tabAreaInsets.top + insets.top;
	  int runHeight = start;
	  int fontHeight = fm.getHeight();
	  top = insets.left + tabAreaInsets.left;
	  for (int i = 0; i < tabCount; i++)
	    {
	      height = calculateTabHeight(tabPlacement, i, fontHeight);
	      rects[i] = new Rectangle(top, runHeight, maxWidth, height);
	      runHeight += height;
	    }
	  tabAreaRect.width = runs * maxTabWidth - (runs - 1) * tabRunOverlay
	                      + tabAreaInsets.left + tabAreaInsets.right;
	  tabAreaRect.height = tabPane.getHeight() - insets.top
	                       - insets.bottom;
	  tabAreaRect.y = insets.top;
	  contentRect.width = tabPane.getWidth() - insets.left - insets.right
	                      - tabAreaRect.width;
	  contentRect.height = tabAreaRect.height;
	  contentRect.y = insets.top;
	  if (tabPlacement == SwingConstants.LEFT)
	    {
	      tabAreaRect.x = insets.left;
	      contentRect.x = tabAreaRect.x + tabAreaRect.width;
	    }
	  else
	    {
	      contentRect.x = insets.left;
	      tabAreaRect.x = contentRect.x + contentRect.width;
	    }
        }
      runCount = runs;

      padSelectedTab(tabPlacement, tabPane.getSelectedIndex());
    }

    /**
     * This method is called when the JTabbedPane is laid out in
     * SCROLL_TAB_LAYOUT. It finds the position for all components in the
     * JTabbedPane.
     *
     * @param pane The JTabbedPane to be laid out.
     */
    public void layoutContainer(Container pane)
    {
      super.layoutContainer(pane);
      int tabCount = tabPane.getTabCount();
      Point p = null;
      if (tabCount == 0)
	return;
      int tabPlacement = tabPane.getTabPlacement();
      incrButton.hide();
      decrButton.hide();
      if (tabPlacement == SwingConstants.TOP
          || tabPlacement == SwingConstants.BOTTOM)
        {
	  if (tabAreaRect.x + tabAreaRect.width < rects[tabCount - 1].x
	      + rects[tabCount - 1].width)
	    {
	      Dimension incrDims = incrButton.getPreferredSize();
	      Dimension decrDims = decrButton.getPreferredSize();

	      decrButton.setBounds(tabAreaRect.x + tabAreaRect.width
	                           - incrDims.width - decrDims.width,
	                           tabAreaRect.y, decrDims.width,
	                           tabAreaRect.height);
	      incrButton.setBounds(tabAreaRect.x + tabAreaRect.width
	                           - incrDims.width, tabAreaRect.y,
	                           decrDims.width, tabAreaRect.height);

	      tabAreaRect.width -= decrDims.width + incrDims.width;
	      incrButton.show();
	      decrButton.show();
	    }
        }

      if (tabPlacement == SwingConstants.LEFT
          || tabPlacement == SwingConstants.RIGHT)
        {
	  if (tabAreaRect.y + tabAreaRect.height < rects[tabCount - 1].y
	      + rects[tabCount - 1].height)
	    {
	      Dimension incrDims = incrButton.getPreferredSize();
	      Dimension decrDims = decrButton.getPreferredSize();

	      decrButton.setBounds(tabAreaRect.x,
	                           tabAreaRect.y + tabAreaRect.height
	                           - incrDims.height - decrDims.height,
	                           tabAreaRect.width, decrDims.height);
	      incrButton.setBounds(tabAreaRect.x,
	                           tabAreaRect.y + tabAreaRect.height
	                           - incrDims.height, tabAreaRect.width,
	                           incrDims.height);

	      tabAreaRect.height -= decrDims.height + incrDims.height;
	      incrButton.show();
	      decrButton.show();
	    }
        }
      viewport.setBounds(tabAreaRect.x, tabAreaRect.y, tabAreaRect.width,
                         tabAreaRect.height);
      int tabC = tabPane.getTabCount() - 1;
      if (tabCount > 0)
        {
	  int w = Math.max(rects[tabC].width + rects[tabC].x, tabAreaRect.width);
	  int h = Math.max(rects[tabC].height, tabAreaRect.height);
	  p = findPointForIndex(currentScrollLocation);

	  // we want to cover that entire space so that borders that run under
	  // the tab area don't show up when we move the viewport around.
	  panel.setSize(w + p.x, h + p.y);
        }
      viewport.setViewPosition(p);
      viewport.repaint();
    }
  }

  /**
   * This class handles ChangeEvents from the JTabbedPane.
   */
  public class TabSelectionHandler implements ChangeListener
  {
    /**
     * This method is called whenever a ChangeEvent is fired from the
     * JTabbedPane.
     *
     * @param e The ChangeEvent fired.
     */
    public void stateChanged(ChangeEvent e)
    {
      selectedRun = getRunForTab(tabPane.getTabCount(),
                                 tabPane.getSelectedIndex());
      tabPane.revalidate();
      tabPane.repaint();
    }
  }

  /**
   * This helper class is a JPanel that fits inside the ScrollViewport. This
   * panel's sole job is to paint the tab rectangles inside the  viewport so
   * that it's clipped correctly.
   */
  private class ScrollingPanel extends JPanel
  {
    /**
     * This is a private UI class for our panel.
     */
    private class ScrollingPanelUI extends BasicPanelUI
    {
      /**
       * This method overrides the default paint method. It paints the tab
       * rectangles for the JTabbedPane in the panel.
       *
       * @param g The Graphics object to paint with.
       * @param c The JComponent to paint.
       */
      public void paint(Graphics g, JComponent c)
      {
	paintTabArea(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
      }
    }

    /**
     * This method overrides the updateUI method. It makes the default UI for
     * this ScrollingPanel to be  a ScrollingPanelUI.
     */
    public void updateUI()
    {
      setUI((PanelUI) new ScrollingPanelUI());
    }
  }

  /**
   * This is a helper class that paints the panel that paints tabs. This
   * custom JViewport is used so that the tabs painted in the panel will be
   * clipped. This class implements UIResource so tabs are not added when
   * this objects of this class are added to the  JTabbedPane.
   */
  private class ScrollingViewport extends JViewport implements UIResource
  {
  }

  /**
   * This is a helper class that implements UIResource so it is not added as a
   * tab when an object of this class is added to the JTabbedPane.
   */
  private static class ScrollingButton extends BasicArrowButton
    implements UIResource
  {
    /**
     * Creates a ScrollingButton given the direction.
     *
     * @param dir The direction to point in.
     */
    public ScrollingButton(int dir)
    {
      super(dir);
    }
  }

  /** The button that increments the current scroll location. */
  private transient ScrollingButton incrButton;

  /** The button that decrements the current scroll location. */
  private transient ScrollingButton decrButton;

  /** The viewport used to display the tabs. */
  private transient ScrollingViewport viewport;

  /** The panel inside the viewport that paints the tabs. */
  private transient ScrollingPanel panel;

  /** The starting visible tab in the run in SCROLL_TAB_MODE. */
  private transient int currentScrollLocation;

  /** A reusable rectangle. */
  protected Rectangle calcRect;

  /** An array of Rectangles keeping track of the tabs' area and position. */
  protected Rectangle[] rects;

  /** The insets around the content area. */
  protected Insets contentBorderInsets;

  /** The extra insets around the selected tab. */
  protected Insets selectedTabPadInsets;

  /** The insets around the tab area. */
  protected Insets tabAreaInsets;

  /** The insets around each and every tab. */
  protected Insets tabInsets;

  /**
   * The outer bottom and right edge color for both the tab and content
   * border.
   */
  protected Color darkShadow;

  /** The color of the focus outline on the selected tab. */
  protected Color focus;

  /** FIXME: find a use for this. */
  protected Color highlight;

  /** The top and left edge color for both the tab and content border. */
  protected Color lightHighlight;

  /** The inner bottom and right edge color for the tab and content border. */
  protected Color shadow;

  /** The maximum tab height. */
  protected int maxTabHeight;

  /** The maximum tab width. */
  protected int maxTabWidth;

  /** The number of runs in the JTabbedPane. */
  protected int runCount;

  /** The index of the run that the selected index is in. */
  protected int selectedRun;

  /** The amount of space each run overlaps the previous by. */
  protected int tabRunOverlay;

  /** The gap between text and label */
  protected int textIconGap;

  // Keeps track of tab runs.
  // The organization of this array is as follows (lots of experimentation to
  // figure this out)
  // index 0 = furthest away from the component area (aka outer run)
  // index 1 = closest to component area (aka selected run)
  // index > 1 = listed in order leading from selected run to outer run.
  // each int in the array is the tab index + 1 (counting starts at 1)
  // for the last tab in the run. (same as the rects array)

  /** This array keeps track of which tabs are in which run. See above. */
  protected int[] tabRuns;

  /**
   * This is the keystroke for moving down.
   *
   * @deprecated 1.3
   */
  protected KeyStroke downKey;

  /**
   * This is the keystroke for moving left.
   *
   * @deprecated 1.3
   */
  protected KeyStroke leftKey;

  /**
   * This is the keystroke for moving right.
   *
   * @deprecated 1.3
   */
  protected KeyStroke rightKey;

  /**
   * This is the keystroke for moving up.
   *
   * @deprecated 1.3
   */
  protected KeyStroke upKey;

  /** The listener that listens for focus events. */
  protected FocusListener focusListener;

  /** The listener that listens for mouse events. */
  protected MouseListener mouseListener;

  /** The listener that listens for property change events. */
  protected PropertyChangeListener propertyChangeListener;

  /** The listener that listens for change events. */
  protected ChangeListener tabChangeListener;

  /** The tab pane that this UI paints. */
  protected JTabbedPane tabPane;

  /** The current layout manager for the tabPane. */
  private transient LayoutManager layoutManager;

  /** The rectangle that describes the tab area's position and size. */
  private transient Rectangle tabAreaRect;

  /** The rectangle that describes the content area's position and size. */
  private transient Rectangle contentRect;

  /**
   * Creates a new BasicTabbedPaneUI object.
   */
  public BasicTabbedPaneUI()
  {
    super();
  }

  /**
   * This method creates a ScrollingButton that  points in the appropriate
   * direction for an increasing button.
   *
   * @return The increase ScrollingButton.
   */
  private ScrollingButton createIncreaseButton()
  {
    if (incrButton == null)
      incrButton = new ScrollingButton(SwingConstants.NORTH);
    if (tabPane.getTabPlacement() == SwingConstants.TOP
        || tabPane.getTabPlacement() == SwingConstants.BOTTOM)
      incrButton.setDirection(SwingConstants.EAST);
    else
      incrButton.setDirection(SwingConstants.SOUTH);
    return incrButton;
  }

  /**
   * This method creates a ScrollingButton that points in the appropriate
   * direction for a decreasing button.
   *
   * @return The decrease ScrollingButton.
   */
  private ScrollingButton createDecreaseButton()
  {
    if (decrButton == null)
      decrButton = new ScrollingButton(SwingConstants.SOUTH);
    if (tabPane.getTabPlacement() == SwingConstants.TOP
        || tabPane.getTabPlacement() == SwingConstants.BOTTOM)
      decrButton.setDirection(SwingConstants.WEST);
    else
      decrButton.setDirection(SwingConstants.NORTH);
    return decrButton;
  }

  /**
   * This method finds the point to set the view  position at given the index
   * of a tab. The tab will be the first visible tab in the run.
   *
   * @param index The index of the first visible tab.
   *
   * @return The position of the first visible tab.
   */
  private Point findPointForIndex(int index)
  {
    int tabPlacement = tabPane.getTabPlacement();
    int selectedIndex = tabPane.getSelectedIndex();
    Insets insets = getSelectedTabPadInsets(tabPlacement);
    int w = 0;
    int h = 0;

    if (tabPlacement == TOP || tabPlacement == BOTTOM)
      {
	if (index > 0)
	  {
	    w += rects[index - 1].x + rects[index - 1].width;
	    if (index > selectedIndex)
	      w -= insets.left + insets.right;
	  }
      }

    else
      {
	if (index > 0)
	  {
	    h += rects[index - 1].y + rects[index - 1].height;
	    if (index > selectedIndex)
	      h -= insets.top + insets.bottom;
	  }
      }

    Point p = new Point(w, h);
    return p;
  }

  /**
   * This method creates a new BasicTabbedPaneUI.
   *
   * @param c The JComponent to create a UI for.
   *
   * @return A new BasicTabbedPaneUI.
   */
  public static ComponentUI createUI(JComponent c)
  {
    return new BasicTabbedPaneUI();
  }

  /**
   * This method installs the UI for the given JComponent.
   *
   * @param c The JComponent to install the UI for.
   */
  public void installUI(JComponent c)
  {
    super.installUI(c);
    if (c instanceof JTabbedPane)
      {
	tabPane = (JTabbedPane) c;

	installComponents();
	installDefaults();
	installListeners();
	installKeyboardActions();

	layoutManager = createLayoutManager();
	tabPane.setLayout(layoutManager);
	tabPane.layout();
      }
  }

  /**
   * This method uninstalls the UI for the  given JComponent.
   *
   * @param c The JComponent to uninstall the UI for.
   */
  public void uninstallUI(JComponent c)
  {
    layoutManager = null;

    uninstallKeyboardActions();
    uninstallListeners();
    uninstallDefaults();
    uninstallComponents();

    tabPane = null;
  }

  /**
   * This method creates the appropriate layout manager for the JTabbedPane's
   * current tab layout policy. If the tab layout policy is
   * SCROLL_TAB_LAYOUT, then all the associated components that need to be
   * created will be done so now.
   *
   * @return A layout manager given the tab layout policy.
   */
  protected LayoutManager createLayoutManager()
  {
    if (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT)
      return new TabbedPaneLayout();
    else
      {
	incrButton = createIncreaseButton();
	decrButton = createDecreaseButton();
	viewport = new ScrollingViewport();
	viewport.setLayout(null);
	panel = new ScrollingPanel();
	viewport.setView(panel);
	tabPane.add(incrButton);
	tabPane.add(decrButton);
	tabPane.add(viewport);
	currentScrollLocation = 0;
	decrButton.setEnabled(false);
	panel.addMouseListener(mouseListener);
	incrButton.addMouseListener(mouseListener);
	decrButton.addMouseListener(mouseListener);
	viewport.setBackground(Color.LIGHT_GRAY);

	return new TabbedPaneScrollLayout();
      }
  }

  /**
   * This method installs components for this JTabbedPane.
   */
  protected void installComponents()
  {
    // Nothing to be done.
  }

  /**
   * This method uninstalls components for this JTabbedPane.
   */
  protected void uninstallComponents()
  {
    // Nothing to be done.
  }

  /**
   * This method installs defaults for the Look and Feel.
   */
  protected void installDefaults()
  {
    UIDefaults defaults = UIManager.getLookAndFeelDefaults();

    tabPane.setFont(defaults.getFont("TabbedPane.font"));
    tabPane.setForeground(defaults.getColor("TabbedPane.foreground"));
    tabPane.setBackground(defaults.getColor("TabbedPane.background"));
    tabPane.setOpaque(true);

    highlight = defaults.getColor("TabbedPane.highlight");
    lightHighlight = defaults.getColor("TabbedPane.lightHighlight");

    shadow = defaults.getColor("TabbedPane.shadow");
    darkShadow = defaults.getColor("TabbedPane.darkShadow");

    focus = defaults.getColor("TabbedPane.focus");

    textIconGap = defaults.getInt("TabbedPane.textIconGap");
    tabRunOverlay = defaults.getInt("TabbedPane.tabRunOverlay");

    tabInsets = defaults.getInsets("TabbedPane.tabbedPaneTabInsets");
    selectedTabPadInsets = defaults.getInsets("TabbedPane.tabbedPaneTabPadInsets");
    tabAreaInsets = defaults.getInsets("TabbedPane.tabbedPaneTabAreaInsets");
    contentBorderInsets = defaults.getInsets("TabbedPane.tabbedPaneContentBorderInsets");

    calcRect = new Rectangle();
    tabRuns = new int[10];
    tabAreaRect = new Rectangle();
    contentRect = new Rectangle();
  }

  /**
   * This method uninstalls defaults for the Look and Feel.
   */
  protected void uninstallDefaults()
  {
    calcRect = null;
    tabAreaRect = null;
    contentRect = null;
    tabRuns = null;

    contentBorderInsets = null;
    tabAreaInsets = null;
    selectedTabPadInsets = null;
    tabInsets = null;

    focus = null;
    darkShadow = null;
    shadow = null;
    lightHighlight = null;
    highlight = null;

    tabPane.setBackground(null);
    tabPane.setForeground(null);
    tabPane.setFont(null);
  }

  /**
   * This method creates and installs the listeners for this UI.
   */
  protected void installListeners()
  {
    mouseListener = createMouseListener();
    tabChangeListener = createChangeListener();
    propertyChangeListener = createPropertyChangeListener();
    focusListener = createFocusListener();

    tabPane.addMouseListener(mouseListener);
    tabPane.addChangeListener(tabChangeListener);
    tabPane.addPropertyChangeListener(propertyChangeListener);
    tabPane.addFocusListener(focusListener);
  }

  /**
   * This method removes and nulls the listeners for this UI.
   */
  protected void uninstallListeners()
  {
    tabPane.removeFocusListener(focusListener);
    tabPane.removePropertyChangeListener(propertyChangeListener);
    tabPane.removeChangeListener(tabChangeListener);
    tabPane.removeMouseListener(mouseListener);

    focusListener = null;
    propertyChangeListener = null;
    tabChangeListener = null;
    mouseListener = null;
  }

  /**
   * This method creates a new MouseListener.
   *
   * @return A new MouseListener.
   */
  protected MouseListener createMouseListener()
  {
    return new MouseHandler();
  }

  /**
   * This method creates a new FocusListener.
   *
   * @return A new FocusListener.
   */
  protected FocusListener createFocusListener()
  {
    return new FocusHandler();
  }

  /**
   * This method creates a new ChangeListener.
   *
   * @return A new ChangeListener.
   */
  protected ChangeListener createChangeListener()
  {
    return new TabSelectionHandler();
  }

  /**
   * This method creates a new PropertyChangeListener.
   *
   * @return A new PropertyChangeListener.
   */
  protected PropertyChangeListener createPropertyChangeListener()
  {
    return new PropertyChangeHandler();
  }

  /**
   * This method installs keyboard actions for the JTabbedPane.
   */
  protected void installKeyboardActions()
  {
    // FIXME: Implement.
  }

  /**
   * This method uninstalls keyboard actions for the JTabbedPane.
   */
  protected void uninstallKeyboardActions()
  {
    // FIXME: Implement.
  }

  /**
   * This method returns the preferred size of the JTabbedPane.
   *
   * @param c The JComponent to find a size for.
   *
   * @return The preferred size.
   */
  public Dimension getPreferredSize(JComponent c)
  {
    return layoutManager.preferredLayoutSize(tabPane);
  }

  /**
   * This method returns the minimum size of the JTabbedPane.
   *
   * @param c The JComponent to find a size for.
   *
   * @return The minimum size.
   */
  public Dimension getMinimumSize(JComponent c)
  {
    return layoutManager.minimumLayoutSize(tabPane);
  }

  /**
   * This method returns the maximum size of the JTabbedPane.
   *
   * @param c The JComponent to find a size for.
   *
   * @return The maximum size.
   */
  public Dimension getMaximumSize(JComponent c)
  {
    return getPreferredSize(c);
  }

  /**
   * This method paints the JTabbedPane.
   *
   * @param g The Graphics object to paint with.
   * @param c The JComponent to paint.
   */
  public void paint(Graphics g, JComponent c)
  {
    if (tabPane.getTabCount() == 0)
      return;
    if (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT)
      paintTabArea(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
    paintContentBorder(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
  }

  /**
   * This method paints the tab area. This includes painting the rectangles
   * that make up the tabs.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param selectedIndex The selected index.
   */
  protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex)
  {
    Rectangle ir = new Rectangle();
    Rectangle tr = new Rectangle();

    boolean isScroll = tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT;

    // Please note: the ordering of the painting is important. 
    // we WANT to paint the outermost run first and then work our way in.
    int tabCount = tabPane.getTabCount();
    int currRun = 1;
    if (tabCount < 1)
      return;

    if (runCount > 1)
      currRun = 0;
    for (int i = 0; i < runCount; i++)
      {
	int first = lastTabInRun(tabCount, getPreviousTabRun(currRun)) + 1;
	if (isScroll)
	  first = currentScrollLocation;
	else if (first == tabCount)
	  first = 0;
	int last = lastTabInRun(tabCount, currRun);
	if (isScroll)
	  {
	    for (int k = first; k < tabCount; k++)
	      {
		if (rects[k].x + rects[k].width - rects[first].x > viewport
		                                                   .getWidth())
		  {
		    last = k;
		    break;
		  }
	      }
	  }

	for (int j = first; j <= last; j++)
	  {
	    if (j != selectedIndex || isScroll)
	      paintTab(g, tabPlacement, rects, j, ir, tr);
	  }
	currRun = getPreviousTabRun(currRun);
      }
    if (! isScroll)
      paintTab(g, tabPlacement, rects, selectedIndex, ir, tr);
  }

  /**
   * This method paints an individual tab.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param rects The array of rectangles that keep the size and position of
   *        the tabs.
   * @param tabIndex The tab index to paint.
   * @param iconRect The rectangle to use for the icon.
   * @param textRect The rectangle to use for the text.
   */
  protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects,
                          int tabIndex, Rectangle iconRect, Rectangle textRect)
  {
    FontMetrics fm = getFontMetrics();
    Icon icon = getIconForTab(tabIndex);
    String title = tabPane.getTitleAt(tabIndex);
    boolean isSelected = tabIndex == tabPane.getSelectedIndex();
    calcRect = getTabBounds(tabPane, tabIndex);

    int x = calcRect.x;
    int y = calcRect.y;
    int w = calcRect.width;
    int h = calcRect.height;
    if (getRunForTab(tabPane.getTabCount(), tabIndex) == 1)
      {
	Insets insets = getTabAreaInsets(tabPlacement);
	switch (tabPlacement)
	  {
	  case TOP:
	    h += insets.bottom;
	    break;
	  case LEFT:
	    w += insets.right;
	    break;
	  case BOTTOM:
	    y -= insets.top;
	    h += insets.top;
	    break;
	  case RIGHT:
	    x -= insets.left;
	    w += insets.left;
	    break;
	  }
      }

    layoutLabel(tabPlacement, fm, tabIndex, title, icon, calcRect, iconRect,
                textRect, isSelected);
    paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
    paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected);

    // FIXME: Paint little folding corner and jagged edge clipped tab.
    if (icon != null)
      paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected);
    if (title != null && ! title.equals(""))
      paintText(g, tabPlacement, tabPane.getFont(), fm, tabIndex, title,
                textRect, isSelected);
  }

  /**
   * This method lays out the tab and finds the location to paint the  icon
   * and text.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param metrics The font metrics for the font to paint with.
   * @param tabIndex The tab index to paint.
   * @param title The string painted.
   * @param icon The icon painted.
   * @param tabRect The tab bounds.
   * @param iconRect The calculated icon bounds.
   * @param textRect The calculated text bounds.
   * @param isSelected Whether this tab is selected.
   */
  protected void layoutLabel(int tabPlacement, FontMetrics metrics,
                             int tabIndex, String title, Icon icon,
                             Rectangle tabRect, Rectangle iconRect,
                             Rectangle textRect, boolean isSelected)
  {
    SwingUtilities.layoutCompoundLabel(metrics, title, icon,
                                       SwingConstants.CENTER,
                                       SwingConstants.CENTER,
                                       SwingConstants.CENTER,
                                       SwingConstants.CENTER, tabRect,
                                       iconRect, textRect, textIconGap);

    int shiftX = getTabLabelShiftX(tabPlacement, tabIndex, isSelected);
    int shiftY = getTabLabelShiftY(tabPlacement, tabIndex, isSelected);

    iconRect.x += shiftX;
    iconRect.y += shiftY;

    textRect.x += shiftX;
    textRect.y += shiftY;
  }

  /**
   * This method paints the icon.
   *
   * @param g The Graphics object to paint.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param tabIndex The tab index to paint.
   * @param icon The icon to paint.
   * @param iconRect The bounds of the icon.
   * @param isSelected Whether this tab is selected.
   */
  protected void paintIcon(Graphics g, int tabPlacement, int tabIndex,
                           Icon icon, Rectangle iconRect, boolean isSelected)
  {
    icon.paintIcon(tabPane, g, iconRect.x, iconRect.y);
  }

  /**
   * This method paints the text for the given tab.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param font The font to paint with.
   * @param metrics The fontmetrics of the given font.
   * @param tabIndex The tab index.
   * @param title The string to paint.
   * @param textRect The bounds of the string.
   * @param isSelected Whether this tab is selected.
   */
  protected void paintText(Graphics g, int tabPlacement, Font font,
                           FontMetrics metrics, int tabIndex, String title,
                           Rectangle textRect, boolean isSelected)
  {
    View textView = getTextViewForTab(tabIndex);
    if (textView != null)
      {
	textView.paint(g, textRect);
	return;
      }

    Color fg = tabPane.getForegroundAt(tabIndex);
    if (fg == null)
      fg = tabPane.getForeground();
    Color bg = tabPane.getBackgroundAt(tabIndex);
    if (bg == null)
      bg = tabPane.getBackground();

    Color saved_color = g.getColor();
    Font f = g.getFont();
    g.setFont(font);

    if (tabPane.isEnabledAt(tabIndex))
      {
	g.setColor(fg);

	int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);

	if (mnemIndex != -1)
	  BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
	                                               textRect.x,
	                                               textRect.y
	                                               + metrics.getAscent());
	else
	  g.drawString(title, textRect.x, textRect.y + metrics.getAscent());
      }
    else
      {
	g.setColor(bg.brighter());

	int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);

	if (mnemIndex != -1)
	  BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
	                                               textRect.x, textRect.y);
	else
	  g.drawString(title, textRect.x, textRect.y);

	g.setColor(bg.darker());
	if (mnemIndex != -1)
	  BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, mnemIndex,
	                                               textRect.x + 1,
	                                               textRect.y + 1);
	else
	  g.drawString(title, textRect.x + 1, textRect.y + 1);
      }

    g.setColor(saved_color);
    g.setFont(f);
  }

  /**
   * This method returns how much the label for the tab should shift in the X
   * direction.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param tabIndex The tab index being painted.
   * @param isSelected Whether this tab is selected.
   *
   * @return The amount the label should shift by in the X direction.
   */
  protected int getTabLabelShiftX(int tabPlacement, int tabIndex,
                                  boolean isSelected)
  {
    // No reason to shift.
    return 0;
  }

  /**
   * This method returns how much the label for the tab should shift in the Y
   * direction.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param tabIndex The tab index being painted.
   * @param isSelected Whether this tab is selected.
   *
   * @return The amount the label should shift by in the Y direction.
   */
  protected int getTabLabelShiftY(int tabPlacement, int tabIndex,
                                  boolean isSelected)
  {
    // No reason to shift.
    return 0;
  }

  /**
   * This method paints the focus rectangle around the selected tab.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param rects The array of rectangles keeping track of size and position.
   * @param tabIndex The tab index.
   * @param iconRect The icon bounds.
   * @param textRect The text bounds.
   * @param isSelected Whether this tab is selected.
   */
  protected void paintFocusIndicator(Graphics g, int tabPlacement,
                                     Rectangle[] rects, int tabIndex,
                                     Rectangle iconRect, Rectangle textRect,
                                     boolean isSelected)
  {
    Color saved = g.getColor();
    calcRect = iconRect.union(textRect);

    g.setColor(focus);

    g.drawRect(calcRect.x, calcRect.y, calcRect.width, calcRect.height);

    g.setColor(saved);
  }

  /**
   * This method paints the border for an individual tab.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param tabIndex The tab index.
   * @param x The x position of the tab.
   * @param y The y position of the tab.
   * @param w The width of the tab.
   * @param h The height of the tab.
   * @param isSelected Whether the tab is selected.
   */
  protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
                                int x, int y, int w, int h, boolean isSelected)
  {
    Color saved = g.getColor();

    if (! isSelected || tabPlacement != SwingConstants.TOP)
      {
	g.setColor(shadow);
	g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
	g.setColor(darkShadow);
	g.drawLine(x, y + h, x + w, y + h);
      }

    if (! isSelected || tabPlacement != SwingConstants.LEFT)
      {
	g.setColor(darkShadow);
	g.drawLine(x + w, y, x + w, y + h);
	g.setColor(shadow);
	g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
      }

    if (! isSelected || tabPlacement != SwingConstants.RIGHT)
      {
	g.setColor(lightHighlight);
	g.drawLine(x, y, x, y + h);
      }

    if (! isSelected || tabPlacement != SwingConstants.BOTTOM)
      {
	g.setColor(lightHighlight);
	g.drawLine(x, y, x + w, y);
      }

    g.setColor(saved);
  }

  /**
   * This method paints the background for an individual tab.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param tabIndex The tab index.
   * @param x The x position of the tab.
   * @param y The y position of the tab.
   * @param w The width of the tab.
   * @param h The height of the tab.
   * @param isSelected Whether the tab is selected.
   */
  protected void paintTabBackground(Graphics g, int tabPlacement,
                                    int tabIndex, int x, int y, int w, int h,
                                    boolean isSelected)
  {
    Color saved = g.getColor();
    if (isSelected)
      g.setColor(Color.LIGHT_GRAY);
    else
      {
	Color bg = tabPane.getBackgroundAt(tabIndex);
	if (bg == null)
	  bg = Color.GRAY;
	g.setColor(bg);
      }

    g.fillRect(x, y, w, h);

    g.setColor(saved);
  }

  /**
   * This method paints the border around the content area.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param selectedIndex The index of the selected tab.
   */
  protected void paintContentBorder(Graphics g, int tabPlacement,
                                    int selectedIndex)
  {
    Insets insets = getContentBorderInsets(tabPlacement);
    int x = contentRect.x;
    int y = contentRect.y;
    int w = contentRect.width;
    int h = contentRect.height;
    paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
    paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h);
    paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h);
    paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h);
  }

  /**
   * This method paints the top edge of the content border.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param selectedIndex The selected tab index.
   * @param x The x coordinate for the content area.
   * @param y The y coordinate for the content area.
   * @param w The width of the content area.
   * @param h The height of the content area.
   */
  protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
                                           int selectedIndex, int x, int y,
                                           int w, int h)
  {
    Color saved = g.getColor();
    g.setColor(lightHighlight);

    int startgap = rects[selectedIndex].x;
    int endgap = rects[selectedIndex].x + rects[selectedIndex].width;

    int diff = 0;

    if (tabPlacement == SwingConstants.TOP)
      {
	if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
	  {
	    Point p = findPointForIndex(currentScrollLocation);
	    diff = p.x;
	  }

	g.drawLine(x, y, startgap - diff, y);
	g.drawLine(endgap - diff, y, x + w, y);
      }
    else
      g.drawLine(x, y, x + w, y);

    g.setColor(saved);
  }

  /**
   * This method paints the left edge of the content border.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param selectedIndex The selected tab index.
   * @param x The x coordinate for the content area.
   * @param y The y coordinate for the content area.
   * @param w The width of the content area.
   * @param h The height of the content area.
   */
  protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
                                            int selectedIndex, int x, int y,
                                            int w, int h)
  {
    Color saved = g.getColor();
    g.setColor(lightHighlight);

    int startgap = rects[selectedIndex].y;
    int endgap = rects[selectedIndex].y + rects[selectedIndex].height;

    int diff = 0;

    if (tabPlacement == SwingConstants.LEFT)
      {
	if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
	  {
	    Point p = findPointForIndex(currentScrollLocation);
	    diff = p.y;
	  }

	g.drawLine(x, y, x, startgap - diff);
	g.drawLine(x, endgap - diff, x, y + h);
      }
    else
      g.drawLine(x, y, x, y + h);

    g.setColor(saved);
  }

  /**
   * This method paints the bottom edge of the content border.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param selectedIndex The selected tab index.
   * @param x The x coordinate for the content area.
   * @param y The y coordinate for the content area.
   * @param w The width of the content area.
   * @param h The height of the content area.
   */
  protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
                                              int selectedIndex, int x, int y,
                                              int w, int h)
  {
    Color saved = g.getColor();

    int startgap = rects[selectedIndex].x;
    int endgap = rects[selectedIndex].x + rects[selectedIndex].width;

    int diff = 0;

    if (tabPlacement == SwingConstants.BOTTOM)
      {
	if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
	  {
	    Point p = findPointForIndex(currentScrollLocation);
	    diff = p.x;
	  }

	g.setColor(shadow);
	g.drawLine(x + 1, y + h - 1, startgap - diff, y + h - 1);
	g.drawLine(endgap - diff, y + h - 1, x + w - 1, y + h - 1);

	g.setColor(darkShadow);
	g.drawLine(x, y + h, startgap - diff, y + h);
	g.drawLine(endgap - diff, y + h, x + w, y + h);
      }
    else
      {
	g.setColor(shadow);
	g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
	g.setColor(darkShadow);
	g.drawLine(x, y + h, x + w, y + h);
      }

    g.setColor(saved);
  }

  /**
   * This method paints the right edge of the content border.
   *
   * @param g The Graphics object to paint with.
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param selectedIndex The selected tab index.
   * @param x The x coordinate for the content area.
   * @param y The y coordinate for the content area.
   * @param w The width of the content area.
   * @param h The height of the content area.
   */
  protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
                                             int selectedIndex, int x, int y,
                                             int w, int h)
  {
    Color saved = g.getColor();
    int startgap = rects[selectedIndex].y;
    int endgap = rects[selectedIndex].y + rects[selectedIndex].height;

    int diff = 0;

    if (tabPlacement == SwingConstants.RIGHT)
      {
	if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
	  {
	    Point p = findPointForIndex(currentScrollLocation);
	    diff = p.y;
	  }

	g.setColor(shadow);
	g.drawLine(x + w - 1, y + 1, x + w - 1, startgap - diff);
	g.drawLine(x + w - 1, endgap - diff, x + w - 1, y + h - 1);

	g.setColor(darkShadow);
	g.drawLine(x + w, y, x + w, startgap - diff);
	g.drawLine(x + w, endgap - diff, x + w, y + h);
      }
    else
      {
	g.setColor(shadow);
	g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
	g.setColor(darkShadow);
	g.drawLine(x + w, y, x + w, y + h);
      }

    g.setColor(saved);
  }

  /**
   * This method returns the tab bounds for the given index.
   *
   * @param pane The JTabbedPane.
   * @param i The index to look for.
   *
   * @return The bounds of the tab with the given index.
   */
  public Rectangle getTabBounds(JTabbedPane pane, int i)
  {
    return rects[i];
  }

  /**
   * This method returns the number of runs.
   *
   * @param pane The JTabbedPane.
   *
   * @return The number of runs.
   */
  public int getTabRunCount(JTabbedPane pane)
  {
    return runCount;
  }

  /**
   * This method returns the tab index given a coordinate.
   *
   * @param pane The JTabbedPane.
   * @param x The x coordinate.
   * @param y The y coordinate.
   *
   * @return The tab index that the coordinate lands in.
   */
  public int tabForCoordinate(JTabbedPane pane, int x, int y)
  {
    Point p = new Point(x, y);
    int tabCount = tabPane.getTabCount();
    int currRun = 1;
    for (int i = 0; i < runCount; i++)
      {
	int first = lastTabInRun(tabCount, getPreviousTabRun(currRun)) + 1;
	if (first == tabCount)
	  first = 0;
	int last = lastTabInRun(tabCount, currRun);
	for (int j = first; j <= last; j++)
	  {
	    if (getTabBounds(pane, j).contains(p))
	      return j;
	  }
	currRun = getNextTabRun(currRun);
      }
    return -1;
  }

  /**
   * This method returns the tab bounds in the given rectangle.
   *
   * @param tabIndex The index to get bounds for.
   * @param dest The rectangle to store bounds in.
   *
   * @return The rectangle passed in.
   */
  protected Rectangle getTabBounds(int tabIndex, Rectangle dest)
  {
    dest.setBounds(getTabBounds(tabPane, tabIndex));
    return dest;
  }

  /**
   * This method returns the component that is shown in  the content area.
   *
   * @return The component that is shown in the content area.
   */
  protected Component getVisibleComponent()
  {
    return tabPane.getComponentAt(tabPane.getSelectedIndex());
  }

  /**
   * This method sets the visible component.
   *
   * @param component The component to be set visible.
   */
  protected void setVisibleComponent(Component component)
  {
    component.setVisible(true);
    tabPane.setSelectedComponent(component);
  }

  /**
   * This method assures that enough rectangles are created given the
   * tabCount. The old array is copied to the  new one.
   *
   * @param tabCount The number of tabs.
   */
  protected void assureRectsCreated(int tabCount)
  {
    if (rects == null)
      rects = new Rectangle[tabCount];
    if (tabCount == rects.length)
      return;
    else
      {
	int numToCopy = Math.min(tabCount, rects.length);
	Rectangle[] tmp = new Rectangle[tabCount];
	System.arraycopy(rects, 0, tmp, 0, numToCopy);
	rects = tmp;
      }
  }

  /**
   * This method expands the tabRuns array to give it more room. The old array
   * is copied to the new one.
   */
  protected void expandTabRunsArray()
  {
    // This method adds another 10 index positions to the tabRuns array.
    if (tabRuns == null)
      tabRuns = new int[10];
    else
      {
	int[] newRuns = new int[tabRuns.length + 10];
	System.arraycopy(tabRuns, 0, newRuns, 0, tabRuns.length);
	tabRuns = newRuns;
      }
  }

  /**
   * This method returns which run a particular tab belongs to.
   *
   * @param tabCount The number of tabs.
   * @param tabIndex The tab to find.
   *
   * @return The tabRuns index that it belongs to.
   */
  protected int getRunForTab(int tabCount, int tabIndex)
  {
    if (runCount == 1 && tabIndex < tabCount && tabIndex >= 0)
      return 1;
    for (int i = 0; i < runCount; i++)
      {
	int first = lastTabInRun(tabCount, getPreviousTabRun(i)) + 1;
	if (first == tabCount)
	  first = 0;
	int last = lastTabInRun(tabCount, i);
	if (last >= tabIndex && first <= tabIndex)
	  return i;
      }
    return -1;
  }

  /**
   * This method returns the index of the last tab in  a run.
   *
   * @param tabCount The number of tabs.
   * @param run The run to check.
   *
   * @return The last tab in the given run.
   */
  protected int lastTabInRun(int tabCount, int run)
  {
    if (tabRuns[run] == 0)
      return tabCount - 1;
    else
      return tabRuns[run] - 1;
  }

  /**
   * This method returns the tab run overlay.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   *
   * @return The tab run overlay.
   */
  protected int getTabRunOverlay(int tabPlacement)
  {
    return tabRunOverlay;
  }

  /**
   * This method returns the tab run indent. It is used in WRAP_TAB_LAYOUT and
   * makes each tab run start indented by a certain amount.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param run The run to get indent for.
   *
   * @return The amount a run should be indented.
   */
  protected int getTabRunIndent(int tabPlacement, int run)
  {
    return 0;
  }

  /**
   * This method returns whether a tab run should be padded.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param run The run to check.
   *
   * @return Whether the given run should be padded.
   */
  protected boolean shouldPadTabRun(int tabPlacement, int run)
  {
    return true;
  }

  /**
   * This method returns whether the tab runs should be rotated.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   *
   * @return Whether runs should be rotated.
   */
  protected boolean shouldRotateTabRuns(int tabPlacement)
  {
    return true;
  }

  /**
   * This method returns an icon for the tab. If the tab is disabled, it
   * should return the disabledIcon. If it is enabled, then it should return
   * the default icon.
   *
   * @param tabIndex The tab index to get an icon for.
   *
   * @return The icon for the tab index.
   */
  protected Icon getIconForTab(int tabIndex)
  {
    if (tabPane.isEnabledAt(tabIndex))
      return tabPane.getIconAt(tabIndex);
    else
      return tabPane.getDisabledIconAt(tabIndex);
  }

  /**
   * This method returns a view that can paint the text for the label.
   *
   * @param tabIndex The tab index to get a view for.
   *
   * @return The view for the tab index.
   */
  protected View getTextViewForTab(int tabIndex)
  {
    return null;
  }

  /**
   * This method returns the tab height, including insets, for the given index
   * and fontheight.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param tabIndex The index of the tab to calculate.
   * @param fontHeight The font height.
   *
   * @return This tab's height.
   */
  protected int calculateTabHeight(int tabPlacement, int tabIndex,
                                   int fontHeight)
  {
    Icon icon = getIconForTab(tabIndex);
    Insets insets = getTabInsets(tabPlacement, tabIndex);

    if (icon != null)
      {
	Rectangle vr = new Rectangle();
	Rectangle ir = new Rectangle();
	Rectangle tr = new Rectangle();
	layoutLabel(tabPlacement, getFontMetrics(), tabIndex,
	            tabPane.getTitleAt(tabIndex), icon, vr, ir, tr,
	            tabIndex == tabPane.getSelectedIndex());
	calcRect = tr.union(ir);
      }
    else
      calcRect.height = fontHeight;

    calcRect.height += insets.top + insets.bottom;
    return calcRect.height;
  }

  /**
   * This method returns the max tab height.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   *
   * @return The maximum tab height.
   */
  protected int calculateMaxTabHeight(int tabPlacement)
  {
    maxTabHeight = 0;

    FontMetrics fm = getFontMetrics();
    int fontHeight = fm.getHeight();

    for (int i = 0; i < tabPane.getTabCount(); i++)
      maxTabHeight = Math.max(calculateTabHeight(tabPlacement, i, fontHeight),
                              maxTabHeight);

    return maxTabHeight;
  }

  /**
   * This method calculates the tab width, including insets, for the given tab
   * index and font metrics.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param tabIndex The tab index to calculate for.
   * @param metrics The font's metrics.
   *
   * @return The tab width for the given index.
   */
  protected int calculateTabWidth(int tabPlacement, int tabIndex,
                                  FontMetrics metrics)
  {
    Icon icon = getIconForTab(tabIndex);
    Insets insets = getTabInsets(tabPlacement, tabIndex);

    if (icon != null)
      {
	Rectangle vr = new Rectangle();
	Rectangle ir = new Rectangle();
	Rectangle tr = new Rectangle();
	layoutLabel(tabPlacement, getFontMetrics(), tabIndex,
	            tabPane.getTitleAt(tabIndex), icon, vr, ir, tr,
	            tabIndex == tabPane.getSelectedIndex());
	calcRect = tr.union(ir);
      }
    else
      calcRect.width = metrics.stringWidth(tabPane.getTitleAt(tabIndex));

    calcRect.width += insets.left + insets.right;
    return calcRect.width;
  }

  /**
   * This method calculates the max tab width.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   *
   * @return The maximum tab width.
   */
  protected int calculateMaxTabWidth(int tabPlacement)
  {
    maxTabWidth = 0;

    FontMetrics fm = getFontMetrics();

    for (int i = 0; i < tabPane.getTabCount(); i++)
      maxTabWidth = Math.max(calculateTabWidth(tabPlacement, i, fm),
                             maxTabWidth);

    return maxTabWidth;
  }

  /**
   * This method calculates the tab area height, including insets, for the
   * given amount of runs and tab height.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param horizRunCount The number of runs.
   * @param maxTabHeight The max tab height.
   *
   * @return The tab area height.
   */
  protected int calculateTabAreaHeight(int tabPlacement, int horizRunCount,
                                       int maxTabHeight)
  {
    Insets insets = getTabAreaInsets(tabPlacement);
    int tabAreaHeight = horizRunCount * maxTabHeight
                        - (horizRunCount - 1) * tabRunOverlay;

    tabAreaHeight += insets.top + insets.bottom;

    return tabAreaHeight;
  }

  /**
   * This method calculates the tab area width, including insets, for the
   * given amount of runs and tab width.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param vertRunCount The number of runs.
   * @param maxTabWidth The max tab width.
   *
   * @return The tab area width.
   */
  protected int calculateTabAreaWidth(int tabPlacement, int vertRunCount,
                                      int maxTabWidth)
  {
    Insets insets = getTabAreaInsets(tabPlacement);
    int tabAreaWidth = vertRunCount * maxTabWidth
                       - (vertRunCount - 1) * tabRunOverlay;

    tabAreaWidth += insets.left + insets.right;

    return tabAreaWidth;
  }

  /**
   * This method returns the tab insets appropriately rotated.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param tabIndex The tab index.
   *
   * @return The tab insets for the given index.
   */
  protected Insets getTabInsets(int tabPlacement, int tabIndex)
  {
    Insets target = new Insets(0, 0, 0, 0);
    rotateInsets(tabInsets, target, tabPlacement);
    return target;
  }

  /**
   * This method returns the selected tab pad insets appropriately rotated.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   *
   * @return The selected tab pad insets.
   */
  protected Insets getSelectedTabPadInsets(int tabPlacement)
  {
    Insets target = new Insets(0, 0, 0, 0);
    rotateInsets(selectedTabPadInsets, target, tabPlacement);
    return target;
  }

  /**
   * This method returns the tab area insets appropriately rotated.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   *
   * @return The tab area insets.
   */
  protected Insets getTabAreaInsets(int tabPlacement)
  {
    Insets target = new Insets(0, 0, 0, 0);
    rotateInsets(tabAreaInsets, target, tabPlacement);
    return target;
  }

  /**
   * This method returns the content border insets appropriately rotated.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   *
   * @return The content border insets.
   */
  protected Insets getContentBorderInsets(int tabPlacement)
  {
    Insets target = new Insets(0, 0, 0, 0);
    rotateInsets(contentBorderInsets, target, tabPlacement);
    return target;
  }

  /**
   * This method returns the fontmetrics for the font of the JTabbedPane.
   *
   * @return The font metrics for the JTabbedPane.
   */
  protected FontMetrics getFontMetrics()
  {
    FontMetrics fm = tabPane.getToolkit().getFontMetrics(tabPane.getFont());
    return fm;
  }

  /**
   * This method navigates from the selected tab into the given direction. As
   * a result, a new tab will be selected (if possible).
   *
   * @param direction The direction to navigate in.
   */
  protected void navigateSelectedTab(int direction)
  {
    int tabPlacement = tabPane.getTabPlacement();
    if (tabPlacement == SwingConstants.TOP
        || tabPlacement == SwingConstants.BOTTOM)
      {
	if (direction == SwingConstants.WEST)
	  selectPreviousTabInRun(tabPane.getSelectedIndex());
	else if (direction == SwingConstants.EAST)
	  selectNextTabInRun(tabPane.getSelectedIndex());

	else
	  {
	    int offset = getTabRunOffset(tabPlacement, tabPane.getTabCount(),
	                                 tabPane.getSelectedIndex(),
	                                 (tabPlacement == SwingConstants.RIGHT)
	                                 ? true : false);
	    selectAdjacentRunTab(tabPlacement, tabPane.getSelectedIndex(),
	                         offset);
	  }
      }
    if (tabPlacement == SwingConstants.LEFT
        || tabPlacement == SwingConstants.RIGHT)
      {
	if (direction == SwingConstants.NORTH)
	  selectPreviousTabInRun(tabPane.getSelectedIndex());
	else if (direction == SwingConstants.SOUTH)
	  selectNextTabInRun(tabPane.getSelectedIndex());
	else
	  {
	    int offset = getTabRunOffset(tabPlacement, tabPane.getTabCount(),
	                                 tabPane.getSelectedIndex(),
	                                 (tabPlacement == SwingConstants.RIGHT)
	                                 ? true : false);
	    selectAdjacentRunTab(tabPlacement, tabPane.getSelectedIndex(),
	                         offset);
	  }
      }
  }

  /**
   * This method selects the next tab in the run.
   *
   * @param current The current selected index.
   */
  protected void selectNextTabInRun(int current)
  {
    tabPane.setSelectedIndex(getNextTabIndexInRun(tabPane.getTabCount(),
                                                  current));
  }

  /**
   * This method selects the previous tab in the run.
   *
   * @param current The current selected index.
   */
  protected void selectPreviousTabInRun(int current)
  {
    tabPane.setSelectedIndex(getPreviousTabIndexInRun(tabPane.getTabCount(),
                                                      current));
  }

  /**
   * This method selects the next tab (regardless of runs).
   *
   * @param current The current selected index.
   */
  protected void selectNextTab(int current)
  {
    tabPane.setSelectedIndex(getNextTabIndex(current));
  }

  /**
   * This method selects the previous tab (regardless of runs).
   *
   * @param current The current selected index.
   */
  protected void selectPreviousTab(int current)
  {
    tabPane.setSelectedIndex(getPreviousTabIndex(current));
  }

  /**
   * This method selects the correct tab given an offset from the current tab
   * index. If the tab placement is TOP or BOTTOM, the offset will be in the
   * y direction, otherwise, it will be in the x direction. A new coordinate
   * will be found by adding the offset to the current location of the tab.
   * The tab that the new location will be selected.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param tabIndex The tab to start from.
   * @param offset The coordinate offset.
   */
  protected void selectAdjacentRunTab(int tabPlacement, int tabIndex,
                                      int offset)
  {
    int x = rects[tabIndex].x + rects[tabIndex].width / 2;
    int y = rects[tabIndex].y + rects[tabIndex].height / 2;

    switch (tabPlacement)
      {
      case SwingConstants.TOP:
      case SwingConstants.BOTTOM:
	y += offset;
	break;
      case SwingConstants.RIGHT:
      case SwingConstants.LEFT:
	x += offset;
	break;
      }

    int index = tabForCoordinate(tabPane, x, y);
    if (index != -1)
      tabPane.setSelectedIndex(index);
  }

  // This method is called when you press up/down to cycle through tab runs.
  // it returns the distance (between the two runs' x/y position.
  // where one run is the current selected run and the other run is the run in the
  // direction of the scroll (dictated by the forward flag)
  // the offset is an absolute value of the difference

  /**
   * This method calculates the offset distance for use in
   * selectAdjacentRunTab. The offset returned will be a difference in the y
   * coordinate between the run in  the desired direction and the current run
   * (for tabPlacement in TOP or BOTTOM). Use x coordinate for LEFT and
   * RIGHT.
   *
   * @param tabPlacement The JTabbedPane's tab placement.
   * @param tabCount The number of tabs.
   * @param tabIndex The starting index.
   * @param forward If forward, the run in the desired direction will be the
   *        next run.
   *
   * @return The offset between the two runs.
   */
  protected int getTabRunOffset(int tabPlacement, int tabCount, int tabIndex,
                                boolean forward)
  {
    int currRun = getRunForTab(tabCount, tabIndex);
    int offset;
    int nextRun = (forward) ? getNextTabRun(currRun) : getPreviousTabRun(currRun);
    if (tabPlacement == SwingConstants.TOP
        || tabPlacement == SwingConstants.BOTTOM)
      offset = rects[lastTabInRun(tabCount, nextRun)].y
               - rects[lastTabInRun(tabCount, currRun)].y;
    else
      offset = rects[lastTabInRun(tabCount, nextRun)].x
               - rects[lastTabInRun(tabCount, currRun)].x;
    return offset;
  }

  /**
   * This method returns the previous tab index.
   *
   * @param base The index to start from.
   *
   * @return The previous tab index.
   */
  protected int getPreviousTabIndex(int base)
  {
    base--;
    if (base < 0)
      return tabPane.getTabCount() - 1;
    return base;
  }

  /**
   * This method returns the next tab index.
   *
   * @param base The index to start from.
   *
   * @return The next tab index.
   */
  protected int getNextTabIndex(int base)
  {
    base++;
    if (base == tabPane.getTabCount())
      return 0;
    return base;
  }

  /**
   * This method returns the next tab index in the run. If the next index is
   * out of this run, it will return the starting tab index for the run.
   *
   * @param tabCount The number of tabs.
   * @param base The index to start from.
   *
   * @return The next tab index in the run.
   */
  protected int getNextTabIndexInRun(int tabCount, int base)
  {
    int index = getNextTabIndex(base);
    int run = getRunForTab(tabCount, base);
    if (index == lastTabInRun(tabCount, run) + 1)
      index = lastTabInRun(tabCount, getPreviousTabRun(run)) + 1;
    return getNextTabIndex(base);
  }

  /**
   * This method returns the previous tab index in the run. If the previous
   * index is out of this run, it will return the last index for the run.
   *
   * @param tabCount The number of tabs.
   * @param base The index to start from.
   *
   * @return The previous tab index in the run.
   */
  protected int getPreviousTabIndexInRun(int tabCount, int base)
  {
    int index = getPreviousTabIndex(base);
    int run = getRunForTab(tabCount, base);
    if (index == lastTabInRun(tabCount, getPreviousTabRun(run)))
      index = lastTabInRun(tabCount, run);
    return getPreviousTabIndex(base);
  }

  /**
   * This method returns the index of the previous run.
   *
   * @param baseRun The run to start from.
   *
   * @return The index of the previous run.
   */
  protected int getPreviousTabRun(int baseRun)
  {
    if (getTabRunCount(tabPane) == 1)
      return 1;

    int prevRun = --baseRun;
    if (prevRun < 0)
      prevRun = getTabRunCount(tabPane) - 1;
    return prevRun;
  }

  /**
   * This method returns the index of the next run.
   *
   * @param baseRun The run to start from.
   *
   * @return The index of the next run.
   */
  protected int getNextTabRun(int baseRun)
  {
    if (getTabRunCount(tabPane) == 1)
      return 1;

    int nextRun = ++baseRun;
    if (nextRun == getTabRunCount(tabPane))
      nextRun = 0;
    return nextRun;
  }

  /**
   * This method rotates the insets given a direction to rotate them in.
   * Target placement should be one of TOP, LEFT, BOTTOM, RIGHT. The  rotated
   * insets will be stored in targetInsets. Passing in TOP as  the direction
   * does nothing. Passing in LEFT switches top and left, right and bottom.
   * Passing in BOTTOM switches top and bottom. Passing in RIGHT switches top
   * for left, left for bottom, bottom for right, and right for top.
   *
   * @param topInsets The reference insets.
   * @param targetInsets An Insets object to store the new insets.
   * @param targetPlacement The rotation direction.
   */
  protected static void rotateInsets(Insets topInsets, Insets targetInsets,
                                     int targetPlacement)
  {
    // Sun's version will happily throw an NPE if params are null,
    // so I won't check it either.
    switch (targetPlacement)
      {
      case SwingConstants.TOP:
	targetInsets.top = topInsets.top;
	targetInsets.left = topInsets.left;
	targetInsets.right = topInsets.right;
	targetInsets.bottom = topInsets.bottom;
	break;
      case SwingConstants.LEFT:
	targetInsets.left = topInsets.top;
	targetInsets.top = topInsets.left;
	targetInsets.right = topInsets.bottom;
	targetInsets.bottom = topInsets.right;
	break;
      case SwingConstants.BOTTOM:
	targetInsets.top = topInsets.bottom;
	targetInsets.bottom = topInsets.top;
	targetInsets.left = topInsets.left;
	targetInsets.right = topInsets.right;
	break;
      case SwingConstants.RIGHT:
	targetInsets.top = topInsets.left;
	targetInsets.left = topInsets.bottom;
	targetInsets.bottom = topInsets.right;
	targetInsets.right = topInsets.top;
	break;
      }
  }
}
