/* JList.java --
   Copyright (C) 2002, 2003, 2004, 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.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Vector;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.ListUI;

/**
 * <p>This class is a facade over three separate objects: {@link
 * javax.swing.ListModel}, {@link javax.swing.ListSelectionModel} and
 * {@link javax.swing.plaf.ListUI}. The facade represents a unified "list"
 * concept, with independently replacable (possibly client-provided) models
 * for its contents and its current selection. In addition, each element in
 * the list is rendered via a strategy class {@link
 * javax.swing.ListCellRenderer}.</p>
 *
 * <p>Lists have many properties, some of which are stored in this class
 * while others are delegated to the list's model or selection. The
 * following properties are available:</p>
 *
 * <table>
 * <tr><th>Property                       </th><th>Stored in</th><th>Bound?</th></tr>
 * <tr><td>accessibleContext              </td><td>list     </td><td>no    </td></tr>
 * <tr><td>anchorSelectionIndex           </td><td>selection</td><td>no    </td></tr>
 * <tr><td>cellRenderer                   </td><td>list     </td><td>yes   </td></tr>
 * <tr><td>dragEnabled                    </td><td>list     </td><td>no    </td></tr>
 * <tr><td>firstVisibleIndex              </td><td>list     </td><td>no    </td></tr>
 * <tr><td>fixedCellHeight                </td><td>list     </td><td>yes   </td></tr>
 * <tr><td>fixedCellWidth                 </td><td>list     </td><td>yes   </td></tr>
 * <tr><td>lastVisibleIndex               </td><td>list     </td><td>no    </td></tr>
 * <tr><td>layoutOrientation              </td><td>list     </td><td>yes   </td></tr>
 * <tr><td>leadSelectionIndex             </td><td>selection</td><td>no    </td></tr>
 * <tr><td>maxSelectionIndex              </td><td>selection</td><td>no    </td></tr>
 * <tr><td>minSelectionIndex              </td><td>selection</td><td>no    </td></tr>
 * <tr><td>model                          </td><td>list     </td><td>yes   </td></tr>
 * <tr><td>opaque                         </td><td>list     </td><td>no    </td></tr>
 * <tr><td>preferredScrollableViewportSize</td><td>list     </td><td>no    </td></tr>
 * <tr><td>prototypeCellValue             </td><td>list     </td><td>yes   </td></tr>
 * <tr><td>scrollableTracksViewportHeight </td><td>list     </td><td>no    </td></tr>
 * <tr><td>scrollableTracksViewportWidth  </td><td>list     </td><td>no    </td></tr>
 * <tr><td>selectedIndex                  </td><td>selection</td><td>no    </td></tr>
 * <tr><td>selectedIndices                </td><td>selection</td><td>no    </td></tr>
 * <tr><td>selectedValue                  </td><td>model    </td><td>no    </td></tr>
 * <tr><td>selectedValues                 </td><td>model    </td><td>no    </td></tr>
 * <tr><td>selectionBackground            </td><td>list     </td><td>yes   </td></tr>
 * <tr><td>selectionEmpty                 </td><td>selection</td><td>no    </td></tr>
 * <tr><td>selectionForeground            </td><td>list     </td><td>yes   </td></tr>
 * <tr><td>selectionMode                  </td><td>selection</td><td>no    </td></tr>
 * <tr><td>selectionModel                 </td><td>list     </td><td>yes   </td></tr>
 * <tr><td>UI                             </td><td>list     </td><td>yes   </td></tr>
 * <tr><td>UIClassID                      </td><td>list     </td><td>no    </td></tr>
 * <tr><td>valueIsAdjusting               </td><td>list     </td><td>no    </td></tr>
 * <tr><td>visibleRowCount                </td><td>list     </td><td>no    </td></tr>
 * </table> 
 *
 * @author Graydon Hoare (graydon@redhat.com)
 */

public class JList extends JComponent implements Accessible, Scrollable
{
  private static final long serialVersionUID = 4406629526391098046L;

  /** 
   * Constant value used in "layoutOrientation" property. This value means
   * that cells are laid out in a single vertical column. This is the default. 
   */
  public static final int VERTICAL = 0;

  /** 
   * Constant value used in "layoutOrientation" property. This value means
   * that cells are laid out in multiple columns "newspaper style", filling
   * vertically first, then horizontally. 
   */
  public static final int VERTICAL_WRAP = 1;
  
  /** 
   * Constant value used in "layoutOrientation" property. This value means
   * that cells are laid out in multiple columns "newspaper style",
   * filling horizontally first, then vertically. 
   */
  public static final int HORIZONTAL_WRAP = 2;

