/* BasicSplitPaneUI.java --
   Copyright (C) 2003, 2004 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.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager2;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JComponent;
import javax.swing.JSplitPane;
import javax.swing.KeyStroke;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.SplitPaneUI;

/**
 * This is the Basic Look and Feel implementation of the SplitPaneUI  class.
 */
public class BasicSplitPaneUI extends SplitPaneUI
{
  /**
   * This Layout Manager controls the position and size of the components when
   * the JSplitPane's orientation is HORIZONTAL_SPLIT.
   */
  protected class BasicHorizontalLayoutManager implements LayoutManager2
  {
    // 3 components at a time.
    // LEFT/TOP = 0
    // RIGHT/BOTTOM = 1
    // DIVIDER = 2    

    /**
     * This array contains the components in the JSplitPane. The  left/top
     * component is at index 0, the right/bottom is at 1, and the divider is
     * at 2.
     */
    protected Component[] components = new Component[3];

    // These are the _current_ widths of the associated component.

    /**
     * This array contains the current width (for HORIZONTAL_SPLIT) or height
     * (for VERTICAL_SPLIT) of the components. The indices are the same as
     * for components.
     */
    protected int[] sizes = new int[3];

    /**
     * This method adds the component given to the JSplitPane. The position of
     * the component is given by the constraints object.
     *
     * @param comp The Component to add.
     * @param constraints The constraints that bind the object.
     */
    public void addLayoutComponent(Component comp, Object constraints)
    {
      addLayoutComponent((String) constraints, comp);
    }

    /**
     * This method is called to add a Component to the JSplitPane. The
     * placement string determines where the Component will be placed. The
     * string should be one of LEFT, RIGHT, TOP, BOTTOM or null (signals that
     * the component is the divider).
     *
     * @param place The placement of the Component.
     * @param component The Component to add.
     *
     * @throws IllegalArgumentException DOCUMENT ME!
     */
    public void addLayoutComponent(String place, Component component)
    {
      int i = 0;
      if (place == null)
	i = 2;
      else if (place.equals(JSplitPane.TOP) || place.equals(JSplitPane.LEFT))
	i = 0;
      else if (place.equals(JSplitPane.BOTTOM)
               || place.equals(JSplitPane.RIGHT))
	i = 1;
      else
	throw new IllegalArgumentException("Illegal placement in JSplitPane");
      components[i] = component;
      resetSizeAt(i);
      splitPane.revalidate();
      splitPane.repaint();
    }

    /**
     * This method returns the width of the JSplitPane minus the insets.
     *
     * @param containerSize The Dimensions of the JSplitPane.
     * @param insets The Insets of the JSplitPane.
     *
     * @return The width of the JSplitPane minus the insets.
     */
    protected int getAvailableSize(Dimension containerSize, Insets insets)
    {
      return containerSize.width - insets.left - insets.right;
    }

    /**
     * This method returns the given insets left value. If the  given inset is
     * null, then 0 is returned.
     *
     * @param insets The Insets to use with the JSplitPane.
     *
     * @return The inset's left value.
     */
    protected int getInitialLocation(Insets insets)
    {
      if (insets != null)
	return insets.left;
      return 0;
    }

    /**
     * This specifies how a component is aligned with respect to  other
     * components in the x fdirection.
     *
     * @param target The container.
     *
     * @return The component's alignment.
     */
    public float getLayoutAlignmentX(Container target)
    {
      return target.getAlignmentX();
    }

    /**
     * This specifies how a component is aligned with respect to  other
     * components in the y direction.
     *
     * @param target The container.
     *
     * @return The component's alignment.
     */
    public float getLayoutAlignmentY(Container target)
    {
      return target.getAlignmentY();
    }

    /**
     * This method returns the preferred width of the component.
     *
     * @param c The component to measure.
     *
     * @return The preferred width of the component.
     */
    protected int getPreferredSizeOfComponent(Component c)
    {
      Dimension dims = c.getPreferredSize();
      if (dims != null)
	return dims.width;
      return 0;
    }

    /**
     * This method returns the current width of the component.
     *
     * @param c The component to measure.
     *
     * @return The width of the component.
     */
    protected int getSizeOfComponent(Component c)
    {
      return c.getWidth();
    }

    /**
     * This method returns the sizes array.
     *
     * @return The sizes array.
     */
    protected int[] getSizes()
    {
      return sizes;
    }

    /**
     * This method invalidates the layout. It does nothing.
     *
     * @param c The container to invalidate.
     */
    public void invalidateLayout(Container c)
    {
      // DO NOTHING
    }

