/* SortingFocusTraversalPolicy.java --
   Copyright (C) 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

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

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 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 java.awt.Component;
import java.awt.Container;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

/**
 * @author Graydon Hoare
 * @author Michael Koch
 * 
 * @since 1.4
 */
public class SortingFocusTraversalPolicy 
  extends InternalFrameFocusTraversalPolicy
{
  /**
   * The comparator used to sort elements in the focus traversal cycle
   * managed by this class.
   */
  Comparator comparator;

  /**
   * <p>Whether or not to perform an "implicit DownCycle" when selecting
   * successor components within a focus cycle.</p>
   *
   * <p>When this is true, requesting the "next" component following a
   * component which is a focus cycle root (and, necessarily, a container)
   * will enter the focus cycle root of that container, and return its
   * default focus.</p>
   *
   * <p>When this property is false, requesting the "next" component will
   * simply advance within the containing focus cycle, subject to the
   * {@link #comparator} order and the {@link #accept} judgment.</p>
   *
   * @see #getImplicitDownCycleTraversal()
   */
  boolean implicitDownCycleTraversal = true;
  
  /**
   * Creates a new <code>SortingFocusTraversalPolicy</code> with no
   * comparator set.
   */
  protected SortingFocusTraversalPolicy()
  {
    // Do nothing here.
  }

  /**
   * Creates a new <code>SortingFocusTraversalPolicy</code> with the given
   * comparator set.
   *
   * @param comparator the comparator to set
   */
  public SortingFocusTraversalPolicy(Comparator comparator)
  {
    this.comparator = comparator;
  }

  /**
   * Decide whether a component is an acceptable focus owner. 
   *
   * @param comp The component which is a candidate for focus ownership.
   *
   * @return true if the component is focusable, displayable, visible, and
   * enabled; otherwise false
   */
  protected boolean accept(Component comp)
  {
    return (comp.isVisible()
	    && comp.isDisplayable()
	    && comp.isEnabled()
	    && comp.isFocusable());
  }

  /**
   * Get the current value of the {@link #comparator} property.
   *
   * @return the current value of the property
   * 
   * @see #setComparator
   */
  protected Comparator getComparator()
  {
    return comparator;
  }

  /**
   * Set the current value of the {@link #comparator} property.
   *
   * @param comparator the new value of the property
   * 
   * @see #getComparator
   */
  protected void setComparator(Comparator comparator)
  {
    this.comparator = comparator;
  }

  private TreeSet getSortedCycle(Container root, TreeSet set)
  {
    if (set == null)
      set = (getComparator() == null 
             ? new TreeSet()
             : new TreeSet(getComparator()));
    
    if (root != null) 
      {
        Component[] comps = root.getComponents();
        for (int i = 0; i < comps.length; ++i)
          {
            Component c = comps[i];
            if (accept(c))
              set.add(c);
            if (c instanceof Container)
              getSortedCycle((Container) c, set);
          }
      }
    return set;
  }

  /**
   * Return the component which follows the specified component in this
   * focus cycle, relative to the order imposed by {@link
   * #comparator}. Candidate components are only considered if they are
   * accepted by the {@link #accept} method.
   *
   * If {@link #getImplicitDownCycleTraversal} is <code>true</code> and the
   * <code>comp</code> is a focus cycle root, an "implicit DownCycle"
   * occurs and the method returns the
   * <code>getDefaultComponent(comp)</code>.
   * 
   * @param root the focus cycle root to search for a successor within
   * @param comp the component to search for the successor of
   *
   * @return the component following the specified component under
   * the specified root, or null if no such component is found
   * 
   * @throws IllegalArgumentException if either argument is null, or
   * if the root is not a focus cycle root of the component
   */
  public Component getComponentAfter(Container root, 
                                     Component comp)
  {
    if (comp == null || root == null || !comp.isFocusCycleRoot(root))
      throw new IllegalArgumentException();

    if (getImplicitDownCycleTraversal() 
        && comp instanceof Container
        && ((Container)comp).isFocusCycleRoot())
      {
        return getDefaultComponent((Container) comp);
      }

    TreeSet set = getSortedCycle(root, null);
    Iterator i = set.iterator();
    while (i.hasNext())
      {
        Component c = (Component) i.next();
        if (c != null && c.equals(comp))
          {
            if (i.hasNext())
              return (Component) i.next();
            break;
          }
      }
    return null;
  }


  /**
   * Return the component which precedes the specified component in this
   * focus cycle, relative to the order imposed by {@link
   * #comparator}. Candidate components are only considered if they are
   * accepted by the {@link #accept} method.
   * 
   * @param root the focus cycle root to search for a predecessor within
   * @param comp the component to search for the predecessor of
   *
   * @return the component preceding the specified component under the
   * specified root, or null if no such component is found
   * 
   * @throws IllegalArgumentException if either argument is null, or
   * if the root is not a focus cycle root of the component
   */
  public Component getComponentBefore(Container root, 
                                      Component comp)
  {
    if (comp == null || root == null || !comp.isFocusCycleRoot(root))
      throw new IllegalArgumentException();
    TreeSet set = getSortedCycle(root, null);
    Iterator i = set.iterator();
    Component prev = null;
    while (i.hasNext())
      {
        Component c = (Component) i.next();
        if (c != null && c.equals(comp))
          break;
        prev = c;
      }
    return prev;
  }

  /**
   * Return the default component of <code>root</code>, which is by default
   * the same as the first component, returned by {@link
   * #getFirstComponent}.
   *
   * @param root the focus cycle root to return the default component of
   *
   * @return the default focus component for <code>root</code>
   *
   * @throws IllegalArgumentException if root is null
   */
  public Component getDefaultComponent(Container root)
  {
    return getFirstComponent(root);
  }

  /** 
   * Return the first focusable component of the focus cycle root
   * <code>comp</code> under the ordering imposed by the {@link
   * #comparator} property. Candidate components are only considered if
   * they are accepted by the {@link #accept} method.
   *
   * @param root the focus cycle root to search for the first component of
   *
   * @return the first component under <code>root</code>, or null if
   * no components are found.
   *
   * @throws IllegalArgumentException if root is null
   */
  public Component getFirstComponent(Container root)
  {
    if (root == null)
      throw new IllegalArgumentException();
    TreeSet set = getSortedCycle(root, null);
    Iterator i = set.iterator();
    if (i.hasNext())
      return (Component) i.next();
    return null;
  }
  
  /** 
   * Return the last focusable component of the focus cycle root
   * <code>comp</code> under the ordering imposed by the {@link
   * #comparator} property. Candidate components are only considered if
   * they are accepted by the {@link #accept} method.
   *
   * @param root the focus cycle root to search for the last component of
   *
   * @return the last component under <code>root</code>, or null if
   * no components are found.
   *
   * @throws IllegalArgumentException if root is null
   */
  public Component getLastComponent(Container root)
  {
    if (root == null)
      throw new IllegalArgumentException();
    TreeSet set = getSortedCycle(root, null);
    Iterator i = set.iterator();
    Component last = null;
    while (i.hasNext())
      last = (Component) i.next();
    return last;
  }

  /**
   * Return the current value of the {@link #implicitDownCycleTraversal}
   * property.
   *
   * @return the current value of the property
   * 
   * @see #setImplicitDownCycleTraversal
   */
  public boolean getImplicitDownCycleTraversal()
  {
    return implicitDownCycleTraversal;
  }

  /**
   * Set the current value of the {@link #implicitDownCycleTraversal}
   * property.
   *
   * @param down the new value of the property
   * 
   * @see #getImplicitDownCycleTraversal
   */
  public void setImplicitDownCycleTraversal(boolean down)
  {
    implicitDownCycleTraversal = down;
  }
}