  /**
   * This property indicates whether "drag and drop" functions are enabled
   * on the list.
   */
  boolean dragEnabled;

  /** This property provides a strategy for rendering cells in the list. */
  ListCellRenderer cellRenderer;

  /**
   * This property indicates an fixed width to assign to all cells in the
   * list. If its value is <code>-1</code>, no width has been
   * assigned. This value can be set explicitly, or implicitly by setting
   * the {@link #prototypeCellValue} property.
   */
  int fixedCellWidth;
  
  /**
   * This property indicates an fixed height to assign to all cells in the
   * list. If its value is <code>-1</code>, no height has been
   * assigned. This value can be set explicitly, or implicitly by setting
   * the {@link #prototypeCellValue} property.
   */
  int fixedCellHeight;

  /** 
   * This property holds the current layout orientation of the list, which
   * is one of the integer constants {@link #VERTICAL}, {@link
   * #VERTICAL_WRAP}, or {@link #HORIZONTAL_WRAP}. 
   */
  int layoutOrientation;
  
  /** This property holds the data elements displayed by the list. */
  ListModel model;

  /**
   * <p>This property holds a reference to a "prototype" data value --
   * typically a String -- which is used to calculate the {@link
   * #fixedCellWidth} and {@link #fixedCellHeight} properties, using the
   * {@link #cellRenderer} property to acquire a component to render the
   * prototype.</p>
   *
   * <p>It is important that you <em>not</em> set this value to a
   * component. It has to be a <em>data value</em> such as the objects you
   * would find in the list's model. Setting it to a component will have
   * undefined (and undesirable) affects. </p>
   */
  Object prototypeCellValue;

  /** 
   * This property specifies a foreground color for the selected cells in
   * the list. When {@link ListCellRenderer.getListCellRendererComponent}
   * is called with a selected cell object, the component returned will
   * have its "foreground" set to this color.
   */
  Color selectionBackground;

  /** 
   * This property specifies a background color for the selected cells in
   * the list. When {@link ListCellRenderer.getListCellRendererComponent}
   * is called with a selected cell object, the component returned will
   * have its "background" property set to this color.
   */
  Color selectionForeground;

  /** 
   * This property holds a description of which data elements in the {@link
   * #model} property should be considered "selected", when displaying and
   * interacting with the list.
   */
  ListSelectionModel selectionModel;


  /**
   * This property indicates that the list's selection is currently
   * "adjusting" -- perhaps due to a user actively dragging the mouse over
   * multiple list elements -- and is therefore likely to change again in
   * the near future. A {@link ListSelectionListener} might choose to delay
   * updating its view of the list's selection until this property is
   * false, meaning that the adjustment has completed.
   */
  boolean valueIsAdjusting;

  /** 
   * This property indicates a <em>preference</em> for the number of rows
   * displayed in the list, and will scale the
   * {@link #preferredScrollableViewportSize} property accordingly. The actual
   * number of displayed rows, when the list is placed in a real {@link
   * Viewport} or other component, may be greater or less than this number.
   */
  int visibleRowCount;

  /**
   * Fire a {@link ListSelectionEvent} to all the registered ListSelectionListeners.
   */
  protected void fireSelectionValueChanged(int firstIndex, int lastIndex, boolean isAdjusting) 
  {
    ListSelectionEvent evt = new ListSelectionEvent(this, firstIndex, lastIndex, isAdjusting);
    ListSelectionListener listeners[] = getListSelectionListeners();
    for (int i = 0; i < listeners.length; ++i)
      {
        listeners[i].valueChanged(evt);
      }
  }

  /**
   * This private listener propagates {@link ListSelectionEvent} events
   * from the list's "selectionModel" property to the list's {@link
   * ListSelectionListener} listeners. It also listens to {@link
   * ListDataEvent} events from the list's {@link #model} property. If this
   * class receives either type of event, it triggers repainting of the
   * list.
   */
  private class ListListener 
    implements ListSelectionListener, ListDataListener
  {
    // ListDataListener events
    public void contentsChanged(ListDataEvent event)
    {
      JList.this.revalidate();
      JList.this.repaint();
    }
    public void intervalAdded(ListDataEvent event)
    {
      JList.this.revalidate();
      JList.this.repaint();
    }
    public void intervalRemoved(ListDataEvent event)
    {
      JList.this.revalidate();
      JList.this.repaint();
    }
    // ListSelectionListener events
    public void valueChanged(ListSelectionEvent event)
    {
      JList.this.fireSelectionValueChanged(event.getFirstIndex(),
                                           event.getLastIndex(),
                                           event.getValueIsAdjusting());
      JList.this.repaint();
    }
  };

  /** 
   * Shared ListListener instance, subscribed to both the current {@link
   * #model} and {@link #selectionModel} properties of the list.
   */
  ListListener listListener;