    /**
     * This method lays out the components in the container.
     *
     * @param container The container to lay out.
     */
    public void layoutContainer(Container container)
    {
      if (container instanceof JSplitPane)
        {
	  JSplitPane split = (JSplitPane) container;
	  distributeExtraSpace();
	  Insets insets = split.getInsets();
	  int width = getInitialLocation(insets);
	  Dimension dims = split.getSize();
	  for (int i = 0; i < components.length; i += 2)
	    {
	      if (components[i] == null)
		continue;
	      setComponentToSize(components[i], sizes[i], width, insets, dims);
	      width += sizes[i];
	    }
	  if (components[1] != null)
	    {
	      setComponentToSize(components[1], sizes[1], width, insets, dims);
	      width += sizes[1];
	    }
        }
    }

    /**
     * This method returns the maximum size for the container given the
     * components. It returns a new Dimension object that has width and
     * height equal to Integer.MAX_VALUE.
     *
     * @param target The container to measure.
     *
     * @return The maximum size.
     */
    public Dimension maximumLayoutSize(Container target)
    {
      return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
    }

    /**
     * This method returns the container's minimum size. The  minimum width is
     * the sum of all the component's minimum widths. The minimum height is
     * the maximum of  all the components' minimum heights.
     *
     * @param target The container to measure.
     *
     * @return The minimum size.
     */
    public Dimension minimumLayoutSize(Container target)
    {
      if (target instanceof JSplitPane)
        {
	  JSplitPane split = (JSplitPane) target;
	  Insets insets = target.getInsets();

	  int height = 0;
	  int width = 0;
	  for (int i = 0; i < components.length; i++)
	    {
	      if (components[i] == null)
		continue;
	      Dimension dims = components[i].getMinimumSize();
	      if (dims != null)
	        {
		  width += dims.width;
		  height = Math.max(height, dims.height);
	        }
	    }
	  return new Dimension(width, height);
        }
      return null;
    }

    /**
     * This method returns the container's preferred size. The preferred width
     * is the sum of all the component's preferred widths. The preferred
     * height is the maximum of all the components' preferred heights.
     *
     * @param target The container to measure.
     *
     * @return The preferred size.
     */
    public Dimension preferredLayoutSize(Container target)
    {
      if (target instanceof JSplitPane)
        {
	  JSplitPane split = (JSplitPane) target;
	  Insets insets = target.getInsets();

	  int height = 0;
	  int width = 0;
	  for (int i = 0; i < components.length; i++)
	    {
	      if (components[i] == null)
		continue;
	      Dimension dims = components[i].getPreferredSize();
	      if (dims != null)
	        {
		  width += dims.width;
		  if (! (components[i] instanceof BasicSplitPaneDivider))
		    height = Math.max(height, dims.height);
	        }
	    }
	  return new Dimension(500, 500); //width, height);	
        }
      return null;
    }

    /**
     * This method removes the component from the layout.
     *
     * @param component The component to remove from the layout.
     */
    public void removeLayoutComponent(Component component)
    {
      for (int i = 0; i < components.length; i++)
        {
	  if (component == components[i])
	    {
	      components[i] = null;
	      sizes[i] = 0;
	    }
        }
    }

    /**
     * This method resets the size of Component to the preferred size.
     *
     * @param index The index of the component to reset.
     */
    protected void resetSizeAt(int index)
    {
      if (components[index] != null)
	sizes[index] = getPreferredSizeOfComponent(components[index]);
    }

    /**
     * This method resets the sizes of all the components.
     */
    public void resetToPreferredSizes()
    {
      for (int i = 0; i < components.length; i++)
	resetSizeAt(i);
    }

    /**
     * This methods sets the bounds of the given component. The width is the
     * size. The height is the container size minus the  top and bottom
     * inset. The x coordinate is the location given.  The y coordinate is
     * the top inset.
     *
     * @param c The component to set.
     * @param size The width of the component.
     * @param location The x coordinate.
     * @param insets The insets to use.
     * @param containerSize The height of the container.
     */
    protected void setComponentToSize(Component c, int size, int location,
                                      Insets insets, Dimension containerSize)
    {
      int w = size;
      int h = containerSize.height - insets.top - insets.bottom;
      int x = location;
      int y = insets.top;
      c.setBounds(x, y, w, h);
    }

    /**
     * This method stores the given int array as the new sizes array.
     *
     * @param newSizes The array to use as sizes.
     */
    protected void setSizes(int[] newSizes)
    {
      sizes = newSizes;
    }

