/* DefaultListModel.java --
   Copyright (C) 2002, 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., 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.util.Enumeration;
import java.util.Vector;

/**
 * The default implementation of {@link AbstractListModel}, used by
 * {@link javax.swing.JList} and similar objects as the model of a list of
 * values. The implementation is based on an underlying {@link
 * java.util.Vector}.
 *
 * @author Andrew Selkirk
 * @author Graydon Hoare (graydon@redhat.com)
 */

public class DefaultListModel extends AbstractListModel
{
  private static final long serialVersionUID = 2315945659722172272L;

  /**
   * The vector of elements in this list model.
   */
  private Vector elements = new Vector();

  /**
   * Gets an element of the list at the provided index.
   *
   * @param index The index of the element to get
   *
   * @return The object at the given index
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   *     outside the bounds of the list <code>[0, size())</code>
   */
  public Object elementAt(int index)
  {
    return elements.elementAt(index);
  }

  /**
   * Convert the list to a string representation.
   *
   * @return A string representation of the list
   */
  public String toString()
  {
    return elements.toString();
  }

  /**
   * Gets the first index of a particular element in the list.
   *
   * @param element The element to search for
   *
   * @return The first index in the list at which an object
   *     <code>obj</code> exists such that <code>obj.equals(element)</code> is
   *     <code>true</code>; if no such object exists, the method returns
   *     <code>-1</code>
   */
  public int indexOf(Object element)
  {
    return elements.indexOf(element);
  }

  /**
   * Gets the first index of a particular element in a list which occurs
   * <em>at or after</em> a particular index.
   *
   * @param element The element to search for
   * @param startIndex The index to begin searching at
   *
   * @return The first index in the list, greater than or equal to
   *     <code>startIndex</code>, at which an object <code>obj</code> exists
   *     such that <code>obj.equals(element)</code> is <code>true</code>; if no
   *     such object exists, the method returns <code>-1</code>
   */
  public int indexOf(Object element, int startIndex)
  {
    return elements.indexOf(element, startIndex);
  }

  /**
   * Gets the last index of a particular element in the list.
   *
   * @param element The element to search for
   *
   * @return The last index in the list at which an object
   *     <code>obj</code> exists such that <code>obj.equals(element)</code> is
   *     <code>true</code>; if no such object exists, the method returns
   *     <code>-1</code>
   */
  public int lastIndexOf(Object element)
  {
    return elements.lastIndexOf(element);
  }

  /**
   * Gets the last index of a particular element in a list which occurs
   * <em>at or before</em> a particular index.
   *
   * @param element The element to search for
   * @param endIndex The index to finish searching at
   *
   * @return The last index in the list, less than to or equal to
   *     <code>endIndexIndex</code>, at which an object <code>obj</code> exists
   *     such that <code>obj.equals(element)</code> is <code>true</code>; if no
   *     such object exists, the method returns <code>-1</code>
   */
  public int lastIndexOf(Object element, int endIndex)
  {
    return elements.lastIndexOf(element, endIndex);
  }

  /**
   * Gets the list element at a particular index.
   *
   * @param index The index to get the list value at
   *
   * @return The list value at the provided index
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   *     outside the bounds of the list <code>[0, size())</code>
   */
  public Object get(int index)
  {
    return elements.get(index);
  }

  /**
   * Sets the list element at a particular index.
   *
   * @param index The list index at which to set a value 
   * @param element The value to set at the specified index
   *
   * @return The value previously held at the specified index
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   *     outside the bounds of the list <code>[0, size())</code>
   */
  public Object set(int index, Object element)
  {
    Object result;
    result = elements.set(index, element);
    fireContentsChanged(this, index, index);
    return result;
  }

  /**
   * Inserts an element at a particular index in the list. Each element at
   * index <code>i >= index</code> is shifted to position <code>i + 1</code>.
   * If <code>index</code> is equal to <code>size()</code>, this is
   * equivalent to appending an element to the array. Any
   * <code>index</code> greater than <code>size()</code> is illegal.
   *
   * @param index The index to insert the element at
   * @param element The element to insert at the index
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   *     outside the bounds <code>[0, size()]</code>
   */
  public void add(int index, Object element)
  {
    elements.add(index, element);
    fireIntervalAdded(this, index, index);
  }

  /**
   * Inserts an element at the end of the list. This is equivalent to
   * calling <code>list.add(list.size(), element)</code>.
   *
   * @param element The element to add to the list
   */
  public void addElement(Object element)
  {
    int s = elements.size();
    elements.add(element);
    fireIntervalAdded(this, s, s);
  }

  /**
   * Gets the number of elements in the list.
   *
   * @return The number of elements in the list
   */
  public int size()
  {
    return elements.size();
  }

  /**
   * Gets an array containing the elements of the list.
   *
   * @return An array of the objects in the list, in the order they occur
   *     in the list
   */
  public Object[] toArray()
  {
    return elements.toArray();
  }

  /**
   * Determines whether a particular element is a member of the list.
   *
   * @param element The element to search for
   *
   * @return <code>true</code> if <code>element</code> is a member of the
   *     list, otherwise <code>false</code>
   */
  public boolean contains(Object element)
  {
    return elements.contains(element);
  }

  /**
   * Copies the list into a provided array. The provided array must be at
   * least as large as the list.
   *
   * @param array The array to copy the list into
   * 
   * @throws IndexOutOfBoundsException if the array is too small to hold the
   *     elements of the list
   */
  public void copyInto(Object[] array)
  {
    elements.copyInto(array);
  }

  /**
   * Erases all the elements of the list, setting the list's size to 0.
   */
  public void clear()
  {
    int s = elements.size();
    if (s > 0)
    {
      elements.clear();
      fireIntervalRemoved(this, 0, s - 1);
    }
  }