  /**
   * Creates a new JList object.
   */
  public JList()
  {
    init();
  }

  /**
   * Creates a new JList object.
   *
   * @param listData Initial data to populate the list with
   */
  public JList(Object[] listData)
  {
    init();
    setListData(listData);
  }

  /**
   * Creates a new JList object.
   *
   * @param listData Initial data to populate the list with
   */
  public JList(Vector listData)
  {
    init();
    setListData(listData);
  }

  /**
   * Creates a new JList object.
   *
   * @param listData Initial data to populate the list with
   */
  public JList(ListModel listData)
  {
    init();
    setModel(listData);
  }

  void init()
  {
    dragEnabled = false;
    fixedCellHeight = -1;
    fixedCellWidth = -1;
    layoutOrientation = VERTICAL;
    opaque = true;
    valueIsAdjusting = false;
    visibleRowCount = 8;

    cellRenderer = new DefaultListCellRenderer();
    listListener = new ListListener();

    setModel(new DefaultListModel());
    setSelectionModel(createSelectionModel());

    updateUI();
  }

  /**
   * Creates the default <code>ListSelectionModel</code>.
   *
   * @return the <code>ListSelectionModel</code>
   */
  protected ListSelectionModel createSelectionModel()
  {
    return new DefaultListSelectionModel();
  }
  
  /**
   * Gets the value of the {@link #fixedCellHeight} property. This property
   * may be <code>-1</code> to indicate that no cell height has been
   * set. This property is also set implicitly when the
   * {@link #prototypeCellValue} property is set.
   *
   * @return The current value of the property 
   * 
   * @see #fixedCellHeight
   * @see #setFixedCellHeight
   * @see #setPrototypeCellValue
   */
  public int getFixedCellHeight()
  {
    return fixedCellHeight;
  }

  /**
   * Sets the value of the {@link #fixedCellHeight} property. This property
   * may be <code>-1</code> to indicate that no cell height has been
   * set. This property is also set implicitly when the {@link
   * #prototypeCellValue} property is set, but setting it explicitly
   * overrides the height computed from {@link #prototypeCellValue}.
   *
   * @see #getFixedCellHeight
   * @see #getPrototypeCellValue
   */
  public void setFixedCellHeight(int h)
  {
    if (fixedCellHeight == h)
      return;

    int old = fixedCellHeight;
    fixedCellHeight = h;
    firePropertyChange("fixedCellWidth", old, h);
  }


  /**
   * Gets the value of the {@link #fixedCellWidth} property. This property
   * may be <code>-1</code> to indicate that no cell width has been
   * set. This property is also set implicitly when the {@link
   * #prototypeCellValue} property is set.
   *
   * @return The current value of the property 
   * 
   * @see #setFixedCellWidth
   * @see #setPrototypeCellValue
   */
  public int getFixedCellWidth()
  {
    return fixedCellWidth;
  }

  /**
   * Sets the value of the {@link #fixedCellWidth} property. This property
   * may be <code>-1</code> to indicate that no cell width has been
   * set. This property is also set implicitly when the {@link
   * #prototypeCellValue} property is set, but setting it explicitly
   * overrides the width computed from {@link #prototypeCellValue}.
   *
   * @see #getFixedCellHeight
   * @see #getPrototypeCellValue
   */
  public void setFixedCellWidth(int w)
  {
    if (fixedCellWidth == w)
      return;
    
    int old = fixedCellWidth;
    fixedCellWidth = w;
    firePropertyChange("fixedCellWidth", old, w);
  }

  /** 
   * Gets the value of the {@link #visibleRowCount} property. 
   *
   * @return the current value of the property.
   */

  public int getVisibleRowCount()
  {
    return visibleRowCount;
  }

  /**
   * Sets the value of the {@link #visibleRowCount} property. 
   *
   * @param visibleRowCount The new property value
   */
  public void setVisibleRowCount(int vc)
  {
    visibleRowCount = vc;
    revalidate();
    repaint();
  }

  /**
   * Adds a {@link ListSelectionListener} to the listener list for this
   * list. The listener will be called back with a {@link
   * ListSelectionEvent} any time the list's {@link #selectionModel}
   * property changes. The source of such events will be the JList,
   * not the selection model.
   *
   * @param listener The new listener to add
   */
  public void addListSelectionListener(ListSelectionListener listener)
  {
    listenerList.add (ListSelectionListener.class, listener);
  }

  /**
   * Removes a {@link ListSelectionListener} from the listener list for
   * this list. The listener will no longer be called when the list's
   * {@link #selectionModel} changes.
   *
   * @param listener The listener to remove
   */
  public void removeListSelectionListener(ListSelectionListener listener)
  {
    listenerList.remove(ListSelectionListener.class, listener);
  }