    /**
     * This method determines the size of each  component. It should be called
     * when a new Layout Manager is created for an existing JSplitPane.
     */
    protected void updateComponents()
    {
      Component left = splitPane.getLeftComponent();
      Component right = splitPane.getRightComponent();

      if (left != null)
        {
	  components[0] = left;
	  resetSizeAt(0);
        }
      if (right != null)
        {
	  components[1] = right;
	  resetSizeAt(1);
        }
      components[2] = divider;
      resetSizeAt(2);
    }

    /**
     * This method resizes the left and right components to fit inside the
     * JSplitPane when there is extra space.
     */
    void distributeExtraSpace()
    {
      int availSize = getAvailableSize(splitPane.getSize(),
                                       splitPane.getInsets());
      int[] newSizes = new int[3];
      double weight = splitPane.getResizeWeight();

      int oldLen = sizes[0] + sizes[1];

      // dividers don't change size.
      availSize -= sizes[2] + oldLen;

      int rightAlloc = (int) (availSize * (1 - weight));
      int leftAlloc = availSize - rightAlloc;

      sizes[0] += leftAlloc;
      sizes[1] += rightAlloc;
    }

    /**
     * This method returns the minimum width of the  component at the given
     * index.
     *
     * @param index The index to check.
     *
     * @return The minimum width.
     */
    int minimumSizeOfComponent(int index)
    {
      Dimension dims = components[index].getMinimumSize();
      if (dims != null)
	return dims.width;
      else
	return 0;
    }
  } //end BasicHorizontalLayoutManager

  /**
   * This class is the Layout Manager for the JSplitPane when the orientation
   * is VERTICAL_SPLIT.
   */
  protected class BasicVerticalLayoutManager
    extends BasicHorizontalLayoutManager
  {
    /**
     * This method returns the height of the container minus the top and
     * bottom inset.
     *
     * @param containerSize The size of the container.
     * @param insets The insets of the container.
     *
     * @return The height minus top and bottom inset.
     */
    protected int getAvailableSize(Dimension containerSize, Insets insets)
    {
      return containerSize.height - insets.top - insets.bottom;
    }

    /**
     * This method returns the top inset.
     *
     * @param insets The Insets to use.
     *
     * @return The top inset.
     */
    protected int getInitialLocation(Insets insets)
    {
      return insets.top;
    }

    /**
     * This method returns the preferred height of the component.
     *
     * @param c The component to measure.
     *
     * @return The preferred height of the component.
     */
    protected int getPreferredSizeOfComponent(Component c)
    {
      Dimension dims = c.getPreferredSize();
      if (dims != null)
	return dims.height;
      return 0;
    }

    /**
     * This method returns the current height of the component.
     *
     * @param c The component to measure.
     *
     * @return The current height of the component.
     */
    protected int getSizeOfComponent(Component c)
    {
      return c.getHeight();
    }

    /**
     * This method returns the minimum layout size. The minimum height is the
     * sum of all the components' minimum heights. The minimum width is the
     * maximum of all the  components' minimum widths.
     *
     * @param container The container to measure.
     *
     * @return The minimum size.
     */
    public Dimension minimumLayoutSize(Container container)
    {
      if (container instanceof JSplitPane)
        {
	  JSplitPane split = (JSplitPane) container;
	  Insets insets = container.getInsets();

	  int height = 0;
	  int width = 0;
	  for (int i = 0; i < components.length; i++)
	    {
	      if (components[i] == null)
		continue;
	      Dimension dims = components[i].getMinimumSize();
	      if (dims != null)
	        {
		  height += dims.height;
		  width = Math.max(width, dims.width);
	        }
	    }
	  return new Dimension(width, height);
        }
      return null;
    }

    /**
     * This method returns the preferred layout size. The preferred height is
     * the sum of all the components'  preferred heights. The preferred width
     * is the maximum of  all the components' preferred widths.
     *
     * @param container The container to measure.
     *
     * @return The preferred size.
     */
    public Dimension preferredLayoutSize(Container container)
    {
      if (container instanceof JSplitPane)
        {
	  JSplitPane split = (JSplitPane) container;
	  Insets insets = container.getInsets();

	  int height = 0;
	  int width = 0;
	  for (int i = 0; i < components.length; i++)
	    {
	      if (components[i] == null)
		continue;
	      Dimension dims = components[i].getPreferredSize();
	      if (dims != null)
	        {
		  height += dims.height;
		  width = Math.max(width, dims.width);
	        }
	    }
	  return new Dimension(500, 500); //width, height);
        }
      return null;
    }

    /**
     * This method sets the bounds of the given component. The y coordinate is
     * the location given. The x coordinate is the left inset. The height is
     * the size given. The width is the container size minus the left and
     * right inset.
     *
     * @param c The component to set bounds for.
     * @param size The height.
     * @param location The y coordinate.
     * @param insets The insets to use.
     * @param containerSize The container's size.
     */
    protected void setComponentToSize(Component c, int size, int location,
                                      Insets insets, Dimension containerSize)
    {
      int y = location;
      int x = insets.left;
      int h = size;
      int w = containerSize.width - insets.left - insets.right;

      c.setBounds(x, y, w, h);
    }

    /**
     * This method returns the minimum height of the component at the given
     * index.
     *
     * @param index The index of the component to check.
     *
     * @return The minimum height of the given component.
     */
    int minimumSizeOfComponent(int index)
    {
      Dimension dims = components[index].getMinimumSize();
      if (dims != null)
	return dims.height;
      else
	return 0;
    }
  }