  /**
   * Removes the element at a particular index from the list.
   *
   * @param index The index of the element to remove
   *
   * @return The value at the index, which has been removed from the list
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   *     outside the bounds of the list <code>[0, size())</code>
   */
  public Object remove(int index)
  {
    Object result;
    result = elements.remove(index);
    fireIntervalRemoved(this, index, index);
    return result;
  }

  /**
   * Determines whether the list is empty.
   *
   * @return <code>true</code> if the list is empty, otherwise
   *     <code>false</code>
   */
  public boolean isEmpty()
  {
    return elements.isEmpty();
  }

  /**
   * Returns an {@link java.util.Enumeration} over the elements of the list.
   *
   * @return A new enumeration which iterates over the list
   */
  public Enumeration elements()
  {
    return elements.elements();
  }

  /**
   * Sets the capacity of the list to be equal to its size. The list's capacity
   * is the number of elements it can hold before it needs to be reallocated.
   * The list's size is the number of elements it currently holds. 
   */
  public void trimToSize()
  {
    elements.trimToSize();
  }

  /**
   * Ensures that the list's capacity is at least equal to
   * <code>size</code>. The list's capacity is the number of elements it
   * can hold before it needs to be reallocated.
   *
   * @param size The capacity to ensure the list can hold
   */
  public void ensureCapacity(int size)
  {
    elements.ensureCapacity(size);
  }

  /**
   * Sets the size of the list to a particular value. If the specified size
   * is greater than the current size, the values at the excess list
   * indices are set to <code>null</code>.  If the specified size is less
   * than the current size, the excess elements are removed from the list.
   *
   * @param size The new size to set the list to
   */
  public void setSize(int size)
  {
    int oldSize = elements.size();
    elements.setSize(size);
    if (oldSize < size)
      {
        fireIntervalAdded(this, oldSize, size - 1);
      }
    else if (oldSize > size)
      {
        this.fireIntervalRemoved(this, size, oldSize - 1);
      }
  }

  /**
   * Gets the capacity of the list. The list's capacity is the number of
   * elements it can hold before it needs to be reallocated. 
   *
   * @return The capacity of the list
   */
  public int capacity()
  {
    return elements.capacity();
  }

  /**
   * Gets the first element in the list.
   *
   * @return The first element in the list
   */
  public Object firstElement()
  {
    return elements.firstElement();
  }

  /**
   * Gets the last element in the list.
   *
   * @return The last element in the list
   */
  public Object lastElement()
  {
    return elements.lastElement();
  }

  /**
   * Sets the list element at a particular index.
   *
   * @param element The value to set at the specified index
   * @param index The list index at which to set a value 
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   *     outside the bounds of the list <code>[0, size())</code>
   */
  public void setElementAt(Object element, int index)
  {
    elements.setElementAt(element, index);
    fireContentsChanged(this, index, index);
  }

  /**
   * Removes the element at a particular index from the list.
   *
   * @param index The index of the element to remove
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   *     outside the bounds of the list <code>[0, size())</code>
   */
  public void removeElementAt(int index)
  {
    elements.remove(index);
    fireIntervalRemoved(this, index, index);
  }

  /**
   * Inserts an element at a particular index in the list. Each element at
   * index <code>i >= index</code> is shifted to position <code>i + 1</code>.
   * If <code>index</code> is equal to <code>size()</code>, this is
   * equivalent to appending an element to the array. Any
   * <code>index</code> greater than <code>size()</code> is illegal.
   *
   * @param element The element to insert at the index
   * @param index The index to insert the element at
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   *     outside the bounds <code>[0, size()]</code>
   */
  public void insertElementAt(Object element, int index)
  {
    elements.insertElementAt(element, index);
    fireIntervalAdded(this, index, index);
  }

  /**
   * Removes the first occurrence of a particular element in the list. If the
   * element does not exist in the list, nothing happens.
   *
   * @param element The element to remove
   *
   * @return <code>true</code> if the element existed in the list (and was
   *     removed), <code>false</code> otherwise
   */
  public boolean removeElement(Object element)
  {
    int index;
    index = elements.indexOf(element);
    if (index != -1)
      {
        elements.remove(index);
        fireIntervalRemoved(this, index, index);
        return true;
      }
    return false;
  }

  /**
   * Remove all elements in the list.
   */
  public void removeAllElements()
  {
    int size;
    size = size();
    if (size > 0)
      {
        elements.clear();
        fireIntervalRemoved(this, 0, size - 1);
      }
  }

  /**
   * Remove all elements between <code>startIndex</code> and
   * <code>endIndex</code> inclusive.
   *
   * @param startIndex The first index in the range to remove
   * @param endIndex The last index in the range to remove
   *
   * @throws ArrayIndexOutOfBoundsException if either index is outside the
   *     valid range of indices for this list <code>[0, size())</code>
   * @throws IllegalArgumentException if <code>startIndex &gt; endIndex</code>
   */
  public void removeRange(int startIndex, int endIndex)
  {
    int index;
    if (startIndex > endIndex)
      throw new IllegalArgumentException();
    for (index = endIndex; index >= startIndex; index--)
      elements.remove(index);
    fireIntervalRemoved(this, startIndex, endIndex);
  }

  /**
   * Gets the size of the list.
   *
   * @return The number of elements currently in the list
   */
  public int getSize()
  {
    return elements.size();
  }

  /**
   * Gets the list element at a particular index.
   *
   * @param index The index to get the list value at
   *
   * @return The list value at the provided index
   *
   * @throws ArrayIndexOutOfBoundsException If the provided index is
   *     outside the bounds of the list <code>[0, size())</code>
   */
  public Object getElementAt(int index)
  {
    return elements.get(index);
  }
}