  /**
   * Returns an array of all ListSelectionListeners subscribed to this
   * list. 
   *
   * @return The current subscribed listeners
   *
   * @since 1.4
   */
  public ListSelectionListener[] getListSelectionListeners()
  {
    return (ListSelectionListener[]) getListeners(ListSelectionListener.class);
  }

  public int getSelectionMode()
  {
    return selectionModel.getSelectionMode();
  }
  
  /**
   * Sets the list's "selectionMode" property, which simply mirrors the
   * same property on the list's {@link #selectionModel} property. This
   * property should be one of the integer constants
   * <code>SINGLE_SELECTION</code>, <code>SINGLE_INTERVAL_SELECTION</code>,
   * or <code>MULTIPLE_INTERVAL_SELECTION</code> from the {@link
   * ListSelectionModel} interface.
   *
   * @param a The new selection mode
   */
  public void setSelectionMode(int a)
  {
    selectionModel.setSelectionMode(a);
  }

  /**
   * Adds the interval <code>[a,a]</code> to the set of selections managed
   * by this list's {@link #selectionModel} property. Depending on the
   * selection mode, this may cause existing selections to become invalid,
   * or may simply expand the set of selections. 
   *
   * @param a A number in the half-open range <code>[0, x)</code> where
   * <code>x = getModel.getSize()</code>, indicating the index of an
   * element in the list to select.
   *
   * @see #setSelectionMode
   * @see #selectionModel
   */
  public void setSelectedIndex(int a)
  {
    selectionModel.setSelectionInterval(a, a);
  }

  /**
   * For each element <code>a[i]</code> of the provided array
   * <code>a</code>, calls {@link #setSelectedIndex} on <code>a[i]</code>.
   *
   * @see #setSelectionMode
   * @see #selectionModel
   */
  public void setSelectedIndices(int [] a)
  {
    for (int i = 0; i < a.length; ++i)
      setSelectedIndex(a[i]);
  }

  /**
   * Returns the minimum index of an element in the list which is currently
   * selected.
   *
   * @return A number in the half-open range <code>[0, x)</code> where
   * <code>x = getModel.getSize()</code>, indicating the minimum index of
   * an element in the list for which the element is selected, or
   * <code>-1</code> if no elements are selected
   */
  public int getSelectedIndex()
  {
    return selectionModel.getMinSelectionIndex();
  }

  /**
   * Returns <code>true</code> if the model's selection is empty, otherwise
   * <code>false</code>. 
   *
   * @return The return value of {@link ListSelectionModel#isSelectionEmpty}
   */
  public boolean isSelectionEmpty()
  {
    return selectionModel.isSelectionEmpty();
  }

  /**
   * Returns the list index of the upper left or upper right corner of the
   * {@link #visibleRect} property, depending on the {@link
   * #componentOrientation} property.
   *
   * @return The index of the first visible list cell, or <code>-1</code>
   * if none is visible.
   */
  public int getFirstVisibleIndex()
  {
    ComponentOrientation or = getComponentOrientation();
    Rectangle r = getVisibleRect();
    if (or == ComponentOrientation.RIGHT_TO_LEFT)
      r.translate((int) r.getWidth(), 0);
    return getUI().locationToIndex(this, r.getLocation());      
  }


  /**
   * Returns index of the cell to which specified location is closest to
   * @param location for which to look for in the list
   * 
   * @return index of the cell to which specified location is closest to.
   */
   public int locationToIndex(Point location) {
     return getUI().locationToIndex(this, location);      
   }

  /**
   * Returns location of the cell located at the specified index in the list.
   * @param index of the cell for which location will be determined
   * 
   * @return location of the cell located at the specified index in the list.
   */
   public Point indexToLocation(int index){
   	//FIXME: Need to implement.
	return null;
   }

  /**
   * Returns the list index of the lower right or lower left corner of the
   * {@link #visibleRect} property, depending on the {@link
   * #componentOrientation} property.
   *
   * @return The index of the first visible list cell, or <code>-1</code>
   * if none is visible.
   */
  public int getLastVisibleIndex()
  {
    ComponentOrientation or = getComponentOrientation();
    Rectangle r = getVisibleRect();
    r.translate(0, (int) r.getHeight());
    if (or == ComponentOrientation.LEFT_TO_RIGHT)
      r.translate((int) r.getWidth(), 0);
    return getUI().locationToIndex(this, r.getLocation());      
  }