  /**
   * This class handles FocusEvents from the JComponent.
   */
  protected class FocusHandler extends FocusAdapter
  {
    /**
     * This method is called when the JSplitPane gains focus.
     *
     * @param ev The FocusEvent.
     */
    public void focusGained(FocusEvent ev)
    {
      // FIXME: implement.
    }

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

  /**
   * This is a deprecated class. It is supposed to be used for handling down
   * and right key presses.
   */
  public class KeyboardDownRightHandler implements ActionListener
  {
    /**
     * This method is called when the down or right keys are pressed.
     *
     * @param ev The ActionEvent
     */
    public void actionPerformed(ActionEvent ev)
    {
      // FIXME: implement.
    }
  }

  /**
   * This is a deprecated class. It is supposed to be used for handling end
   * key presses.
   */
  public class KeyboardEndHandler implements ActionListener
  {
    /**
     * This method is called when the end key is pressed.
     *
     * @param ev The ActionEvent.
     */
    public void actionPerformed(ActionEvent ev)
    {
      // FIXME: implement.
    }
  }

  /**
   * This is a deprecated class. It is supposed to be used for handling home
   * key presses.
   */
  public class KeyboardHomeHandler implements ActionListener
  {
    /**
     * This method is called when the home key is pressed.
     *
     * @param ev The ActionEvent.
     */
    public void actionPerformed(ActionEvent ev)
    {
      // FIXME: implement.
    }
  }

  /**
   * This is a deprecated class. It is supposed to be used for handling resize
   * toggles.
   */
  public class KeyboardResizeToggleHandler implements ActionListener
  {
    /**
     * This method is called when a resize is toggled.
     *
     * @param ev The ActionEvent.
     */
    public void actionPerformed(ActionEvent ev)
    {
      // FIXME: implement.
    }
  }

  /**
   * This is a deprecated class. It is supposed to be used for handler up and
   * left key presses.
   */
  public class KeyboardUpLeftHandler implements ActionListener
  {
    /**
     * This method is called when the left or up keys are pressed.
     *
     * @param ev The ActionEvent.
     */
    public void actionPerformed(ActionEvent ev)
    {
      // FIXME: implement.
    }
  }

  /**
   * This helper class handles PropertyChangeEvents from the JSplitPane. When
   * a property changes, this will update the UI accordingly.
   */
  public class PropertyHandler implements PropertyChangeListener
  {
    /**
     * This method is called whenever one of the JSplitPane's properties
     * change.
     *
     * @param e DOCUMENT ME!
     */
    public void propertyChange(PropertyChangeEvent e)
    {
      if (e.getPropertyName().equals(JSplitPane.DIVIDER_SIZE_PROPERTY))
        {
	  int newSize = splitPane.getDividerSize();
	  int[] tmpSizes = layoutManager.getSizes();
	  dividerSize = tmpSizes[2];
	  Component left = splitPane.getLeftComponent();
	  Component right = splitPane.getRightComponent();
	  int newSpace = newSize - tmpSizes[2];

	  tmpSizes[2] = newSize;

	  tmpSizes[0] += newSpace / 2;
	  tmpSizes[1] += newSpace / 2;

	  layoutManager.setSizes(tmpSizes);
        }
      else if (e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY))
        {
	  int max = layoutManager.getAvailableSize(splitPane.getSize(),
	                                           splitPane.getInsets());
	  int dividerLoc = getDividerLocation(splitPane);
	  double prop = ((double) dividerLoc) / max;

	  resetLayoutManager();
	  if (prop <= 1 && prop >= 0)
	    splitPane.setDividerLocation(prop);
        }
      layoutManager.layoutContainer(splitPane);
      splitPane.repaint();
      // Don't have to deal with continuous_layout - only
      // necessary in dragging modes (and it's checked
      // every time you drag there)
      // Don't have to deal with resize_weight (as there
      // will be no extra space associated with this
      // event - the changes to the weighting will
      // be taken into account the next time the 
      // sizes change.)
      // Don't have to deal with divider_location 
      // The method in JSplitPane calls our setDividerLocation
      // so we'll know about those anyway.
      // Don't have to deal with last_divider_location
      // Although I'm not sure why, it doesn't seem to 
      // have any effect on Sun's JSplitPane.
      // one_touch_expandable changes are dealt with
      // by our divider.
    }
  }

