/* 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., 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.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 #getNextFocusableComponent
   */
  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 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;
  }
}