  /**
   * Returns the indices of values in the {@link #model} property which are
   * selected.
   *
   * @return An array of model indices, each of which is selected according
   * to the {@link #selection} property
   */
  public int[] getSelectedIndices()
  {
    int lo, hi, n, i, j;
    if (selectionModel.isSelectionEmpty())
      return new int[0];
    lo = selectionModel.getMinSelectionIndex();
    hi = selectionModel.getMaxSelectionIndex();
    n = 0;
    for (i = lo; i < hi; ++i)
      if (selectionModel.isSelectedIndex(i))
        n++;
    int [] v = new int[n];
    j = 0;
    for (i = lo; i < hi; ++i)
      if (selectionModel.isSelectedIndex(i))
        v[j++] = i;
    return v;
  }

  /**
   * Indicates whether the list element at a given index value is
   * currently selected.
   *
   * @param a The index to check 
   * @return <code>true</code> if <code>a</code> is the index of a selected
   * list element
   */
  public boolean isSelectedIndex(int a)
  {
    return selectionModel.isSelectedIndex(a);
  }

  /**
   * Returns the first value in the list's {@link #model} property which is
   * selected, according to the list's {@link #selectionModel} property.
   * This is equivalent to calling
   * <code>getModel()getElementAt(getSelectedIndex())</code>, with a check
   * for the special index value of <code>-1</code> which returns null
   * <code>null</code>.
   *
   * @return The first selected element, or <code>null</code> if no element
   * is selected.
   *
   * @see getSelectedValues
   */
  public Object getSelectedValue()
  {
    int index = getSelectedIndex();
    if (index == -1)
      return null;
    return getModel().getElementAt(index);
  }

  /**
   * Returns all the values in the list's {@link #model} property which
   * are selected, according to the list's {@link #selectionModel} property.
   *
   * @return An array containing all the selected values
   *
   * @see getSelectedValue
   */
  public Object[] getSelectedValues()
  {
    int [] idx = getSelectedIndices();
    Object [] v = new Object[idx.length];
    for (int i = 0; i < idx.length; ++i)
      v[i] = getModel().getElementAt(i);
    return v;
  }

  /**
   * Gets the value of the {@link #selectionBackground} property.
   *
   * @return The current value of the property
   */
  public Color getSelectionBackground()
  {
    return selectionBackground;
  }

  /**
   * Sets the value of the {@link #selectionBackground} property.
   *
   * @param c The new value of the property
   */
  public void setSelectionBackground(Color c)
  {
    if (selectionBackground == c)
      return;

    Color old = selectionBackground;
    selectionBackground = c;
    firePropertyChange("selectionBackground", old, c);
    repaint();
  }

  /**
   * Gets the value of the {@link #selectionForeground} property.
   *
   * @return The current value of the property
   */
  public Color getSelectionForeground()
  {
    return selectionForeground;
  }
  
  /**
   * Sets the value of the {@link #selectionForeground} property.
   *
   * @param c The new value of the property
   */
  public void setSelectionForeground(Color c)
  {
    if (selectionForeground == c)
      return;

    Color old = selectionForeground;
    selectionForeground = c;
    firePropertyChange("selectionForeground", old, c);
  }

  /**
   * Sets the selection to cover only the specified value, if it
   * exists in the model. 
   *
   * @param obj The object to select
   * @param scroll Whether to scroll the list to make the newly selected
   * value visible
   *
   * @see #ensureIndexIsVisible
   */

  public void setSelectedValue(Object obj, boolean scroll)
  {
    for (int i = 0; i < model.getSize(); ++i)
      {
        if (model.getElementAt(i).equals(obj))
          {
            setSelectedIndex(i);
            if (scroll)
              ensureIndexIsVisible(i);
            break;
          }
      }
  }

  /**
   * Scrolls this list to make the specified cell visible. This
   * only works if the list is contained within a viewport.
   *
   * @param i The list index to make visible
   *
   * @see JComponent#scrollRectToVisible
   */
  public void ensureIndexIsVisible(int i)
  {
    scrollRectToVisible(getUI().getCellBounds(this, i, i));
  }

  /**
   * Sets the {@link #model} property of the list to a new anonymous
   * {@link AbstractListModel} subclass which accesses the provided Object
   * array directly.
   *
   * @param listData The object array to build a new list model on
   * @see #setModel
   */
  public void setListData(final Object[] listData)
  {
    setModel(new AbstractListModel()
        {
          public int getSize()
          {
            return listData.length;
          }

          public Object getElementAt(int i)
          {
            return listData[i];
          }
        });
  }

  /**
   * Sets the {@link #model} property of the list to a new anonymous {@link
   * AbstractListModel} subclass which accesses the provided vector
   * directly.
   *
   * @param listData The object array to build a new list model on
   * @see #setModel
   */
  public void setListData(final Vector listData)
  {
    setModel(new AbstractListModel()
        {
          public int getSize()
          {
            return listData.size();
          }

          public Object getElementAt(int i)
          {
            return listData.elementAt(i);
          }
        });
  }