  /** The location of the divider when dragging began. */
  protected int beginDragDividerLocation;

  /** The size of the divider while dragging. */
  protected int dividerSize;

  /** The location where the last drag location ended. */
  transient int lastDragLocation = -1;

  /** The distance the divider is moved when moved by keyboard actions. */
  protected static int KEYBOARD_DIVIDER_MOVE_OFFSET;

  /** The divider that divides this JSplitPane. */
  protected BasicSplitPaneDivider divider;

  /** The listener that listens for PropertyChangeEvents from the JSplitPane. */
  protected PropertyChangeListener propertyChangeListener;

  /** The JSplitPane's focus handler. */
  protected FocusListener focusListener;

  /** @deprecated The handler for down and right key presses. */
  protected ActionListener keyboardDownRightListener;

  /** @deprecated The handler for end key presses. */
  protected ActionListener keyboardEndListener;

  /** @deprecated The handler for home key presses. */
  protected ActionListener keyboardHomeListener;

  /** @deprecated The handler for toggling resizes. */
  protected ActionListener keyboardResizeToggleListener;

  /** @deprecated The handler for up and left key presses. */
  protected ActionListener keyboardUpLeftListener;

  /** The JSplitPane's current layout manager. */
  protected BasicHorizontalLayoutManager layoutManager;

  /** @deprecated The divider resize toggle key. */
  protected KeyStroke dividerResizeToggleKey;

  /** @deprecated The down key. */
  protected KeyStroke downKey;

  /** @deprecated The end key. */
  protected KeyStroke endKey;

  /** @deprecated The home key. */
  protected KeyStroke homeKey;

  /** @deprecated The left key. */
  protected KeyStroke leftKey;

  /** @deprecated The right key. */
  protected KeyStroke rightKey;

  /** @deprecated The up key. */
  protected KeyStroke upKey;

  /** Set to true when dragging heavy weight components. */
  protected boolean draggingHW;

  /**
   * The constraints object used when adding the non-continuous divider to the
   * JSplitPane.
   */
  protected static final String NON_CONTINUOUS_DIVIDER
    = "nonContinuousDivider";

  /** The dark divider used when dragging in non-continuous layout mode. */
  protected Component nonContinuousLayoutDivider;

  /** The JSplitPane that this UI draws. */
  protected JSplitPane splitPane;

  /**
   * Creates a new BasicSplitPaneUI object.
   */
  public BasicSplitPaneUI()
  {
  }

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

  /**
   * This method installs the BasicSplitPaneUI for the given JComponent.
   *
   * @param c The JComponent to install the UI for.
   */
  public void installUI(JComponent c)
  {
    if (c instanceof JSplitPane)
      {
	splitPane = (JSplitPane) c;
	installDefaults();
	installListeners();
	installKeyboardActions();
      }
  }

  /**
   * This method uninstalls the BasicSplitPaneUI for the given JComponent.
   *
   * @param c The JComponent to uninstall the UI for.
   */
  public void uninstallUI(JComponent c)
  {
    uninstallKeyboardActions();
    uninstallListeners();
    uninstallDefaults();

    splitPane = null;
  }

  /**
   * This method installs the defaults given by the Look and Feel.
   */
  protected void installDefaults()
  {
    resetLayoutManager();
    divider = createDefaultDivider();
    nonContinuousLayoutDivider = createDefaultNonContinuousLayoutDivider();
    splitPane.add(divider, JSplitPane.DIVIDER);

    // There is no need to add the nonContinuousLayoutDivider
    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
    splitPane.setBackground(defaults.getColor("SplitPane.background"));
    splitPane.setBorder(defaults.getBorder("SplitPane.border"));
    splitPane.setDividerSize(defaults.getInt("SplitPane.dividerSize"));
  }

