/* JSplitPane.java -- 
   Copyright (C) 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;

import java.awt.Component;
import java.awt.Graphics;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleValue;
import javax.swing.plaf.SplitPaneUI;

/**
 * This class implements JSplitPane. It is used to divide two components. By
 * dragging the SplitPane's divider, the user can resize the two components.
 * Note that the divider cannot resize a component to smaller than it's
 * minimum size.
 */
public class JSplitPane extends JComponent implements Accessible
{
  /**
   * DOCUMENT ME!
   */
  protected class AccessibleJSplitPane extends JComponent.AccessibleJComponent
    implements AccessibleValue
  {
  private static final long serialVersionUID = -1788116871416305366L;
  
    /**
     * Creates a new AccessibleJSplitPane object.
     *
     * @param value0 DOCUMENT ME!
     */
    protected AccessibleJSplitPane()
    {
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public AccessibleStateSet getAccessibleStateSet()
    {
      return null;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public AccessibleRole getAccessibleRole()
    {
      return null;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public AccessibleValue getAccessibleValue()
    {
      return null;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public Number getCurrentAccessibleValue()
    {
      return null;
    }

    /**
     * DOCUMENT ME!
     *
     * @param value0 DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public boolean setCurrentAccessibleValue(Number value0)
    {
      return false;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public Number getMinimumAccessibleValue()
    {
      return null;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public Number getMaximumAccessibleValue()
    {
      return null;
    }
  }

  private static final long serialVersionUID = -5634142046175988380L;
  
  /** The constraints string used to add components to the bottom. */
  public static final String BOTTOM = "bottom";

  /** The property fired when the continuousLayout property changes. */
  public static final String CONTINUOUS_LAYOUT_PROPERTY = "continuousLayout";

  /** The property fired when the divider property changes. */
  public static final String DIVIDER = "divider";

  /** The property fired when the divider location property changes. */
  public static final String DIVIDER_LOCATION_PROPERTY = "dividerLocation";

  /** The property fired when the divider size property changes. */
  public static final String DIVIDER_SIZE_PROPERTY = "dividerSize";

  /**
   * The value of the orientation when the components are split horizontally.
   */
  public static final int HORIZONTAL_SPLIT = 1;

  /** The property fired when the last divider location property changes. */
  public static final String LAST_DIVIDER_LOCATION_PROPERTY = "lastDividerLocation";

  /** The constraints string used to add components to the left. */
  public static final String LEFT = "left";

  /** The property fired when the one touch expandable property changes. */
  public static final String ONE_TOUCH_EXPANDABLE_PROPERTY = "oneTouchExpandable";

  /** The property fired when the orientation property changes. */
  public static final String ORIENTATION_PROPERTY = "orientation";

  /** The property fired when the resize weight property changes. */
  public static final String RESIZE_WEIGHT_PROPERTY = "resizeWeight";

  /** The constraints string used to add components to the right. */
  public static final String RIGHT = "right";

  /** The constraints string used to add components to the top. */
  public static final String TOP = "top";

  /** The value of the orientation when the components are split vertically. */
  public static final int VERTICAL_SPLIT = 0;

  /** Whether the JSplitPane uses continuous layout. */
  protected boolean continuousLayout;

  /** Whether the JSplitPane uses one touch expandable buttons. */
  protected boolean oneTouchExpandable = false;

  // This is the master dividerSize variable and sets the BasicSplitPaneDivider one accordingly

  /** The size of the divider. */
  protected int dividerSize = 10;

  /** The last location of the divider given by the UI. */
  protected int lastDividerLocation;

  /** The orientation of the JSplitPane. */
  protected int orientation;

  /** The component on the top or left. */
  protected Component leftComponent;

  /** The component on the right or bottom. */
  protected Component rightComponent;

  /** Determines how extra space should be allocated. */
  private transient double resizeWeight;

  /**
   * Creates a new JSplitPane object with the given orientation, layout mode,
   * and left and right components.
   *
   * @param newOrientation The orientation to use.
   * @param newContinuousLayout The layout mode to use.
   * @param newLeftComponent The left component.
   * @param newRightComponent The right component.
   *
   * @throws IllegalArgumentException DOCUMENT ME!
   */
  public JSplitPane(int newOrientation, boolean newContinuousLayout,
                    Component newLeftComponent, Component newRightComponent)
  {
    if (newOrientation != HORIZONTAL_SPLIT && newOrientation != VERTICAL_SPLIT)
      throw new IllegalArgumentException("orientation is invalid.");
    orientation = newOrientation;
    continuousLayout = newContinuousLayout;
    setLeftComponent(newLeftComponent);
    setRightComponent(newRightComponent);

    updateUI();
  }

  /**
   * Creates a new JSplitPane object using nonContinuousLayout mode, the given
   * orientation and left and right components.
   *
   * @param newOrientation The orientation to use.
   * @param newLeftComponent The left component.
   * @param newRightComponent The right component.
   */
  public JSplitPane(int newOrientation, Component newLeftComponent,
                    Component newRightComponent)
  {
    this(newOrientation, false, newLeftComponent, newRightComponent);
  }

  /**
   * Creates a new JSplitPane object with the given layout mode and
   * orientation.
   *
   * @param newOrientation The orientation to use.
   * @param newContinuousLayout The layout mode to use.
   */
  public JSplitPane(int newOrientation, boolean newContinuousLayout)
  {
    this(newOrientation, newContinuousLayout, null, null);
  }

  /**
   * Creates a new JSplitPane object using a nonContinuousLayout mode and the
   * given orientation.
   *
   * @param newOrientation The orientation to use.
   */
  public JSplitPane(int newOrientation)
  {
    this(newOrientation, false, null, null);
  }

  /**
   * Creates a new JSplitPane object using HORIZONTAL_SPLIT and a
   * nonContinuousLayout mode.
   */
  public JSplitPane()
  {
    this(HORIZONTAL_SPLIT, false, null, null);
  }

  /**
   * This method adds a component to the JSplitPane. The constraints object is
   * a string that identifies where this component should go. If the
   * constraints is not a known one, it will throw an
   * IllegalArgumentException. The valid constraints are LEFT, TOP, RIGHT,
   * BOTTOM and DIVIDER.
   *
   * @param comp The component to add.
   * @param constraints The constraints string to use.
   * @param index Where to place to component in the list of components.
   *
   * @throws IllegalArgumentException When the constraints is not a known identifier.
   */
  protected void addImpl(Component comp, Object constraints, int index)
  {
    int left = 0;
    int right = 1;
    int div = 2;
    int place;
    if (constraints == null)
      {
	if (leftComponent == null)
	  constraints = LEFT;
	else if (rightComponent == null)
	  constraints = RIGHT;
      }

    if (constraints instanceof String)
      {
	String placement = (String) constraints;

	if (placement.equals(BOTTOM) || placement.equals(RIGHT))
	  {
	    if (rightComponent != null)
		remove(rightComponent);
	    rightComponent = comp;
	  }
	else if (placement.equals(LEFT) || placement.equals(TOP))
	  {
	    if (leftComponent != null)
	      remove(leftComponent);
	    leftComponent = comp;
	  }
	else if (placement.equals(DIVIDER))
	  constraints = null;
	else
	  throw new IllegalArgumentException("Constraints is not a known identifier.");

	super.addImpl(comp, constraints, index);
      }
    invalidate();
    layout();
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleJSplitPane();
    
    return accessibleContext;
  }

  /**
   * This method returns the bottom component.
   *
   * @return The bottom component.
   */
  public Component getBottomComponent()
  {
    return rightComponent;
  }

  /**
   * This method returns the location of the divider. This method is passed to
   * the UI.
   *
   * @return The location of the divider.
   */
  public int getDividerLocation()
  {
    if (ui != null)
      return ((SplitPaneUI) ui).getDividerLocation(this);
    else
      return -1;
  }

  /**
   * This method returns the size of the divider.
   *
   * @return The size of the divider.
   */
  public int getDividerSize()
  {
    return dividerSize;
  }

  /**
   * This method returns the last divider location.
   *
   * @return The last divider location.
   */
  public int getLastDividerLocation()
  {
    return lastDividerLocation;
  }

  /**
   * This method returns the left component.
   *
   * @return The left component.
   */
  public Component getLeftComponent()
  {
    return leftComponent;
  }

  /**
   * This method returns the maximum divider location. This method is passed
   * to  the UI.
   *
   * @return DOCUMENT ME!
   */
  public int getMaximumDividerLocation()
  {
    if (ui != null)
      return ((SplitPaneUI) ui).getMaximumDividerLocation(this);
    else
      return -1;
  }

  /**
   * This method returns the minimum divider location. This method is passed
   * to the UI.
   *
   * @return The minimum divider location.
   */
  public int getMinimumDividerLocation()
  {
    if (ui != null)
      return ((SplitPaneUI) ui).getMinimumDividerLocation(this);
    else
      return -1;
  }

  /**
   * This method returns the orientation that the JSplitPane is using.
   *
   * @return The current orientation.
   */
  public int getOrientation()
  {
    return orientation;
  }

  /**
   * This method returns the current resize weight.
   *
   * @return The current resize weight.
   */
  public double getResizeWeight()
  {
    return resizeWeight;
  }

  /**
   * This method returns the right component.
   *
   * @return The right component.
   */
  public Component getRightComponent()
  {
    return rightComponent;
  }

  /**
   * This method returns the top component.
   *
   * @return The top component.
   */
  public Component getTopComponent()
  {
    return leftComponent;
  }

  /**
   * This method returns the UI.
   *
   * @return The UI.
   */
  public SplitPaneUI getUI()
  {
    return (SplitPaneUI) ui;
  }

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

  /**
   * This method returns true if the divider has one touch expandable buttons.
   *
   * @return True if one touch expandable is used.
   */
  public boolean isOneTouchExpandable()
  {
    return oneTouchExpandable;
  }

  /**
   * This method returns true.
   *
   * @return true.
   */
  public boolean isValidateRoot()
  {
    return true;
  }

  /**
   * This method overrides JComponent's paintChildren so the UI can be
   * messaged when the children have finished painting.
   *
   * @param g The Graphics object to paint with.
   */
  protected void paintChildren(Graphics g)
  {
    super.paintChildren(g);
    if (ui != null)
      ((SplitPaneUI) ui).finishedPaintingChildren(this, g);
  }

  /**
   * This method returns a String that describes this JSplitPane. The string
   * is primarily used for debugging purposes.
   *
   * @return A String used for debugging purposes.
   */
  protected String paramString()
  {
    return "JSplitPane";
  }

  /**
   * This method removes the given component from the JSplitPane.
   *
   * @param component The Component to remove.
   */
  public void remove(Component component)
  {
    if (component == leftComponent)
      leftComponent = null;
    else if (component == rightComponent)
      rightComponent = null;
    super.remove(component);
  }

  /**
   * This method removes the component at the given index.
   *
   * @param index The index of the component to remove.
   */
  public void remove(int index)
  {
    Component component = getComponent(index);
    if (component == leftComponent)
      leftComponent = null;
    else if (component == rightComponent)
      rightComponent = null;
    super.remove(index);
  }

  /**
   * This method removes all components from the JSplitPane.
   */
  public void removeAll()
  {
    leftComponent = null;
    rightComponent = null;
    super.removeAll();
  }

  /**
   * This method resets all children of the JSplitPane to their preferred
   * sizes.
   */
  public void resetToPreferredSizes()
  {
    if (ui != null)
      ((SplitPaneUI) ui).resetToPreferredSizes(this);
  }

  /**
   * This method sets the bottom component.
   *
   * @param comp The Component to be placed at the bottom.
   */
  public void setBottomComponent(Component comp)
  {
    if (comp != null)
      add(comp, BOTTOM);
    else
      add(new JButton("right button"), BOTTOM);
  }

  /**
   * This method sets the layout mode for the JSplitPane.
   *
   * @param newContinuousLayout Whether the JSplitPane is in continuousLayout
   *        mode.
   */
  public void setContinuousLayout(boolean newContinuousLayout)
  {
    if (newContinuousLayout != continuousLayout)
      {
	boolean oldValue = continuousLayout;
	continuousLayout = newContinuousLayout;
	firePropertyChange(CONTINUOUS_LAYOUT_PROPERTY, oldValue,
	                   continuousLayout);
      }
  }

  /**
   * This method sets the location of the divider. A value of 0 sets the
   * divider to the farthest left. A value of 1 sets the divider to the
   * farthest right.
   *
   * @param proportionalLocation A double that describes the location of the
   *        divider.
   *
   * @throws IllegalArgumentException DOCUMENT ME!
   */
  public void setDividerLocation(double proportionalLocation)
  {
    if (proportionalLocation > 1 || proportionalLocation < 0)
      throw new IllegalArgumentException("proportion has to be between 0 and 1.");

    int max = (orientation == HORIZONTAL_SPLIT) ? getWidth() : getHeight();
    setDividerLocation((int) (proportionalLocation * max));
  }

  /**
   * This method sets the location of the divider.
   *
   * @param location The location of the divider.
   */
  public void setDividerLocation(int location)
  {
    if (ui != null && location != getDividerLocation())
      {
	int oldLocation = getDividerLocation();
	((SplitPaneUI) ui).setDividerLocation(this, location);
	firePropertyChange(DIVIDER_LOCATION_PROPERTY, oldLocation, location);
      }
  }

  /**
   * This method sets the size of the divider.
   *
   * @param newSize The size of the divider.
   */
  public void setDividerSize(int newSize)
  {
    if (newSize != dividerSize)
      {
	int oldSize = dividerSize;
	dividerSize = newSize;
	firePropertyChange(DIVIDER_SIZE_PROPERTY, oldSize, dividerSize);
      }
  }

  // This doesn't appear to do anything when set from user side.
  // so it probably is only used from the UI side to change the
  // lastDividerLocation var.

  /**
   * This method sets the last location of the divider.
   *
   * @param newLastLocation The last location of the divider.
   */
  public void setLastDividerLocation(int newLastLocation)
  {
    if (newLastLocation != lastDividerLocation)
      {
	int oldValue = lastDividerLocation;
	lastDividerLocation = newLastLocation;
	firePropertyChange(LAST_DIVIDER_LOCATION_PROPERTY, oldValue,
	                   lastDividerLocation);
      }
  }

  /**
   * This method sets the left component.
   *
   * @param comp The left component.
   */
  public void setLeftComponent(Component comp)
  {
    if (comp != null)
      add(comp, LEFT);
    else
      add(new JButton("left button"), LEFT);
  }

  /**
   * This method sets whether the divider has one touch expandable buttons.
   * The one touch expandable buttons can expand the size of either component
   * to the maximum allowed size.
   *
   * @param newValue Whether the divider will have one touch expandable
   *        buttons.
   */
  public void setOneTouchExpandable(boolean newValue)
  {
    if (newValue != oneTouchExpandable)
      {
	boolean oldValue = oneTouchExpandable;
	oneTouchExpandable = newValue;
	firePropertyChange(ONE_TOUCH_EXPANDABLE_PROPERTY, oldValue,
	                   oneTouchExpandable);
      }
  }

  /**
   * This method sets the orientation of the JSplitPane.
   *
   * @param orientation The orientation of the JSplitPane.
   *
   * @throws IllegalArgumentException DOCUMENT ME!
   */
  public void setOrientation(int orientation)
  {
    if (orientation != HORIZONTAL_SPLIT && orientation != VERTICAL_SPLIT)
      throw new IllegalArgumentException("orientation must be one of VERTICAL_SPLIT, HORIZONTAL_SPLIT");
    if (orientation != this.orientation)
      {
	int oldOrientation = this.orientation;
	this.orientation = orientation;
	firePropertyChange(ORIENTATION_PROPERTY, oldOrientation,
	                   this.orientation);
      }
  }

  /**
   * This method determines how extra space will be distributed among the left
   * and right components. A value of 0 will allocate all extra space to the
   * right component. A value of 1 indicates that all extra space will go to
   * the left component. A value in between 1 and 0 will split the space
   * accordingly.
   *
   * @param value The resize weight.
   */
  public void setResizeWeight(double value)
  {
    resizeWeight = value;
  }

  /**
   * This method sets the right component.
   *
   * @param comp The right component.
   */
  public void setRightComponent(Component comp)
  {
    if (comp != null)
      add(comp, RIGHT);
    else
	add(new JButton("right button"), RIGHT);
  }

  /**
   * This method sets the top component.
   *
   * @param comp The top component.
   */
  public void setTopComponent(Component comp)
  {
    if (comp != null)
      add(comp, TOP);
    else
      add(new JButton("left button"), TOP);
  }

  /**
   * This method sets the UI used by the JSplitPane.
   *
   * @param ui The UI to use.
   */
  public void setUI(SplitPaneUI ui)
  {
    super.setUI(ui);
  }

  /**
   * This method resets the UI to the one specified by the current Look and
   * Feel.
   */
  public void updateUI()
  {
    setUI((SplitPaneUI) UIManager.getUI(this));
    invalidate();
    repaint();
  }

  /**
   * This method returns a string identifier to determine which UI class it
   * needs.
   *
   * @return A string that identifies it's UI class.
   */
  public String getUIClassID()
  {
    return "SplitPaneUI";
  }
}