  /**
   * Gets the value of the {@link #cellRenderer} property. 
   *
   * @return The current value of the property
   */
  public ListCellRenderer getCellRenderer()
  {
    return cellRenderer;
  }

  /**
   * Sets the value of the {@link #celLRenderer} property.
   *
   * @param renderer The new property value
   */
  public void setCellRenderer(ListCellRenderer renderer)
  {
    if (cellRenderer == renderer)
      return;
    
    ListCellRenderer old = cellRenderer;
    cellRenderer = renderer;
    firePropertyChange("cellRenderer", old, renderer);
    revalidate();
    repaint();
  }

  /**
   * Gets the value of the {@link #model} property. 
   *
   * @return The current value of the property
   */
  public ListModel getModel()
  {
    return model;
  }

  /**
   * Sets the value of the {@link #model} property. The list's {@link
   * #listListener} is unsubscribed from the existing model, if it exists,
   * and re-subscribed to the new model.
   *
   * @param model The new property value
   */
  public void setModel(ListModel model)
  {
    if (this.model == model)
      return;
    
    if (this.model != null)
      this.model.removeListDataListener(listListener);
    
    ListModel old = this.model;
    this.model = model;
    
    if (this.model != null)
      this.model.addListDataListener(listListener);
    
    firePropertyChange("model", old, model);
    revalidate();
    repaint();
  }


  public ListSelectionModel getSelectionModel()
  {
    return selectionModel;
  }

  /**
   * Sets the value of the {@link #selectionModel} property. The list's
   * {@link #listListener} is unsubscribed from the existing selection
   * model, if it exists, and re-subscribed to the new selection model.
   *
   * @param model The new property value
   */
  public void setSelectionModel(ListSelectionModel model)
  {
    if (selectionModel == model)
      return;
    
    if (selectionModel != null)
      selectionModel.removeListSelectionListener(listListener);
    
    ListSelectionModel old = selectionModel;
    selectionModel = model;
    
    if (selectionModel != null)
      selectionModel.addListSelectionListener(listListener);
    
    firePropertyChange("selectionModel", old, model);
    revalidate();
    repaint();
  }

  /**
   * Gets the value of the UI property.
   *
   * @return The current property value
   */
  public ListUI getUI()
  {
    return (ListUI) ui;
  }

  /**
   * Sets the value of the UI property.
   *
   * @param ui The new property value
   */
  public void setUI(ListUI ui)
  {
    super.setUI(ui);
  }

  /**
   * Calls {@link #setUI} with the {@link ListUI} subclass
   * returned from calling {@link UIManager#getUI}.
   */
  public void updateUI()
  {
    setUI((ListUI) UIManager.getUI(this));
  }

  /**
   * Return the class identifier for the list's UI property.  This should
   * be the constant string <code>"ListUI"</code>, and map to an
   * appropriate UI class in the {@link UIManager}.
   *
   * @return The class identifier
   */
  public String getUIClassID()
  {
    return "ListUI";
  }


  /**
   * Returns the current value of the {@link #prototypeCellValue}
   * property. This property holds a reference to a "prototype" data value
   * -- typically a String -- which is used to calculate the {@link
   * #fixedCellWidth} and {@link #fixedCellHeight} properties, using the
   * {@link #cellRenderer} property to acquire a component to render the
   * prototype.
   *
   * @return The current prototype cell value
   * @see #setPrototypeCellValue
   */
  public Object getPrototypeCellValue()
  {
    return prototypeCellValue;
  }

  /**
   * <p>Set the {@link #prototypeCellValue} property. This property holds a
   * reference to a "prototype" data value -- typically a String -- which
   * is used to calculate the {@link #fixedCellWidth} and {@link
   * #fixedCellHeight} properties, using the {@link #cellRenderer} property
   * to acquire a component to render the prototype.</p>
   *
   * <p>It is important that you <em>not</em> set this value to a
   * component. It has to be a <em>data value</em> such as the objects you
   * would find in the list's model. Setting it to a component will have
   * undefined (and undesirable) affects. </p>
   *
   * @param obj The new prototype cell value
   * @see #getPrototypeCellValue
   */
  public void setPrototypeCellValue(Object obj)
  {
    if (prototypeCellValue == obj)
      return;

    Object old = prototypeCellValue;
    Component comp = getCellRenderer()
      .getListCellRendererComponent(this, obj, 0, false, false); 
    Dimension d = comp.getPreferredSize();
    fixedCellWidth = d.width;
    fixedCellHeight = d.height;
    prototypeCellValue = obj;
    firePropertyChange("prototypeCellValue", old, obj);
  }