  /**
   * This method uninstalls the defaults and nulls any objects created during
   * install.
   */
  protected void uninstallDefaults()
  {
    layoutManager = null;
    splitPane.remove(divider);
    divider = null;
    nonContinuousLayoutDivider = null;

    splitPane.setBackground(null);
    splitPane.setBorder(null);
  }

  /**
   * This method installs the listeners needed for this UI to function.
   */
  protected void installListeners()
  {
    propertyChangeListener = createPropertyChangeListener();
    focusListener = createFocusListener();

    splitPane.addPropertyChangeListener(propertyChangeListener);
    splitPane.addFocusListener(focusListener);
  }

  /**
   * This method uninstalls all listeners registered for the UI.
   */
  protected void uninstallListeners()
  {
    splitPane.removePropertyChangeListener(propertyChangeListener);
    splitPane.removeFocusListener(focusListener);

    focusListener = null;
    propertyChangeListener = null;
  }

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

  /**
   * This method reverses the work done in installKeyboardActions.
   */
  protected void uninstallKeyboardActions()
  {
    // FIXME: implement.
  }

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

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

  /**
   * This method creates a new ActionListener for up and left key presses.
   *
   * @return A new ActionListener for up and left keys.
   *
   * @deprecated 1.3
   */
  protected ActionListener createKeyboardUpLeftListener()
  {
    return new KeyboardUpLeftHandler();
  }

  /**
   * This method creates a new ActionListener for down and right key presses.
   *
   * @return A new ActionListener for down and right keys.
   *
   * @deprecated 1.3
   */
  protected ActionListener createKeyboardDownRightListener()
  {
    return new KeyboardDownRightHandler();
  }

  /**
   * This method creates a new ActionListener for home key presses.
   *
   * @return A new ActionListener for home keys.
   *
   * @deprecated
   */
  protected ActionListener createKeyboardHomeListener()
  {
    return new KeyboardHomeHandler();
  }

  /**
   * This method creates a new ActionListener for end key presses.i
   *
   * @return A new ActionListener for end keys.
   *
   * @deprecated 1.3
   */
  protected ActionListener createKeyboardEndListener()
  {
    return new KeyboardEndHandler();
  }

  /**
   * This method creates a new ActionListener for resize toggle key events.
   *
   * @return A new ActionListener for resize toggle keys.
   *
   * @deprecated 1.3
   */
  protected ActionListener createKeyboardResizeToggleListener()
  {
    return new KeyboardResizeToggleHandler();
  }

  /**
   * This method returns the orientation of the JSplitPane.
   *
   * @return The orientation of the JSplitPane.
   */
  public int getOrientation()
  {
    return splitPane.getOrientation();
  }

  /**
   * This method sets the orientation of the JSplitPane.
   *
   * @param orientation The new orientation of the JSplitPane.
   */
  public void setOrientation(int orientation)
  {
    splitPane.setOrientation(orientation);
  }

  /**
   * This method returns true if the JSplitPane is using continuous layout.
   *
   * @return True if the JSplitPane is using continuous layout.
   */
  public boolean isContinuousLayout()
  {
    return splitPane.isContinuousLayout();
  }

  /**
   * This method sets the continuous layout property of the JSplitPane.
   *
   * @param b True if the JsplitPane is to use continuous layout.
   */
  public void setContinuousLayout(boolean b)
  {
    splitPane.setContinuousLayout(b);
  }

  /**
   * This method returns the last location the divider was dragged to.
   *
   * @return The last location the divider was dragged to.
   */
  public int getLastDragLocation()
  {
    return lastDragLocation;
  }

  /**
   * This method sets the last location the divider was dragged to.
   *
   * @param l The last location the divider was dragged to.
   */
  public void setLastDragLocation(int l)
  {
    lastDragLocation = l;
  }

  /**
   * This method returns the BasicSplitPaneDivider that divides this
   * JSplitPane.
   *
   * @return The divider for the JSplitPane.
   */
  public BasicSplitPaneDivider getDivider()
  {
    return divider;
  }

  /**
   * This method creates a nonContinuousLayoutDivider for use with the
   * JSplitPane in nonContinousLayout mode. The default divider is a gray
   * Canvas.
   *
   * @return The default nonContinousLayoutDivider.
   */
  protected Component createDefaultNonContinuousLayoutDivider()
  {
    if (nonContinuousLayoutDivider == null)
      {
	nonContinuousLayoutDivider = new Canvas();
	nonContinuousLayoutDivider.setBackground(Color.DARK_GRAY);
      }
    return nonContinuousLayoutDivider;
  }

