/* JTabbedPane.java --
   Copyright (C) 2002, 2004, 2005, 2006,  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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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;

import gnu.java.lang.CPStringBuilder;

import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.Locale;
import java.util.Vector;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.TabbedPaneUI;
import javax.swing.plaf.UIResource;

/**
 * This is a container for components where only one component is displayed at
 * a given time and the displayed component can be switched by clicking on
 * tabs.
 *
 * <p>
 * Tabs can be oriented in several ways. They can be above, below, left and
 * right of the component. Tabs can either wrap around (by creating multiple
 * rows of tabs) or they can be scrolled (where only a subset of the  tabs
 * can be seen at once). More tabs can be added by calling the
 * add/addTab/insertTab methods.
 * </p>
 */
public class JTabbedPane extends JComponent implements Serializable,
                                                       Accessible,
                                                       SwingConstants
{
  /**
   * Accessibility support for <code>JTabbedPane</code>.
   */
  protected class AccessibleJTabbedPane extends JComponent.AccessibleJComponent
    implements AccessibleSelection, ChangeListener
  {
    /**
     * The serialization UID.
     */
    private static final long serialVersionUID = 7610530885966830483L;

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

    /**
     * Receives notification when the selection state of the
     * <code>JTabbedPane</code> changes and fires appropriate property change
     * events to interested listeners.
     *
     * @param e the change event describing the change
     */
    public void stateChanged(ChangeEvent e)
    {
      // I couldn't figure out what else should be done here.
      Object source = e.getSource();
      firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
                         null, source);
    }

    /**
     * Returns the accessible role of the <code>JTabbedPane</code>, which is
     * {@link AccessibleRole#PAGE_TAB_LIST}.
     *
     * @return the accessible role of the <code>JTabbedPane</code>
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.PAGE_TAB_LIST;
    }

    /**
     * Returns the number of accessible child components of the
     * <code>JTabbedPane</code>.
     *
     * @return the number of accessible child components of the
     *         <code>JTabbedPane</code>
     */
    public int getAccessibleChildrenCount()
    {
      return getTabCount();
    }

    /**
     * Returns the accessible child component at the specified index.
     *
     * @param i the index of the child component to fetch
     *
     * @return the accessible child component at the specified index
     */
    public Accessible getAccessibleChild(int i)
    {
      // Testing shows that the reference implementation returns instances
      // of page here.
      Accessible child = null;
      if (i >= 0 && i < tabs.size())
        child = (Page) tabs.get(i);
      return child;
    }

    /**
     * Returns the current selection state of the <code>JTabbedPane</code>
     * as AccessibleSelection object.
     *
     * @return the current selection state of the <code>JTabbedPane</code>
     */
    public AccessibleSelection getAccessibleSelection()
    {
      return this;
    }

    /**
     * Returns the accessible child component at the specified coordinates.
     * If there is no child component at this location, then return the
     * currently selected tab.
     *
     * @param p the coordinates at which to look up the child component
     *
     * @return the accessible child component at the specified coordinates or
     *         the currently selected tab if there is no child component at
     *         this location
     */
    public Accessible getAccessibleAt(Point p)
    {
      int tabIndex = indexAtLocation(p.x, p.y);
      if (tabIndex >= 0)
        return getAccessibleChild(tabIndex);
      else
        return getAccessibleSelection(0);
    }

    /**
     * Returns the number of selected child components of the
     * <code>JTabbedPane</code>. The reference implementation appears
     * to return <code>1</code> always and we do the same.
     *
     * @return <code>1</code>
     */
    public int getAccessibleSelectionCount()
    {
      return 1;
    }

    /**
     * Returns the selected tab, or <code>null</code> if there is no
     * selection.
     *
     * @param i  the selection index (ignored here).
     *
     * @return The selected tab, or <code>null</code>.
     */
    public Accessible getAccessibleSelection(int i)
    {
      Accessible result = null;
      int selected = getSelectedIndex();
      if (selected >= 0)
        result = (Page) tabs.get(selected);
      return result;
    }

    /**
     * Returns <code>true</code> if the specified child is selected,
     * and <code>false</code> otherwise.
     *
     * @param i the child index.
     *
     * @return A boolean.
     */
    public boolean isAccessibleChildSelected(int i)
    {
      return i == getSelectedIndex();
    }

    /**
     * Selects the specified tab.
     *
     * @param i  the index of the item to select.
     */
    public void addAccessibleSelection(int i)
    {
      setSelectedIndex(i);
    }

    /**
     * Does nothing - it makes no sense to remove a selection for a
     * tabbed pane, since one tab must always be selected.
     *
     * @param i  the item index.
     *
     * @see #addAccessibleSelection(int)
     */
    public void removeAccessibleSelection(int i)
    {
      // do nothing
    }

    /**
     * Does nothing - it makes no sense to clear the selection for
     * a tabbed pane, since one tab must always be selected.
     *
     * @see #addAccessibleSelection(int)
     */
    public void clearAccessibleSelection()
    {
      // do nothing
    }

    /**
     * Does nothing - it makes no sense to select all for a tabbed
     * pane, since only one tab can be selected at a time.
     *
     * @see #addAccessibleSelection(int)
     */
    public void selectAllAccessibleSelection()
    {
      // do nothing
    }
  }

  /**
   * A helper class that listens for changes to the model.
   */
  protected class ModelListener implements ChangeListener, Serializable
  {
    private static final long serialVersionUID = 497359819958114132L;

    /**
     * Creates a new ModelListener object.
     */
    protected ModelListener()
    {
      // Nothing to do here.
    }

    /**
     * This method is called whenever the model  is changed.
     *
     * @param e The ChangeEvent that is passed from the model.
     */
    public void stateChanged(ChangeEvent e)
    {
      // Propagate to our listeners.
      fireStateChanged();
    }
  }

  /**
   * A private class that holds all the information  for each tab.
   */
  private class Page
    extends AccessibleContext
    implements Accessible
  {
    /** The tooltip string. */
    private String tip;

    /** The component associated with the tab. */
    private Component component;

    /** The active icon associated with the tab. */
    private transient Icon icon;

    /** The disabled icon associated with the tab. */
    private transient Icon disabledIcon;

    /** The tab's enabled status. */
    private transient boolean enabled = true;

    /** The string painted on the tab. */
    private transient String title;

    /** The background color of the tab. */
    private transient Color bg;

    /** The foreground color of the tab. */
    private transient Color fg;

    /** The mnemonic associated with the tab. */
    private transient int mnemonicKey;

    /** The index of the underlined character in the string. */
    private transient int underlinedChar = -1;

    /**
     * Creates a new data storage for the tab.
     *
     * @param title The string displayed on the tab.
     * @param icon The active icon displayed on the tab.
     * @param component The component associated with the tab.
     * @param tip The tooltip associated with the tab.
     */
    protected Page(String title, Icon icon, Component component, String tip)
    {
      this.title = title;
      this.icon = icon;
      this.component = component;
      this.tip = tip;
    }

    /**
     * This method returns the component associated with the tab.
     *
     * @return The component associated with the tab.
     */
    public Component getComponent()
    {
      return component;
    }

    /**
     * This method sets the component associated with the tab.
     *
     * @param c The component associated with the tab.
     */
    public void setComponent(Component c)
    {
      int i = indexOfComponent(component);
      insertTab(title, icon, c, tip, i);
      component = c;
      removeTabAt(i);
    }

    /**
     * This method returns the tooltip string.
     *
     * @return The tooltip string.
     */
    public String getTip()
    {
      return tip;
    }

    /**
     * This method sets the tooltip string.
     *
     * @param tip The tooltip string.
     */
    public void setTip(String tip)
    {
      this.tip = tip;
    }

    /**
     * This method returns the background color.
     *
     * @return The background color.
     */
    public Color getBackground()
    {
      Color background;
      if (bg == null)
        background = JTabbedPane.this.getBackground();
      else
        background = bg;
      return background;
    }

    /**
     * This method sets the background color.
     *
     * @param background The background color.
     */
    public void setBackground(Color background)
    {
      bg = background;
    }

    /**
     * This method returns the foreground color.
     *
     * @return The foreground color.
     */
    public Color getForeground()
    {
      Color foreground;
      if (fg == null)
        foreground = JTabbedPane.this.getForeground();
      else
        foreground = fg;
      return foreground;
    }

    /**
     * This method sets the foreground color.
     *
     * @param foreground The foreground color.
     */
    public void setForeground(Color foreground)
    {
      fg = foreground;
    }

    /**
     * This method returns the title associated with the tab.
     *
     * @return The title of the tab.
     */
    public String getTitle()
    {
      return title;
    }

    private static final long serialVersionUID = 1614381073220130939L;

    /**
     * This method sets the title of the tab.
     *
     * @param text The title of the tab.
     */
    public void setTitle(String text)
    {
      title = text;
      if (title != null && title.length() <= underlinedChar)
        setDisplayedMnemonicIndex(title.length() - 1);
    }

    /**
     * This method returns the active icon.
     *
     * @return The active icon.
     */
    public Icon getIcon()
    {
      return icon;
    }

    /**
     * This method sets the active icon.
     *
     * @param icon The active icon.
     */
    public void setIcon(Icon icon)
    {
      this.icon = icon;
    }

    /**
     * This method returns the disabled icon.
     *
     * @return The disabled icon.
     */
    public Icon getDisabledIcon()
    {
      if (disabledIcon == null && icon instanceof ImageIcon)
        setDisabledIcon(icon);
      return disabledIcon;
    }

    /**
     * This method sets the disabled icon.
     *
     * @param disabledIcon The disabled icon.
     */
    public void setDisabledIcon(Icon disabledIcon)
    {
      this.disabledIcon = disabledIcon;
    }

    /**
     * This method returns whether the tab is enabled.
     *
     * @return Whether the tab is enabled.
     */
    public boolean isEnabled()
    {
      return enabled;
    }

    /**
     * This method sets whether the tab is enabled.
     *
     * @param enabled Whether this tab is enabled.
     */
    public void setEnabled(boolean enabled)
    {
      this.enabled = enabled;
    }

    /**
     * This method returns the mnemonic.
     *
     * @return The mnemonic.
     */
    public int getMnemonic()
    {
      return mnemonicKey;
    }

    /**
     * This method sets the mnemonic. If the title is set, it will update the
     * mnemonicIndex.
     *
     * @param key The mnemonic.
     */
    public void setMnemonic(int key)
    {
      setMnemonic((char) key);
    }

    /**
     * This method sets the mnemonic. If the title is set, it will update the
     * mnemonicIndex.
     *
     * @param aChar The mnemonic.
     */
    public void setMnemonic(char aChar)
    {
      mnemonicKey = aChar;
      if (title != null)
        setDisplayedMnemonicIndex(title.indexOf(mnemonicKey));
    }

    /**
     * This method returns the mnemonicIndex.
     *
     * @return The mnemonicIndex.
     */
    public int getDisplayedMnemonicIndex()
    {
      return underlinedChar;
    }

    /**
     * This method sets the mnemonicIndex.
     *
     * @param index The mnemonicIndex.
     *
     * @throws IllegalArgumentException If index less than -1 || index greater
     *         or equal to title.length.
     */
    public void setDisplayedMnemonicIndex(int index)
      throws IllegalArgumentException
    {
      if (index < -1 || title != null && index >= title.length())
        throw new IllegalArgumentException();

      if (title == null || mnemonicKey == 0 || (index > -1 && title.charAt(index) != mnemonicKey))
        index = -1;

      underlinedChar = index;
    }

    /**
     * Returns the accessible context, which is this object itself.
     *
     * @return the accessible context, which is this object itself
     */
    public AccessibleContext getAccessibleContext()
    {
      return this;
    }

    /**
     * Returns the accessible name for this tab.
     *
     * @return The accessible name.
     */
    public String getAccessibleName()
    {
      if (accessibleName != null)
        return accessibleName;
      else
        return title;
    }

    /**
     * Returns the accessible role of this tab, which is always
     * {@link AccessibleRole#PAGE_TAB}.
     *
     * @return the accessible role of this tab
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.PAGE_TAB;
    }

    /**
     * Returns the accessible state set of this object.
     *
     * @return the accessible state set of this object
     */
    public AccessibleStateSet getAccessibleStateSet()
    {
      AccessibleContext parentCtx = JTabbedPane.this.getAccessibleContext();
      AccessibleStateSet state = parentCtx.getAccessibleStateSet();
      state.add(AccessibleState.SELECTABLE);
      if (component == getSelectedComponent())
        state.add(AccessibleState.SELECTED);
      return state;
    }

    /**
     * Returns the index of this tab inside its parent.
     *
     * @return the index of this tab inside its parent
     */
    public int getAccessibleIndexInParent()
    {
      // TODO: Not sure if the title is unambiguous, but I can't figure
      // another way of doing this.
      return indexOfTab(title);
    }

    /**
     * Returns the number of accessible children, which is always one (the
     * component of this tab).
     *
     * @return the number of accessible children
     */
    public int getAccessibleChildrenCount()
    {
      return 1;
    }

    /**
     * Returns the accessible child of this tab, which is the component
     * displayed by the tab.
     *
     * @return the accessible child of this tab
     */
    public Accessible getAccessibleChild(int i)
    {
      // A quick test shows that this method always returns the component
      // displayed by the tab, regardless of the index.
      return (Accessible) component;
    }

    /**
     * Returns the locale of this accessible object.
     *
     * @return the locale of this accessible object
     */
    public Locale getLocale()
    {
      // TODO: Is this ok?
      return Locale.getDefault();
    }
  }

  private static final long serialVersionUID = 1614381073220130939L;

  /** The changeEvent used to fire changes to listeners. */
  protected ChangeEvent changeEvent;

  /** The listener that listens to the model. */
  protected ChangeListener changeListener;

  /** The model that describes this JTabbedPane. */
  protected SingleSelectionModel model;

  /** Indicates that the TabbedPane is in scrolling mode. */
  public static final int SCROLL_TAB_LAYOUT = 1;

  /** Indicates that the TabbedPane is in wrap mode. */
  public static final int WRAP_TAB_LAYOUT = 0;

  /** The current tabPlacement of the TabbedPane. */
  protected int tabPlacement = SwingConstants.TOP;

  /** The current tabLayoutPolicy of the TabbedPane. */
  private transient int layoutPolicy;

  /** The list of tabs associated with the TabbedPane. */
  transient Vector tabs = new Vector();

  /**
   * Creates a new JTabbedPane object with tabs on top and using wrap tab
   * layout.
   */
  public JTabbedPane()
  {
    this(SwingConstants.TOP, WRAP_TAB_LAYOUT);
  }

  /**
   * Creates a new JTabbedPane object using wrap tab layout  and the given
   * <code>tabPlacement</code>, where <code>tabPlacement</code> can be one
   * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or
   * {@link #RIGHT}.
   *
   * @param tabPlacement where the tabs will be placed
   */
  public JTabbedPane(int tabPlacement)
  {
    this(tabPlacement, WRAP_TAB_LAYOUT);
  }

  /**
   * Creates a new JTabbedPane object with the given <code>tabPlacement</code>
   * and <code>tabLayoutPolicy</code>. The <code>tabPlacement</code> can be one
   * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or
   * {@link #RIGHT}. The <code>tabLayoutPolicy</code> can be either
   * {@link #SCROLL_TAB_LAYOUT} or {@link #WRAP_TAB_LAYOUT}.
   *
   * @param tabPlacement where the tabs will be placed
   * @param tabLayoutPolicy the way tabs will be placed
   *
   * @throws IllegalArgumentException If tabLayoutPolicy or tabPlacement are
   *         not valid.
   */
  public JTabbedPane(int tabPlacement, int tabLayoutPolicy)
  {
    if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
        && tabPlacement != LEFT)
      throw new IllegalArgumentException("tabPlacement is not valid.");
    if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
        && tabLayoutPolicy != WRAP_TAB_LAYOUT)
      throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
    this.tabPlacement = tabPlacement;
    layoutPolicy = tabLayoutPolicy;

    setModel(new DefaultSingleSelectionModel());

    updateUI();
  }

  /**
   * This method returns the UI used to display the JTabbedPane.
   *
   * @return The UI used to display the JTabbedPane.
   */
  public TabbedPaneUI getUI()
  {
    return (TabbedPaneUI) ui;
  }

  /**
   * This method sets the UI used to display the JTabbedPane.
   *
   * @param ui The UI used to display the JTabbedPane.
   */
  public void setUI(TabbedPaneUI ui)
  {
    super.setUI(ui);
  }

  /**
   * This method restores the UI to the defaults given by the UIManager.
   */
  public void updateUI()
  {
    setUI((TabbedPaneUI) UIManager.getUI(this));
  }

  /**
   * This method returns a string identifier that  is used to determine which
   * UI will be used with  the JTabbedPane.
   *
   * @return A string identifier for the UI.
   */
  public String getUIClassID()
  {
    return "TabbedPaneUI";
  }

  /**
   * This method creates a ChangeListener that is used to  listen to the model
   * for events.
   *
   * @return A ChangeListener to listen to the model.
   */
  protected ChangeListener createChangeListener()
  {
    return new ModelListener();
  }

  /**
   * This method adds a ChangeListener to the JTabbedPane.
   *
   * @param l The ChangeListener to add.
   */
  public void addChangeListener(ChangeListener l)
  {
    listenerList.add(ChangeListener.class, l);
  }

  /**
   * This method removes a ChangeListener to the JTabbedPane.
   *
   * @param l The ChangeListener to remove.
   */
  public void removeChangeListener(ChangeListener l)
  {
    listenerList.remove(ChangeListener.class, l);
  }

  /**
   * This method fires a ChangeEvent to all the JTabbedPane's ChangeListeners.
   */
  protected void fireStateChanged()
  {
    Object[] changeListeners = listenerList.getListenerList();
    if (changeEvent == null)
      changeEvent = new ChangeEvent(this);
    for (int i = changeListeners.length - 2; i >= 0; i -= 2)
      {
        if (changeListeners[i] == ChangeListener.class)
          ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
      }
  }

  /**
   * This method returns all ChangeListeners registered with the JTabbedPane.
   *
   * @return The ChangeListeners registered with the JTabbedPane.
   */
  public ChangeListener[] getChangeListeners()
  {
    return (ChangeListener[]) super.getListeners(ChangeListener.class);
  }

  /**
   * This method returns the model used with the JTabbedPane.
   *
   * @return The JTabbedPane's model.
   */
  public SingleSelectionModel getModel()
  {
    return model;
  }

  /**
   * This method changes the model property of the JTabbedPane.
   *
   * @param m The new model to use with the JTabbedPane.
   */
  public void setModel(SingleSelectionModel m)
  {
    if (m != model)
      {
        SingleSelectionModel oldModel = this.model;
        if (oldModel != null && changeListener != null)
          oldModel.removeChangeListener(changeListener);

        model = m;

        if (model != null)
          {
            if (changeListener == null)
              changeListener = createChangeListener();
            model.addChangeListener(changeListener);
          }
        firePropertyChange("model", oldModel, this.model);
      }
  }

  /**
   * This method returns the tabPlacement.
   *
   * @return The tabPlacement used with the JTabbedPane.
   */
  public int getTabPlacement()
  {
    return tabPlacement;
  }

  /**
   * This method changes the tabPlacement property of the JTabbedPane.
   *
   * @param tabPlacement The tabPlacement to use.
   *
   * @throws IllegalArgumentException If tabPlacement is not one of TOP,
   *         BOTTOM, LEFT, or RIGHT.
   */
  public void setTabPlacement(int tabPlacement)
  {
    if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
        && tabPlacement != LEFT)
      throw new IllegalArgumentException("tabPlacement is not valid.");
    if (tabPlacement != this.tabPlacement)
      {
        int oldPlacement = this.tabPlacement;
        this.tabPlacement = tabPlacement;
        firePropertyChange("tabPlacement", oldPlacement, this.tabPlacement);
      }
  }

  /**
   * This method returns the tabLayoutPolicy.
   *
   * @return The tabLayoutPolicy.
   */
  public int getTabLayoutPolicy()
  {
    return layoutPolicy;
  }

  /**
   * This method changes the tabLayoutPolicy property of the JTabbedPane.
   *
   * @param tabLayoutPolicy The tabLayoutPolicy to use.
   *
   * @throws IllegalArgumentException If tabLayoutPolicy is not one of
   *         SCROLL_TAB_LAYOUT or WRAP_TAB_LAYOUT.
   */
  public void setTabLayoutPolicy(int tabLayoutPolicy)
  {
    if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
        && tabLayoutPolicy != WRAP_TAB_LAYOUT)
      throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
    if (tabLayoutPolicy != layoutPolicy)
      {
        int oldPolicy = layoutPolicy;
        layoutPolicy = tabLayoutPolicy;
        firePropertyChange("tabLayoutPolicy", oldPolicy, layoutPolicy);
      }
  }

  /**
   * This method returns the index of the tab that is currently selected.
   *
   * @return The index of the selected tab.
   */
  public int getSelectedIndex()
  {
    return model.getSelectedIndex();
  }

  /**
   * This method checks the index.
   *
   * @param index The index to check.
   * @param start DOCUMENT ME!
   * @param end DOCUMENT ME!
   *
   * @throws IndexOutOfBoundsException DOCUMENT ME!
   */
  private void checkIndex(int index, int start, int end)
  {
    if (index < start || index >= end)
      throw new IndexOutOfBoundsException("Index < " + start + " || Index >= "
                                          + end);
  }

  /**
   * This method sets the selected index. This method will hide the old
   * component and show the new component.
   *
   * @param index The index to set it at.
   */
  public void setSelectedIndex(int index)
  {
    checkIndex(index, -1, tabs.size());
    if (index != getSelectedIndex())
      {
        // Hiding and showing the involved components
        // is done by the JTabbedPane's UI.
        model.setSelectedIndex(index);
      }
  }

  /**
   * This method returns the component at the selected index.
   *
   * @return The component at the selected index.
   */
  public Component getSelectedComponent()
  {
    int selectedIndex = getSelectedIndex();
    Component selected = null;
    if (selectedIndex >= 0)
      selected = getComponentAt(selectedIndex);
    return selected;
  }

  /**
   * This method sets the component at the selected index.
   *
   * @param c The component associated with the selected index.
   */
  public void setSelectedComponent(Component c)
  {
    if (c.getParent() == this)
      setSelectedIndex(indexOfComponent(c));
    else
      setComponentAt(getSelectedIndex(), c);
  }

  /**
   * This method inserts tabs into JTabbedPane. This includes adding the
   * component to the JTabbedPane and hiding it.
   *
   * @param title the title of the tab; may be <code>null</code>
   * @param icon the tab's icon; may be <code>null</code>
   * @param component the component associated with the tab
   * @param tip the tooltip for the tab
   * @param index the index to insert the tab at
   */
  public void insertTab(String title, Icon icon, Component component,
                        String tip, int index)
  {
    if (title == null)
      title = "";
    Page p = new Page(title, icon, component, tip);
    tabs.insertElementAt(p, index);

    // Hide the component so we don't see it. Do it before we parent it
    // so we don't trigger a repaint.
    if (component != null)
      {
        component.hide();
        super.add(component);
      }

    if (getSelectedIndex() == -1)
      {
        setSelectedIndex(0);
        fireStateChanged();
      }

    revalidate();
    repaint();
  }

  /**
   * This method adds a tab to the JTabbedPane.
   *
   * @param title the title of the tab; may be <code>null</code>
   * @param icon the icon for the tab; may be <code>null</code>
   * @param component the associated component
   * @param tip the associated tooltip
   */
  public void addTab(String title, Icon icon, Component component, String tip)
  {
    insertTab(title, icon, component, tip, tabs.size());
  }

  /**
   * This method adds a tab to the JTabbedPane.
   *
   * @param title the title of the tab; may be <code>null</code>
   * @param icon the icon for the tab; may be <code>null</code>
   * @param component the associated component
   */
  public void addTab(String title, Icon icon, Component component)
  {
    insertTab(title, icon, component, null, tabs.size());
  }

  /**
   * This method adds a tab to the JTabbedPane.
   *
   * @param title the title of the tab; may be <code>null</code>
   * @param component the associated component
   */
  public void addTab(String title, Component component)
  {
    insertTab(title, null, component, null, tabs.size());
  }

  /**
   * This method adds a tab to the JTabbedPane. The title of the tab is the
   * Component's name. If the Component is an instance of UIResource, it
   * doesn't add the tab and instead add the component directly to the
   * JTabbedPane.
   *
   * @param component The associated component.
   *
   * @return The Component that was added.
   */
  public Component add(Component component)
  {
    if (component instanceof UIResource)
      super.add(component);
    else
      insertTab(component.getName(), null, component, null, tabs.size());

    return component;
  }

  /**
   * This method adds a tab to the JTabbedPane. If the Component is an
   * instance of UIResource, it doesn't add the tab and instead add the
   * component directly to the JTabbedPane.
   *
   * @param title the title of the tab; may be <code>null</code>
   * @param component the associated component
   *
   * @return The Component that was added.
   */
  public Component add(String title, Component component)
  {
    if (component instanceof UIResource)
      super.add(component);
    else
      insertTab(title, null, component, null, tabs.size());
    return component;
  }

  /**
   * This method adds a tab to the JTabbedPane. If the Component is an
   * instance of UIResource, it doesn't add the tab and instead add the
   * component directly to the JTabbedPane.
   *
   * @param component The associated component.
   * @param index The index to insert the tab at.
   *
   * @return The Component that was added.
   */
  public Component add(Component component, int index)
  {
    if (component instanceof UIResource)
      super.add(component);
    else
      insertTab(component.getName(), null, component, null, index);
    return component;
  }

  /**
   * This method adds a tab to the JTabbedPane. If the Component is an
   * instance of UIResource, it doesn't add the tab and instead add the
   * component directly to the JTabbedPane. If the constraints object is an
   * icon, it will be used as the tab's icon. If the constraints object is a
   * string, we will use it as the title.
   *
   * @param component The associated component.
   * @param constraints The constraints object.
   */
  public void add(Component component, Object constraints)
  {
    add(component, constraints, tabs.size());
  }

  /**
   * This method adds a tab to the JTabbedPane. If the Component is an
   * instance of UIResource, it doesn't add the tab and instead add the
   * component directly to the JTabbedPane. If the constraints object is an
   * icon, it will be used as the tab's icon. If the constraints object is a
   * string, we will use it as the title.
   *
   * @param component The associated component.
   * @param constraints The constraints object.
   * @param index The index to insert the tab at.
   */
  public void add(Component component, Object constraints, int index)
  {
    if (component instanceof UIResource)
      super.add(component);
    else
      {
        if (constraints instanceof String)
          insertTab((String) constraints, null, component, null, index);
        else
          insertTab(component.getName(),
                    (constraints instanceof Icon) ? (Icon) constraints : null,
                    component, null, index);
      }
  }

  /**
   * Removes the tab at index. After the component associated with
   * index is removed, its visibility is reset to true to ensure it
   * will be visible if added to other containers.
   *
   * @param index The index of the tab to remove.
   */
  public void removeTabAt(int index)
  {
    checkIndex(index, 0, tabs.size());

    // We need to adjust the selection if we remove a tab that comes
    // before the selected tab or if the selected tab is removed.
    // This decrements the selected index by 1 if any of this is the case.
    // Note that this covers all cases:
    // - When the selected tab comes after the removed tab, this simply
    //   adjusts the selection so that after the removal the selected tab
    //   is still the same.
    // - When we remove the currently selected tab, then the tab before the
    //   selected tab gets selected.
    // - When the last tab is removed, then we have an index==0, which gets
    //   decremented to -1, which means no selection, which is 100% perfect.
    int selectedIndex = getSelectedIndex();
    if (selectedIndex >= index)
      setSelectedIndex(selectedIndex - 1);

    Component comp = getComponentAt(index);

    // Remove the tab object.
    tabs.remove(index);

    // Remove the component. I think we cannot assume that the tab order
    // is equal to the component order, so we iterate over the children
    // here to find the and remove the correct component.
    if (comp != null)
      {
        Component[] children = getComponents();
        for (int i = children.length - 1; i >= 0; --i)
          {
            if (children[i] == comp)
              {
                super.remove(i);
                comp.setVisible(true);
                break;
              }
          }
      }
    revalidate();
    repaint();
  }

  /**
   * Removes the specified Component from the JTabbedPane.
   *
   * @param component The Component to remove.
   */
  public void remove(Component component)
  {
    // Since components implementing UIResource
    // are not added as regular tabs by the add()
    // methods we have to take special care when
    // removing these object. Especially
    // Container.remove(Component) cannot be used
    // because it will call JTabbedPane.remove(int)
    // later which is overridden and can only
    // handle tab components.
    // This implementation can even cope with a
    // situation that someone called insertTab()
    // with a component that implements UIResource.
    int index = indexOfComponent(component);

    // If the component is not a tab component
    // find out its Container-given index
    // and call that class' implementation
    // directly.
    if (index == -1)
      {
        Component[] cs = getComponents();
        for (int i = 0; i< cs.length; i++)
          if (cs[i] == component)
            super.remove(i);
      }
    else
      removeTabAt(index);
  }

  /**
   * Removes the tab and component which corresponds to the specified index.
   *
   * @param index The index of the tab to remove.
   */
  public void remove(int index)
  {
    removeTabAt(index);
  }

  /**
   * This method removes all tabs and associated components from the
   * JTabbedPane.
   */
  public void removeAll()
  {
    setSelectedIndex(-1);
    for (int i = getTabCount() - 1; i >= 0; i--)
      removeTabAt(i);
  }

  /**
   * This method returns how many tabs are in the JTabbedPane.
   *
   * @return The number of tabs in the JTabbedPane.
   */
  public int getTabCount()
  {
    return tabs.size();
  }

  /**
   * This method returns the number of runs used  to paint the JTabbedPane.
   *
   * @return The number of runs.
   */
  public int getTabRunCount()
  {
    return ((TabbedPaneUI) ui).getTabRunCount(this);
  }

  /**
   * This method returns the tab title given the index.
   *
   * @param index The index of the tab.
   *
   * @return The title for the tab.
   */
  public String getTitleAt(int index)
  {
    checkIndex(index, 0, tabs.size());
    return ((Page) tabs.elementAt(index)).getTitle();
  }

  /**
   * This method returns the active icon given the index.
   *
   * @param index The index of the tab.
   *
   * @return The active icon for the tab.
   */
  public Icon getIconAt(int index)
  {
    checkIndex(index, 0, tabs.size());
    return ((Page) tabs.elementAt(index)).getIcon();
  }

  /**
   * This method returns the disabled icon given the index.
   *
   * @param index The index of the tab.
   *
   * @return The disabled icon for the tab.
   */
  public Icon getDisabledIconAt(int index)
  {
    checkIndex(index, 0, tabs.size());
    return ((Page) tabs.elementAt(index)).getDisabledIcon();
  }

  /**
   * This method returns the tooltip string for the tab.
   *
   * @param index The index of the tab.
   *
   * @return The tooltip string for the tab.
   */
  public String getToolTipTextAt(int index)
  {
    checkIndex(index, 0, tabs.size());
    return ((Page) tabs.elementAt(index)).getTip();
  }

  /**
   * This method returns the foreground color for the tab.
   *
   * @param index The index of the tab.
   *
   * @return The foreground color for the tab.
   */
  public Color getForegroundAt(int index)
  {
    checkIndex(index, 0, tabs.size());
    return ((Page) tabs.elementAt(index)).getForeground();
  }

  /**
   * This method returns the background color for the tab.
   *
   * @param index The index of the tab.
   *
   * @return The background color for the tab.
   */
  public Color getBackgroundAt(int index)
  {
    checkIndex(index, 0, tabs.size());
    return ((Page) tabs.elementAt(index)).getBackground();
  }

  /**
   * This method returns the component associated with the tab.
   *
   * @param index The index of the tab.
   *
   * @return The component associated with the tab.
   */
  public Component getComponentAt(int index)
  {
    checkIndex(index, 0, tabs.size());
    return ((Page) tabs.elementAt(index)).getComponent();
  }

  /**
   * This method returns whether this tab is enabled. Disabled tabs cannot be
   * selected.
   *
   * @param index The index of the tab.
   *
   * @return Whether the tab is enabled.
   */
  public boolean isEnabledAt(int index)
  {
    checkIndex(index, 0, tabs.size());
    return ((Page) tabs.elementAt(index)).isEnabled();
  }

  /**
   * This method returns the mnemonic for the tab.
   *
   * @param tabIndex The index of the tab.
   *
   * @return The mnemonic for the tab.
   */
  public int getMnemonicAt(int tabIndex)
  {
    checkIndex(tabIndex, 0, tabs.size());
    return ((Page) tabs.elementAt(tabIndex)).getMnemonic();
  }

  /**
   * This method returns the mnemonic index for the tab.
   *
   * @param tabIndex The index of the tab.
   *
   * @return The mnemonic index for the tab.
   */
  public int getDisplayedMnemonicIndexAt(int tabIndex)
  {
    checkIndex(tabIndex, 0, tabs.size());
    return ((Page) tabs.elementAt(tabIndex)).getDisplayedMnemonicIndex();
  }

  /**
   * This method returns the bounds of the tab given the index.
   *
   * @param index The index of the tab.
   *
   * @return A rectangle describing the bounds of the tab.
   */
  public Rectangle getBoundsAt(int index)
  {
    checkIndex(index, 0, tabs.size());
    return ((TabbedPaneUI) ui).getTabBounds(this, index);
  }

  /**
   * This method sets the title of the tab.
   *
   * @param index The index of the tab.
   * @param title The new title.
   */
  public void setTitleAt(int index, String title)
  {
    checkIndex(index, 0, tabs.size());
    ((Page) tabs.elementAt(index)).setTitle(title);
  }

  /**
   * This method sets the icon of the tab.
   *
   * @param index The index of the tab.
   * @param icon The new icon.
   */
  public void setIconAt(int index, Icon icon)
  {
    checkIndex(index, 0, tabs.size());
    ((Page) tabs.elementAt(index)).setIcon(icon);
  }

  /**
   * This method sets the disabled icon of the tab.
   *
   * @param index The index of the tab.
   * @param disabledIcon The new disabled icon.
   */
  public void setDisabledIconAt(int index, Icon disabledIcon)
  {
    checkIndex(index, 0, tabs.size());
    ((Page) tabs.elementAt(index)).setDisabledIcon(disabledIcon);
  }

  /**
   * This method sets the tooltip text of the tab.
   *
   * @param index The index of the tab.
   * @param toolTipText The tooltip text.
   */
  public void setToolTipTextAt(int index, String toolTipText)
  {
    checkIndex(index, 0, tabs.size());
    ((Page) tabs.elementAt(index)).setTip(toolTipText);
  }

  /**
   * This method sets the background color of the tab.
   *
   * @param index The index of the tab.
   * @param background The background color of the tab.
   */
  public void setBackgroundAt(int index, Color background)
  {
    checkIndex(index, 0, tabs.size());
    ((Page) tabs.elementAt(index)).setBackground(background);
  }

  /**
   * This method sets the foreground color of the tab.
   *
   * @param index The index of the tab.
   * @param foreground The foreground color of the tab.
   */
  public void setForegroundAt(int index, Color foreground)
  {
    checkIndex(index, 0, tabs.size());
    ((Page) tabs.elementAt(index)).setForeground(foreground);
  }

  /**
   * This method sets whether the tab is enabled.
   *
   * @param index The index of the tab.
   * @param enabled Whether the tab is enabled.
   */
  public void setEnabledAt(int index, boolean enabled)
  {
    checkIndex(index, 0, tabs.size());
    ((Page) tabs.elementAt(index)).setEnabled(enabled);
  }

  /**
   * This method sets the component associated with the tab.
   *
   * @param index The index of the tab.
   * @param component The component associated with the tab.
   */
  public void setComponentAt(int index, Component component)
  {
    checkIndex(index, 0, tabs.size());
    ((Page) tabs.elementAt(index)).setComponent(component);
  }

  /**
   * This method sets the displayed mnemonic index of the tab.
   *
   * @param tabIndex The index of the tab.
   * @param mnemonicIndex The mnemonic index.
   */
  public void setDisplayedMnemonicIndexAt(int tabIndex, int mnemonicIndex)
  {
    checkIndex(tabIndex, 0, tabs.size());
    ((Page) tabs.elementAt(tabIndex)).setDisplayedMnemonicIndex(mnemonicIndex);
  }

  /**
   * This method sets the mnemonic for the tab.
   *
   * @param tabIndex The index of the tab.
   * @param mnemonic The mnemonic.
   */
  public void setMnemonicAt(int tabIndex, int mnemonic)
  {
    checkIndex(tabIndex, 0, tabs.size());
    ((Page) tabs.elementAt(tabIndex)).setMnemonic(mnemonic);
  }

  /**
   * This method finds the index of a tab given the title.
   *
   * @param title The title that belongs to a tab.
   *
   * @return The index of the tab that has the title or -1 if not found.
   */
  public int indexOfTab(String title)
  {
    int index = -1;
    for (int i = 0; i < tabs.size(); i++)
      {
        if (((Page) tabs.elementAt(i)).getTitle().equals(title))
          {
            index = i;
            break;
          }
      }
    return index;
  }

  /**
   * This method finds the index of a tab given the icon.
   *
   * @param icon The icon that belongs to a tab.
   *
   * @return The index of the tab that has the icon or -1 if not found.
   */
  public int indexOfTab(Icon icon)
  {
    int index = -1;
    for (int i = 0; i < tabs.size(); i++)
      {
        if (((Page) tabs.elementAt(i)).getIcon() == icon)
          {
            index = i;
            break;
          }
      }
    return index;
  }

  /**
   * This method finds the index of a tab given the component.
   *
   * @param component A component associated with a tab.
   *
   * @return The index of the tab that has this component or -1 if not found.
   */
  public int indexOfComponent(Component component)
  {
    int index = -1;
    for (int i = 0; i < tabs.size(); i++)
      {
        if (((Page) tabs.elementAt(i)).getComponent() == component)
          {
            index = i;
            break;
          }
      }
    return index;
  }

  /**
   * This method returns a tab index given an (x,y) location. The origin of
   * the (x,y) pair will be the JTabbedPane's top left position. The  tab
   * returned will be the one that contains the point. This method is
   * delegated to the UI.
   *
   * @param x The x coordinate of the point.
   * @param y The y coordinate of the point.
   *
   * @return The index of the tab that contains the point.
   */
  public int indexAtLocation(int x, int y)
  {
    return ((TabbedPaneUI) ui).tabForCoordinate(this, x, y);
  }

  /**
   * This method returns the tooltip text given a mouse event.
   *
   * @param event The mouse event.
   *
   * @return The tool tip text that is associated with this mouse event.
   */
  public String getToolTipText(MouseEvent event)
  {
    int index = indexAtLocation(event.getX(), event.getY());
    return ((Page) tabs.elementAt(index)).getTip();
  }

  /**
   * Returns a string describing the attributes for the
   * <code>JTabbedPane</code> component, for use in debugging.  The return
   * value is guaranteed to be non-<code>null</code>, but the format of the
   * string may vary between implementations.
   *
   * @return A string describing the attributes of the
   *     <code>JTabbedPane</code>.
   */
  protected String paramString()
  {
    CPStringBuilder sb = new CPStringBuilder(super.paramString());
    sb.append(",tabPlacement=");
    if (tabPlacement == TOP)
      sb.append("TOP");
    if (tabPlacement == BOTTOM)
      sb.append("BOTTOM");
    if (tabPlacement == LEFT)
      sb.append("LEFT");
    if (tabPlacement == RIGHT)
      sb.append("RIGHT");
    return sb.toString();
  }

  /**
   * Returns the object that provides accessibility features for this
   * <code>JTabbedPane</code> component.
   *
   * @return The accessible context (an instance of
   *         {@link AccessibleJTabbedPane}).
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      {
        AccessibleJTabbedPane ctx = new AccessibleJTabbedPane();
        addChangeListener(ctx);
        accessibleContext = ctx;
      }

    return accessibleContext;
  }
}