  public AccessibleContext getAccessibleContext()
  {
    return null;
  }

  /**
   * Returns a size indicating how much space this list would like to
   * consume, when contained in a scrollable viewport. This is part of the
   * {@link Scrollable} interface, which interacts with {@link
   * ScrollPaneLayout} and {@link Viewport} to define scrollable objects.
   *
   * @return The preferred size
   */
  public Dimension getPreferredScrollableViewportSize()
  {
    int vis = getVisibleRowCount();
    int nrows = getModel() == null ? 0 : getModel().getSize();
    // FIXME: this is a somewhat arbitrary default, but.. ?
    Dimension single = new Dimension(10, 10);;
    Rectangle bounds = null;

    if (vis > nrows)
      {
        if (fixedCellWidth != -1 && 
            fixedCellHeight != -1)
          {
            single = new Dimension(fixedCellWidth, fixedCellHeight);
          }
        else if (nrows != 0 && getUI() != null)
          {
            Rectangle tmp = getUI().getCellBounds(this, 0, 0);
            if (tmp != null)
              single = tmp.getSize();
          }
      }
    else if (getUI() != null)
      {
        return getUI().getCellBounds(this, 0, vis - 1).getSize();
      }

    return new Dimension(single.width, single.height * vis);
  }

  /**
   * <p>Return the number of pixels the list must scroll in order to move a
   * "unit" of the list into the provided visible rectangle. When the
   * provided direction is positive, the call describes a "downwards"
   * scroll, which will be exposing a cell at a <em>greater</em> index in
   * the list than those elements currently showing. Then the provided
   * direction is negative, the call describes an "upwards" scroll, which
   * will be exposing a cell at a <em>lesser</em> index in the list than
   * those elements currently showing.</p>
   *
   * <p>If the provided orientation is <code>HORIZONTAL</code>, the above
   * comments refer to "rightwards" for positive direction, and "leftwards"
   * for negative.</p>
   * 
   *
   * @param visibleRect The rectangle to scroll an element into
   * @param orientation One of the numeric consants <code>VERTICAL</code>
   * or <code>HORIZONTAL</code>
   * @param direction An integer indicating the scroll direction: positive means
   * forwards (down, right), negative means backwards (up, left)
   *
   * @return The scrollable unit increment, in pixels
   */
  public int getScrollableUnitIncrement(Rectangle visibleRect,
                                        int orientation, int direction)
  {
    ListUI lui = this.getUI();
    if (orientation == SwingConstants.VERTICAL)
      {
        if (direction > 0)
          {
            // Scrolling down
            Point bottomLeft = new Point(visibleRect.x,
                                         visibleRect.y + visibleRect.height);
            int curIdx = lui.locationToIndex(this, bottomLeft);
            Rectangle curBounds = lui.getCellBounds(this, curIdx, curIdx);
            if (curBounds.y + curBounds.height == bottomLeft.y)
              {
                // we are at the exact bottom of the current cell, so we 
                // are being asked to scroll to the end of the next one
                if (curIdx + 1 < model.getSize())
                  {
                    // there *is* a next item in the list
                    Rectangle nxtBounds = lui.getCellBounds(this, curIdx + 1, curIdx + 1);
                    return nxtBounds.height;
                  }
                else
                  {
                    // no next item, no advance possible
                    return 0;
                  }
              }
            else
              {
                // we are part way through an existing cell, so we are being
                // asked to scroll to the bottom of it
                return (curBounds.y + curBounds.height) - bottomLeft.y;
              }		      
          }
        else
          {
            // scrolling up
            Point topLeft = new Point(visibleRect.x, visibleRect.y);
            int curIdx = lui.locationToIndex(this, topLeft);
            Rectangle curBounds = lui.getCellBounds(this, curIdx, curIdx);
            if (curBounds.y == topLeft.y)
              {
                // we are at the exact top of the current cell, so we 
                // are being asked to scroll to the top of the previous one
                if (curIdx > 0)
                  {
                    // there *is* a previous item in the list
                    Rectangle nxtBounds = lui.getCellBounds(this, curIdx - 1, curIdx - 1);
                    return -nxtBounds.height;
                  }
                else
                  {
                    // no previous item, no advance possible
                    return 0;
                  }
              }
            else
              {
                // we are part way through an existing cell, so we are being
                // asked to scroll to the top of it
                return curBounds.y - topLeft.y;
              }		      
          }
      }

    // FIXME: handle horizontal scrolling (also wrapping?)
    return 1;
  }