  /**
   * This method sets the component to use as the nonContinuousLayoutDivider.
   *
   * @param newDivider The component to use as the nonContinuousLayoutDivider.
   */
  protected void setNonContinuousLayoutDivider(Component newDivider)
  {
    setNonContinuousLayoutDivider(newDivider, true);
  }

  /**
   * This method sets the component to use as the nonContinuousLayoutDivider.
   *
   * @param newDivider The component to use as the nonContinuousLayoutDivider.
   * @param rememberSizes FIXME: document.
   */
  protected void setNonContinuousLayoutDivider(Component newDivider,
                                               boolean rememberSizes)
  {
    // FIXME: use rememberSizes for something
    nonContinuousLayoutDivider = newDivider;
  }

  /**
   * This method returns the nonContinuousLayoutDivider.
   *
   * @return The nonContinuousLayoutDivider.
   */
  public Component getNonContinuousLayoutDivider()
  {
    return nonContinuousLayoutDivider;
  }

  /**
   * This method returns the JSplitPane that this BasicSplitPaneUI draws.
   *
   * @return The JSplitPane.
   */
  public JSplitPane getSplitPane()
  {
    return splitPane;
  }

  /**
   * This method creates the divider used normally with the JSplitPane.
   *
   * @return The default divider.
   */
  public BasicSplitPaneDivider createDefaultDivider()
  {
    if (divider == null)
      divider = new BasicSplitPaneDivider(this);
    return divider;
  }

  /**
   * This method is called when JSplitPane's resetToPreferredSizes is called.
   * It resets the sizes of all components in the JSplitPane.
   *
   * @param jc The JSplitPane to reset.
   */
  public void resetToPreferredSizes(JSplitPane jc)
  {
    layoutManager.resetToPreferredSizes();
  }

  /**
   * This method sets the location of the divider.
   *
   * @param jc The JSplitPane to set the divider location in.
   * @param location The new location of the divider.
   */
  public void setDividerLocation(JSplitPane jc, int location)
  {
    setLastDragLocation(getDividerLocation(splitPane));
    splitPane.setLastDividerLocation(getDividerLocation(splitPane));
    int[] tmpSizes = layoutManager.getSizes();
    tmpSizes[0] = location
                  - layoutManager.getInitialLocation(splitPane.getInsets());
    tmpSizes[1] = layoutManager.getAvailableSize(splitPane.getSize(),
                                                 splitPane.getInsets())
                  - tmpSizes[0] - tmpSizes[1];

    layoutManager.setSizes(tmpSizes);
    splitPane.revalidate();
    splitPane.repaint();
  }

  /**
   * This method returns the location of the divider.
   *
   * @param jc The JSplitPane to retrieve the location for.
   *
   * @return The location of the divider.
   */
  public int getDividerLocation(JSplitPane jc)
  {
    return layoutManager.sizes[0]
           + layoutManager.getInitialLocation(splitPane.getInsets());
  }

  /**
   * This method returns the smallest value possible for the location of the
   * divider.
   *
   * @param jc The JSplitPane.
   *
   * @return The minimum divider location.
   */
  public int getMinimumDividerLocation(JSplitPane jc)
  {
    int value = layoutManager.getInitialLocation(jc.getInsets());
    if (layoutManager.components[0] != null)
      value += layoutManager.minimumSizeOfComponent(0);
    return value;
  }

  /**
   * This method returns the largest value possible for the location of the
   * divider.
   *
   * @param jc The JSplitPane.
   *
   * @return The maximum divider location.
   */
  public int getMaximumDividerLocation(JSplitPane jc)
  {
    int value = layoutManager.getInitialLocation(jc.getInsets())
                + layoutManager.getAvailableSize(jc.getSize(), jc.getInsets())
                - splitPane.getDividerSize();
    if (layoutManager.components[1] != null)
      value -= layoutManager.minimumSizeOfComponent(1);
    return value;
  }

  /**
   * This method is called after the children of the JSplitPane are painted.
   *
   * @param jc The JSplitPane.
   * @param g The Graphics object to paint with.
   */
  public void finishedPaintingChildren(JSplitPane jc, Graphics g)
  {
    if (! splitPane.isContinuousLayout() && nonContinuousLayoutDivider != null
        && nonContinuousLayoutDivider.isVisible())
      javax.swing.SwingUtilities.paintComponent(g, nonContinuousLayoutDivider,
                                                null,
                                                nonContinuousLayoutDivider
                                                .getBounds());
  }

  /**
   * This method is called to paint the JSplitPane.
   *
   * @param g The Graphics object to paint with.
   * @param jc The JSplitPane to paint.
   */
  public void paint(Graphics g, JComponent jc)
  {
    // Do nothing. All the painting is handled by children.
  }