  /**
   * <p>Return the number of pixels the list must scroll in order to move a
   * "block" of the list into the provided visible rectangle. When the
   * provided direction is positive, the call describes a "downwards"
   * scroll, which will be exposing a cell at a <em>greater</em> index in
   * the list than those elements currently showing. Then the provided
   * direction is negative, the call describes an "upwards" scroll, which
   * will be exposing a cell at a <em>lesser</em> index in the list than
   * those elements currently showing.</p>
   *
   * <p>If the provided orientation is <code>HORIZONTAL</code>, the above
   * comments refer to "rightwards" for positive direction, and "leftwards"
   * for negative.</p>
   * 
   *
   * @param visibleRect The rectangle to scroll an element into
   * @param orientation One of the numeric consants <code>VERTICAL</code>
   * or <code>HORIZONTAL</code>
   * @param direction An integer indicating the scroll direction: positive means
   * forwards (down, right), negative means backwards (up, left)
   *
   * @return The scrollable unit increment, in pixels
   */
  public int getScrollableBlockIncrement(Rectangle visibleRect,
                                         int orientation, int direction)
  {
      if (orientation == VERTICAL)
	  return visibleRect.height * direction;
      else
	  return visibleRect.width * direction;
  }

  /**
   * Gets the value of the {@link #scrollableTracksViewportWidth} property.
   *
   * @return <code>true</code> if the viewport is larger (horizontally)
   * than the list and the list should be expanded to fit the viewport;
   * <code>false</code> if the viewport is smaller than the list and the
   * list should scroll (horizontally) within the viewport
   */
  public boolean getScrollableTracksViewportWidth()
  {
    return false;
  }

  /**
   * Gets the value of the {@link #scrollableTracksViewportWidth} property.
   *
   * @return <code>true</code> if the viewport is larger (vertically)
   * than the list and the list should be expanded to fit the viewport;
   * <code>false</code> if the viewport is smaller than the list and the
   * list should scroll (vertically) within the viewport
   */
  public boolean getScrollableTracksViewportHeight()
  {
    return false;
  }

  public int getAnchorSelectionIndex()
  {
    return selectionModel.getAnchorSelectionIndex();
  }

  public int getLeadSelectionIndex()
  {
    return selectionModel.getLeadSelectionIndex();
  }

  public int getMinSelectionIndex()
  {
    return selectionModel.getMaxSelectionIndex();
  }

  public int getMaxSelectionIndex()
  {
    return selectionModel.getMaxSelectionIndex();
  }

  public void clearSelection()
  {
    selectionModel.clearSelection();
  }

  public void setSelectionInterval(int anchor, int lead)
  {
    selectionModel.setSelectionInterval(anchor, lead);
  }

  public void addSelectionInterval(int anchor, int lead)
  {
    selectionModel.addSelectionInterval(anchor, lead);
  }

  public void removeSelectionInterval(int index0, int index1)
  {
    selectionModel.removeSelectionInterval(index0, index1);
  }

  /**
   * Returns the value of the <code>valueIsAdjusting</code> property.
   *
   * @return the value
   */
  public boolean getValueIsAdjusting()
  {
    return valueIsAdjusting;
  }

  /**
   * Sets the <code>valueIsAdjusting</code> property.
   *
   * @param isAdjusting the new value
   */
  public void setValueIsAdjusting(boolean isAdjusting)
  {
    valueIsAdjusting = isAdjusting;
  }

  /**
   * Return the value of the <code>dragEnabled</code> property.
   *
   * @return the value
   * 
   * @since 1.4
   */
  public boolean getDragEnabled()
  {
    return dragEnabled;
  }

  /**
   * Set the <code>dragEnabled</code> property.
   *
   * @param enabled new value
   * 
   * @since 1.4
   */
  public void setDragEnabled(boolean enabled)
  {
    dragEnabled = enabled;
  }

  /**
   * Returns the layout orientation.
   *
   * @return the orientation, one of <code>JList.VERTICAL</code>,
   * <code>JList.VERTICAL_WRAP</code> and <code>JList.HORIZONTAL_WRAP</code>
   *
   * @since 1.4
   */
  public int getLayoutOrientation()
  {
    return layoutOrientation;
  }

  /**
   * Sets the layout orientation.
   *
   * @param orientation the orientation to set, one of <code>JList.VERTICAL</code>,
   * <code>JList.VERTICAL_WRAP</code> and <code>JList.HORIZONTAL_WRAP</code>
   *
   * @since 1.4
   */
  public void setLayoutOrientation(int orientation)
  {
    if (layoutOrientation == orientation)
      return;

    int old = layoutOrientation;
    layoutOrientation = orientation;
    firePropertyChange("layoutOrientation", old, orientation);
  }
}