  /**
   * This method returns the preferred size of the JSplitPane.
   *
   * @param jc The JSplitPane.
   *
   * @return The preferred size of the JSplitPane.
   */
  public Dimension getPreferredSize(JComponent jc)
  {
    return layoutManager.preferredLayoutSize((Container) jc);
  }

  /**
   * This method returns the minimum size of the JSplitPane.
   *
   * @param jc The JSplitPane.
   *
   * @return The minimum size of the JSplitPane.
   */
  public Dimension getMinimumSize(JComponent jc)
  {
    return layoutManager.minimumLayoutSize((Container) jc);
  }

  /**
   * This method returns the maximum size of the JSplitPane.
   *
   * @param jc The JSplitPane.
   *
   * @return The maximum size of the JSplitPane.
   */
  public Dimension getMaximumSize(JComponent jc)
  {
    return layoutManager.maximumLayoutSize((Container) jc);
  }

  /**
   * This method returns the border insets of the current border.
   *
   * @param jc The JSplitPane.
   *
   * @return The current border insets.
   */
  public Insets getInsets(JComponent jc)
  {
    return splitPane.getBorder().getBorderInsets(splitPane);
  }

  /**
   * This method resets the current layout manager. The type of layout manager
   * is dependent on the current orientation.
   */
  protected void resetLayoutManager()
  {
    if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
      layoutManager = new BasicHorizontalLayoutManager();
    else
      layoutManager = new BasicVerticalLayoutManager();
    layoutManager.invalidateLayout(splitPane);
    layoutManager.updateComponents();
    getSplitPane().setLayout(layoutManager);

    // invalidating by itself does not invalidate the layout.
    getSplitPane().revalidate();
  }

  /**
   * This method is called when dragging starts. It resets lastDragLocation
   * and dividerSize.
   */
  protected void startDragging()
  {
    dividerSize = divider.getDividerSize();
    setLastDragLocation(-1);

    if (! splitPane.getLeftComponent().isLightweight()
        || ! splitPane.getRightComponent().isLightweight())
      draggingHW = true;

    if (splitPane.isContinuousLayout())
      nonContinuousLayoutDivider.setVisible(false);
    else
      {
	nonContinuousLayoutDivider.setVisible(true);
	nonContinuousLayoutDivider.setBounds(divider.getBounds());
      }
    splitPane.revalidate();
    splitPane.repaint();
  }

  /**
   * This method is called whenever the divider is dragged. If the JSplitPane
   * is in continuousLayout mode, the divider needs to be moved and the
   * JSplitPane needs to be laid out.
   *
   * @param location The new location of the divider.
   */
  protected void dragDividerTo(int location)
  {
    location = validLocation(location);
    if (beginDragDividerLocation == -1)
      beginDragDividerLocation = location;

    if (splitPane.isContinuousLayout())
      splitPane.setDividerLocation(location);
    else
      {
	Point p = nonContinuousLayoutDivider.getLocation();
	if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
	  p.x = location;
	else
	  p.y = location;
	nonContinuousLayoutDivider.setLocation(p);
      }
    setLastDragLocation(location);
    splitPane.repaint();
  }

  /**
   * This method is called when the dragging is finished.
   *
   * @param location The location where the drag finished.
   */
  protected void finishDraggingTo(int location)
  {
    if (nonContinuousLayoutDivider != null)
      nonContinuousLayoutDivider.setVisible(false);
    draggingHW = false;
    location = validLocation(location);
    dragDividerTo(location);
    splitPane.setDividerLocation(location);
    splitPane.setLastDividerLocation(beginDragDividerLocation);
    beginDragDividerLocation = -1;
    splitPane.repaint();
  }

  /**
   * This method returns the width of one of the sides of the divider's border.
   *
   * @return The width of one side of the divider's border.
   *
   * @deprecated 1.3
   */
  protected int getDividerBorderSize()
  {
    if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
      return divider.getBorder().getBorderInsets(divider).left;
    else
      return divider.getBorder().getBorderInsets(divider).top;
  }

  /**
   * This is a helper method that returns a valid location for the divider
   * when dragging.
   *
   * @param location The location to check.
   *
   * @return A valid location.
   */
  private int validLocation(int location)
  {
    if (location < getMinimumDividerLocation(splitPane))
      return getMinimumDividerLocation(splitPane);
    if (location > getMaximumDividerLocation(splitPane))
      return getMaximumDividerLocation(splitPane);
    return location;
  }
}
